@@ -139,6 +139,36 @@ bool enable_extension(const char *requested_exte
139
139
return is_available;
140
140
}
141
141
142
+ bool enable_layer_setting (const vk::LayerSettingEXT &requested_layer_setting,
143
+ const std::vector<const char *> &enabled_layers,
144
+ std::vector<vk::LayerSettingEXT> &enabled_layer_settings)
145
+ {
146
+ // We are checking if the layer is available.
147
+ // Vulkan does not provide a reflection API for layer settings. Layer settings are described in each layer JSON manifest.
148
+ bool is_available =
149
+ std::ranges::any_of (enabled_layers,
150
+ [&requested_layer_setting](auto const &available_layer) { return strcmp (available_layer, requested_layer_setting.pLayerName ) == 0 ; });
151
+ if (!is_available)
152
+ {
153
+ LOGW (" Layer: {} not found. Disabling layer setting: {}" , requested_layer_setting.pLayerName , requested_layer_setting.pSettingName );
154
+ return false ;
155
+ }
156
+
157
+ bool is_already_enabled =
158
+ std::ranges::any_of (enabled_layer_settings,
159
+ [&requested_layer_setting](VkLayerSettingEXT const &enabled_layer_setting) { return (strcmp (requested_layer_setting.pLayerName , enabled_layer_setting.pLayerName ) == 0 ) && (strcmp (requested_layer_setting.pSettingName , enabled_layer_setting.pSettingName ) == 0 ); });
160
+
161
+ if (is_already_enabled)
162
+ {
163
+ LOGW (" Ignoring duplicated layer setting {} in layer {}." , requested_layer_setting.pSettingName , requested_layer_setting.pLayerName );
164
+ return false ;
165
+ }
166
+
167
+ LOGI (" Enabling layer setting {} in layer {}." , requested_layer_setting.pSettingName , requested_layer_setting.pLayerName );
168
+ enabled_layer_settings.push_back (requested_layer_setting);
169
+ return true ;
170
+ }
171
+
142
172
bool enable_layer (const char *requested_layer,
143
173
const std::vector<vk::LayerProperties> &available_layers,
144
174
std::vector<const char *> &enabled_layers)
@@ -169,7 +199,7 @@ bool enable_layer(const char *requested_layer,
169
199
HPPInstance::HPPInstance (const std::string &application_name,
170
200
const std::unordered_map<const char *, bool > &requested_extensions,
171
201
const std::unordered_map<const char *, bool > &requested_layers,
172
- const std::vector<vk::LayerSettingEXT> &required_layer_settings ,
202
+ const std::vector<vk::LayerSettingEXT> &requested_layer_settings ,
173
203
uint32_t api_version)
174
204
{
175
205
std::vector<vk::ExtensionProperties> available_instance_extensions = vk::enumerateInstanceExtensionProperties ();
@@ -194,14 +224,16 @@ HPPInstance::HPPInstance(const std::string &applicati
194
224
bool portability_enumeration_available = enable_extension (VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME, available_instance_extensions, enabled_extensions);
195
225
#endif
196
226
197
- #ifdef USE_VALIDATION_LAYER_FEATURES
227
+ #ifdef USE_VALIDATION_LAYERS
228
+ const char *validation_layer_name = " VK_LAYER_KHRONOS_validation" ;
229
+ # ifdef USE_VALIDATION_LAYER_FEATURES
198
230
bool validation_features = false ;
199
231
{
200
- std::vector<vk::ExtensionProperties> available_layer_instance_extensions = vk::enumerateInstanceExtensionProperties (std::string (" VK_LAYER_KHRONOS_validation" ));
201
-
202
- enable_extension (VK_EXT_VALIDATION_FEATURES_EXTENSION_NAME, available_layer_instance_extensions, enabled_extensions);
232
+ std::vector<vk::ExtensionProperties> available_layer_instance_extensions = vk::enumerateInstanceExtensionProperties (std::string (validation_layer_name));
233
+ validation_features = enable_extension (VK_EXT_LAYER_SETTINGS_EXTENSION_NAME, available_layer_instance_extensions, enabled_extensions);
203
234
}
204
- #endif
235
+ # endif // USE_VALIDATION_LAYER_FEATURES
236
+ #endif // USE_VALIDATION_LAYERS
205
237
206
238
// Specific surface extensions are obtained from Window::get_required_surface_extensions
207
239
// They are already added to requested_extensions by VulkanSample::prepare
@@ -257,7 +289,7 @@ HPPInstance::HPPInstance(const std::string &applicati
257
289
#ifdef USE_VALIDATION_LAYERS
258
290
// NOTE: It's important to have the validation layer as the last one here!!!!
259
291
// Otherwise, device creation fails !?!
260
- enable_layer (" VK_LAYER_KHRONOS_validation " , supported_layers, enabled_layers);
292
+ enable_layer (validation_layer_name , supported_layers, enabled_layers);
261
293
#endif
262
294
263
295
vk::ApplicationInfo app_info{.pApplicationName = application_name.c_str (), .pEngineName = " Vulkan Samples" , .apiVersion = api_version};
@@ -268,6 +300,13 @@ HPPInstance::HPPInstance(const std::string &applicati
268
300
.enabledExtensionCount = static_cast <uint32_t >(enabled_extensions.size ()),
269
301
.ppEnabledExtensionNames = enabled_extensions.data ()};
270
302
303
+ std::vector<vk::LayerSettingEXT> enabled_layer_settings;
304
+
305
+ for (const vk::LayerSettingEXT &layer_setting : requested_layer_settings)
306
+ {
307
+ enable_layer_setting (layer_setting, enabled_layers, enabled_layer_settings);
308
+ }
309
+
271
310
#ifdef USE_VALIDATION_LAYERS
272
311
vk::DebugUtilsMessengerCreateInfoEXT debug_utils_create_info;
273
312
vk::DebugReportCallbackCreateInfoEXT debug_report_create_info;
@@ -297,31 +336,52 @@ HPPInstance::HPPInstance(const std::string &applicati
297
336
}
298
337
#endif
299
338
339
+ // Some of the specialized layers need to be enabled explicitly
340
+ // The validation layer does not need to be enabled in code and it can also be configured using the vulkan configurator.
300
341
#ifdef USE_VALIDATION_LAYER_FEATURES
301
- vk::ValidationFeaturesEXT validation_features_info;
302
- std::vector<vk::ValidationFeatureEnableEXT> enable_features{};
342
+
343
+ # if defined(VKB_VALIDATION_LAYERS_GPU_ASSISTED)
344
+ const VkBool32 setting_validate_gpuav = VK_TRUE;
303
345
if (validation_features)
304
346
{
305
- # if defined(VKB_VALIDATION_LAYERS_GPU_ASSISTED)
306
- enable_features.push_back (vk::ValidationFeatureEnableEXT::eGpuAssistedReserveBindingSlot);
307
- enable_features.push_back (vk::ValidationFeatureEnableEXT::eGpuAssisted);
347
+ enable_layer_setting (vk::LayerSettingEXT (validation_layer_name, " gpuav_enable" , vk::LayerSettingTypeEXT::eBool32, 1 , &setting_validate_gpuav), enabled_layers, enabled_layer_settings);
348
+ }
308
349
# endif
350
+
309
351
# if defined(VKB_VALIDATION_LAYERS_BEST_PRACTICES)
310
- enable_features.push_back (vk::ValidationFeatureEnableEXT::eBestPractices);
352
+ const VkBool32 setting_validate_best_practices = VK_TRUE;
353
+ const VkBool32 setting_validate_best_practices_arm = VK_TRUE;
354
+ const VkBool32 setting_validate_best_practices_amd = VK_TRUE;
355
+ const VkBool32 setting_validate_best_practices_img = VK_TRUE;
356
+ const VkBool32 setting_validate_best_practices_nvidia = VK_TRUE;
357
+ if (validation_features)
358
+ {
359
+ enable_layer_setting (vk::LayerSettingEXT (validation_layer_name, " validate_best_practices" , vk::LayerSettingTypeEXT::eBool32, 1 , &setting_validate_best_practices), enabled_layers, enabled_layer_settings);
360
+ enable_layer_setting (vk::LayerSettingEXT (validation_layer_name, " validate_best_practices_arm" , vk::LayerSettingTypeEXT::eBool32, 1 , &setting_validate_best_practices_arm), enabled_layers, enabled_layer_settings);
361
+ enable_layer_setting (vk::LayerSettingEXT (validation_layer_name, " validate_best_practices_amd" , vk::LayerSettingTypeEXT::eBool32, 1 , &setting_validate_best_practices_amd), enabled_layers, enabled_layer_settings);
362
+ enable_layer_setting (vk::LayerSettingEXT (validation_layer_name, " validate_best_practices_img" , vk::LayerSettingTypeEXT::eBool32, 1 , &setting_validate_best_practices_img), enabled_layers, enabled_layer_settings);
363
+ enable_layer_setting (vk::LayerSettingEXT (validation_layer_name, " validate_best_practices_nvidia" , vk::LayerSettingTypeEXT::eBool32, 1 , &setting_validate_best_practices_nvidia), enabled_layers, enabled_layer_settings);
364
+ }
311
365
# endif
312
- validation_features_info.setEnabledValidationFeatures (enable_features);
313
- validation_features_info.pNext = instance_info.pNext ;
314
- instance_info.pNext = &validation_features_info;
366
+
367
+ # if defined(VKB_VALIDATION_LAYERS_SYNCHRONIZATION)
368
+ const VkBool32 setting_validate_sync = VK_TRUE;
369
+ const VkBool32 setting_validate_sync_heuristics = VK_TRUE;
370
+ if (validation_features)
371
+ {
372
+ enable_layer_setting (vk::LayerSettingEXT (validation_layer_name, " validate_sync" , vk::LayerSettingTypeEXT::eBool32, 1 , &setting_validate_sync), enabled_layers, enabled_layer_settings);
373
+ enable_layer_setting (vk::LayerSettingEXT (validation_layer_name, " syncval_shader_accesses_heuristic" , vk::LayerSettingTypeEXT::eBool32, 1 , &setting_validate_sync_heuristics), enabled_layers, enabled_layer_settings);
315
374
}
375
+ # endif
316
376
#endif
317
377
318
378
vk::LayerSettingsCreateInfoEXT layerSettingsCreateInfo;
319
379
320
380
// If layer settings are defined, then activate the sample's required layer settings during instance creation
321
- if (required_layer_settings .size () > 0 )
381
+ if (enabled_layer_settings .size () > 0 )
322
382
{
323
- layerSettingsCreateInfo.settingCount = static_cast <uint32_t >(required_layer_settings .size ());
324
- layerSettingsCreateInfo.pSettings = required_layer_settings .data ();
383
+ layerSettingsCreateInfo.settingCount = static_cast <uint32_t >(enabled_layer_settings .size ());
384
+ layerSettingsCreateInfo.pSettings = enabled_layer_settings .data ();
325
385
layerSettingsCreateInfo.pNext = instance_info.pNext ;
326
386
instance_info.pNext = &layerSettingsCreateInfo;
327
387
}
0 commit comments