From e134c44708aa27b3f9fa5241630dcb019c533742 Mon Sep 17 00:00:00 2001 From: asuessenbach Date: Thu, 27 Nov 2025 14:22:42 +0100 Subject: [PATCH] Refactor instance creation --- framework/common/helpers.h | 7 +- framework/common/vk_common.h | 6 + framework/core/hpp_debug.h | 60 +++ framework/core/instance.h | 435 +++++------------- framework/vulkan_sample.h | 391 ++++++++++------ .../swapchain_recreation.cpp | 12 +- .../swapchain_recreation.h | 3 +- .../buffer_device_address.cpp | 9 +- .../buffer_device_address.h | 3 + .../calibrated_timestamps.cpp | 2 - .../color_write_enable/color_write_enable.cpp | 1 - .../conservative_rasterization.cpp | 3 - .../extensions/debug_utils/debug_utils.cpp | 4 +- .../descriptor_buffer_basic.cpp | 2 - .../descriptor_indexing.cpp | 36 +- .../descriptor_indexing/descriptor_indexing.h | 14 +- .../dynamic_blending/dynamic_blending.cpp | 1 - .../dynamic_multisample_rasterization.cpp | 6 +- .../dynamic_multisample_rasterization.h | 3 + .../dynamic_primitive_clipping.cpp | 2 - .../dynamic_rendering/dynamic_rendering.cpp | 9 +- .../dynamic_rendering/dynamic_rendering.h | 3 + .../dynamic_rendering_local_read.cpp | 7 +- .../dynamic_rendering_local_read.h | 3 + .../extended_dynamic_state2.cpp | 1 - .../fragment_density_map.cpp | 1 - .../fragment_shader_barycentric.cpp | 2 +- .../fragment_shading_rate.cpp | 1 - .../fragment_shading_rate_dynamic.cpp | 3 +- .../graphics_pipeline_library.cpp | 1 - .../gshader_to_mshader/gshader_to_mshader.cpp | 1 - .../host_image_copy/host_image_copy.cpp | 1 - .../hpp_mesh_shading/hpp_mesh_shading.cpp | 2 - .../hpp_push_descriptors.cpp | 1 - .../logic_op_dynamic_state.cpp | 1 - .../memory_budget/memory_budget.cpp | 1 - .../mesh_shader_culling.cpp | 3 - .../extensions/mesh_shading/mesh_shading.cpp | 4 +- .../open_cl_interop/open_cl_interop.cpp | 11 +- .../open_cl_interop/open_cl_interop.h | 5 +- .../open_cl_interop_arm.cpp | 8 +- .../open_cl_interop_arm/open_cl_interop_arm.h | 5 +- .../open_gl_interop/open_gl_interop.cpp | 10 +- .../open_gl_interop/open_gl_interop.h | 7 +- .../patch_control_points.cpp | 1 - .../extensions/portability/portability.cpp | 16 +- samples/extensions/portability/portability.h | 4 + .../push_descriptors/push_descriptors.cpp | 1 - .../extensions/ray_queries/ray_queries.cpp | 2 - .../ray_tracing_basic/ray_tracing_basic.cpp | 3 - .../ray_tracing_extended.cpp | 3 - .../ray_tracing_position_fetch.cpp | 3 - .../ray_tracing_reflection.cpp | 7 +- .../ray_tracing_reflection.h | 3 + .../shader_debugprintf/shader_debugprintf.cpp | 182 ++------ .../shader_debugprintf/shader_debugprintf.h | 35 +- .../shader_object/shader_object.cpp | 11 +- .../extensions/shader_object/shader_object.h | 3 + .../simple_tensor_and_data_graph.cpp | 7 +- .../simple_tensor_and_data_graph.h | 3 + .../timeline_semaphore/timeline_semaphore.cpp | 1 - .../vertex_dynamic_state.cpp | 1 - samples/general/mobile_nerf/mobile_nerf.cpp | 3 +- .../mobile_nerf_rayquery.cpp | 2 - .../16bit_arithmetic/16bit_arithmetic.cpp | 1 - .../16bit_storage_input_output.cpp | 3 - .../constant_data/constant_data.cpp | 1 - .../image_compression_control.cpp | 9 +- .../image_compression_control.h | 3 + .../layout_transitions/layout_transitions.cpp | 11 +- .../layout_transitions/layout_transitions.h | 5 +- samples/performance/msaa/msaa.cpp | 1 - .../multi_draw_indirect.cpp | 6 +- .../multi_draw_indirect/multi_draw_indirect.h | 3 + .../pipeline_barriers/pipeline_barriers.cpp | 11 +- .../pipeline_barriers/pipeline_barriers.h | 5 +- samples/performance/subpasses/subpasses.cpp | 11 +- samples/performance/subpasses/subpasses.h | 3 + .../patch_control_points/hlsl/tess.tese.spv | Bin 1396 -> 1384 bytes 79 files changed, 723 insertions(+), 732 deletions(-) diff --git a/framework/common/helpers.h b/framework/common/helpers.h index adaf07032b..24ecdb38fe 100644 --- a/framework/common/helpers.h +++ b/framework/common/helpers.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2018-2024, Arm Limited and Contributors +/* Copyright (c) 2018-2025, Arm Limited and Contributors * * SPDX-License-Identifier: Apache-2.0 * @@ -41,6 +41,11 @@ namespace vkb { +inline bool contains(std::vector const &range, char const *value) +{ + return std::ranges::find_if(range, [value](std::string const &range_value) { return range_value == value; }) != range.end(); +} + template inline void read(std::istringstream &is, T &value) { diff --git a/framework/common/vk_common.h b/framework/common/vk_common.h index 10fe0df2c4..1897fa7b7b 100644 --- a/framework/common/vk_common.h +++ b/framework/common/vk_common.h @@ -55,6 +55,12 @@ enum class CommandBufferResetMode AlwaysAllocate, }; +enum class RequestMode +{ + Optional, + Required +}; + /** * @brief Helper function to determine if a Vulkan format is depth only. * @param format Vulkan format to check. diff --git a/framework/core/hpp_debug.h b/framework/core/hpp_debug.h index bcd577b9e4..209904153f 100644 --- a/framework/core/hpp_debug.h +++ b/framework/core/hpp_debug.h @@ -148,5 +148,65 @@ class HPPScopedDebugLabel final vk::CommandBuffer command_buffer; }; +#if defined(VKB_DEBUG) || defined(VKB_VALIDATION_LAYERS) +inline VKAPI_ATTR vk::Bool32 VKAPI_CALL debug_utils_messenger_callback(vk::DebugUtilsMessageSeverityFlagBitsEXT message_severity, + vk::DebugUtilsMessageTypeFlagsEXT message_type, + vk::DebugUtilsMessengerCallbackDataEXT const *callback_data, + void *user_data) +{ + // Log debug message + if (message_severity & vk::DebugUtilsMessageSeverityFlagBitsEXT::eWarning) + { + LOGW("{} - {}: {}", callback_data->messageIdNumber, callback_data->pMessageIdName, callback_data->pMessage); + } + else if (message_severity & vk::DebugUtilsMessageSeverityFlagBitsEXT::eError) + { + LOGE("{} - {}: {}", callback_data->messageIdNumber, callback_data->pMessageIdName, callback_data->pMessage); + } + return false; +} + +inline vk::DebugUtilsMessengerCreateInfoEXT getDefaultDebugUtilsMessengerCreateInfoEXT() +{ + return vk::DebugUtilsMessengerCreateInfoEXT{.messageSeverity = vk::DebugUtilsMessageSeverityFlagBitsEXT::eError | vk::DebugUtilsMessageSeverityFlagBitsEXT::eWarning, + .messageType = vk::DebugUtilsMessageTypeFlagBitsEXT::eValidation | vk::DebugUtilsMessageTypeFlagBitsEXT::ePerformance, + .pfnUserCallback = debug_utils_messenger_callback}; +} + +inline VKAPI_ATTR vk::Bool32 VKAPI_CALL debug_callback(vk::DebugReportFlagsEXT flags, + vk::DebugReportObjectTypeEXT /*type*/, + uint64_t /*object*/, + size_t /*location*/, + int32_t /*message_code*/, + char const *layer_prefix, + char const *message, + void * /*user_data*/) +{ + if (flags & vk::DebugReportFlagBitsEXT::eError) + { + LOGE("{}: {}", layer_prefix, message); + } + else if (flags & vk::DebugReportFlagBitsEXT::eWarning) + { + LOGW("{}: {}", layer_prefix, message); + } + else if (flags & vk::DebugReportFlagBitsEXT::ePerformanceWarning) + { + LOGW("{}: {}", layer_prefix, message); + } + else + { + LOGI("{}: {}", layer_prefix, message); + } + return false; +} + +inline vk::DebugReportCallbackCreateInfoEXT getDefaultDebugReportCallbackCreateInfoEXT() +{ + return vk::DebugReportCallbackCreateInfoEXT{.flags = vk::DebugReportFlagBitsEXT::eError | vk::DebugReportFlagBitsEXT::eWarning | vk::DebugReportFlagBitsEXT::ePerformanceWarning, + .pfnCallback = debug_callback}; +} + +#endif } // namespace core } // namespace vkb \ No newline at end of file diff --git a/framework/core/instance.h b/framework/core/instance.h index 4f4781f574..48b1aafd73 100644 --- a/framework/core/instance.h +++ b/framework/core/instance.h @@ -18,8 +18,11 @@ #pragma once +#include "common/helpers.h" #include "common/vk_common.h" +#include "core/hpp_debug.h" #include +#include #include #if defined(VKB_DEBUG) || defined(VKB_VALIDATION_LAYERS) @@ -50,8 +53,10 @@ template class Instance { public: - using InstanceType = typename std::conditional::type; - using SurfaceType = typename std::conditional::type; + using InstanceCreateFlagsType = typename std::conditional::type; + using InstanceType = typename std::conditional::type; + using LayerSettingType = typename std::conditional::type; + using SurfaceType = typename std::conditional::type; public: /** @@ -62,22 +67,31 @@ class Instance /** * @brief Initializes the connection to Vulkan * @param application_name The name of the application - * @param requested_extensions The extensions requested to be enabled - * @param requested_layers The validation layers to be enabled - * @param requested_layer_settings The layer settings to be enabled * @param api_version The Vulkan API version that the instance will be using - * @throws runtime_error if the required extensions and validation layers are not found + * @param requested_layers The requested layers to be enabled + * @param requested_extensions The requested extensions to be enabled + * @param get_pNext A function pointer returning the pNext pointer for the InstanceCreateInfo + * @param get_create_flags A function pointer returning the InstanceCreateFlags for the InstanceCreateInfo + * @throws runtime_error if a required layer or extension is not available */ - Instance(std::string const &application_name, - std::unordered_map const &requested_extensions = {}, - std::unordered_map const &requested_layers = {}, - const std::vector &requested_layer_settings = {}, - uint32_t api_version = VK_API_VERSION_1_1); - Instance(std::string const &application_name, - std::unordered_map const &requested_extensions, - std::unordered_map const &requested_layers, - std::vector const &requested_layer_settings, - uint32_t api_version = VK_API_VERSION_1_1); + Instance( + std::string const &application_name, + uint32_t api_version = VK_API_VERSION_1_1, + std::unordered_map const &requested_layers = {}, + std::unordered_map const &requested_extensions = {}, + std::function const &, std::vector const &)> const &get_pNext = + [](std::vector const &, std::vector const &) { return nullptr; }, + std::function const &)> const &get_create_flags = + [](std::vector const &) { + if constexpr (bindingType == vkb::BindingType::Cpp) + { + return vk::InstanceCreateFlags{}; + } + else + { + return 0; + } + }); /** * @brief Queries the GPUs of a InstanceType that is already created @@ -96,7 +110,7 @@ class Instance Instance &operator=(Instance const &) = delete; Instance &operator=(Instance &&) = delete; - const std::vector &get_extensions(); + const std::vector &get_extensions(); /** * @brief Tries to find the first available discrete GPU @@ -127,7 +141,7 @@ class Instance void query_gpus(); private: - std::vector enabled_extensions; // The enabled extensions + std::vector enabled_extensions; // The enabled extensions std::vector> gpus; // The physical devices found on the machine vk::Instance handle; // The Vulkan instance @@ -150,63 +164,16 @@ namespace core { namespace { -#ifdef USE_VALIDATION_LAYERS -inline VKAPI_ATTR vk::Bool32 VKAPI_CALL debug_utils_messenger_callback(vk::DebugUtilsMessageSeverityFlagBitsEXT message_severity, - vk::DebugUtilsMessageTypeFlagsEXT message_type, - vk::DebugUtilsMessengerCallbackDataEXT const *callback_data, - void *user_data) -{ - // Log debug message - if (message_severity & vk::DebugUtilsMessageSeverityFlagBitsEXT::eWarning) - { - LOGW("{} - {}: {}", callback_data->messageIdNumber, callback_data->pMessageIdName, callback_data->pMessage); - } - else if (message_severity & vk::DebugUtilsMessageSeverityFlagBitsEXT::eError) - { - LOGE("{} - {}: {}", callback_data->messageIdNumber, callback_data->pMessageIdName, callback_data->pMessage); - } - return false; -} - -inline VKAPI_ATTR vk::Bool32 VKAPI_CALL debug_callback(vk::DebugReportFlagsEXT flags, - vk::DebugReportObjectTypeEXT /*type*/, - uint64_t /*object*/, - size_t /*location*/, - int32_t /*message_code*/, - char const *layer_prefix, - char const *message, - void * /*user_data*/) -{ - if (flags & vk::DebugReportFlagBitsEXT::eError) - { - LOGE("{}: {}", layer_prefix, message); - } - else if (flags & vk::DebugReportFlagBitsEXT::eWarning) - { - LOGW("{}: {}", layer_prefix, message); - } - else if (flags & vk::DebugReportFlagBitsEXT::ePerformanceWarning) - { - LOGW("{}: {}", layer_prefix, message); - } - else - { - LOGI("{}: {}", layer_prefix, message); - } - return false; -} -#endif - -inline bool enable_extension(char const *requested_extension, +inline bool enable_extension(std::string const &requested_extension, std::vector const &available_extensions, - std::vector &enabled_extensions) + std::vector &enabled_extensions) { - bool is_available = std::ranges::any_of(available_extensions, - [&requested_extension](auto const &available_extension) { return strcmp(requested_extension, available_extension.extensionName) == 0; }); + bool is_available = std::ranges::any_of( + available_extensions, [&requested_extension](auto const &available_extension) { return requested_extension == available_extension.extensionName; }); if (is_available) { - bool is_already_enabled = std::ranges::any_of( - enabled_extensions, [&requested_extension](auto const &enabled_extension) { return strcmp(requested_extension, enabled_extension) == 0; }); + bool is_already_enabled = + std::ranges::any_of(enabled_extensions, [&requested_extension](auto const &enabled_extension) { return requested_extension == enabled_extension; }); if (!is_already_enabled) { LOGI("Extension {} available, enabling it", requested_extension); @@ -221,18 +188,19 @@ inline bool enable_extension(char const *request return is_available; } -inline bool enable_layer(char const *requested_layer, std::vector const &available_layers, std::vector &enabled_layers) +inline bool + enable_layer(std::string const &requested_layer, std::vector const &available_layers, std::vector &enabled_layers) { - bool is_available = std::ranges::any_of( - available_layers, [&requested_layer](auto const &available_layer) { return strcmp(requested_layer, available_layer.layerName) == 0; }); + bool is_available = + std::ranges::any_of(available_layers, [&requested_layer](auto const &available_layer) { return requested_layer == available_layer.layerName; }); if (is_available) { bool is_already_enabled = - std::ranges::any_of(enabled_layers, [&requested_layer](auto const &enabled_layer) { return strcmp(requested_layer, enabled_layer) == 0; }); + std::ranges::any_of(enabled_layers, [&requested_layer](auto const &enabled_layer) { return requested_layer == enabled_layer; }); if (!is_already_enabled) { LOGI("Layer {} available, enabling it", requested_layer); - enabled_layers.emplace_back(requested_layer); + enabled_layers.emplace_back(requested_layer.c_str()); } } else @@ -243,49 +211,6 @@ inline bool enable_layer(char const *requested_layer, std::vector const &enabled_layers, - std::vector &enabled_layer_settings) -{ - // We are checking if the layer is available. - // Vulkan does not provide a reflection API for layer settings. Layer settings are described in each layer JSON manifest. - bool is_available = std::ranges::any_of( - enabled_layers, [&requested_layer_setting](auto const &available_layer) { return strcmp(available_layer, requested_layer_setting.pLayerName) == 0; }); -#if defined(PLATFORM__MACOS) - // On Apple platforms the MoltenVK layer is implicitly enabled and available, and cannot be explicitly added or checked via enabled_layers. - is_available = is_available || strcmp(requested_layer_setting.pLayerName, "MoltenVK") == 0; -#endif - - if (!is_available) - { - LOGW("Layer: {} not found. Disabling layer setting: {}", requested_layer_setting.pLayerName, requested_layer_setting.pSettingName); - return false; - } - - bool is_already_enabled = std::ranges::any_of(enabled_layer_settings, - [&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); - }); - - if (is_already_enabled) - { - LOGW("Ignoring duplicated layer setting {} in layer {}.", requested_layer_setting.pSettingName, requested_layer_setting.pLayerName); - return false; - } - - LOGI("Enabling layer setting {} in layer {}.", requested_layer_setting.pSettingName, requested_layer_setting.pLayerName); - enabled_layer_settings.push_back(requested_layer_setting); - return true; -} - -inline bool enable_layer_setting(VkLayerSettingEXT const &requested_layer_setting, - std::vector const &enabled_layers, - std::vector &enabled_layer_settings) -{ - return enable_layer_setting(reinterpret_cast(requested_layer_setting), enabled_layers, enabled_layer_settings); -} - inline bool validate_layers(std::vector const &required, std::vector const &available) { for (auto layer : required) @@ -312,220 +237,101 @@ inline bool validate_layers(std::vector const &required, std::vect } // namespace template -inline Instance::Instance(std::string const &application_name, - std::unordered_map const &requested_extensions, - std::unordered_map const &requested_layers, - std::vector const &requested_layer_settings, - uint32_t api_version) +inline Instance::Instance(std::string const &application_name, + uint32_t api_version, + std::unordered_map const &requested_layers, + std::unordered_map const &requested_extensions, + std::function const &, std::vector const &)> const &get_pNext, + std::function const &)> const &get_create_flags) { - std::vector available_instance_extensions = vk::enumerateInstanceExtensionProperties(); - -#ifdef USE_VALIDATION_LAYERS - // Check if VK_EXT_debug_utils is supported, which supersedes VK_EXT_Debug_Report - const bool has_debug_utils = enable_extension(VK_EXT_DEBUG_UTILS_EXTENSION_NAME, available_instance_extensions, enabled_extensions); - bool has_debug_report = false; - - if (!has_debug_utils) + // check API version + LOGI("Requesting Vulkan API version {}.{}", VK_VERSION_MAJOR(api_version), VK_VERSION_MINOR(api_version)); + if (api_version < VK_API_VERSION_1_1) { - has_debug_report = enable_extension(VK_EXT_DEBUG_REPORT_EXTENSION_NAME, available_instance_extensions, enabled_extensions); - if (!has_debug_report) - { - LOGW("Neither of {} or {} are available; disabling debug reporting", VK_EXT_DEBUG_UTILS_EXTENSION_NAME, VK_EXT_DEBUG_REPORT_EXTENSION_NAME); - } + LOGE("Vulkan API version {}.{} is requested but version 1.1 or higher is required.", VK_VERSION_MAJOR(api_version), VK_VERSION_MINOR(api_version)); + throw std::runtime_error("Requested Vulkan API version is too low."); } -#endif - -#if (defined(VKB_ENABLE_PORTABILITY)) - enable_extension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, available_instance_extensions, enabled_extensions); - bool portability_enumeration_available = enable_extension(VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME, available_instance_extensions, enabled_extensions); -#endif - -#ifdef USE_VALIDATION_LAYERS - const char *validation_layer_name = "VK_LAYER_KHRONOS_validation"; -# ifdef USE_VALIDATION_LAYER_FEATURES - bool validation_features = false; + uint32_t instance_api_version = vk::enumerateInstanceVersion(); + LOGI("Vulkan instance supports API version {}.{}", VK_VERSION_MAJOR(instance_api_version), VK_VERSION_MINOR(instance_api_version)); + if (instance_api_version < api_version) { - std::vector available_layer_instance_extensions = vk::enumerateInstanceExtensionProperties(std::string(validation_layer_name)); - validation_features = enable_extension(VK_EXT_LAYER_SETTINGS_EXTENSION_NAME, available_layer_instance_extensions, enabled_extensions); + LOGE("Vulkan API version {}.{} is requested but only version {}.{} is supported.", + VK_VERSION_MAJOR(api_version), + VK_VERSION_MINOR(api_version), + VK_VERSION_MAJOR(instance_api_version), + VK_VERSION_MINOR(instance_api_version)); + throw std::runtime_error("Requested Vulkan API version is too high."); } -# endif // USE_VALIDATION_LAYER_FEATURES -#endif // USE_VALIDATION_LAYERS - - // Specific surface extensions are obtained from Window::get_required_surface_extensions - // They are already added to requested_extensions by VulkanSample::prepare - - // Even for a headless surface a swapchain is still required - enable_extension(VK_KHR_SURFACE_EXTENSION_NAME, available_instance_extensions, enabled_extensions); - - // VK_KHR_get_physical_device_properties2 is a prerequisite of VK_KHR_performance_query - // which will be used for stats gathering where available. - enable_extension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, available_instance_extensions, enabled_extensions); - for (auto requested_extension : requested_extensions) + // Check for optional and required layers + std::vector available_layers = vk::enumerateInstanceLayerProperties(); + std::vector enabled_layers; + for (auto const &requested_layer : requested_layers) { - auto const &extension_name = requested_extension.first; - auto extension_is_optional = requested_extension.second; - if (!enable_extension(extension_name, available_instance_extensions, enabled_extensions)) + if (!enable_layer(requested_layer.first, available_layers, enabled_layers)) { - if (extension_is_optional) + if (requested_layer.second == vkb::RequestMode::Optional) { - LOGW("Optional instance extension {} not available, some features may be disabled", extension_name); + LOGW("Optional layer {} not available, some features may be disabled", requested_layer.first); } else { - LOGE("Required instance extension {} not available, cannot run", extension_name); - throw std::runtime_error("Required instance extensions are missing."); + LOGE("Required layer {} not available, cannot run", requested_layer.first); + throw std::runtime_error("Required layers are missing."); } } } + std::vector enabled_layers_cstr; + for (auto &layer : enabled_layers) + { + enabled_layers_cstr.push_back(layer.c_str()); + } - std::vector supported_layers = vk::enumerateInstanceLayerProperties(); + // Check for optional and required extensions + std::vector available_extensions = vk::enumerateInstanceExtensionProperties(); - std::vector enabled_layers; + if (contains(enabled_layers, "VK_LAYER_KHRONOS_validation")) + { + const std::string validation_layer_name = "VK_LAYER_KHRONOS_validation"; + std::vector available_layer_instance_extensions = vk::enumerateInstanceExtensionProperties(validation_layer_name); + available_extensions.insert(available_extensions.end(), + available_layer_instance_extensions.begin(), + available_layer_instance_extensions.end()); + } - auto layer_error = false; - for (auto const &requested_layer : requested_layers) + for (auto const &requested_extension : requested_extensions) { - auto const &layer_name = requested_layer.first; - auto layer_is_optional = requested_layer.second; - if (!enable_layer(layer_name, supported_layers, enabled_layers)) + if (!enable_extension(requested_extension.first, available_extensions, enabled_extensions)) { - if (layer_is_optional) + if (requested_extension.second == vkb::RequestMode::Optional) { - LOGW("Optional layer {} not available, some features may be disabled", layer_name); + LOGW("Optional instance extension {} not available, some features may be disabled", requested_extension.first); } else { - LOGE("Required layer {} not available, cannot run", layer_name); - throw std::runtime_error("Required layers are missing."); + LOGE("Required instance extension {} not available, cannot run", requested_extension.first); + throw std::runtime_error("Required instance extensions are missing."); } } } - -#ifdef USE_VALIDATION_LAYERS - // NOTE: It's important to have the validation layer as the last one here!!!! - // Otherwise, device creation fails !?! - enable_layer(validation_layer_name, supported_layers, enabled_layers); -#endif - - vk::ApplicationInfo app_info{.pApplicationName = application_name.c_str(), .pEngineName = "Vulkan Samples", .apiVersion = api_version}; - - vk::InstanceCreateInfo instance_info{.pApplicationInfo = &app_info, - .enabledLayerCount = static_cast(enabled_layers.size()), - .ppEnabledLayerNames = enabled_layers.data(), - .enabledExtensionCount = static_cast(enabled_extensions.size()), - .ppEnabledExtensionNames = enabled_extensions.data()}; - - std::vector enabled_layer_settings; - - for (auto const &layer_setting : requested_layer_settings) + std::vector enabled_extensions_cstr; + for (auto &extension : enabled_extensions) { - enable_layer_setting(layer_setting, enabled_layers, enabled_layer_settings); + enabled_extensions_cstr.push_back(extension.c_str()); } -#ifdef USE_VALIDATION_LAYERS - vk::DebugUtilsMessengerCreateInfoEXT debug_utils_create_info; - vk::DebugReportCallbackCreateInfoEXT debug_report_create_info; - if (has_debug_utils) - { - debug_utils_create_info = vk::DebugUtilsMessengerCreateInfoEXT{ - .messageSeverity = vk::DebugUtilsMessageSeverityFlagBitsEXT::eError | vk::DebugUtilsMessageSeverityFlagBitsEXT::eWarning, - .messageType = vk::DebugUtilsMessageTypeFlagBitsEXT::eValidation | vk::DebugUtilsMessageTypeFlagBitsEXT::ePerformance, - .pfnUserCallback = debug_utils_messenger_callback}; - - instance_info.pNext = &debug_utils_create_info; - } - else if (has_debug_report) - { - debug_report_create_info = {.flags = - vk::DebugReportFlagBitsEXT::eError | vk::DebugReportFlagBitsEXT::eWarning | vk::DebugReportFlagBitsEXT::ePerformanceWarning, - .pfnCallback = debug_callback}; - - instance_info.pNext = &debug_report_create_info; - } -#endif - -#if (defined(VKB_ENABLE_PORTABILITY)) - if (portability_enumeration_available) - { - instance_info.flags |= vk::InstanceCreateFlagBits::eEnumeratePortabilityKHR; - } -#endif - - // Some of the specialized layers need to be enabled explicitly - // The validation layer does not need to be enabled in code and it can also be configured using the vulkan configurator. -#ifdef USE_VALIDATION_LAYER_FEATURES - -# if defined(VKB_VALIDATION_LAYERS_GPU_ASSISTED) - const vk::Bool32 setting_validate_gpuav = true; - if (validation_features) - { - enable_layer_setting(vk::LayerSettingEXT(validation_layer_name, "gpuav_enable", vk::LayerSettingTypeEXT::eBool32, 1, &setting_validate_gpuav), enabled_layers, enabled_layer_settings); - } -# endif - -# if defined(VKB_VALIDATION_LAYERS_BEST_PRACTICES) - const vk::Bool32 setting_validate_best_practices = true; - const vk::Bool32 setting_validate_best_practices_arm = true; - const vk::Bool32 setting_validate_best_practices_amd = true; - const vk::Bool32 setting_validate_best_practices_img = true; - const vk::Bool32 setting_validate_best_practices_nvidia = true; - if (validation_features) - { - enable_layer_setting( - vk::LayerSettingEXT(validation_layer_name, "validate_best_practices", vk::LayerSettingTypeEXT::eBool32, 1, &setting_validate_best_practices), - enabled_layers, - enabled_layer_settings); - 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); - 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); - 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); - 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); - } -# endif - -# if defined(VKB_VALIDATION_LAYERS_SYNCHRONIZATION) - const vk::Bool32 setting_validate_sync = true; - const vk::Bool32 setting_validate_sync_heuristics = true; - if (validation_features) - { - enable_layer_setting(vk::LayerSettingEXT(validation_layer_name, "validate_sync", vk::LayerSettingTypeEXT::eBool32, 1, &setting_validate_sync), - enabled_layers, - enabled_layer_settings); - 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); - } -# endif -#endif - - vk::LayerSettingsCreateInfoEXT layerSettingsCreateInfo; + vk::ApplicationInfo app_info{.pApplicationName = application_name.c_str(), .pEngineName = "Vulkan Samples", .apiVersion = api_version}; - // If layer settings are defined, then activate the sample's required layer settings during instance creation - if (enabled_layer_settings.size() > 0) - { - layerSettingsCreateInfo.settingCount = static_cast(enabled_layer_settings.size()); - layerSettingsCreateInfo.pSettings = enabled_layer_settings.data(); - layerSettingsCreateInfo.pNext = instance_info.pNext; - instance_info.pNext = &layerSettingsCreateInfo; - } + vk::InstanceCreateInfo create_info{.pNext = get_pNext(enabled_layers, enabled_extensions), + .flags = static_cast(get_create_flags(enabled_extensions)), + .pApplicationInfo = &app_info, + .enabledLayerCount = static_cast(enabled_layers_cstr.size()), + .ppEnabledLayerNames = enabled_layers_cstr.data(), + .enabledExtensionCount = static_cast(enabled_extensions_cstr.size()), + .ppEnabledExtensionNames = enabled_extensions_cstr.data()}; // Create the Vulkan instance - handle = vk::createInstance(instance_info); + handle = vk::createInstance(create_info); // initialize the Vulkan-Hpp default dispatcher on the instance VULKAN_HPP_DEFAULT_DISPATCHER.init(handle); @@ -533,33 +339,20 @@ inline Instance::Instance(std::string const // Need to load volk for all the not-yet Vulkan-Hpp calls volkLoadInstance(handle); -#ifdef USE_VALIDATION_LAYERS - if (has_debug_utils) +#if defined(VKB_DEBUG) || defined(VKB_VALIDATION_LAYERS) + if (contains(enabled_extensions, VK_EXT_DEBUG_UTILS_EXTENSION_NAME)) { - debug_utils_messenger = handle.createDebugUtilsMessengerEXT(debug_utils_create_info); + debug_utils_messenger = handle.createDebugUtilsMessengerEXT(vkb::core::getDefaultDebugUtilsMessengerCreateInfoEXT()); } - else if (has_debug_report) + else if (contains(enabled_extensions, VK_EXT_DEBUG_REPORT_EXTENSION_NAME)) { - debug_report_callback = handle.createDebugReportCallbackEXT(debug_report_create_info); + debug_report_callback = handle.createDebugReportCallbackEXT(vkb::core::getDefaultDebugReportCallbackCreateInfoEXT()); } #endif query_gpus(); } -template -inline Instance::Instance(std::string const &application_name, - std::unordered_map const &requested_extensions, - std::unordered_map const &requested_layers, - std::vector const &requested_layer_settings, - uint32_t api_version) : - Instance(application_name, - requested_extensions, - requested_layers, - reinterpret_cast const &>(requested_layer_settings), - api_version) -{} - template inline Instance::Instance(vk::Instance instance, const std::vector &externally_enabled_extensions, bool needsToInitializeDispatcher) : handle{instance} @@ -601,7 +394,7 @@ inline Instance::Instance(VkInstance instance, const std::vector inline Instance::~Instance() { -#ifdef USE_VALIDATION_LAYERS +#if defined(VKB_DEBUG) || defined(VKB_VALIDATION_LAYERS) if (debug_utils_messenger) { handle.destroyDebugUtilsMessengerEXT(debug_utils_messenger); @@ -731,7 +524,7 @@ inline PhysicalDevice &Instance::get_suitable_gpu(Surf template inline bool Instance::is_enabled(char const *extension) const { - return std::ranges::find_if(enabled_extensions, [extension](char const *enabled_extension) { return strcmp(extension, enabled_extension) == 0; }) != + return std::ranges::find_if(enabled_extensions, [extension](std::string const &enabled_extension) { return enabled_extension == extension; }) != enabled_extensions.end(); } @@ -760,7 +553,7 @@ inline void Instance::query_gpus() } template -inline std::vector const &Instance::get_extensions() +inline std::vector const &Instance::get_extensions() { return enabled_extensions; } diff --git a/framework/vulkan_sample.h b/framework/vulkan_sample.h index ec7106ac62..16aaa58cca 100644 --- a/framework/vulkan_sample.h +++ b/framework/vulkan_sample.h @@ -140,10 +140,13 @@ class VulkanSample : public vkb::Application using RenderTargetType = typename std::conditional::type; using SceneType = typename std::conditional::type; using StatsType = typename std::conditional::type; - using Extent2DType = typename std::conditional::type; - using LayerSettingType = typename std::conditional::type; - using SurfaceFormatType = typename std::conditional::type; - using SurfaceType = typename std::conditional::type; + + using InstanceCreateFlagsType = typename std::conditional::type; + using Extent2DType = typename std::conditional::type; + using LayerSettingType = typename std::conditional::type; + using SurfaceFormatType = typename std::conditional::type; + using SurfaceType = typename std::conditional::type; + using ValidationFeatureEnableType = typename std::conditional::type; Configuration &get_configuration(); vkb::rendering::RenderContext &get_render_context(); @@ -195,6 +198,10 @@ class VulkanSample : public vkb::Application */ virtual void draw_renderpass(vkb::core::CommandBuffer &command_buffer, RenderTargetType &render_target); + virtual uint32_t get_api_version() const; + virtual InstanceCreateFlagsType get_instance_create_flags(std::vector const &enabled_extensions) const; + virtual void *get_instance_create_info_extensions(std::vector const &enabled_layers, std::vector const &enabled_extensions) const; + /** * @brief Override this to customise the creation of the swapchain and render_context */ @@ -211,6 +218,11 @@ class VulkanSample : public vkb::Application */ virtual void request_gpu_features(vkb::core::PhysicalDevice &gpu); + virtual void request_instance_extensions(std::unordered_map &requested_extensions) const; + virtual void request_layers(std::unordered_map &requested_layers) const; + virtual void request_layer_settings(std::vector &requested_layer_settings) const; + virtual void request_validation_feature_enables(std::vector &requested_validation_feature_enables) const; + /** * @brief Resets the stats view max values for high demanding configs * Should be overridden by the samples since they @@ -233,26 +245,6 @@ class VulkanSample : public vkb::Application */ void add_device_extension(const char *extension, bool optional = false); - /** - * @brief Add a sample-specific instance extension - * @param extension The extension name - * @param optional (Optional) Whether the extension is optional - */ - void add_instance_extension(const char *extension, bool optional = false); - - /** - * @brief Add a sample-specific instance layer - * @param layer The layer name - * @param optional (Optional) Whether the extension is optional - */ - void add_instance_layer(const char *layer, bool optional = false); - - /** - * @brief Add a sample-specific layer setting - * @param layerSetting The layer setting - */ - void add_layer_setting(LayerSettingType const &layerSetting); - void create_gui(const Window &window, StatsType const *stats = nullptr, const float font_size = 21.0f, bool explicit_update = false); /** @@ -291,11 +283,6 @@ class VulkanSample : public vkb::Application */ bool prepare(const ApplicationOptions &options) override; - /** - * @brief Set the Vulkan API version to request at instance creation time - */ - void set_api_version(uint32_t requested_api_version); - /** * @brief Sets whether or not the first graphics queue should have higher priority than other queues. * Very specific feature which is used by async compute samples. @@ -345,6 +332,7 @@ class VulkanSample : public vkb::Application void draw_impl(vkb::core::CommandBufferCpp &command_buffer, vkb::rendering::HPPRenderTarget &render_target); void draw_renderpass_impl(vkb::core::CommandBufferCpp &command_buffer, vkb::rendering::HPPRenderTarget &render_target); void render_impl(vkb::core::CommandBufferCpp &command_buffer); + void request_layer_settings_impl(std::vector &requested_layer_settings) const; static void set_viewport_and_scissor_impl(vkb::core::CommandBufferCpp const &command_buffer, vk::Extent2D const &extent); /** @@ -354,27 +342,6 @@ class VulkanSample : public vkb::Application */ std::unordered_map const &get_device_extensions() const; - /** - * @brief Get sample-specific instance extensions. - * - * @return Map of instance extensions and whether or not they are optional. Default is empty map. - */ - std::unordered_map const &get_instance_extensions() const; - - /** - * @brief Get sample-specific instance layers. - * - * @return Map of instance layers and whether or not they are optional. Default is empty map. - */ - std::unordered_map const &get_instance_layers() const; - - /** - * @brief Get sample-specific layer settings. - * - * @return Vector of layer settings. Default is empty vector. - */ - std::vector const &get_layer_settings() const; - /// /// PRIVATE MEMBERS /// @@ -430,18 +397,6 @@ class VulkanSample : public vkb::Application /** @brief Set of device extensions to be enabled for this example and whether they are optional (must be set in the derived constructor) */ std::unordered_map device_extensions; - /** @brief Set of instance extensions to be enabled for this example and whether they are optional (must be set in the derived constructor) */ - std::unordered_map instance_extensions; - - /** @brief Set of instance layers to be enabled for this example and whether they are optional (must be set in the derived constructor) */ - std::unordered_map instance_layers; - - /** @brief Vector of layer settings to be enabled for this example (must be set in the derived constructor) */ - std::vector layer_settings; - - /** @brief The Vulkan API version to request for this sample at instance creation time */ - uint32_t api_version = VK_API_VERSION_1_1; - /** @brief Whether or not we want a high priority graphics queue. */ bool high_priority_graphics_queue{false}; @@ -481,25 +436,6 @@ inline void VulkanSample::add_device_extension(const char *extensio device_extensions[extension] = optional; } -template -inline void VulkanSample::add_instance_extension(const char *extension, bool optional) -{ - instance_extensions[extension] = optional; -} - -template -inline void VulkanSample::add_layer_setting(LayerSettingType const &layerSetting) -{ - if constexpr (bindingType == BindingType::Cpp) - { - layer_settings.push_back(layerSetting); - } - else - { - layer_settings.push_back(reinterpret_cast(layerSetting)); - } -} - template inline std::unique_ptr> VulkanSample::create_device(vkb::core::PhysicalDevice &gpu) @@ -522,7 +458,26 @@ inline std::unique_ptr> template inline std::unique_ptr> VulkanSample::create_instance() { - return std::make_unique>(get_name(), get_instance_extensions(), get_instance_layers(), get_layer_settings(), api_version); + std::unordered_map requested_layers, requested_extensions; + request_layers(requested_layers); + request_instance_extensions(requested_extensions); + + return std::make_unique>( + get_name(), + get_api_version(), + requested_layers, + requested_extensions, + [this](std::vector const &enabled_layers, std::vector const &enabled_extensions) { return get_instance_create_info_extensions(enabled_layers, enabled_extensions); }, + [this](std::vector const &enabled_extensions) { + if constexpr (bindingType == BindingType::Cpp) + { + return get_instance_create_flags(enabled_extensions); + } + else + { + return static_cast(get_instance_create_flags(enabled_extensions)); + } + }); } template @@ -690,6 +645,135 @@ inline void VulkanSample::finish() } } +template +inline uint32_t VulkanSample::get_api_version() const +{ + return VK_API_VERSION_1_1; +} + +inline bool enable_layer_setting(vk::LayerSettingEXT const &requested_layer_setting, + std::vector const &enabled_layers, + std::vector &enabled_layer_settings) +{ + // We are checking if the layer is available. + // Vulkan does not provide a reflection API for layer settings. Layer settings are described in each layer JSON manifest. + bool is_available = std::ranges::any_of( + enabled_layers, [&requested_layer_setting](auto const &enabled_layer) { return enabled_layer == requested_layer_setting.pLayerName; }); +#if defined(PLATFORM__MACOS) + // On Apple platforms the MoltenVK layer is implicitly enabled and available, and cannot be explicitly added or checked via enabled_layers. + is_available = is_available || strcmp(requested_layer_setting.pLayerName, "MoltenVK") == 0; +#endif + + if (!is_available) + { + LOGW("Layer: {} not found. Disabling layer setting: {}", requested_layer_setting.pLayerName, requested_layer_setting.pSettingName); + return false; + } + + bool is_already_enabled = std::ranges::any_of(enabled_layer_settings, + [&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); + }); + + if (is_already_enabled) + { + LOGW("Ignoring duplicated layer setting {} in layer {}.", requested_layer_setting.pSettingName, requested_layer_setting.pLayerName); + return false; + } + + LOGI("Enabling layer setting {} in layer {}.", requested_layer_setting.pSettingName, requested_layer_setting.pLayerName); + enabled_layer_settings.push_back(requested_layer_setting); + return true; +} + +inline bool enable_layer_setting(VkLayerSettingEXT const &requested_layer_setting, + std::vector const &enabled_layers, + std::vector &enabled_layer_settings) +{ + return enable_layer_setting(reinterpret_cast(requested_layer_setting), enabled_layers, enabled_layer_settings); +} + +template +inline typename VulkanSample::InstanceCreateFlagsType VulkanSample::get_instance_create_flags(std::vector const &enabled_extensions) const +{ + vk::InstanceCreateFlags flags; +#if defined(VKB_ENABLE_PORTABILITY) + if (std::ranges::any_of(enabled_extensions, + [](auto const &enabled_extension) { return enabled_extension == VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME; })) + { + flags = vk::InstanceCreateFlagBits::eEnumeratePortabilityKHR; + } +#endif + if constexpr (bindingType == vkb::BindingType::Cpp) + { + return flags; + } + else + { + return static_cast(flags); + } +} + +template +inline void *VulkanSample::get_instance_create_info_extensions(std::vector const &enabled_layers, + std::vector const &enabled_extensions) const +{ + void *pNext = nullptr; + +#if defined(VKB_DEBUG) || defined(VKB_VALIDATION_LAYERS) + if (contains(enabled_extensions, VK_EXT_DEBUG_UTILS_EXTENSION_NAME)) + { + static vk::DebugReportCallbackCreateInfoEXT debug_report_create_info = vkb::core::getDefaultDebugReportCallbackCreateInfoEXT(); + debug_report_create_info.pNext = pNext; + pNext = &debug_report_create_info; + } + else if (contains(enabled_extensions, VK_EXT_DEBUG_REPORT_EXTENSION_NAME)) + { + static vk::DebugUtilsMessengerCreateInfoEXT debug_utils_create_info = vkb::core::getDefaultDebugUtilsMessengerCreateInfoEXT(); + debug_utils_create_info.pNext = pNext; + pNext = &debug_utils_create_info; + } +#endif + + if (contains(enabled_extensions, VK_EXT_LAYER_SETTINGS_EXTENSION_NAME)) + { + std::vector requested_layer_settings; + request_layer_settings(requested_layer_settings); + + static std::vector enabled_layer_settings; + for (auto const &layer_setting : requested_layer_settings) + { + enable_layer_setting(layer_setting, enabled_layers, enabled_layer_settings); + } + + if (!enabled_layer_settings.empty()) + { + // If layer settings are defined, then activate the sample's required layer settings during instance creation + static vk::LayerSettingsCreateInfoEXT layer_settings_create_info_ext{.pNext = pNext, + .settingCount = static_cast(enabled_layer_settings.size()), + .pSettings = enabled_layer_settings.data()}; + pNext = &layer_settings_create_info_ext; + } + } + else if (contains(enabled_extensions, VK_EXT_VALIDATION_FEATURES_EXTENSION_NAME)) + { + static std::vector requested_validation_feature_enables; + request_validation_feature_enables(requested_validation_feature_enables); + + if (!requested_validation_feature_enables.empty()) + { + static vk::ValidationFeaturesEXT validation_features_ext{ + .pNext = pNext, + .enabledValidationFeatureCount = static_cast(requested_validation_feature_enables.size()), + .pEnabledValidationFeatures = reinterpret_cast(requested_validation_feature_enables.data())}; + pNext = &validation_features_ext; + } + } + + return pNext; +} + template inline Configuration &VulkanSample::get_configuration() { @@ -806,37 +890,6 @@ inline vkb::core::Instance const &VulkanSample::get_in } } -template -inline std::unordered_map const &VulkanSample::get_instance_extensions() const -{ - return instance_extensions; -} - -template -inline std::unordered_map const &VulkanSample::get_instance_layers() const -{ - return instance_layers; -} - -template -inline void VulkanSample::add_instance_layer(const char *layer, bool optional) -{ - instance_layers[layer] = optional; -} - -template -inline std::vector::LayerSettingType> const &VulkanSample::get_layer_settings() const -{ - if constexpr (bindingType == BindingType::Cpp) - { - return layer_settings; - } - else - { - return reinterpret_cast const &>(layer_settings); - } -} - template inline vkb::rendering::RenderContext const &VulkanSample::get_render_context() const { @@ -1046,12 +1099,6 @@ inline bool VulkanSample::prepare(const ApplicationOptions &options throw VulkanException(result, "Failed to initialize volk."); } - // Creating the vulkan instance - for (const char *extension_name : window->get_required_surface_extensions()) - { - add_instance_extension(extension_name); - } - #ifdef VKB_VULKAN_DEBUG { std::vector available_instance_extensions = vk::enumerateInstanceExtensionProperties(); @@ -1063,7 +1110,6 @@ inline bool VulkanSample::prepare(const ApplicationOptions &options LOGI("Vulkan debug utils enabled ({})", VK_EXT_DEBUG_UTILS_EXTENSION_NAME); debug_utils = std::make_unique(); - add_instance_extension(VK_EXT_DEBUG_UTILS_EXTENSION_NAME); } } #endif @@ -1098,7 +1144,7 @@ inline bool VulkanSample::prepare(const ApplicationOptions &options { add_device_extension(VK_KHR_SWAPCHAIN_EXTENSION_NAME); - if (instance_extensions.find(VK_KHR_DISPLAY_EXTENSION_NAME) != instance_extensions.end()) + if (instance->is_enabled(VK_KHR_DISPLAY_EXTENSION_NAME)) { add_device_extension(VK_KHR_DISPLAY_SWAPCHAIN_EXTENSION_NAME, /*optional=*/true); } @@ -1107,10 +1153,7 @@ inline bool VulkanSample::prepare(const ApplicationOptions &options // Shaders generated by Slang require a certain SPIR-V environment that can't be satisfied by Vulkan 1.0, so we need to expliclity up that to at least 1.1 and enable some required extensions if (get_shading_language() == ShadingLanguage::SLANG) { - if (api_version < VK_API_VERSION_1_1) - { - api_version = VK_API_VERSION_1_1; - } + assert(VK_API_VERSION_1_1 <= get_api_version()); add_device_extension(VK_KHR_SPIRV_1_4_EXTENSION_NAME); add_device_extension(VK_KHR_SHADER_FLOAT_CONTROLS_EXTENSION_NAME); add_device_extension(VK_KHR_SHADER_DRAW_PARAMETERS_EXTENSION_NAME); @@ -1222,6 +1265,98 @@ inline void VulkanSample::request_gpu_features(vkb::core::PhysicalD // To be overridden by sample } +template +inline void VulkanSample::request_instance_extensions(std::unordered_map &requested_extensions) const +{ + assert(window && "Window is not valid"); + std::vector surface_extensions = window->get_required_surface_extensions(); + for (auto const &surface_extension : surface_extensions) + { + requested_extensions[surface_extension] = vkb::RequestMode::Required; + } + +#if defined(VKB_VULKAN_DEBUG) || defined(VKB_DEBUG) || defined(VKB_VALIDATION_LAYERS) + requested_extensions[VK_EXT_DEBUG_UTILS_EXTENSION_NAME] = vkb::RequestMode::Required; +#endif + +#if defined(VKB_ENABLE_PORTABILITY) + requested_extensions[VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME] = vkb::RequestMode::Required; +#endif + + // VK_KHR_get_physical_device_properties2 is a prerequisite of VK_KHR_performance_query + // which will be used for stats gathering where available. + requested_extensions[VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME] = vkb::RequestMode::Required; + +#if defined(VKB_DEBUG) || defined(VKB_VALIDATION_LAYERS) + requested_extensions[VK_EXT_DEBUG_REPORT_EXTENSION_NAME] = vkb::RequestMode::Optional; +#endif + +#if defined(VKB_DEBUG) || defined(VKB_VALIDATION_LAYERS) && (defined(VKB_VALIDATION_LAYERS_GPU_ASSISTED) || defined(VKB_VALIDATION_LAYERS_BEST_PRACTICES) || defined(VKB_VALIDATION_LAYERS_SYNCHRONIZATION)) + requested_extensions[VK_EXT_LAYER_SETTINGS_EXTENSION_NAME] = vkb::RequestMode::Optional; +#endif +} + +template +inline void VulkanSample::request_layers(std::unordered_map &requested_layers) const +{ +#if defined(VKB_DEBUG) || defined(VKB_VALIDATION_LAYERS) + requested_layers["VK_LAYER_KHRONOS_validation"] = vkb::RequestMode::Required; +#endif +} + +template +inline void VulkanSample::request_layer_settings(std::vector &requested_layer_settings) const +{ + if constexpr (bindingType == vkb::BindingType::Cpp) + { + request_layer_settings_impl(requested_layer_settings); + } + else + { + request_layer_settings_impl(reinterpret_cast &>(requested_layer_settings)); + } +} + +template +inline void VulkanSample::request_layer_settings_impl(std::vector &requested_layer_settings) const +{ +#if defined(VKB_VALIDATION_LAYERS_GPU_ASSISTED) + static const vk::Bool32 setting_validate_gpuav = true; + requested_layer_settings.push_back({"VK_LAYER_KHRONOS_validation", "gpuav_enable", vk::LayerSettingTypeEXT::eBool32, 1, &setting_validate_gpuav}); +#endif + +#if defined(VKB_VALIDATION_LAYERS_BEST_PRACTICES) + static const vk::Bool32 setting_validate_best_practices = true; + static const vk::Bool32 setting_validate_best_practices_amd = true; + static const vk::Bool32 setting_validate_best_practices_arm = true; + static const vk::Bool32 setting_validate_best_practices_img = true; + static const vk::Bool32 setting_validate_best_practices_nvidia = true; + requested_layer_settings.push_back( + {"VK_LAYER_KHRONOS_validation", "validate_best_practices", vk::LayerSettingTypeEXT::eBool32, 1, &setting_validate_best_practices}); + requested_layer_settings.push_back( + {"VK_LAYER_KHRONOS_validation", "validate_best_practices_amd", vk::LayerSettingTypeEXT::eBool32, 1, &setting_validate_best_practices_amd}); + requested_layer_settings.push_back( + {"VK_LAYER_KHRONOS_validation", "validate_best_practices_arm", vk::LayerSettingTypeEXT::eBool32, 1, &setting_validate_best_practices_arm}); + requested_layer_settings.push_back( + {"VK_LAYER_KHRONOS_validation", "validate_best_practices_img", vk::LayerSettingTypeEXT::eBool32, 1, &setting_validate_best_practices_img}); + requested_layer_settings.push_back( + {"VK_LAYER_KHRONOS_validation", "validate_best_practices_nvidia", vk::LayerSettingTypeEXT::eBool32, 1, &setting_validate_best_practices_nvidia}); +#endif + +#if defined(VKB_VALIDATION_LAYERS_SYNCHRONIZATION) + static const vk::Bool32 setting_validate_sync = true; + static const vk::Bool32 setting_validate_sync_heuristics = true; + requested_layer_settings.push_back({"VK_LAYER_KHRONOS_validation", "validate_sync", vk::LayerSettingTypeEXT::eBool32, 1, &setting_validate_sync}); + requested_layer_settings.push_back( + {"VK_LAYER_KHRONOS_validation", "syncval_shader_accesses_heuristic", vk::LayerSettingTypeEXT::eBool32, 1, &setting_validate_sync_heuristics}); +#endif +} + +template +inline void VulkanSample::request_validation_feature_enables(std::vector &requested_layer_settings) const +{ +} + template inline void VulkanSample::reset_stats_view() { @@ -1257,12 +1392,6 @@ inline bool VulkanSample::resize(uint32_t width, uint32_t height) return true; } -template -inline void VulkanSample::set_api_version(uint32_t requested_api_version) -{ - api_version = requested_api_version; -} - template inline void VulkanSample::set_high_priority_graphics_queue_enable(bool enable) { diff --git a/samples/api/swapchain_recreation/swapchain_recreation.cpp b/samples/api/swapchain_recreation/swapchain_recreation.cpp index daf14227cd..50216facd3 100644 --- a/samples/api/swapchain_recreation/swapchain_recreation.cpp +++ b/samples/api/swapchain_recreation/swapchain_recreation.cpp @@ -896,8 +896,6 @@ SwapchainRecreation::SwapchainRecreation() if ((use_maintenance1 == nullptr) || (strcmp(use_maintenance1, "no") != 0)) { // Request sample-specific extensions as optional - add_instance_extension(VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME, true); - add_instance_extension(VK_EXT_SURFACE_MAINTENANCE_1_EXTENSION_NAME, true); add_device_extension(VK_EXT_SWAPCHAIN_MAINTENANCE_1_EXTENSION_NAME, true); } else @@ -981,6 +979,16 @@ void SwapchainRecreation::request_gpu_features(vkb::core::PhysicalDeviceC &gpu) } } +void SwapchainRecreation::request_instance_extensions(std::unordered_map &requested_extensions) const +{ + vkb::VulkanSampleC::request_instance_extensions(requested_extensions); + if (allow_maintenance1) + { + requested_extensions[VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME] = vkb::RequestMode::Optional; + requested_extensions[VK_EXT_SURFACE_MAINTENANCE_1_EXTENSION_NAME] = vkb::RequestMode::Optional; + } +} + std::unique_ptr SwapchainRecreation::create_device(vkb::core::PhysicalDeviceC &gpu) { std::unique_ptr device = vkb::VulkanSampleC::create_device(gpu); diff --git a/samples/api/swapchain_recreation/swapchain_recreation.h b/samples/api/swapchain_recreation/swapchain_recreation.h index 16351c5905..164ffb3d36 100644 --- a/samples/api/swapchain_recreation/swapchain_recreation.h +++ b/samples/api/swapchain_recreation/swapchain_recreation.h @@ -173,8 +173,9 @@ class SwapchainRecreation : public vkb::VulkanSampleC bool recreate_swapchain_on_present_mode_change = false; // from vkb::VulkanSample - void request_gpu_features(vkb::core::PhysicalDeviceC &gpu) override; std::unique_ptr create_device(vkb::core::PhysicalDeviceC &gpu) override; + void request_gpu_features(vkb::core::PhysicalDeviceC &gpu) override; + void request_instance_extensions(std::unordered_map &requested_extensions) const override; void get_queue(); void query_surface_format(); diff --git a/samples/extensions/buffer_device_address/buffer_device_address.cpp b/samples/extensions/buffer_device_address/buffer_device_address.cpp index 420cbdb0c2..aab996bd3d 100644 --- a/samples/extensions/buffer_device_address/buffer_device_address.cpp +++ b/samples/extensions/buffer_device_address/buffer_device_address.cpp @@ -22,13 +22,10 @@ BufferDeviceAddress::BufferDeviceAddress() title = "Buffer device address"; // Need to enable buffer device address extension. - add_instance_extension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); add_device_extension(VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME); // Provides support for VkAllocateMemoryFlagsInfo. Otherwise, core in Vulkan 1.1. add_device_extension(VK_KHR_DEVICE_GROUP_EXTENSION_NAME); - // Required by VK_KHR_device_group. - add_instance_extension(VK_KHR_DEVICE_GROUP_CREATION_EXTENSION_NAME); } BufferDeviceAddress::~BufferDeviceAddress() @@ -432,6 +429,12 @@ void BufferDeviceAddress::request_gpu_features(vkb::core::PhysicalDeviceC &gpu) REQUEST_REQUIRED_FEATURE(gpu, VkPhysicalDeviceBufferDeviceAddressFeaturesKHR, bufferDeviceAddress); } +void BufferDeviceAddress::request_instance_extensions(std::unordered_map &requested_extensions) const +{ + ApiVulkanSample::request_instance_extensions(requested_extensions); + requested_extensions[VK_KHR_DEVICE_GROUP_CREATION_EXTENSION_NAME] = vkb::RequestMode::Required; // Required by VK_KHR_device_group. +} + std::unique_ptr create_buffer_device_address() { return std::make_unique(); diff --git a/samples/extensions/buffer_device_address/buffer_device_address.h b/samples/extensions/buffer_device_address/buffer_device_address.h index 959795d45c..067583c54d 100644 --- a/samples/extensions/buffer_device_address/buffer_device_address.h +++ b/samples/extensions/buffer_device_address/buffer_device_address.h @@ -70,6 +70,9 @@ class BufferDeviceAddress : public ApiVulkanSample uint32_t descriptor_offset{}; float accumulated_time{}; uint32_t num_indices_per_mesh{}; + + protected: + void request_instance_extensions(std::unordered_map &requested_extensions) const override; }; std::unique_ptr create_buffer_device_address(); diff --git a/samples/extensions/calibrated_timestamps/calibrated_timestamps.cpp b/samples/extensions/calibrated_timestamps/calibrated_timestamps.cpp index d9987a3afd..6a9b7c91f9 100644 --- a/samples/extensions/calibrated_timestamps/calibrated_timestamps.cpp +++ b/samples/extensions/calibrated_timestamps/calibrated_timestamps.cpp @@ -39,8 +39,6 @@ CalibratedTimestamps::CalibratedTimestamps() : { title = "Calibrated Timestamps"; - // Add instance extensions required for calibrated timestamps - add_instance_extension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); // NOTICE THAT: calibrated timestamps is a DEVICE extension! add_device_extension(VK_EXT_CALIBRATED_TIMESTAMPS_EXTENSION_NAME); } diff --git a/samples/extensions/color_write_enable/color_write_enable.cpp b/samples/extensions/color_write_enable/color_write_enable.cpp index 24723b0f37..eb83fc11cc 100644 --- a/samples/extensions/color_write_enable/color_write_enable.cpp +++ b/samples/extensions/color_write_enable/color_write_enable.cpp @@ -19,7 +19,6 @@ ColorWriteEnable::ColorWriteEnable() { - add_instance_extension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); add_device_extension(VK_EXT_COLOR_WRITE_ENABLE_EXTENSION_NAME); add_device_extension(VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME); } diff --git a/samples/extensions/conservative_rasterization/conservative_rasterization.cpp b/samples/extensions/conservative_rasterization/conservative_rasterization.cpp index d69f5812b6..7408c9feb1 100644 --- a/samples/extensions/conservative_rasterization/conservative_rasterization.cpp +++ b/samples/extensions/conservative_rasterization/conservative_rasterization.cpp @@ -32,9 +32,6 @@ ConservativeRasterization::ConservativeRasterization() { title = "Conservative rasterization"; - // Reading device properties of conservative rasterization requires VK_KHR_get_physical_device_properties2 to be enabled - add_instance_extension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); - // Enable extension required for conservative rasterization add_device_extension(VK_EXT_CONSERVATIVE_RASTERIZATION_EXTENSION_NAME); } diff --git a/samples/extensions/debug_utils/debug_utils.cpp b/samples/extensions/debug_utils/debug_utils.cpp index ff0dd6b4a0..0cbf904d57 100644 --- a/samples/extensions/debug_utils/debug_utils.cpp +++ b/samples/extensions/debug_utils/debug_utils.cpp @@ -71,10 +71,10 @@ DebugUtils::~DebugUtils() */ void DebugUtils::debug_check_extension() { - std::vector enabled_instance_extensions = get_instance().get_extensions(); + std::vector enabled_instance_extensions = get_instance().get_extensions(); for (auto &enabled_extension : enabled_instance_extensions) { - if (strcmp(enabled_extension, VK_EXT_DEBUG_UTILS_EXTENSION_NAME) == 0) + if (enabled_extension == VK_EXT_DEBUG_UTILS_EXTENSION_NAME) { debug_utils_supported = true; break; diff --git a/samples/extensions/descriptor_buffer_basic/descriptor_buffer_basic.cpp b/samples/extensions/descriptor_buffer_basic/descriptor_buffer_basic.cpp index da175a50a6..a698cb142a 100644 --- a/samples/extensions/descriptor_buffer_basic/descriptor_buffer_basic.cpp +++ b/samples/extensions/descriptor_buffer_basic/descriptor_buffer_basic.cpp @@ -30,8 +30,6 @@ DescriptorBufferBasic::DescriptorBufferBasic() { title = "Descriptor buffers"; - set_api_version(VK_API_VERSION_1_1); - // Enable extension required for descriptor buffers add_device_extension(VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME); add_device_extension(VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME); diff --git a/samples/extensions/descriptor_indexing/descriptor_indexing.cpp b/samples/extensions/descriptor_indexing/descriptor_indexing.cpp index 7f853d0e72..475a3d1d8c 100644 --- a/samples/extensions/descriptor_indexing/descriptor_indexing.cpp +++ b/samples/extensions/descriptor_indexing/descriptor_indexing.cpp @@ -24,30 +24,12 @@ DescriptorIndexing::DescriptorIndexing() { title = "Descriptor indexing"; - add_instance_extension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); add_device_extension(VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME); add_device_extension(VK_KHR_MAINTENANCE3_EXTENSION_NAME); // Works around a validation layer bug with descriptor pool allocation with VARIABLE_COUNT. // See: https://github.com/KhronosGroup/Vulkan-ValidationLayers/issues/2350. add_device_extension(VK_KHR_MAINTENANCE1_EXTENSION_NAME); - -#if defined(PLATFORM__MACOS) - // On Apple use layer setting to enable MoltenVK's Metal argument buffers - needed for descriptor indexing/scaling - add_instance_extension(VK_EXT_LAYER_SETTINGS_EXTENSION_NAME, /*optional*/ true); - - VkLayerSettingEXT layerSetting; - layerSetting.pLayerName = "MoltenVK"; - layerSetting.pSettingName = "MVK_CONFIG_USE_METAL_ARGUMENT_BUFFERS"; - layerSetting.type = VK_LAYER_SETTING_TYPE_INT32_EXT; - layerSetting.valueCount = 1; - - // Make this static so layer setting reference remains valid after leaving constructor scope - static const int32_t useMetalArgumentBuffers = 1; - layerSetting.pValues = &useMetalArgumentBuffers; - - add_layer_setting(layerSetting); -#endif } DescriptorIndexing::~DescriptorIndexing() @@ -559,6 +541,24 @@ void DescriptorIndexing::request_gpu_features(vkb::core::PhysicalDeviceC &gpu) vkGetPhysicalDeviceProperties2KHR(gpu.get_handle(), &device_properties); } +#if defined(PLATFORM__MACOS) +void DescriptorIndexing::request_instance_extensions(std::unordered_map &requested_extensions) const +{ + ApiVulkanSample::request_instance_extensions(requested_extensions); + // On Apple use layer setting to enable MoltenVK's Metal argument buffers - needed for descriptor indexing/scaling + requested_extensions[VK_EXT_LAYER_SETTINGS_EXTENSION_NAME] = vkb::RequestMode::Optional; +} + +void DescriptorIndexing::request_layer_settings(std::vector &requested_layer_settings) const +{ + // Make this static so layer setting reference remains valid after leaving the current scope + static const int32_t useMetalArgumentBuffers = 1; + + ApiVulkanSample::request_layer_settings(requested_layer_settings); + requested_layer_settings.push_back({"MoltenVK", "MVK_CONFIG_USE_METAL_ARGUMENT_BUFFERS", VK_LAYER_SETTING_TYPE_INT32_EXT, 1, &useMetalArgumentBuffers}); +} +#endif + std::unique_ptr create_descriptor_indexing() { return std::make_unique(); diff --git a/samples/extensions/descriptor_indexing/descriptor_indexing.h b/samples/extensions/descriptor_indexing/descriptor_indexing.h index 2e5daecb59..d539646053 100644 --- a/samples/extensions/descriptor_indexing/descriptor_indexing.h +++ b/samples/extensions/descriptor_indexing/descriptor_indexing.h @@ -28,11 +28,15 @@ class DescriptorIndexing : public ApiVulkanSample ~DescriptorIndexing(); private: - virtual void request_gpu_features(vkb::core::PhysicalDeviceC &gpu) override; - virtual void render(float delta_time) override; - virtual void build_command_buffers() override; - virtual void on_update_ui_overlay(vkb::Drawer &drawer) override; - virtual bool prepare(const vkb::ApplicationOptions &options) override; + void request_gpu_features(vkb::core::PhysicalDeviceC &gpu) override; + void render(float delta_time) override; + void build_command_buffers() override; + void on_update_ui_overlay(vkb::Drawer &drawer) override; + bool prepare(const vkb::ApplicationOptions &options) override; +#if defined(PLATFORM__MACOS) + void request_instance_extensions(std::unordered_map &requested_extensions) const override; + void request_layer_settings(std::vector &requested_layer_settings) const override; +#endif void create_bindless_descriptors(); void create_immutable_sampler_descriptor_set(); diff --git a/samples/extensions/dynamic_blending/dynamic_blending.cpp b/samples/extensions/dynamic_blending/dynamic_blending.cpp index 87dc987a77..518673231e 100644 --- a/samples/extensions/dynamic_blending/dynamic_blending.cpp +++ b/samples/extensions/dynamic_blending/dynamic_blending.cpp @@ -22,7 +22,6 @@ DynamicBlending::DynamicBlending() { - add_instance_extension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); add_device_extension(VK_EXT_EXTENDED_DYNAMIC_STATE_3_EXTENSION_NAME); add_device_extension(VK_EXT_BLEND_OPERATION_ADVANCED_EXTENSION_NAME); diff --git a/samples/extensions/dynamic_multisample_rasterization/dynamic_multisample_rasterization.cpp b/samples/extensions/dynamic_multisample_rasterization/dynamic_multisample_rasterization.cpp index 242f936635..2005b365f5 100644 --- a/samples/extensions/dynamic_multisample_rasterization/dynamic_multisample_rasterization.cpp +++ b/samples/extensions/dynamic_multisample_rasterization/dynamic_multisample_rasterization.cpp @@ -27,7 +27,6 @@ DynamicMultisampleRasterization::DynamicMultisampleRasterization() { title = "DynamicState3 Multisample Rasterization"; - set_api_version(VK_API_VERSION_1_2); add_device_extension(VK_EXT_EXTENDED_DYNAMIC_STATE_3_EXTENSION_NAME); add_device_extension(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME); } @@ -51,6 +50,11 @@ DynamicMultisampleRasterization::~DynamicMultisampleRasterization() } } +uint32_t DynamicMultisampleRasterization::get_api_version() const +{ + return VK_API_VERSION_1_2; +} + void DynamicMultisampleRasterization::request_gpu_features(vkb::core::PhysicalDeviceC &gpu) { REQUEST_REQUIRED_FEATURE(gpu, VkPhysicalDeviceExtendedDynamicState3FeaturesEXT, extendedDynamicState3RasterizationSamples); diff --git a/samples/extensions/dynamic_multisample_rasterization/dynamic_multisample_rasterization.h b/samples/extensions/dynamic_multisample_rasterization/dynamic_multisample_rasterization.h index 75390a2ec4..3b1420853e 100644 --- a/samples/extensions/dynamic_multisample_rasterization/dynamic_multisample_rasterization.h +++ b/samples/extensions/dynamic_multisample_rasterization/dynamic_multisample_rasterization.h @@ -125,6 +125,9 @@ class DynamicMultisampleRasterization : public ApiVulkanSample void draw_node(VkCommandBuffer &, SceneNode &); void destroy_image_data(ImageData &image_data); void attachments_setup(std::vector &attachments, std::vector &clear_values); + + protected: + uint32_t get_api_version() const override; }; std::unique_ptr> create_dynamic_multisample_rasterization(); diff --git a/samples/extensions/dynamic_primitive_clipping/dynamic_primitive_clipping.cpp b/samples/extensions/dynamic_primitive_clipping/dynamic_primitive_clipping.cpp index ba8200bbfc..4435ec05d2 100644 --- a/samples/extensions/dynamic_primitive_clipping/dynamic_primitive_clipping.cpp +++ b/samples/extensions/dynamic_primitive_clipping/dynamic_primitive_clipping.cpp @@ -24,10 +24,8 @@ DynamicPrimitiveClipping::DynamicPrimitiveClipping() { title = "Dynamic primitive clipping"; - set_api_version(VK_API_VERSION_1_1); // Extensions required by vkCmdSetDepthClipEnableEXT(). - add_instance_extension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); add_device_extension(VK_EXT_DEPTH_CLIP_ENABLE_EXTENSION_NAME); add_device_extension(VK_EXT_EXTENDED_DYNAMIC_STATE_3_EXTENSION_NAME); } diff --git a/samples/extensions/dynamic_rendering/dynamic_rendering.cpp b/samples/extensions/dynamic_rendering/dynamic_rendering.cpp index f955082369..d6ec071a91 100644 --- a/samples/extensions/dynamic_rendering/dynamic_rendering.cpp +++ b/samples/extensions/dynamic_rendering/dynamic_rendering.cpp @@ -23,9 +23,6 @@ DynamicRendering::DynamicRendering() : { title = "Dynamic Rendering"; - // Dynamic Rendering is a Vulkan 1.2 extension - set_api_version(VK_API_VERSION_1_2); - add_instance_extension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); add_device_extension(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME); } @@ -47,6 +44,12 @@ DynamicRendering::~DynamicRendering() } } +uint32_t DynamicRendering::get_api_version() const +{ + // Dynamic Rendering is a Vulkan 1.2 extension + return VK_API_VERSION_1_2; +} + bool DynamicRendering::prepare(const vkb::ApplicationOptions &options) { if (!ApiVulkanSample::prepare(options)) diff --git a/samples/extensions/dynamic_rendering/dynamic_rendering.h b/samples/extensions/dynamic_rendering/dynamic_rendering.h index b84c2aeb92..41f0d54df1 100644 --- a/samples/extensions/dynamic_rendering/dynamic_rendering.h +++ b/samples/extensions/dynamic_rendering/dynamic_rendering.h @@ -34,6 +34,9 @@ class DynamicRendering : public ApiVulkanSample void on_update_ui_overlay(vkb::Drawer &drawer) override; void request_gpu_features(vkb::core::PhysicalDeviceC &gpu) override; + protected: + uint32_t get_api_version() const override; + private: void load_assets(); void prepare_uniform_buffers(); diff --git a/samples/extensions/dynamic_rendering_local_read/dynamic_rendering_local_read.cpp b/samples/extensions/dynamic_rendering_local_read/dynamic_rendering_local_read.cpp index d5f129bedb..594699571b 100644 --- a/samples/extensions/dynamic_rendering_local_read/dynamic_rendering_local_read.cpp +++ b/samples/extensions/dynamic_rendering_local_read/dynamic_rendering_local_read.cpp @@ -31,8 +31,6 @@ DynamicRenderingLocalRead::DynamicRenderingLocalRead() camera.set_perspective(60.f, static_cast(width) / static_cast(height), 256.f, 0.1f); #if defined(USE_DYNAMIC_RENDERING) - set_api_version(VK_API_VERSION_1_2); - add_instance_extension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); add_device_extension(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME); add_device_extension(VK_KHR_DYNAMIC_RENDERING_LOCAL_READ_EXTENSION_NAME); // To simplify barrier setup used for dynamic rendering, we use sync2 @@ -71,6 +69,11 @@ DynamicRenderingLocalRead::~DynamicRenderingLocalRead() } } +uint32_t DynamicRenderingLocalRead::get_api_version() const +{ + return VK_API_VERSION_1_2; +} + void DynamicRenderingLocalRead::request_gpu_features(vkb::core::PhysicalDeviceC &gpu) { if (gpu.get_features().samplerAnisotropy) diff --git a/samples/extensions/dynamic_rendering_local_read/dynamic_rendering_local_read.h b/samples/extensions/dynamic_rendering_local_read/dynamic_rendering_local_read.h index dd0b7a0235..d25830ae3f 100644 --- a/samples/extensions/dynamic_rendering_local_read/dynamic_rendering_local_read.h +++ b/samples/extensions/dynamic_rendering_local_read/dynamic_rendering_local_read.h @@ -35,6 +35,9 @@ class DynamicRenderingLocalRead : public ApiVulkanSample void request_gpu_features(vkb::core::PhysicalDeviceC &gpu) override; void on_update_ui_overlay(vkb::Drawer &drawer) override; + protected: + uint32_t get_api_version() const override; + private: struct Scenes { diff --git a/samples/extensions/extended_dynamic_state2/extended_dynamic_state2.cpp b/samples/extensions/extended_dynamic_state2/extended_dynamic_state2.cpp index 4bf4399b03..9c017b4a46 100644 --- a/samples/extensions/extended_dynamic_state2/extended_dynamic_state2.cpp +++ b/samples/extensions/extended_dynamic_state2/extended_dynamic_state2.cpp @@ -29,7 +29,6 @@ ExtendedDynamicState2::ExtendedDynamicState2() { title = "Extended Dynamic State2"; - add_instance_extension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); add_device_extension(VK_EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME); add_device_extension(VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME); add_device_extension(VK_EXT_PRIMITIVE_TOPOLOGY_LIST_RESTART_EXTENSION_NAME); diff --git a/samples/extensions/fragment_density_map/fragment_density_map.cpp b/samples/extensions/fragment_density_map/fragment_density_map.cpp index a3cc019827..c1fdc85b53 100644 --- a/samples/extensions/fragment_density_map/fragment_density_map.cpp +++ b/samples/extensions/fragment_density_map/fragment_density_map.cpp @@ -52,7 +52,6 @@ void FragmentDensityMap::destroy_pipeline(FragmentDensityMap::PipelineData &pipe FragmentDensityMap::FragmentDensityMap() { title = "Fragment Density Map"; - add_instance_extension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); add_device_extension(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME); add_device_extension(VK_KHR_MAINTENANCE2_EXTENSION_NAME); add_device_extension(VK_EXT_FRAGMENT_DENSITY_MAP_EXTENSION_NAME); diff --git a/samples/extensions/fragment_shader_barycentric/fragment_shader_barycentric.cpp b/samples/extensions/fragment_shader_barycentric/fragment_shader_barycentric.cpp index 55a915033b..51f2df54ca 100644 --- a/samples/extensions/fragment_shader_barycentric/fragment_shader_barycentric.cpp +++ b/samples/extensions/fragment_shader_barycentric/fragment_shader_barycentric.cpp @@ -21,7 +21,6 @@ FragmentShaderBarycentric::FragmentShaderBarycentric() { title = "Fragment shader barycentric"; - add_instance_extension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); add_device_extension(VK_KHR_FRAGMENT_SHADER_BARYCENTRIC_EXTENSION_NAME); } @@ -42,6 +41,7 @@ FragmentShaderBarycentric::~FragmentShaderBarycentric() vkDestroyDescriptorSetLayout(get_device().get_handle(), descriptor_set_layout, VK_NULL_HANDLE); } } + /** * @fn bool FragmentShaderBarycentric::prepare(const vkb::ApplicationOptions &options) * @brief Configuring all sample specific settings, creating descriptor sets/pool, pipelines, generating or loading models etc. diff --git a/samples/extensions/fragment_shading_rate/fragment_shading_rate.cpp b/samples/extensions/fragment_shading_rate/fragment_shading_rate.cpp index 388ac54a9b..420efd8282 100644 --- a/samples/extensions/fragment_shading_rate/fragment_shading_rate.cpp +++ b/samples/extensions/fragment_shading_rate/fragment_shading_rate.cpp @@ -26,7 +26,6 @@ FragmentShadingRate::FragmentShadingRate() { title = "Fragment shading rate"; // Enable instance and device extensions required to use VK_KHR_fragment_shading_rate - add_instance_extension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); add_device_extension(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME); add_device_extension(VK_KHR_MULTIVIEW_EXTENSION_NAME); add_device_extension(VK_KHR_MAINTENANCE2_EXTENSION_NAME); diff --git a/samples/extensions/fragment_shading_rate_dynamic/fragment_shading_rate_dynamic.cpp b/samples/extensions/fragment_shading_rate_dynamic/fragment_shading_rate_dynamic.cpp index a6cbcf01fc..4bf36f1783 100644 --- a/samples/extensions/fragment_shading_rate_dynamic/fragment_shading_rate_dynamic.cpp +++ b/samples/extensions/fragment_shading_rate_dynamic/fragment_shading_rate_dynamic.cpp @@ -25,7 +25,6 @@ FragmentShadingRateDynamic::FragmentShadingRateDynamic() : (void) ubo_scene.skysphere_modelview; // this is used in the shader // Enable instance and device extensions required to use VK_KHR_fragment_shading_rate - add_instance_extension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); add_device_extension(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME); add_device_extension(VK_KHR_MULTIVIEW_EXTENSION_NAME); add_device_extension(VK_KHR_MAINTENANCE2_EXTENSION_NAME); @@ -1108,7 +1107,7 @@ bool FragmentShadingRateDynamic::prepare(const vkb::ApplicationOptions &options) const auto enabled_instance_extensions = get_instance().get_extensions(); debug_utils_supported = - std::ranges::find_if(enabled_instance_extensions, [](const char *ext) { return strcmp(ext, VK_EXT_DEBUG_UTILS_EXTENSION_NAME) == 0; }) != + std::ranges::find_if(enabled_instance_extensions, [](std::string const &ext) { return ext == VK_EXT_DEBUG_UTILS_EXTENSION_NAME; }) != enabled_instance_extensions.cend(); camera.type = vkb::CameraType::FirstPerson; diff --git a/samples/extensions/graphics_pipeline_library/graphics_pipeline_library.cpp b/samples/extensions/graphics_pipeline_library/graphics_pipeline_library.cpp index ee986fa2f4..afe47470bc 100644 --- a/samples/extensions/graphics_pipeline_library/graphics_pipeline_library.cpp +++ b/samples/extensions/graphics_pipeline_library/graphics_pipeline_library.cpp @@ -53,7 +53,6 @@ GraphicsPipelineLibrary::GraphicsPipelineLibrary() title = "Graphics pipeline library"; // Graphics pipeline library related extensions required by this sample - add_instance_extension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); add_device_extension(VK_KHR_PIPELINE_LIBRARY_EXTENSION_NAME); add_device_extension(VK_EXT_GRAPHICS_PIPELINE_LIBRARY_EXTENSION_NAME); } diff --git a/samples/extensions/gshader_to_mshader/gshader_to_mshader.cpp b/samples/extensions/gshader_to_mshader/gshader_to_mshader.cpp index 7c96d70439..c6966639b9 100644 --- a/samples/extensions/gshader_to_mshader/gshader_to_mshader.cpp +++ b/samples/extensions/gshader_to_mshader/gshader_to_mshader.cpp @@ -21,7 +21,6 @@ GshaderToMshader::GshaderToMshader() { title = "task_mesh_migration"; - set_api_version(VK_API_VERSION_1_1); add_device_extension(VK_EXT_MESH_SHADER_EXTENSION_NAME); add_device_extension(VK_KHR_SPIRV_1_4_EXTENSION_NAME); add_device_extension(VK_KHR_SHADER_FLOAT_CONTROLS_EXTENSION_NAME); diff --git a/samples/extensions/host_image_copy/host_image_copy.cpp b/samples/extensions/host_image_copy/host_image_copy.cpp index 54614a9780..00b4a62cc5 100644 --- a/samples/extensions/host_image_copy/host_image_copy.cpp +++ b/samples/extensions/host_image_copy/host_image_copy.cpp @@ -24,7 +24,6 @@ HostImageCopy::HostImageCopy() rotation = {-25.0f, 45.0f, 0.0f}; // Enable required extensions - add_instance_extension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); add_device_extension(VK_KHR_FORMAT_FEATURE_FLAGS_2_EXTENSION_NAME); add_device_extension(VK_KHR_COPY_COMMANDS_2_EXTENSION_NAME); add_device_extension(VK_EXT_HOST_IMAGE_COPY_EXTENSION_NAME); diff --git a/samples/extensions/hpp_mesh_shading/hpp_mesh_shading.cpp b/samples/extensions/hpp_mesh_shading/hpp_mesh_shading.cpp index 74e4c8757a..aff1fcd571 100644 --- a/samples/extensions/hpp_mesh_shading/hpp_mesh_shading.cpp +++ b/samples/extensions/hpp_mesh_shading/hpp_mesh_shading.cpp @@ -27,8 +27,6 @@ HPPMeshShading::HPPMeshShading() title = "Mesh shading"; // VK_EXT_mesh_shader depends on VK_KHR_spirv_1_4, which in turn depends on Vulkan 1.1 and VK_KHR_shader_float_controls - set_api_version(VK_API_VERSION_1_1); - add_device_extension(VK_EXT_MESH_SHADER_EXTENSION_NAME); add_device_extension(VK_KHR_SHADER_FLOAT_CONTROLS_EXTENSION_NAME); add_device_extension(VK_KHR_SPIRV_1_4_EXTENSION_NAME); diff --git a/samples/extensions/hpp_push_descriptors/hpp_push_descriptors.cpp b/samples/extensions/hpp_push_descriptors/hpp_push_descriptors.cpp index 3ce0487093..3d208b6726 100644 --- a/samples/extensions/hpp_push_descriptors/hpp_push_descriptors.cpp +++ b/samples/extensions/hpp_push_descriptors/hpp_push_descriptors.cpp @@ -34,7 +34,6 @@ HPPPushDescriptors::HPPPushDescriptors() title = "Push descriptors"; // Enable extension required for push descriptors - add_instance_extension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); add_device_extension(VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME); } diff --git a/samples/extensions/logic_op_dynamic_state/logic_op_dynamic_state.cpp b/samples/extensions/logic_op_dynamic_state/logic_op_dynamic_state.cpp index 19851eaba7..89ec6b7efe 100644 --- a/samples/extensions/logic_op_dynamic_state/logic_op_dynamic_state.cpp +++ b/samples/extensions/logic_op_dynamic_state/logic_op_dynamic_state.cpp @@ -32,7 +32,6 @@ LogicOpDynamicState::LogicOpDynamicState() title = "Logic Operations Dynamic State"; /* Extensions required for dynamic logic operations */ - add_instance_extension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); add_device_extension(VK_EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME); add_device_extension(VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME); add_device_extension(VK_EXT_PRIMITIVE_TOPOLOGY_LIST_RESTART_EXTENSION_NAME); diff --git a/samples/extensions/memory_budget/memory_budget.cpp b/samples/extensions/memory_budget/memory_budget.cpp index 11cd717a50..5ae3ed8bfa 100644 --- a/samples/extensions/memory_budget/memory_budget.cpp +++ b/samples/extensions/memory_budget/memory_budget.cpp @@ -29,7 +29,6 @@ MemoryBudget::MemoryBudget() title = "Memory Budget"; // Enable instance and device extensions required to use VK_EXT_memory_budget - add_instance_extension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); add_device_extension(VK_EXT_MEMORY_BUDGET_EXTENSION_NAME); // Initialize physical device memory properties variables diff --git a/samples/extensions/mesh_shader_culling/mesh_shader_culling.cpp b/samples/extensions/mesh_shader_culling/mesh_shader_culling.cpp index bc56f79835..72c14ca695 100644 --- a/samples/extensions/mesh_shader_culling/mesh_shader_culling.cpp +++ b/samples/extensions/mesh_shader_culling/mesh_shader_culling.cpp @@ -24,9 +24,6 @@ MeshShaderCulling::MeshShaderCulling() { title = "Mesh shader culling"; - // Configure application version - set_api_version(VK_API_VERSION_1_1); - // Adding device extensions add_device_extension(VK_KHR_SPIRV_1_4_EXTENSION_NAME); add_device_extension(VK_EXT_MESH_SHADER_EXTENSION_NAME); diff --git a/samples/extensions/mesh_shading/mesh_shading.cpp b/samples/extensions/mesh_shading/mesh_shading.cpp index a5465a4ba3..03ed8180e2 100644 --- a/samples/extensions/mesh_shading/mesh_shading.cpp +++ b/samples/extensions/mesh_shading/mesh_shading.cpp @@ -27,9 +27,7 @@ MeshShading::MeshShading() : { title = "Mesh shading"; - // vk_mesh_ext requires Vulkan 1.1 and device properties 2. SPIR-V must also be set to at least 1.4. - set_api_version(VK_API_VERSION_1_1); - add_instance_extension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); + // vk_mesh_ext requires device properties 2. SPIR-V must also be set to at least 1.4. add_device_extension(VK_KHR_SPIRV_1_4_EXTENSION_NAME); add_device_extension(VK_EXT_MESH_SHADER_EXTENSION_NAME); add_device_extension(VK_KHR_SHADER_FLOAT_CONTROLS_EXTENSION_NAME); diff --git a/samples/extensions/open_cl_interop/open_cl_interop.cpp b/samples/extensions/open_cl_interop/open_cl_interop.cpp index f68f2cc548..7e13639fee 100644 --- a/samples/extensions/open_cl_interop/open_cl_interop.cpp +++ b/samples/extensions/open_cl_interop/open_cl_interop.cpp @@ -115,9 +115,6 @@ OpenCLInterop::OpenCLInterop() add_device_extension(VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME); add_device_extension(VK_KHR_EXTERNAL_FENCE_FD_EXTENSION_NAME); #endif - add_instance_extension(VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME); - add_instance_extension(VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME); - add_instance_extension(VK_KHR_EXTERNAL_FENCE_CAPABILITIES_EXTENSION_NAME); } OpenCLInterop::~OpenCLInterop() @@ -218,6 +215,14 @@ void OpenCLInterop::render(float delta_time) CL_CHECK(clEnqueueSignalSemaphoresKHR(opencl_objects.command_queue, 1, &opencl_objects.cl_update_vk_semaphore, nullptr, 0, nullptr, nullptr)); } +void OpenCLInterop::request_instance_extensions(std::unordered_map &requested_extensions) const +{ + ApiVulkanSample::request_instance_extensions(requested_extensions); + requested_extensions[VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME] = vkb::RequestMode::Required; + requested_extensions[VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME] = vkb::RequestMode::Required; + requested_extensions[VK_KHR_EXTERNAL_FENCE_CAPABILITIES_EXTENSION_NAME] = vkb::RequestMode::Required; +} + void OpenCLInterop::view_changed() { update_uniform_buffers(); diff --git a/samples/extensions/open_cl_interop/open_cl_interop.h b/samples/extensions/open_cl_interop/open_cl_interop.h index 435eea4207..85ffbb52c7 100644 --- a/samples/extensions/open_cl_interop/open_cl_interop.h +++ b/samples/extensions/open_cl_interop/open_cl_interop.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2023-2024, Sascha Willems +/* Copyright (c) 2023-2025, Sascha Willems * * SPDX-License-Identifier: Apache-2.0 * @@ -48,6 +48,9 @@ class OpenCLInterop : public ApiVulkanSample void view_changed() override; void build_command_buffers() override; + protected: + void request_instance_extensions(std::unordered_map &requested_extensions) const override; + private: void prepare_pipelines(); void prepare_opencl_resources(); diff --git a/samples/extensions/open_cl_interop_arm/open_cl_interop_arm.cpp b/samples/extensions/open_cl_interop_arm/open_cl_interop_arm.cpp index eb484c3cf0..2b2211dca5 100644 --- a/samples/extensions/open_cl_interop_arm/open_cl_interop_arm.cpp +++ b/samples/extensions/open_cl_interop_arm/open_cl_interop_arm.cpp @@ -51,8 +51,6 @@ OpenCLInteropArm::OpenCLInteropArm() add_device_extension(VK_KHR_MAINTENANCE1_EXTENSION_NAME); add_device_extension(VK_KHR_BIND_MEMORY_2_EXTENSION_NAME); add_device_extension(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME); - add_instance_extension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); - add_instance_extension(VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME); add_device_extension(VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME); add_device_extension(VK_EXT_QUEUE_FAMILY_FOREIGN_EXTENSION_NAME); add_device_extension(VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME); @@ -139,6 +137,12 @@ void OpenCLInteropArm::render(float delta_time) ApiVulkanSample::submit_frame(); } +void OpenCLInteropArm::request_instance_extensions(std::unordered_map &requested_extensions) const +{ + ApiVulkanSample::request_instance_extensions(requested_extensions); + requested_extensions[VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME] = vkb::RequestMode::Required; +} + void OpenCLInteropArm::view_changed() { update_uniform_buffers(); diff --git a/samples/extensions/open_cl_interop_arm/open_cl_interop_arm.h b/samples/extensions/open_cl_interop_arm/open_cl_interop_arm.h index 85649ae4fc..9aef80fea5 100644 --- a/samples/extensions/open_cl_interop_arm/open_cl_interop_arm.h +++ b/samples/extensions/open_cl_interop_arm/open_cl_interop_arm.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2021-2024, Arm Limited and Contributors +/* Copyright (c) 2021-2025, Arm Limited and Contributors * * SPDX-License-Identifier: Apache-2.0 * @@ -36,6 +36,9 @@ class OpenCLInteropArm : public ApiVulkanSample void view_changed() override; void build_command_buffers() override; + protected: + void request_instance_extensions(std::unordered_map &requested_extensions) const override; + private: void prepare_pipelines(); void prepare_open_cl_resources(); diff --git a/samples/extensions/open_gl_interop/open_gl_interop.cpp b/samples/extensions/open_gl_interop/open_gl_interop.cpp index a43efaa87a..fb8496efbd 100644 --- a/samples/extensions/open_gl_interop/open_gl_interop.cpp +++ b/samples/extensions/open_gl_interop/open_gl_interop.cpp @@ -117,9 +117,6 @@ OpenGLInterop::OpenGLInterop() { zoom = -2.5f; title = "Interoperability with OpenGL"; - add_instance_extension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); - add_instance_extension(VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME); - add_instance_extension(VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME); add_device_extension(VK_KHR_EXTERNAL_SEMAPHORE_EXTENSION_NAME); add_device_extension(VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME); @@ -320,6 +317,13 @@ void OpenGLInterop::generate_quad() index_buffer->update(indices.data(), index_buffer_size); } +void OpenGLInterop::request_instance_extensions(std::unordered_map &requested_extensions) const +{ + ApiVulkanSample::request_instance_extensions(requested_extensions); + requested_extensions[VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME] = vkb::RequestMode::Required; + requested_extensions[VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME] = vkb::RequestMode::Required; +} + void OpenGLInterop::setup_descriptor_pool() { // Example uses one ubo and one image sampler diff --git a/samples/extensions/open_gl_interop/open_gl_interop.h b/samples/extensions/open_gl_interop/open_gl_interop.h index 6b0051ca8e..8460be81a8 100644 --- a/samples/extensions/open_gl_interop/open_gl_interop.h +++ b/samples/extensions/open_gl_interop/open_gl_interop.h @@ -1,5 +1,5 @@ -/* Copyright (c) 2020-2024, Bradley Austin Davis - * Copyright (c) 2020-2024, Arm Limited +/* Copyright (c) 2020-2025, Bradley Austin Davis + * Copyright (c) 2020-2025, Arm Limited * * SPDX-License-Identifier: Apache-2.0 * @@ -56,6 +56,9 @@ class OpenGLInterop : public ApiVulkanSample void view_changed() override; void on_update_ui_overlay(vkb::Drawer &drawer) override; + protected: + void request_instance_extensions(std::unordered_map &requested_extensions) const override; + private: void prepare_shared_resources(); void generate_quad(); diff --git a/samples/extensions/patch_control_points/patch_control_points.cpp b/samples/extensions/patch_control_points/patch_control_points.cpp index ed5cda7dad..333318179d 100644 --- a/samples/extensions/patch_control_points/patch_control_points.cpp +++ b/samples/extensions/patch_control_points/patch_control_points.cpp @@ -21,7 +21,6 @@ PatchControlPoints::PatchControlPoints() { title = "Patch Control Points"; - add_instance_extension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); add_device_extension(VK_EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME); add_device_extension(VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME); } diff --git a/samples/extensions/portability/portability.cpp b/samples/extensions/portability/portability.cpp index a600960e7f..41f38c6247 100644 --- a/samples/extensions/portability/portability.cpp +++ b/samples/extensions/portability/portability.cpp @@ -33,10 +33,6 @@ Portability::Portability() : filter_pass() { title = "Portability"; - // Portability is a Vulkan 1.3 extension - set_api_version(VK_API_VERSION_1_3); - add_instance_extension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); - add_instance_extension(VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME, /*optional*/ true); } Portability::~Portability() @@ -76,6 +72,12 @@ Portability::~Portability() } } +uint32_t Portability::get_api_version() const +{ + // Portability is a Vulkan 1.3 extension + return VK_API_VERSION_1_3; +} + void Portability::request_gpu_features(vkb::core::PhysicalDeviceC &gpu) { // Enable anisotropic filtering if supported @@ -85,6 +87,12 @@ void Portability::request_gpu_features(vkb::core::PhysicalDeviceC &gpu) } } +void Portability::request_instance_extensions(std::unordered_map &requested_extensions) const +{ + ApiVulkanSample::request_instance_extensions(requested_extensions); + requested_extensions[VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME] = vkb::RequestMode::Optional; +} + void Portability::build_command_buffers() { VkCommandBufferBeginInfo command_buffer_begin_info = vkb::initializers::command_buffer_begin_info(); diff --git a/samples/extensions/portability/portability.h b/samples/extensions/portability/portability.h index dd0beed11d..c3dace1c55 100644 --- a/samples/extensions/portability/portability.h +++ b/samples/extensions/portability/portability.h @@ -144,6 +144,10 @@ class Portability : public ApiVulkanSample void render(float delta_time) override; void on_update_ui_overlay(vkb::Drawer &drawer) override; bool resize(const uint32_t width, const uint32_t height) override; + + protected: + uint32_t get_api_version() const override; + void request_instance_extensions(std::unordered_map &requested_extensions) const override; }; std::unique_ptr create_portability(); diff --git a/samples/extensions/push_descriptors/push_descriptors.cpp b/samples/extensions/push_descriptors/push_descriptors.cpp index ec18d4a3ea..5867b41c20 100644 --- a/samples/extensions/push_descriptors/push_descriptors.cpp +++ b/samples/extensions/push_descriptors/push_descriptors.cpp @@ -36,7 +36,6 @@ PushDescriptors::PushDescriptors() title = "Push descriptors"; // Enable extension required for push descriptors - add_instance_extension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); add_device_extension(VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME); } diff --git a/samples/extensions/ray_queries/ray_queries.cpp b/samples/extensions/ray_queries/ray_queries.cpp index 73fff200a7..a04b3cd749 100644 --- a/samples/extensions/ray_queries/ray_queries.cpp +++ b/samples/extensions/ray_queries/ray_queries.cpp @@ -63,8 +63,6 @@ RayQueries::RayQueries() { title = "Ray queries"; - // SPIRV 1.4 requires Vulkan 1.1 - set_api_version(VK_API_VERSION_1_1); add_device_extension(VK_KHR_RAY_QUERY_EXTENSION_NAME); // Ray tracing related extensions required by this sample diff --git a/samples/extensions/ray_tracing_basic/ray_tracing_basic.cpp b/samples/extensions/ray_tracing_basic/ray_tracing_basic.cpp index ab66c0481f..758e62d413 100644 --- a/samples/extensions/ray_tracing_basic/ray_tracing_basic.cpp +++ b/samples/extensions/ray_tracing_basic/ray_tracing_basic.cpp @@ -25,9 +25,6 @@ RaytracingBasic::RaytracingBasic() { title = "Hardware accelerated ray tracing"; - // SPIRV 1.4 requires Vulkan 1.1 - set_api_version(VK_API_VERSION_1_1); - // Ray tracing related extensions required by this sample add_device_extension(VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME); add_device_extension(VK_KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME); diff --git a/samples/extensions/ray_tracing_extended/ray_tracing_extended.cpp b/samples/extensions/ray_tracing_extended/ray_tracing_extended.cpp index ef8afdb626..921896d094 100644 --- a/samples/extensions/ray_tracing_extended/ray_tracing_extended.cpp +++ b/samples/extensions/ray_tracing_extended/ray_tracing_extended.cpp @@ -90,9 +90,6 @@ RaytracingExtended::RaytracingExtended() : { title = "Ray tracing with extended features"; - // SPIRV 1.4 requires Vulkan 1.1 - set_api_version(VK_API_VERSION_1_1); - // Ray tracing related extensions required by this sample add_device_extension(VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME); add_device_extension(VK_KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME); diff --git a/samples/extensions/ray_tracing_position_fetch/ray_tracing_position_fetch.cpp b/samples/extensions/ray_tracing_position_fetch/ray_tracing_position_fetch.cpp index 8d326e6327..7dc12a96b2 100644 --- a/samples/extensions/ray_tracing_position_fetch/ray_tracing_position_fetch.cpp +++ b/samples/extensions/ray_tracing_position_fetch/ray_tracing_position_fetch.cpp @@ -22,9 +22,6 @@ RayTracingPositionFetch::RayTracingPositionFetch() { title = "Ray tracing position fetch"; - // SPIRV 1.4 requires Vulkan 1.1 - set_api_version(VK_API_VERSION_1_1); - // Ray tracing related extensions required by this sample add_device_extension(VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME); add_device_extension(VK_KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME); diff --git a/samples/extensions/ray_tracing_reflection/ray_tracing_reflection.cpp b/samples/extensions/ray_tracing_reflection/ray_tracing_reflection.cpp index 31a6ded930..a05f48911a 100644 --- a/samples/extensions/ray_tracing_reflection/ray_tracing_reflection.cpp +++ b/samples/extensions/ray_tracing_reflection/ray_tracing_reflection.cpp @@ -85,8 +85,6 @@ RaytracingReflection::RaytracingReflection() { title = "Hardware accelerated ray tracing"; - set_api_version(VK_API_VERSION_1_2); - // Ray tracing related extensions required by this sample add_device_extension(VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME); add_device_extension(VK_KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME); @@ -124,6 +122,11 @@ RaytracingReflection::~RaytracingReflection() } } +uint32_t RaytracingReflection::get_api_version() const +{ + return VK_API_VERSION_1_2; +} + /* Enable extension features required by this sample These are passed to device creation via a pNext structure chain diff --git a/samples/extensions/ray_tracing_reflection/ray_tracing_reflection.h b/samples/extensions/ray_tracing_reflection/ray_tracing_reflection.h index d2c38f17e6..115f5dfeee 100644 --- a/samples/extensions/ray_tracing_reflection/ray_tracing_reflection.h +++ b/samples/extensions/ray_tracing_reflection/ray_tracing_reflection.h @@ -131,6 +131,9 @@ class RaytracingReflection : public ApiVulkanSample void request_gpu_features(vkb::core::PhysicalDeviceC &gpu) override; bool prepare(const vkb::ApplicationOptions &options) override; void render(float delta_time) override; + + protected: + uint32_t get_api_version() const override; }; std::unique_ptr create_ray_tracing_reflection(); diff --git a/samples/extensions/shader_debugprintf/shader_debugprintf.cpp b/samples/extensions/shader_debugprintf/shader_debugprintf.cpp index 29f2ef96ea..ebba1f930e 100644 --- a/samples/extensions/shader_debugprintf/shader_debugprintf.cpp +++ b/samples/extensions/shader_debugprintf/shader_debugprintf.cpp @@ -47,8 +47,6 @@ ShaderDebugPrintf::ShaderDebugPrintf() title = "Shader debugprintf"; add_device_extension(VK_KHR_SHADER_NON_SEMANTIC_INFO_EXTENSION_NAME); - - add_instance_layer(validation_layer_name); } ShaderDebugPrintf::~ShaderDebugPrintf() @@ -71,6 +69,32 @@ ShaderDebugPrintf::~ShaderDebugPrintf() } } +uint32_t ShaderDebugPrintf::get_api_version() const +{ + // The validation layer (VVL) version is needed to work around validation layer performance issues when running with Vulkan SDKs <= 1.3.290 + uint32_t layer_property_count; + VK_CHECK(vkEnumerateInstanceLayerProperties(&layer_property_count, nullptr)); + std::vector layer_properties(layer_property_count); + VK_CHECK(vkEnumerateInstanceLayerProperties(&layer_property_count, layer_properties.data())); + + const auto vvl_properties = std::ranges::find_if(layer_properties, + [](VkLayerProperties const &properties) { return strcmp(properties.layerName, validation_layer_name) == 0; }); + + // Make sure we have found the validation layer before checking the VVL version and enumerating VVL instance extensions for VK_EXT_layer_settings + if (vvl_properties != layer_properties.end()) + { + // debugPrintfEXT layer feature requires Vulkan API 1.1, but override with API 1.2 for Vulkan SDKs <= 1.3.290 to work around VVL performance defect + // See VVL issue https://github.com/KhronosGroup/Vulkan-ValidationLayers/issues/7562 for defect and fix information (fix available in SDK 1.3.296) + // Note: An additional, unrelated VVL performance issue affecting nVidia GPUs was found in SDK 1.3.296 following release - for nVidia GPUs please + // use SDK 1.3.290 until a fix is made available in a later SDK (see https://github.com/KhronosGroup/Vulkan-ValidationLayers/pull/8766). + if (vvl_properties->specVersion <= VK_MAKE_API_VERSION(0, 1, 3, 290)) + { + return VK_API_VERSION_1_2; + } + } + return VK_API_VERSION_1_1; +} + void ShaderDebugPrintf::request_gpu_features(vkb::core::PhysicalDeviceC &gpu) { auto const &supportedFeatures = gpu.get_features(); @@ -94,6 +118,27 @@ void ShaderDebugPrintf::request_gpu_features(vkb::core::PhysicalDeviceC &gpu) } } +void ShaderDebugPrintf::request_layer_settings(std::vector &requested_layer_settings) const +{ + // Make this static so layer setting reference remains valid after leaving the current scope + static const VkBool32 printf_enable = VK_TRUE; + + ApiVulkanSample::request_layer_settings(requested_layer_settings); + requested_layer_settings.push_back({validation_layer_name, "printf_enable", VK_LAYER_SETTING_TYPE_BOOL32_EXT, 1, &printf_enable}); +} + +void ShaderDebugPrintf::request_validation_feature_enables(std::vector &requested_layer_settings) const +{ + ApiVulkanSample::request_validation_feature_enables(requested_layer_settings); + requested_layer_settings.push_back(VK_VALIDATION_FEATURE_ENABLE_DEBUG_PRINTF_EXT); +} + +void ShaderDebugPrintf::request_layers(std::unordered_map &requested_layers) const +{ + ApiVulkanSample::request_layers(requested_layers); + requested_layers[validation_layer_name] = vkb::RequestMode::Required; +} + void ShaderDebugPrintf::build_command_buffers() { VkCommandBufferBeginInfo command_buffer_begin_info = vkb::initializers::command_buffer_begin_info(); @@ -395,7 +440,7 @@ bool ShaderDebugPrintf::prepare(const vkb::ApplicationOptions &options) return false; } - // Register debug utils callback here vs in ShaderDebugPrintf::create_instance() so it works with both override and layer settings + // Register debug utils callback here so it works with both override and layer settings VkDebugUtilsMessengerCreateInfoEXT debug_utils_messenger_create_info{VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT}; debug_utils_messenger_create_info.messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT; debug_utils_messenger_create_info.messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT; @@ -420,137 +465,6 @@ bool ShaderDebugPrintf::prepare(const vkb::ApplicationOptions &options) return true; } -// This sample overrides the instance creation part of the framework to chain in additional structures -std::unique_ptr ShaderDebugPrintf::create_instance() -{ - auto debugprintf_api_version = VK_API_VERSION_1_1; - - // Enumerate all instance layer properties so we can find and use the validation layer (VVL) version in subsequent steps - // The VVL version is needed to work around validation layer performance issues when running with Vulkan SDKs <= 1.3.290 - uint32_t layer_property_count; - VK_CHECK(vkEnumerateInstanceLayerProperties(&layer_property_count, nullptr)); - std::vector layer_properties(layer_property_count); - VK_CHECK(vkEnumerateInstanceLayerProperties(&layer_property_count, layer_properties.data())); - - const auto vvl_properties = std::ranges::find_if(layer_properties, - [](VkLayerProperties const &properties) { return strcmp(properties.layerName, validation_layer_name) == 0; }); - - // Make sure we have found the validation layer before checking the VVL version and enumerating VVL instance extensions for VK_EXT_layer_settings - if (vvl_properties != layer_properties.end()) - { - // debugPrintfEXT layer feature requires Vulkan API 1.1, but override with API 1.2 for Vulkan SDKs <= 1.3.290 to work around VVL performance defect - // See VVL issue https://github.com/KhronosGroup/Vulkan-ValidationLayers/issues/7562 for defect and fix information (fix available in SDK 1.3.296) - // Note: An additional, unrelated VVL performance issue affecting nVidia GPUs was found in SDK 1.3.296 following release - for nVidia GPUs please - // use SDK 1.3.290 until a fix is made available in a later SDK (see https://github.com/KhronosGroup/Vulkan-ValidationLayers/pull/8766). - if (vvl_properties->specVersion <= VK_MAKE_API_VERSION(0, 1, 3, 290)) - { - debugprintf_api_version = VK_API_VERSION_1_2; - } - - // Enumerate all instance extensions for the validation layer to determine if VK_EXT_layer_settings is supported by the layer - uint32_t vvl_extension_count; - VK_CHECK(vkEnumerateInstanceExtensionProperties(validation_layer_name, &vvl_extension_count, nullptr)); - std::vector vvl_instance_extensions(vvl_extension_count); - VK_CHECK(vkEnumerateInstanceExtensionProperties(validation_layer_name, &vvl_extension_count, vvl_instance_extensions.data())); - - // When VK_EXT_layer_settings is available at runtime, the debugPrintfEXT layer feature is enabled using the standard framework - // For this case set Vulkan API version and return via base class, otherwise the remainder of this custom override is required - if (std::ranges::any_of(vvl_instance_extensions, - [](VkExtensionProperties const &extension) { return strcmp(extension.extensionName, VK_EXT_LAYER_SETTINGS_EXTENSION_NAME) == 0; })) - { - set_api_version(debugprintf_api_version); - - // Since layer settings extension is available, use it to configure validation layer for debugPrintfEXT - VkLayerSettingEXT layerSetting; - layerSetting.pLayerName = validation_layer_name; - layerSetting.pSettingName = "enables"; - layerSetting.type = VK_LAYER_SETTING_TYPE_STRING_EXT; - layerSetting.valueCount = 1; - - // Make this static so layer setting reference remains valid after leaving the current scope - static const char *layerEnables = "VK_VALIDATION_FEATURE_ENABLE_DEBUG_PRINTF_EXT"; - layerSetting.pValues = &layerEnables; - - add_layer_setting(layerSetting); - - // Run standard create_instance() from framework with set_api_version() and add_layer_setting() support - return VulkanSample::create_instance(); - } - } - - // As a fallack, run remainder of this custom create_instance() override (without layer settings support) and return - std::vector enabled_extensions; - enabled_extensions.push_back(VK_KHR_SURFACE_EXTENSION_NAME); - - for (const char *extension_name : window->get_required_surface_extensions()) - { - enabled_extensions.push_back(extension_name); - } - - enabled_extensions.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME); - enabled_extensions.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); - -#if (defined(VKB_ENABLE_PORTABILITY)) - // Enumerate all instance extensions for the loader + driver to determine if VK_KHR_portability_enumeration is available - uint32_t available_extension_count; - VK_CHECK(vkEnumerateInstanceExtensionProperties(nullptr, &available_extension_count, nullptr)); - std::vector available_instance_extensions(available_extension_count); - VK_CHECK(vkEnumerateInstanceExtensionProperties(nullptr, &available_extension_count, available_instance_extensions.data())); - - // If VK_KHR_portability_enumeration is available in the portability implementation, then we must enable the extension - bool portability_enumeration_available = false; - if (std::ranges::any_of(available_instance_extensions, - [](VkExtensionProperties const &extension) { return strcmp(extension.extensionName, VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME) == 0; })) - { - enabled_extensions.push_back(VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME); - portability_enumeration_available = true; - } -#endif - - VkApplicationInfo app_info{VK_STRUCTURE_TYPE_APPLICATION_INFO}; - app_info.pApplicationName = "Shader debugprintf"; - app_info.pEngineName = "Vulkan Samples"; - app_info.apiVersion = debugprintf_api_version; - - // Enable VK_EXT_validation_features extension for configuring validation layer features using VkValidationFeaturesEXT - enabled_extensions.push_back(VK_EXT_VALIDATION_FEATURES_EXTENSION_NAME); - - // Shader printf is a feature of the validation layers that needs to be enabled - std::vector validation_feature_enables = {VK_VALIDATION_FEATURE_ENABLE_DEBUG_PRINTF_EXT}; - - VkValidationFeaturesEXT validation_features{VK_STRUCTURE_TYPE_VALIDATION_FEATURES_EXT}; - validation_features.enabledValidationFeatureCount = static_cast(validation_feature_enables.size()); - validation_features.pEnabledValidationFeatures = validation_feature_enables.data(); - - std::vector validation_layers = {validation_layer_name}; - - VkInstanceCreateInfo instance_create_info{VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO}; - instance_create_info.ppEnabledExtensionNames = enabled_extensions.data(); - instance_create_info.enabledExtensionCount = static_cast(enabled_extensions.size()); - instance_create_info.pApplicationInfo = &app_info; - instance_create_info.ppEnabledLayerNames = validation_layers.data(); - instance_create_info.enabledLayerCount = static_cast(validation_layers.size()); -#if (defined(VKB_ENABLE_PORTABILITY)) - if (portability_enumeration_available) - { - instance_create_info.flags |= VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR; - } -#endif - instance_create_info.pNext = &validation_features; - - VkInstance vulkan_instance; - VkResult result = vkCreateInstance(&instance_create_info, nullptr, &vulkan_instance); - - if (result != VK_SUCCESS) - { - throw vkb::VulkanException{result, "Could not create instance"}; - } - - volkLoadInstance(vulkan_instance); - - return std::make_unique(vulkan_instance, enabled_extensions); -} - void ShaderDebugPrintf::render(float delta_time) { if (!prepared) diff --git a/samples/extensions/shader_debugprintf/shader_debugprintf.h b/samples/extensions/shader_debugprintf/shader_debugprintf.h index 88e632c611..ea1010db62 100644 --- a/samples/extensions/shader_debugprintf/shader_debugprintf.h +++ b/samples/extensions/shader_debugprintf/shader_debugprintf.h @@ -82,21 +82,26 @@ class ShaderDebugPrintf : public ApiVulkanSample ShaderDebugPrintf(); ~ShaderDebugPrintf(); - virtual void request_gpu_features(vkb::core::PhysicalDeviceC &gpu) override; - void build_command_buffers() override; - void load_assets(); - void setup_descriptor_pool(); - void setup_descriptor_set_layout(); - void setup_descriptor_sets(); - void prepare_pipelines(); - void prepare_uniform_buffers(); - void update_uniform_buffers(); - void draw(); - bool prepare(const vkb::ApplicationOptions &options) override; - std::unique_ptr create_instance() override; - virtual void render(float delta_time) override; - virtual void on_update_ui_overlay(vkb::Drawer &drawer) override; - virtual bool resize(const uint32_t width, const uint32_t height) override; + void request_gpu_features(vkb::core::PhysicalDeviceC &gpu) override; + void request_layer_settings(std::vector &requested_layer_settings) const override; + void request_validation_feature_enables(std::vector &requested_layer_settings) const override; + void build_command_buffers() override; + void load_assets(); + void setup_descriptor_pool(); + void setup_descriptor_set_layout(); + void setup_descriptor_sets(); + void prepare_pipelines(); + void prepare_uniform_buffers(); + void update_uniform_buffers(); + void draw(); + bool prepare(const vkb::ApplicationOptions &options) override; + virtual void render(float delta_time) override; + virtual void on_update_ui_overlay(vkb::Drawer &drawer) override; + virtual bool resize(const uint32_t width, const uint32_t height) override; + + protected: + virtual uint32_t get_api_version() const override; + virtual void request_layers(std::unordered_map &requested_layers) const override; }; std::unique_ptr create_shader_debugprintf(); diff --git a/samples/extensions/shader_object/shader_object.cpp b/samples/extensions/shader_object/shader_object.cpp index 0f8b836ac4..e8c84d96d6 100644 --- a/samples/extensions/shader_object/shader_object.cpp +++ b/samples/extensions/shader_object/shader_object.cpp @@ -26,11 +26,6 @@ ShaderObject::ShaderObject() title = "Shader Object"; rng = std::default_random_engine(12345); // Use a fixed seed, makes random deterministic. - // Show that shader object is usable with Vulkan 1.1 + Dynamic Rendering - set_api_version(VK_API_VERSION_1_1); - - add_instance_layer("VK_LAYER_KHRONOS_shader_object"); - // Enable the Shader Object extension add_device_extension(VK_EXT_SHADER_OBJECT_EXTENSION_NAME); @@ -380,6 +375,12 @@ void ShaderObject::request_gpu_features(vkb::core::PhysicalDeviceC &gpu) } } +void ShaderObject::request_layers(std::unordered_map &requested_layers) const +{ + ApiVulkanSample::request_layers(requested_layers); + requested_layers["VK_LAYER_KHRONOS_shader_object"] = vkb::RequestMode::Required; +} + void ShaderObject::load_assets() { // Load models diff --git a/samples/extensions/shader_object/shader_object.h b/samples/extensions/shader_object/shader_object.h index 30d33f4e4d..5716d6f1ca 100644 --- a/samples/extensions/shader_object/shader_object.h +++ b/samples/extensions/shader_object/shader_object.h @@ -140,6 +140,9 @@ class ShaderObject : public ApiVulkanSample void build_shader(VkDevice device, Shader *shader); void bind_shader(VkCommandBuffer cmd_buffer, ShaderObject::Shader *shader); + protected: + virtual void request_layers(std::unordered_map &requested_layers) const override; + private: void create_default_sampler(); void load_assets(); diff --git a/samples/extensions/tensor_and_data_graph/simple_tensor_and_data_graph/simple_tensor_and_data_graph.cpp b/samples/extensions/tensor_and_data_graph/simple_tensor_and_data_graph/simple_tensor_and_data_graph.cpp index 2c248d09dd..4daf9d28c2 100644 --- a/samples/extensions/tensor_and_data_graph/simple_tensor_and_data_graph/simple_tensor_and_data_graph.cpp +++ b/samples/extensions/tensor_and_data_graph/simple_tensor_and_data_graph/simple_tensor_and_data_graph.cpp @@ -21,8 +21,6 @@ SimpleTensorAndDataGraph::SimpleTensorAndDataGraph() { - set_api_version(VK_API_VERSION_1_3); // Required by the emulation layers - // Declare that we need the data graph and tensor extensions add_device_extension("VK_ARM_tensors"); add_device_extension("VK_ARM_data_graph"); @@ -46,6 +44,11 @@ SimpleTensorAndDataGraph::~SimpleTensorAndDataGraph() set_render_pipeline(nullptr); } +uint32_t SimpleTensorAndDataGraph::get_api_version() const +{ + return VK_API_VERSION_1_3; // Required by the emulation layers +} + /** * @brief Overridden to declare that we require some physical device features to be enabled. */ diff --git a/samples/extensions/tensor_and_data_graph/simple_tensor_and_data_graph/simple_tensor_and_data_graph.h b/samples/extensions/tensor_and_data_graph/simple_tensor_and_data_graph/simple_tensor_and_data_graph.h index c77c8db2f4..d85798af0d 100644 --- a/samples/extensions/tensor_and_data_graph/simple_tensor_and_data_graph/simple_tensor_and_data_graph.h +++ b/samples/extensions/tensor_and_data_graph/simple_tensor_and_data_graph/simple_tensor_and_data_graph.h @@ -60,6 +60,9 @@ class SimpleTensorAndDataGraph : public vkb::VulkanSampleC void draw_gui() override; + protected: + uint32_t get_api_version() const override; + private: void prepare_descriptor_pool(); diff --git a/samples/extensions/timeline_semaphore/timeline_semaphore.cpp b/samples/extensions/timeline_semaphore/timeline_semaphore.cpp index 3c7ee9fd22..ed97680756 100644 --- a/samples/extensions/timeline_semaphore/timeline_semaphore.cpp +++ b/samples/extensions/timeline_semaphore/timeline_semaphore.cpp @@ -38,7 +38,6 @@ TimelineSemaphore::TimelineSemaphore() title = "Timeline Semaphore"; add_device_extension(VK_KHR_TIMELINE_SEMAPHORE_EXTENSION_NAME); - add_instance_extension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); } TimelineSemaphore::~TimelineSemaphore() diff --git a/samples/extensions/vertex_dynamic_state/vertex_dynamic_state.cpp b/samples/extensions/vertex_dynamic_state/vertex_dynamic_state.cpp index 6b03063d60..5ed0856144 100644 --- a/samples/extensions/vertex_dynamic_state/vertex_dynamic_state.cpp +++ b/samples/extensions/vertex_dynamic_state/vertex_dynamic_state.cpp @@ -21,7 +21,6 @@ VertexDynamicState::VertexDynamicState() { title = "Vertex Dynamic State"; - add_instance_extension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); add_device_extension(VK_EXT_VERTEX_INPUT_DYNAMIC_STATE_EXTENSION_NAME); } diff --git a/samples/general/mobile_nerf/mobile_nerf.cpp b/samples/general/mobile_nerf/mobile_nerf.cpp index 697faa3153..8757a79f03 100644 --- a/samples/general/mobile_nerf/mobile_nerf.cpp +++ b/samples/general/mobile_nerf/mobile_nerf.cpp @@ -79,8 +79,7 @@ void camera_set_look_at(vkb::Camera &camera, const glm::vec3 look, const glm::ve MobileNerf::MobileNerf() { title = "Mobile NeRF"; - // SPIRV 1.4 requires Vulkan 1.1 - set_api_version(VK_API_VERSION_1_1); + add_device_extension(VK_KHR_SPIRV_1_4_EXTENSION_NAME); // Required by VK_KHR_spirv_1_4 add_device_extension(VK_KHR_SHADER_FLOAT_CONTROLS_EXTENSION_NAME); diff --git a/samples/general/mobile_nerf_rayquery/mobile_nerf_rayquery.cpp b/samples/general/mobile_nerf_rayquery/mobile_nerf_rayquery.cpp index 2d4b2e04de..c86a969777 100644 --- a/samples/general/mobile_nerf_rayquery/mobile_nerf_rayquery.cpp +++ b/samples/general/mobile_nerf_rayquery/mobile_nerf_rayquery.cpp @@ -76,8 +76,6 @@ MobileNerfRayQuery::MobileNerfRayQuery() { title = "Mobile Nerf Ray Query"; - set_api_version(VK_API_VERSION_1_1); - // Required by VK_KHR_acceleration_structure add_device_extension(VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME); add_device_extension(VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME); diff --git a/samples/performance/16bit_arithmetic/16bit_arithmetic.cpp b/samples/performance/16bit_arithmetic/16bit_arithmetic.cpp index a2fd2e3f80..666b818caf 100644 --- a/samples/performance/16bit_arithmetic/16bit_arithmetic.cpp +++ b/samples/performance/16bit_arithmetic/16bit_arithmetic.cpp @@ -32,7 +32,6 @@ KHR16BitArithmeticSample::KHR16BitArithmeticSample() // For this sample, this is not optional. // This sample also serves as a tutorial on how to use 16-bit storage // for SSBOs and push constants. - add_instance_extension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, false); add_device_extension(VK_KHR_STORAGE_BUFFER_STORAGE_CLASS_EXTENSION_NAME, false); add_device_extension(VK_KHR_16BIT_STORAGE_EXTENSION_NAME, false); diff --git a/samples/performance/16bit_storage_input_output/16bit_storage_input_output.cpp b/samples/performance/16bit_storage_input_output/16bit_storage_input_output.cpp index 2d83b7ab77..f42c480602 100644 --- a/samples/performance/16bit_storage_input_output/16bit_storage_input_output.cpp +++ b/samples/performance/16bit_storage_input_output/16bit_storage_input_output.cpp @@ -25,9 +25,6 @@ KHR16BitStorageInputOutputSample::KHR16BitStorageInputOutputSample() { - // For enabling 16-bit storage device extensions. - add_instance_extension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, true); - // Will be used in vertex and fragment shaders to declare varying data as FP16 rather than FP32. // This significantly reduces bandwidth as varyings are stored in main memory on TBDR architectures. // On Vulkan 1.1, this extension is in core, but just enable the extension in case we are running on a Vulkan 1.0 implementation. diff --git a/samples/performance/constant_data/constant_data.cpp b/samples/performance/constant_data/constant_data.cpp index a7bda6d223..3dc9b290b8 100644 --- a/samples/performance/constant_data/constant_data.cpp +++ b/samples/performance/constant_data/constant_data.cpp @@ -76,7 +76,6 @@ ConstantData::ConstantData() } // Request sample-specific extensions as optional - add_instance_extension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, true); add_device_extension(VK_KHR_MAINTENANCE3_EXTENSION_NAME, true); add_device_extension(VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME, true); } diff --git a/samples/performance/image_compression_control/image_compression_control.cpp b/samples/performance/image_compression_control/image_compression_control.cpp index e3934bda7c..631c1bc0a1 100644 --- a/samples/performance/image_compression_control/image_compression_control.cpp +++ b/samples/performance/image_compression_control/image_compression_control.cpp @@ -31,9 +31,6 @@ ImageCompressionControlSample::ImageCompressionControlSample() add_device_extension(VK_EXT_IMAGE_COMPRESSION_CONTROL_EXTENSION_NAME, true); add_device_extension(VK_EXT_IMAGE_COMPRESSION_CONTROL_SWAPCHAIN_EXTENSION_NAME, true); - // Extension dependency requirements (given that instance API version is 1.0.0) - add_instance_extension(VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME, true); - auto &config = get_configuration(); // Batch mode will test the toggle between different compression modes @@ -55,6 +52,12 @@ void ImageCompressionControlSample::request_gpu_features(vkb::core::PhysicalDevi } } +void ImageCompressionControlSample::request_instance_extensions(std::unordered_map &requested_extensions) const +{ + vkb::VulkanSampleC::request_instance_extensions(requested_extensions); + requested_extensions[VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME] = vkb::RequestMode::Optional; +} + bool ImageCompressionControlSample::prepare(const vkb::ApplicationOptions &options) { if (!VulkanSample::prepare(options)) diff --git a/samples/performance/image_compression_control/image_compression_control.h b/samples/performance/image_compression_control/image_compression_control.h index 14477fabd8..29c22a613c 100644 --- a/samples/performance/image_compression_control/image_compression_control.h +++ b/samples/performance/image_compression_control/image_compression_control.h @@ -50,6 +50,9 @@ class ImageCompressionControlSample : public vkb::VulkanSampleC void draw_gui() override; + protected: + void request_instance_extensions(std::unordered_map &requested_extensions) const override; + private: vkb::sg::PerspectiveCamera *camera{nullptr}; diff --git a/samples/performance/layout_transitions/layout_transitions.cpp b/samples/performance/layout_transitions/layout_transitions.cpp index 7667f48091..6dbae41dfd 100644 --- a/samples/performance/layout_transitions/layout_transitions.cpp +++ b/samples/performance/layout_transitions/layout_transitions.cpp @@ -39,8 +39,6 @@ LayoutTransitions::LayoutTransitions() #if defined(PLATFORM__MACOS) && TARGET_OS_IOS && TARGET_OS_SIMULATOR // On iOS Simulator use layer setting to disable MoltenVK's Metal argument buffers - otherwise blank display - add_instance_extension(VK_EXT_LAYER_SETTINGS_EXTENSION_NAME, /*optional*/ true); - VkLayerSettingEXT layerSetting; layerSetting.pLayerName = "MoltenVK"; layerSetting.pSettingName = "MVK_CONFIG_USE_METAL_ARGUMENT_BUFFERS"; @@ -93,6 +91,15 @@ bool LayoutTransitions::prepare(const vkb::ApplicationOptions &options) return true; } +#if defined(PLATFORM__MACOS) && TARGET_OS_IOS && TARGET_OS_SIMULATOR +void LayoutTransitions::request_instance_extensions(std::unordered_map &requested_extensions) const +{ + // On iOS Simulator use layer setting to disable MoltenVK's Metal argument buffers - otherwise blank display + vkb::VulkanSampleC::request_instance_extensions(requested_extensions); + requested_extensions[VK_EXT_LAYER_SETTINGS_EXTENSION_NAME] = vkb::RequestMode::Optional; +} +#endif + void LayoutTransitions::prepare_render_context() { get_render_context().prepare(1, [this](vkb::core::Image &&swapchain_image) { return create_render_target(std::move(swapchain_image)); }); diff --git a/samples/performance/layout_transitions/layout_transitions.h b/samples/performance/layout_transitions/layout_transitions.h index 04072b479d..b5a9e05970 100644 --- a/samples/performance/layout_transitions/layout_transitions.h +++ b/samples/performance/layout_transitions/layout_transitions.h @@ -32,7 +32,10 @@ class LayoutTransitions : public vkb::VulkanSampleC virtual ~LayoutTransitions() = default; - virtual bool prepare(const vkb::ApplicationOptions &options) override; + bool prepare(const vkb::ApplicationOptions &options) override; +#if defined(PLATFORM__MACOS) && TARGET_OS_IOS && TARGET_OS_SIMULATOR + void request_instance_extensions(std::unordered_map &requested_extensions) const override; +#endif private: enum LayoutTransitionType : int diff --git a/samples/performance/msaa/msaa.cpp b/samples/performance/msaa/msaa.cpp index 324760432d..dcc39c65a5 100644 --- a/samples/performance/msaa/msaa.cpp +++ b/samples/performance/msaa/msaa.cpp @@ -77,7 +77,6 @@ MSAASample::MSAASample() add_device_extension(VK_KHR_DEPTH_STENCIL_RESOLVE_EXTENSION_NAME, true); // Extension dependency requirements (given that instance API version is 1.0.0) - add_instance_extension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, true); add_device_extension(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME, true); add_device_extension(VK_KHR_MAINTENANCE2_EXTENSION_NAME, true); add_device_extension(VK_KHR_MULTIVIEW_EXTENSION_NAME, true); diff --git a/samples/performance/multi_draw_indirect/multi_draw_indirect.cpp b/samples/performance/multi_draw_indirect/multi_draw_indirect.cpp index 77989aa420..bae778b325 100644 --- a/samples/performance/multi_draw_indirect/multi_draw_indirect.cpp +++ b/samples/performance/multi_draw_indirect/multi_draw_indirect.cpp @@ -59,7 +59,6 @@ struct CopyBuffer MultiDrawIndirect::MultiDrawIndirect() { - set_api_version(VK_API_VERSION_1_2); add_device_extension(VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME, true /* optional */); } @@ -93,6 +92,11 @@ MultiDrawIndirect::~MultiDrawIndirect() } } +uint32_t MultiDrawIndirect::get_api_version() const +{ + return VK_API_VERSION_1_2; +} + void MultiDrawIndirect::request_gpu_features(vkb::core::PhysicalDeviceC &gpu) { if (gpu.get_features().multiDrawIndirect) diff --git a/samples/performance/multi_draw_indirect/multi_draw_indirect.h b/samples/performance/multi_draw_indirect/multi_draw_indirect.h index 4ed143167a..01c7aa660e 100644 --- a/samples/performance/multi_draw_indirect/multi_draw_indirect.h +++ b/samples/performance/multi_draw_indirect/multi_draw_indirect.h @@ -150,6 +150,9 @@ class MultiDrawIndirect : public ApiVulkanSample bool m_supports_mdi = false; bool m_supports_first_instance = false; bool m_supports_buffer_device = false; + + protected: + uint32_t get_api_version() const override; }; std::unique_ptr create_multi_draw_indirect(); diff --git a/samples/performance/pipeline_barriers/pipeline_barriers.cpp b/samples/performance/pipeline_barriers/pipeline_barriers.cpp index 1f8272427a..88d6df4426 100644 --- a/samples/performance/pipeline_barriers/pipeline_barriers.cpp +++ b/samples/performance/pipeline_barriers/pipeline_barriers.cpp @@ -41,8 +41,6 @@ PipelineBarriers::PipelineBarriers() #if defined(PLATFORM__MACOS) && TARGET_OS_IOS && TARGET_OS_SIMULATOR // On iOS Simulator use layer setting to disable MoltenVK's Metal argument buffers - otherwise blank display - add_instance_extension(VK_EXT_LAYER_SETTINGS_EXTENSION_NAME, /*optional*/ true); - VkLayerSettingEXT layerSetting; layerSetting.pLayerName = "MoltenVK"; layerSetting.pSettingName = "MVK_CONFIG_USE_METAL_ARGUMENT_BUFFERS"; @@ -127,6 +125,15 @@ bool PipelineBarriers::prepare(const vkb::ApplicationOptions &options) return true; } +#if defined(PLATFORM__MACOS) && TARGET_OS_IOS && TARGET_OS_SIMULATOR +void PipelineBarriers::request_instance_extensions(std::unordered_map &requested_extensions) const +{ + // On iOS Simulator use layer setting to disable MoltenVK's Metal argument buffers - otherwise blank display + vkb::VulkanSampleC::request_instance_extensions(requested_extensions); + requested_extensions[VK_EXT_LAYER_SETTINGS_EXTENSION_NAME] = vkb::RequestMode::Optional; +} +#endif + void PipelineBarriers::prepare_render_context() { get_render_context().prepare(1, [this](vkb::core::Image &&swapchain_image) { return create_render_target(std::move(swapchain_image)); }); diff --git a/samples/performance/pipeline_barriers/pipeline_barriers.h b/samples/performance/pipeline_barriers/pipeline_barriers.h index c6e6b6a693..5e359ffbc2 100644 --- a/samples/performance/pipeline_barriers/pipeline_barriers.h +++ b/samples/performance/pipeline_barriers/pipeline_barriers.h @@ -32,7 +32,10 @@ class PipelineBarriers : public vkb::VulkanSampleC virtual ~PipelineBarriers() = default; - virtual bool prepare(const vkb::ApplicationOptions &options) override; + bool prepare(const vkb::ApplicationOptions &options) override; +#if defined(PLATFORM__MACOS) && TARGET_OS_IOS && TARGET_OS_SIMULATOR + void request_instance_extensions(std::unordered_map &requested_extensions) const override; +#endif private: enum DependencyType : int diff --git a/samples/performance/subpasses/subpasses.cpp b/samples/performance/subpasses/subpasses.cpp index 42a66f78cb..0e338bdab9 100644 --- a/samples/performance/subpasses/subpasses.cpp +++ b/samples/performance/subpasses/subpasses.cpp @@ -53,8 +53,6 @@ Subpasses::Subpasses() #if defined(PLATFORM__MACOS) && TARGET_OS_IOS && TARGET_OS_SIMULATOR // On iOS Simulator use layer setting to disable MoltenVK's Metal argument buffers - otherwise blank display - add_instance_extension(VK_EXT_LAYER_SETTINGS_EXTENSION_NAME, /*optional*/ true); - VkLayerSettingEXT layerSetting; layerSetting.pLayerName = "MoltenVK"; layerSetting.pSettingName = "MVK_CONFIG_USE_METAL_ARGUMENT_BUFFERS"; @@ -185,6 +183,15 @@ bool Subpasses::prepare(const vkb::ApplicationOptions &options) return true; } +#if defined(PLATFORM__MACOS) && TARGET_OS_IOS && TARGET_OS_SIMULATOR +void Subpasses::request_instance_extensions(std::unordered_map &requested_extensions) const +{ + // On iOS Simulator use layer setting to disable MoltenVK's Metal argument buffers - otherwise blank display + vkb::VulkanSampleC::request_instance_extensions(requested_extensions); + requested_extensions[VK_EXT_LAYER_SETTINGS_EXTENSION_NAME] = vkb::RequestMode::Optional; +} +#endif + void Subpasses::update(float delta_time) { // Check whether the user changed the render technique diff --git a/samples/performance/subpasses/subpasses.h b/samples/performance/subpasses/subpasses.h index 4b51da39a0..4746bbb5f3 100644 --- a/samples/performance/subpasses/subpasses.h +++ b/samples/performance/subpasses/subpasses.h @@ -34,6 +34,9 @@ class Subpasses : public vkb::VulkanSampleC Subpasses(); bool prepare(const vkb::ApplicationOptions &options) override; +#if defined(PLATFORM__MACOS) && TARGET_OS_IOS && TARGET_OS_SIMULATOR + void request_instance_extensions(std::unordered_map &requested_extensions) const override; +#endif void update(float delta_time) override; diff --git a/shaders/patch_control_points/hlsl/tess.tese.spv b/shaders/patch_control_points/hlsl/tess.tese.spv index 49228d526b2772dd929fc54f67c9b1b7123ea019..f8735de47a775e5e25fe20c50af4ffa13b84cdda 100644 GIT binary patch delta 12 Tcmeyu^@3}I5aVV!#xNEDAOZv6 delta 20 bcmaFC^@VGL5F