1- /* Copyright (c) 2022-2024 , NVIDIA CORPORATION. All rights reserved.
2- * Copyright (c) 2024, Arm Limited and Contributors
1+ /* Copyright (c) 2022-2025 , NVIDIA CORPORATION. All rights reserved.
2+ * Copyright (c) 2024-2025 , Arm Limited and Contributors
33 *
44 * SPDX-License-Identifier: Apache-2.0
55 *
@@ -103,109 +103,86 @@ bool validate_layers(const std::vector<const char *> &required,
103103
104104namespace core
105105{
106- std::vector<const char *> get_optimal_validation_layers (const std::vector<vk::LayerProperties> &supported_instance_layers)
107- {
108- std::vector<std::vector<const char *>> validation_layer_priority_list =
109- {
110- // The preferred validation layer is "VK_LAYER_KHRONOS_validation"
111- {" VK_LAYER_KHRONOS_validation" },
112-
113- // Otherwise we fallback to using the LunarG meta layer
114- {" VK_LAYER_LUNARG_standard_validation" },
115-
116- // Otherwise we attempt to enable the individual layers that compose the LunarG meta layer since it doesn't exist
117- {
118- " VK_LAYER_GOOGLE_threading" ,
119- " VK_LAYER_LUNARG_parameter_validation" ,
120- " VK_LAYER_LUNARG_object_tracker" ,
121- " VK_LAYER_LUNARG_core_validation" ,
122- " VK_LAYER_GOOGLE_unique_objects" ,
123- },
124-
125- // Otherwise as a last resort we fallback to attempting to enable the LunarG core layer
126- {" VK_LAYER_LUNARG_core_validation" }};
127-
128- for (auto &validation_layers : validation_layer_priority_list)
129- {
130- if (validate_layers (validation_layers, supported_instance_layers))
131- {
132- return validation_layers;
133- }
134-
135- LOGW (" Couldn't enable validation layers (see log for error) - falling back" );
136- }
137-
138- // Else return nothing
139- return {};
140- }
141-
142106Optional<uint32_t > HPPInstance::selected_gpu_index;
143107
144108namespace
145109{
146- bool enable_extension (const char *required_ext_name ,
147- const std::vector<vk::ExtensionProperties> &available_exts ,
110+ bool enable_extension (const char *requested_extension ,
111+ const std::vector<vk::ExtensionProperties> &available_extensions ,
148112 std::vector<const char *> &enabled_extensions)
149113{
150- for (auto &avail_ext_it : available_exts)
151- {
152- if (strcmp (avail_ext_it.extensionName , required_ext_name) == 0 )
114+ bool is_available =
115+ std::any_of (available_extensions.begin (),
116+ available_extensions.end (),
117+ [&requested_extension](auto const &available_extension) { return strcmp (requested_extension, available_extension.extensionName ) == 0 ; });
118+ if (is_available)
119+ {
120+ bool is_already_enabled =
121+ std::any_of (enabled_extensions.begin (),
122+ enabled_extensions.end (),
123+ [&requested_extension](auto const &enabled_extension) { return strcmp (requested_extension, enabled_extension) == 0 ; });
124+ if (!is_already_enabled)
153125 {
154- auto it = std::find_if (enabled_extensions.begin (), enabled_extensions.end (),
155- [required_ext_name](const char *enabled_ext_name) {
156- return strcmp (enabled_ext_name, required_ext_name) == 0 ;
157- });
158- if (it != enabled_extensions.end ())
159- {
160- // Extension is already enabled
161- }
162- else
163- {
164- LOGI (" Extension {} found, enabling it" , required_ext_name);
165- enabled_extensions.emplace_back (required_ext_name);
166- }
167- return true ;
126+ LOGI (" Extension {} available, enabling it" , requested_extension);
127+ enabled_extensions.emplace_back (requested_extension);
168128 }
169129 }
130+ else
131+ {
132+ LOGI (" Extension {} not available" , requested_extension);
133+ }
170134
171- LOGI (" Extension {} not found" , required_ext_name);
172- return false ;
135+ return is_available;
173136}
174137
175- bool enable_all_extensions (const std::vector< const char *> required_ext_names ,
176- const std::vector<vk::ExtensionProperties > &available_exts ,
177- std::vector<const char *> &enabled_extensions )
138+ bool enable_layer (const char *requested_layer ,
139+ const std::vector<vk::LayerProperties > &available_layers ,
140+ std::vector<const char *> &enabled_layers )
178141{
179- using std::placeholders::_1;
142+ bool is_available =
143+ std::any_of (available_layers.begin (),
144+ available_layers.end (),
145+ [&requested_layer](auto const &available_layer) { return strcmp (requested_layer, available_layer.layerName ) == 0 ; });
146+ if (is_available)
147+ {
148+ bool is_already_enabled =
149+ std::any_of (enabled_layers.begin (),
150+ enabled_layers.end (),
151+ [&requested_layer](auto const &enabled_layer) { return strcmp (requested_layer, enabled_layer) == 0 ; });
152+ if (!is_already_enabled)
153+ {
154+ LOGI (" Layer {} available, enabling it" , requested_layer);
155+ enabled_layers.emplace_back (requested_layer);
156+ }
157+ }
158+ else
159+ {
160+ LOGI (" Layer {} not available" , requested_layer);
161+ }
180162
181- return std::all_of (required_ext_names.begin (), required_ext_names.end (),
182- std::bind (enable_extension, _1, available_exts, enabled_extensions));
163+ return is_available;
183164}
184-
185165} // namespace
186166
187167HPPInstance::HPPInstance (const std::string &application_name,
188- const std::unordered_map<const char *, bool > &required_extensions ,
189- const std::vector <const char *> &required_validation_layers ,
168+ const std::unordered_map<const char *, bool > &requested_extensions ,
169+ const std::unordered_map <const char *, bool > &requested_layers ,
190170 const std::vector<vk::LayerSettingEXT> &required_layer_settings,
191171 uint32_t api_version)
192172{
193173 std::vector<vk::ExtensionProperties> available_instance_extensions = vk::enumerateInstanceExtensionProperties ();
194174
195175#ifdef USE_VALIDATION_LAYERS
196176 // Check if VK_EXT_debug_utils is supported, which supersedes VK_EXT_Debug_Report
197- const bool has_debug_utils = enable_extension (VK_EXT_DEBUG_UTILS_EXTENSION_NAME,
198- available_instance_extensions, enabled_extensions);
177+ const bool has_debug_utils = enable_extension (VK_EXT_DEBUG_UTILS_EXTENSION_NAME, available_instance_extensions, enabled_extensions);
199178 bool has_debug_report = false ;
200179
201180 if (!has_debug_utils)
202181 {
203- has_debug_report = enable_extension (VK_EXT_DEBUG_REPORT_EXTENSION_NAME,
204- available_instance_extensions, enabled_extensions);
182+ has_debug_report = enable_extension (VK_EXT_DEBUG_REPORT_EXTENSION_NAME, available_instance_extensions, enabled_extensions);
205183 if (!has_debug_report)
206184 {
207- LOGW (" Neither of {} or {} are available; disabling debug reporting" ,
208- VK_EXT_DEBUG_UTILS_EXTENSION_NAME, VK_EXT_DEBUG_REPORT_EXTENSION_NAME);
185+ LOGW (" Neither of {} or {} are available; disabling debug reporting" , VK_EXT_DEBUG_UTILS_EXTENSION_NAME, VK_EXT_DEBUG_REPORT_EXTENSION_NAME);
209186 }
210187 }
211188#endif
@@ -220,34 +197,24 @@ HPPInstance::HPPInstance(const std::string &applicati
220197 {
221198 std::vector<vk::ExtensionProperties> available_layer_instance_extensions = vk::enumerateInstanceExtensionProperties (std::string (" VK_LAYER_KHRONOS_validation" ));
222199
223- for (auto &available_extension : available_layer_instance_extensions)
224- {
225- if (strcmp (available_extension.extensionName , VK_EXT_VALIDATION_FEATURES_EXTENSION_NAME) == 0 )
226- {
227- validation_features = true ;
228- LOGI (" {} is available, enabling it" , VK_EXT_VALIDATION_FEATURES_EXTENSION_NAME);
229- enabled_extensions.push_back (VK_EXT_VALIDATION_FEATURES_EXTENSION_NAME);
230- }
231- }
200+ enable_extension (VK_EXT_VALIDATION_FEATURES_EXTENSION_NAME, available_layer_instance_extensions, enabled_extensions);
232201 }
233202#endif
234203
235204 // Specific surface extensions are obtained from Window::get_required_surface_extensions
236- // They are already added to required_extensions by VulkanSample::prepare
205+ // They are already added to requested_extensions by VulkanSample::prepare
237206
238- // If using VK_EXT_headless_surface, we still create and use a surface
239- enabled_extensions. push_back (VK_KHR_SURFACE_EXTENSION_NAME);
207+ // Even for a headless surface a swapchain is still required
208+ enable_extension (VK_KHR_SURFACE_EXTENSION_NAME, available_instance_extensions, enabled_extensions );
240209
241210 // VK_KHR_get_physical_device_properties2 is a prerequisite of VK_KHR_performance_query
242211 // which will be used for stats gathering where available.
243- enable_extension (VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME,
244- available_instance_extensions, enabled_extensions);
212+ enable_extension (VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, available_instance_extensions, enabled_extensions);
245213
246- auto extension_error = false ;
247- for (auto extension : required_extensions)
214+ for (auto requested_extension : requested_extensions)
248215 {
249- auto extension_name = extension .first ;
250- auto extension_is_optional = extension .second ;
216+ auto const & extension_name = requested_extension .first ;
217+ auto extension_is_optional = requested_extension .second ;
251218 if (!enable_extension (extension_name, available_instance_extensions, enabled_extensions))
252219 {
253220 if (extension_is_optional)
@@ -257,43 +224,43 @@ HPPInstance::HPPInstance(const std::string &applicati
257224 else
258225 {
259226 LOGE (" Required instance extension {} not available, cannot run" , extension_name);
260- extension_error = true ;
227+ throw std::runtime_error ( " Required instance extensions are missing. " ) ;
261228 }
262- extension_error = extension_error || !extension_is_optional;
263229 }
264230 }
265231
266- if (extension_error)
267- {
268- throw std::runtime_error (" Required instance extensions are missing." );
269- }
270-
271- std::vector<vk::LayerProperties> supported_validation_layers = vk::enumerateInstanceLayerProperties ();
232+ std::vector<vk::LayerProperties> supported_layers = vk::enumerateInstanceLayerProperties ();
272233
273- std::vector<const char *> requested_validation_layers (required_validation_layers) ;
234+ std::vector<const char *> enabled_layers ;
274235
275- #ifdef USE_VALIDATION_LAYERS
276- // Determine the optimal validation layers to enable that are necessary for useful debugging
277- std::vector<const char *> optimal_validation_layers = get_optimal_validation_layers (supported_validation_layers);
278- requested_validation_layers.insert (requested_validation_layers.end (), optimal_validation_layers.begin (), optimal_validation_layers.end ());
279- #endif
280-
281- if (validate_layers (requested_validation_layers, supported_validation_layers))
236+ auto layer_error = false ;
237+ for (auto const &requested_layer : requested_layers)
282238 {
283- LOGI (" Enabled Validation Layers:" )
284- for (const auto &layer : requested_validation_layers)
239+ auto const &layer_name = requested_layer.first ;
240+ auto layer_is_optional = requested_layer.second ;
241+ if (!enable_layer (layer_name, supported_layers, enabled_layers))
285242 {
286- LOGI (" \t {}" , layer);
243+ if (layer_is_optional)
244+ {
245+ LOGW (" Optional layer {} not available, some features may be disabled" , layer_name);
246+ }
247+ else
248+ {
249+ LOGE (" Required layer {} not available, cannot run" , layer_name);
250+ throw std::runtime_error (" Required layers are missing." );
251+ }
287252 }
288253 }
289- else
290- {
291- throw std::runtime_error (" Required validation layers are missing." );
292- }
254+
255+ #ifdef USE_VALIDATION_LAYERS
256+ // NOTE: It's important to have the validation layer as the last one here!!!!
257+ // Otherwise, device creation fails !?!
258+ enable_layer (" VK_LAYER_KHRONOS_validation" , supported_layers, enabled_layers);
259+ #endif
293260
294261 vk::ApplicationInfo app_info (application_name.c_str (), 0 , " Vulkan Samples" , 0 , api_version);
295262
296- vk::InstanceCreateInfo instance_info ({}, &app_info, requested_validation_layers , enabled_extensions);
263+ vk::InstanceCreateInfo instance_info ({}, &app_info, enabled_layers , enabled_extensions);
297264
298265#ifdef USE_VALIDATION_LAYERS
299266 vk::DebugUtilsMessengerCreateInfoEXT debug_utils_create_info;
@@ -450,7 +417,7 @@ vkb::core::HPPPhysicalDevice &HPPInstance::get_suitable_gpu(vk::SurfaceKHR surfa
450417 }
451418 return *gpus[selected_gpu_index.value ()];
452419 }
453- if ( headless_surface )
420+ if (headless_surface)
454421 {
455422 LOGW (" Using headless surface with multiple GPUs. Considered explicitly selecting the target GPU." )
456423 }
0 commit comments