@@ -139,6 +139,36 @@ bool enable_extension(const char *requested_exte
139139 return is_available;
140140}
141141
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+
142172bool enable_layer (const char *requested_layer,
143173 const std::vector<vk::LayerProperties> &available_layers,
144174 std::vector<const char *> &enabled_layers)
@@ -169,7 +199,7 @@ bool enable_layer(const char *requested_layer,
169199HPPInstance::HPPInstance (const std::string &application_name,
170200 const std::unordered_map<const char *, bool > &requested_extensions,
171201 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 ,
173203 uint32_t api_version)
174204{
175205 std::vector<vk::ExtensionProperties> available_instance_extensions = vk::enumerateInstanceExtensionProperties ();
@@ -194,14 +224,16 @@ HPPInstance::HPPInstance(const std::string &applicati
194224 bool portability_enumeration_available = enable_extension (VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME, available_instance_extensions, enabled_extensions);
195225#endif
196226
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
198230 bool validation_features = false ;
199231 {
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);
203234 }
204- #endif
235+ # endif // USE_VALIDATION_LAYER_FEATURES
236+ #endif // USE_VALIDATION_LAYERS
205237
206238 // Specific surface extensions are obtained from Window::get_required_surface_extensions
207239 // They are already added to requested_extensions by VulkanSample::prepare
@@ -257,7 +289,7 @@ HPPInstance::HPPInstance(const std::string &applicati
257289#ifdef USE_VALIDATION_LAYERS
258290 // NOTE: It's important to have the validation layer as the last one here!!!!
259291 // 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);
261293#endif
262294
263295 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
268300 .enabledExtensionCount = static_cast <uint32_t >(enabled_extensions.size ()),
269301 .ppEnabledExtensionNames = enabled_extensions.data ()};
270302
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+
271310#ifdef USE_VALIDATION_LAYERS
272311 vk::DebugUtilsMessengerCreateInfoEXT debug_utils_create_info;
273312 vk::DebugReportCallbackCreateInfoEXT debug_report_create_info;
@@ -297,31 +336,52 @@ HPPInstance::HPPInstance(const std::string &applicati
297336 }
298337#endif
299338
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.
300341#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;
303345 if (validation_features)
304346 {
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+ }
308349# endif
350+
309351# 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+ }
311365# 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);
315374 }
375+ # endif
316376#endif
317377
318378 vk::LayerSettingsCreateInfoEXT layerSettingsCreateInfo;
319379
320380 // 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 )
322382 {
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 ();
325385 layerSettingsCreateInfo.pNext = instance_info.pNext ;
326386 instance_info.pNext = &layerSettingsCreateInfo;
327387 }
0 commit comments