@@ -54,7 +54,7 @@ bool CapabilitiesVK::AreValidationsEnabled() const {
54
54
return enable_validations_;
55
55
}
56
56
57
- std::optional<std::vector<std::string>> CapabilitiesVK::GetRequiredLayers ()
57
+ std::optional<std::vector<std::string>> CapabilitiesVK::GetEnabledLayers ()
58
58
const {
59
59
std::vector<std::string> required;
60
60
@@ -71,7 +71,7 @@ std::optional<std::vector<std::string>> CapabilitiesVK::GetRequiredLayers()
71
71
}
72
72
73
73
std::optional<std::vector<std::string>>
74
- CapabilitiesVK::GetRequiredInstanceExtensions () const {
74
+ CapabilitiesVK::GetEnabledInstanceExtensions () const {
75
75
std::vector<std::string> required;
76
76
77
77
if (!HasExtension (" VK_KHR_surface" )) {
@@ -150,9 +150,29 @@ CapabilitiesVK::GetRequiredInstanceExtensions() const {
150
150
return required;
151
151
}
152
152
153
- std::optional<std::vector<std::string>>
154
- CapabilitiesVK::GetRequiredDeviceExtensions (
155
- const vk::PhysicalDevice& physical_device) const {
153
+ static const char * GetDeviceExtensionName (OptionalDeviceExtensionVK ext) {
154
+ switch (ext) {
155
+ case OptionalDeviceExtensionVK::kEXTPipelineCreationFeedback :
156
+ return VK_EXT_PIPELINE_CREATION_FEEDBACK_EXTENSION_NAME;
157
+ case OptionalDeviceExtensionVK::kLast :
158
+ return " Unknown" ;
159
+ }
160
+ return " Unknown" ;
161
+ }
162
+
163
+ static void IterateOptionalDeviceExtensions (
164
+ const std::function<void (OptionalDeviceExtensionVK)>& it) {
165
+ if (!it) {
166
+ return ;
167
+ }
168
+ for (size_t i = 0 ;
169
+ i < static_cast <uint32_t >(OptionalDeviceExtensionVK::kLast ); i++) {
170
+ it (static_cast <OptionalDeviceExtensionVK>(i));
171
+ }
172
+ }
173
+
174
+ static std::optional<std::set<std::string>> GetSupportedDeviceExtensions (
175
+ const vk::PhysicalDevice& physical_device) {
156
176
auto device_extensions = physical_device.enumerateDeviceExtensionProperties ();
157
177
if (device_extensions.result != vk::Result::eSuccess) {
158
178
return std::nullopt;
@@ -161,21 +181,42 @@ CapabilitiesVK::GetRequiredDeviceExtensions(
161
181
std::set<std::string> exts;
162
182
for (const auto & device_extension : device_extensions.value ) {
163
183
exts.insert (device_extension.extensionName );
184
+ };
185
+
186
+ return exts;
187
+ }
188
+
189
+ std::optional<std::vector<std::string>>
190
+ CapabilitiesVK::GetEnabledDeviceExtensions (
191
+ const vk::PhysicalDevice& physical_device) const {
192
+ auto exts = GetSupportedDeviceExtensions (physical_device);
193
+
194
+ if (!exts.has_value ()) {
195
+ return std::nullopt;
164
196
}
165
197
166
- std::vector<std::string> required ;
198
+ std::vector<std::string> enabled ;
167
199
168
- if (exts. find (" VK_KHR_swapchain" ) == exts. end ()) {
200
+ if (exts-> find (" VK_KHR_swapchain" ) == exts-> end ()) {
169
201
VALIDATION_LOG << " Device does not support the swapchain extension." ;
170
202
return std::nullopt;
171
203
}
172
- required .push_back (" VK_KHR_swapchain" );
204
+ enabled .push_back (" VK_KHR_swapchain" );
173
205
174
206
// Required for non-conformant implementations like MoltenVK.
175
- if (exts. find (" VK_KHR_portability_subset" ) != exts. end ()) {
176
- required .push_back (" VK_KHR_portability_subset" );
207
+ if (exts-> find (" VK_KHR_portability_subset" ) != exts-> end ()) {
208
+ enabled .push_back (" VK_KHR_portability_subset" );
177
209
}
178
- return required;
210
+
211
+ // Enable all optional extensions if the device supports it.
212
+ IterateOptionalDeviceExtensions ([&](auto ext) {
213
+ auto ext_name = GetDeviceExtensionName (ext);
214
+ if (exts->find (ext_name) != exts->end ()) {
215
+ enabled.push_back (ext_name);
216
+ }
217
+ });
218
+
219
+ return enabled;
179
220
}
180
221
181
222
static bool HasSuitableColorFormat (const vk::PhysicalDevice& device,
@@ -227,7 +268,7 @@ static bool HasRequiredQueues(const vk::PhysicalDevice& physical_device) {
227
268
}
228
269
229
270
std::optional<vk::PhysicalDeviceFeatures>
230
- CapabilitiesVK::GetRequiredDeviceFeatures (
271
+ CapabilitiesVK::GetEnabledDeviceFeatures (
231
272
const vk::PhysicalDevice& device) const {
232
273
if (!PhysicalDeviceSupportsRequiredFormats (device)) {
233
274
VALIDATION_LOG << " Device doesn't support the required formats." ;
@@ -244,7 +285,7 @@ CapabilitiesVK::GetRequiredDeviceFeatures(
244
285
return std::nullopt;
245
286
}
246
287
247
- if (!GetRequiredDeviceExtensions (device).has_value ()) {
288
+ if (!GetEnabledDeviceExtensions (device).has_value ()) {
248
289
VALIDATION_LOG << " Device doesn't support the required queues." ;
249
290
return std::nullopt;
250
291
}
@@ -282,7 +323,7 @@ void CapabilitiesVK::SetOffscreenFormat(PixelFormat pixel_format) const {
282
323
color_format_ = pixel_format;
283
324
}
284
325
285
- bool CapabilitiesVK::SetDevice (const vk::PhysicalDevice& device) {
326
+ bool CapabilitiesVK::SetPhysicalDevice (const vk::PhysicalDevice& device) {
286
327
if (HasSuitableDepthStencilFormat (device, vk::Format::eS8Uint)) {
287
328
depth_stencil_format_ = PixelFormat::kS8UInt ;
288
329
} else if (HasSuitableDepthStencilFormat (device,
@@ -307,6 +348,21 @@ bool CapabilitiesVK::SetDevice(const vk::PhysicalDevice& device) {
307
348
.supportedOperations &
308
349
vk::SubgroupFeatureFlagBits::eArithmetic);
309
350
351
+ // Determine the optional device extensions this physical device supports.
352
+ {
353
+ optional_device_extensions_.clear ();
354
+ auto exts = GetSupportedDeviceExtensions (device);
355
+ if (!exts.has_value ()) {
356
+ return false ;
357
+ }
358
+ IterateOptionalDeviceExtensions ([&](auto ext) {
359
+ auto ext_name = GetDeviceExtensionName (ext);
360
+ if (exts->find (ext_name) != exts->end ()) {
361
+ optional_device_extensions_.insert (ext);
362
+ }
363
+ });
364
+ }
365
+
310
366
return true ;
311
367
}
312
368
@@ -348,7 +404,7 @@ bool CapabilitiesVK::SupportsCompute() const {
348
404
349
405
// |Capabilities|
350
406
bool CapabilitiesVK::SupportsComputeSubgroups () const {
351
- // Set by |SetDevice |.
407
+ // Set by |SetPhysicalDevice |.
352
408
return supports_compute_subgroups_;
353
409
}
354
410
@@ -381,4 +437,10 @@ CapabilitiesVK::GetPhysicalDeviceProperties() const {
381
437
return device_properties_;
382
438
}
383
439
440
+ bool CapabilitiesVK::HasOptionalDeviceExtension (
441
+ OptionalDeviceExtensionVK extension) const {
442
+ return optional_device_extensions_.find (extension) !=
443
+ optional_device_extensions_.end ();
444
+ }
445
+
384
446
} // namespace impeller
0 commit comments