From 6b10cd32d90e7d35e6020cbae955c9675e67f351 Mon Sep 17 00:00:00 2001 From: asuessenbach Date: Wed, 22 Apr 2026 17:47:03 +0200 Subject: [PATCH 1/2] Use StructureChainBuilder to create the debug callbacks. --- framework/core/instance.h | 2 +- framework/structure_chain_builder.h | 33 +++-- framework/vulkan_sample.h | 134 +++++++++--------- .../shader_debugprintf/shader_debugprintf.cpp | 35 +++-- .../shader_debugprintf/shader_debugprintf.h | 40 +++--- 5 files changed, 131 insertions(+), 113 deletions(-) diff --git a/framework/core/instance.h b/framework/core/instance.h index b8a86d7b5..db6a9adb2 100644 --- a/framework/core/instance.h +++ b/framework/core/instance.h @@ -247,7 +247,7 @@ inline Instance::Instance(std::string const .enabledExtensionCount = static_cast(enabled_extensions_cstr.size()), .ppEnabledExtensionNames = enabled_extensions_cstr.data()}; - vkb::StructureChainBuilder scb; + vkb::StructureChainBuilderCpp scb; scb.set_anchor_struct(create_info); if constexpr (bindingType == vkb::BindingType::Cpp) { diff --git a/framework/structure_chain_builder.h b/framework/structure_chain_builder.h index 7b68905de..caa66c654 100644 --- a/framework/structure_chain_builder.h +++ b/framework/structure_chain_builder.h @@ -25,9 +25,9 @@ namespace vkb template class StructureChainBuilder { - public: - StructureChainBuilder(); + static_assert((offsetof(AnchorStructType, sType) == 0) && (offsetof(AnchorStructType, pNext) == sizeof(void *))); + public: template T &add_chain_data(T const &data_to_add = {}); // Adds data to the structure chain builder that is not part of the structure chain itself, but is used by the // structures in the chain (e.g. pointed to by a member of a struct in the structure chain) @@ -66,13 +66,6 @@ T &StructureChainBuilder::add_chain_data(T const return *std::any_cast(chain_data.back().get()); } -template -inline StructureChainBuilder::StructureChainBuilder() -{ - static_assert((offsetof(AnchorStructType, sType) == 0) && (offsetof(AnchorStructType, pNext) == sizeof(void *))); - structure_chain.push_back(std::make_unique(std::make_any())); -} - template template inline StructType &StructureChainBuilder::add_struct(StructType const &struct_to_add) @@ -92,6 +85,11 @@ template template inline StructType &StructureChainBuilder::add_struct_impl(StructType const &struct_to_add) { + if (structure_chain.empty()) + { + structure_chain.push_back(std::make_unique(std::make_any())); + } + #if !defined(NDEBUG) auto it = std::ranges::find_if(structure_chain, [](auto const &chain_element) { return std::any_cast(chain_element.get()) != nullptr; @@ -115,7 +113,7 @@ inline StructType const *StructureChainBuilder::g } else { - return reinterpret_cast(get_struct_impl::Type>(skip)); + return reinterpret_cast(get_struct_impl::Type>(skip)); } } @@ -146,7 +144,7 @@ inline void StructureChainBuilder::set_anchor_str } else { - return reinterpret_cast::Type> *>(this)->add_anchor_struct( + reinterpret_cast::Type> *>(this)->set_anchor_struct( reinterpret_cast::Type const &>(anchor_struct)); } } @@ -154,9 +152,16 @@ inline void StructureChainBuilder::set_anchor_str template inline void StructureChainBuilder::set_anchor_struct_impl(AnchorStructType const &anchor_struct) { - void const *pNext = std::any_cast(structure_chain.front().get())->pNext; - *std::any_cast(structure_chain.front().get()) = anchor_struct; - std::any_cast(structure_chain.front().get())->pNext = pNext; + if (structure_chain.empty()) + { + structure_chain.push_back(std::make_unique(std::make_any(anchor_struct))); + } + else + { + void const *pNext = std::any_cast(structure_chain.front().get())->pNext; + *std::any_cast(structure_chain.front().get()) = anchor_struct; + std::any_cast(structure_chain.front().get())->pNext = pNext; + } } } // namespace vkb diff --git a/framework/vulkan_sample.h b/framework/vulkan_sample.h index 529de70ab..8b89e29a7 100644 --- a/framework/vulkan_sample.h +++ b/framework/vulkan_sample.h @@ -203,11 +203,11 @@ class VulkanSample : public vkb::Application */ virtual void draw_renderpass(vkb::core::CommandBuffer &command_buffer, vkb::rendering::RenderTarget &render_target); - virtual void extend_instance_create_info(vkb::StructureChainBuilder &create_info) const; - virtual uint32_t get_api_version() const; - virtual DebugReportCallbackCreateInfoType const *get_debug_report_callback_create_info() const; - virtual DebugUtilsMessengerCreateInfoType const *get_debug_utils_messenger_create_info() const; - virtual InstanceCreateFlagsType get_instance_create_flags(std::vector const &enabled_extensions) const; + virtual void extend_instance_create_info(vkb::StructureChainBuilder &scb) const; + virtual void extend_debug_report_callback_create_info(vkb::StructureChainBuilder &scb) const; + virtual void extend_debug_utils_messenger_create_info(vkb::StructureChainBuilder &scb) const; + virtual uint32_t get_api_version() const; + virtual InstanceCreateFlagsType get_instance_create_flags(std::vector const &enabled_extensions) const; /** * @brief Override this to customise the creation of the swapchain and render_context @@ -346,6 +346,11 @@ class VulkanSample : public vkb::Application void request_layer_settings_impl(std::vector &requested_layer_settings, vkb::StructureChainBuilderCpp &scb) const; static void set_viewport_and_scissor_impl(vkb::core::CommandBufferCpp const &command_buffer, vk::Extent2D const &extent); +#if defined(VKB_DEBUG) || defined(VKB_VALIDATION_LAYERS) + vk::DebugReportCallbackCreateInfoEXT get_debug_report_callback_create_info() const; + vk::DebugUtilsMessengerCreateInfoEXT get_debug_utils_messenger_create_info() const; +#endif + /** * @brief Get sample-specific device extensions. * @@ -786,16 +791,11 @@ inline void VulkanSample::extend_instance_create_info_impl(vkb::Str #if defined(VKB_DEBUG) || defined(VKB_VALIDATION_LAYERS) if (contains(create_info->enabledExtensionCount, create_info->ppEnabledExtensionNames, VK_EXT_DEBUG_UTILS_EXTENSION_NAME)) { - vk::DebugUtilsMessengerCreateInfoEXT debug_utils_messenger_create_info{.messageSeverity = vk::DebugUtilsMessageSeverityFlagBitsEXT::eError | vk::DebugUtilsMessageSeverityFlagBitsEXT::eWarning, - .messageType = vk::DebugUtilsMessageTypeFlagBitsEXT::eValidation | vk::DebugUtilsMessageTypeFlagBitsEXT::ePerformance, - .pfnUserCallback = vkb::core::debug_utils_messenger_callback}; - scb.add_struct(debug_utils_messenger_create_info); + scb.add_struct(get_debug_utils_messenger_create_info()); } else if (contains(create_info->enabledExtensionCount, create_info->ppEnabledExtensionNames, VK_EXT_DEBUG_REPORT_EXTENSION_NAME)) { - vk::DebugReportCallbackCreateInfoEXT debug_report_callback_create_info{.flags = vk::DebugReportFlagBitsEXT::eError | vk::DebugReportFlagBitsEXT::eWarning | vk::DebugReportFlagBitsEXT::ePerformanceWarning, - .pfnCallback = vkb::core::debug_callback}; - scb.add_struct(debug_report_callback_create_info); + scb.add_struct(get_debug_report_callback_create_info()); } #endif @@ -842,48 +842,17 @@ inline void VulkanSample::extend_instance_create_info_impl(vkb::Str } template -inline uint32_t VulkanSample::get_api_version() const -{ - return VK_API_VERSION_1_1; -} +inline void VulkanSample::extend_debug_report_callback_create_info(vkb::StructureChainBuilder &scb) const +{} template -inline typename VulkanSample::DebugReportCallbackCreateInfoType const *VulkanSample::get_debug_report_callback_create_info() const -{ -#if defined(VKB_DEBUG) || defined(VKB_VALIDATION_LAYERS) - static vk::DebugReportCallbackCreateInfoEXT debug_report_callback_create_info{.flags = vk::DebugReportFlagBitsEXT::eError | vk::DebugReportFlagBitsEXT::eWarning | vk::DebugReportFlagBitsEXT::ePerformanceWarning, - .pfnCallback = vkb::core::debug_callback}; - if constexpr (bindingType == vkb::BindingType::Cpp) - { - return &debug_report_callback_create_info; - } - else - { - return reinterpret_cast(&debug_report_callback_create_info); - } -#else - return nullptr; -#endif -} +inline void VulkanSample::extend_debug_utils_messenger_create_info(vkb::StructureChainBuilder &scb) const +{} template -inline typename VulkanSample::DebugUtilsMessengerCreateInfoType const *VulkanSample::get_debug_utils_messenger_create_info() const +inline uint32_t VulkanSample::get_api_version() const { -#if defined(VKB_DEBUG) || defined(VKB_VALIDATION_LAYERS) - static vk::DebugUtilsMessengerCreateInfoEXT debug_utils_messenger_create_info{.messageSeverity = vk::DebugUtilsMessageSeverityFlagBitsEXT::eError | vk::DebugUtilsMessageSeverityFlagBitsEXT::eWarning, - .messageType = vk::DebugUtilsMessageTypeFlagBitsEXT::eValidation | vk::DebugUtilsMessageTypeFlagBitsEXT::ePerformance, - .pfnUserCallback = vkb::core::debug_utils_messenger_callback}; - if constexpr (bindingType == vkb::BindingType::Cpp) - { - return &debug_utils_messenger_create_info; - } - else - { - return reinterpret_cast(&debug_utils_messenger_create_info); - } -#else - return nullptr; -#endif + return VK_API_VERSION_1_1; } template @@ -939,6 +908,23 @@ inline vkb::core::Device &VulkanSample::get_device() } } +#if defined(VKB_DEBUG) || defined(VKB_VALIDATION_LAYERS) +template +inline vk::DebugReportCallbackCreateInfoEXT VulkanSample::get_debug_report_callback_create_info() const +{ + return {.flags = vk::DebugReportFlagBitsEXT::eError | vk::DebugReportFlagBitsEXT::eWarning | vk::DebugReportFlagBitsEXT::ePerformanceWarning, + .pfnCallback = vkb::core::debug_callback}; +} + +template +inline vk::DebugUtilsMessengerCreateInfoEXT VulkanSample::get_debug_utils_messenger_create_info() const +{ + return {.messageSeverity = vk::DebugUtilsMessageSeverityFlagBitsEXT::eError | vk::DebugUtilsMessageSeverityFlagBitsEXT::eWarning, + .messageType = vk::DebugUtilsMessageTypeFlagBitsEXT::eValidation | vk::DebugUtilsMessageTypeFlagBitsEXT::ePerformance, + .pfnUserCallback = vkb::core::debug_utils_messenger_callback}; +} +#endif + template inline std::unordered_map const &VulkanSample::get_device_extensions() const { @@ -1259,32 +1245,46 @@ inline bool VulkanSample::prepare(const ApplicationOptions &options // initialize debug utils or report callback based on enabled extensions, if any if (instance->is_extension_enabled(VK_EXT_DEBUG_UTILS_EXTENSION_NAME)) { - auto const *debug_utils_messenger_create_info = get_debug_utils_messenger_create_info(); + vkb::StructureChainBuilderCpp scb; +#if defined(VKB_DEBUG) || defined(VKB_VALIDATION_LAYERS) + scb.set_anchor_struct(get_debug_utils_messenger_create_info()); +#endif + + if constexpr (bindingType == BindingType::Cpp) + { + extend_debug_utils_messenger_create_info(scb); + } + else + { + extend_debug_utils_messenger_create_info(reinterpret_cast &>(scb)); + } + + vk::DebugUtilsMessengerCreateInfoEXT const *debug_utils_messenger_create_info = scb.get_struct(); if (debug_utils_messenger_create_info) { - if constexpr (bindingType == BindingType::Cpp) - { - debug_utils_messenger = instance->get_handle().createDebugUtilsMessengerEXT(*debug_utils_messenger_create_info); - } - else - { - debug_utils_messenger = instance->get_handle().createDebugUtilsMessengerEXT(*reinterpret_cast(debug_utils_messenger_create_info)); - } + debug_utils_messenger = instance->get_handle().createDebugUtilsMessengerEXT(*debug_utils_messenger_create_info); } } else if (instance->is_extension_enabled(VK_EXT_DEBUG_REPORT_EXTENSION_NAME)) { - auto const *debug_report_callback_create_info = get_debug_report_callback_create_info(); + vkb::StructureChainBuilderCpp scb; +#if defined(VKB_DEBUG) || defined(VKB_VALIDATION_LAYERS) + scb.set_anchor_struct(get_debug_report_callback_create_info()); +#endif + + if constexpr (bindingType == BindingType::Cpp) + { + extend_debug_report_callback_create_info(scb); + } + else + { + extend_debug_report_callback_create_info(reinterpret_cast &>(scb)); + } + + vk::DebugReportCallbackCreateInfoEXT const *debug_report_callback_create_info = scb.get_struct(); if (debug_report_callback_create_info) { - if constexpr (bindingType == BindingType::Cpp) - { - debug_report_callback = instance->get_handle().createDebugReportCallbackEXT(*debug_report_callback_create_info); - } - else - { - debug_report_callback = instance->get_handle().createDebugReportCallbackEXT(*reinterpret_cast(debug_report_callback_create_info)); - } + debug_report_callback = instance->get_handle().createDebugReportCallbackEXT(*debug_report_callback_create_info); } } diff --git a/samples/extensions/shader_debugprintf/shader_debugprintf.cpp b/samples/extensions/shader_debugprintf/shader_debugprintf.cpp index c67758c5a..7725f141b 100644 --- a/samples/extensions/shader_debugprintf/shader_debugprintf.cpp +++ b/samples/extensions/shader_debugprintf/shader_debugprintf.cpp @@ -458,27 +458,38 @@ bool ShaderDebugPrintf::prepare(const vkb::ApplicationOptions &options) return true; } +VkDebugUtilsMessengerCreateInfoEXT ShaderDebugPrintf::get_debug_utils_messenger_create_info() const +{ + return {.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT, + .pNext = nullptr, + .messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT, + .messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT, + .pfnUserCallback = debug_utils_message_callback, + .pUserData = nullptr}; +} + void ShaderDebugPrintf::extend_instance_create_info(vkb::StructureChainBuilderC &scb) const { ApiVulkanSample::extend_instance_create_info(scb); // Register a sample specific debug utils callback in addition to the one registered by the base class - VkDebugUtilsMessengerCreateInfoEXT debug_utils_messenger_create_info{.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT, - .messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT, - .messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT, - .pfnUserCallback = debug_utils_message_callback}; - scb.add_struct(debug_utils_messenger_create_info); + scb.add_struct(get_debug_utils_messenger_create_info()); } -VkDebugUtilsMessengerCreateInfoEXT const *ShaderDebugPrintf::get_debug_utils_messenger_create_info() const +void ShaderDebugPrintf::extend_debug_utils_messenger_create_info(vkb::StructureChainBuilderC &scb) const { + ApiVulkanSample::extend_debug_utils_messenger_create_info(scb); + // Register a sample specific debug utils callback in addition to the one registered by the base class - static VkDebugUtilsMessengerCreateInfoEXT local_debug_utils_messenger_create_info{.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT, - .pNext = ApiVulkanSample::get_debug_utils_messenger_create_info(), - .messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT, - .messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT, - .pfnUserCallback = debug_utils_message_callback}; - return &local_debug_utils_messenger_create_info; +#if 0 + scb.add_struct(get_debug_utils_messenger_create_info()); +#else + // for some unknown reason, this VkDebugUtilsMessengerCreateInfoEXT needs to be the first one! + // That is, we need to replace the current anchor with this one, and add the current anchor as the second struct in the chain. + VkDebugUtilsMessengerCreateInfoEXT tmp = *scb.get_struct(); + scb.set_anchor_struct(get_debug_utils_messenger_create_info()); + scb.add_struct(tmp); +#endif } void ShaderDebugPrintf::render(float delta_time) diff --git a/samples/extensions/shader_debugprintf/shader_debugprintf.h b/samples/extensions/shader_debugprintf/shader_debugprintf.h index 9cc86a7fb..cf1af7729 100644 --- a/samples/extensions/shader_debugprintf/shader_debugprintf.h +++ b/samples/extensions/shader_debugprintf/shader_debugprintf.h @@ -80,30 +80,32 @@ class ShaderDebugPrintf : public ApiVulkanSample ShaderDebugPrintf(); ~ShaderDebugPrintf(); - void request_gpu_features(vkb::core::PhysicalDeviceC &gpu) override; - void request_instance_extensions(std::unordered_map &requested_extensions) const override; - void request_layer_settings(std::vector &requested_layer_settings, vkb::StructureChainBuilderC &scb) 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 extend_instance_create_info(vkb::StructureChainBuilderC &scb) const override; - virtual VkDebugUtilsMessengerCreateInfoEXT const *get_debug_utils_messenger_create_info() const 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_instance_extensions(std::unordered_map &requested_extensions) const override; + void request_layer_settings(std::vector &requested_layer_settings, vkb::StructureChainBuilderC &scb) 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 extend_instance_create_info(vkb::StructureChainBuilderC &scb) const override; + virtual void extend_debug_utils_messenger_create_info(vkb::StructureChainBuilderC &scb) const 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; private: // from vkb::VulkanSample virtual uint32_t get_api_version() const override; virtual void request_layers(std::unordered_map &requested_layers) const override; + + VkDebugUtilsMessengerCreateInfoEXT get_debug_utils_messenger_create_info() const; }; std::unique_ptr create_shader_debugprintf(); From 4b45ae1152b50c9a42ee4e70dd74fbd76f2fe17b Mon Sep 17 00:00:00 2001 From: asuessenbach Date: Mon, 4 May 2026 11:57:21 +0200 Subject: [PATCH 2/2] Remove unneeded code. --- samples/extensions/shader_debugprintf/shader_debugprintf.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/samples/extensions/shader_debugprintf/shader_debugprintf.cpp b/samples/extensions/shader_debugprintf/shader_debugprintf.cpp index 7725f141b..b50c928db 100644 --- a/samples/extensions/shader_debugprintf/shader_debugprintf.cpp +++ b/samples/extensions/shader_debugprintf/shader_debugprintf.cpp @@ -481,15 +481,11 @@ void ShaderDebugPrintf::extend_debug_utils_messenger_create_info(vkb::StructureC ApiVulkanSample::extend_debug_utils_messenger_create_info(scb); // Register a sample specific debug utils callback in addition to the one registered by the base class -#if 0 - scb.add_struct(get_debug_utils_messenger_create_info()); -#else // for some unknown reason, this VkDebugUtilsMessengerCreateInfoEXT needs to be the first one! // That is, we need to replace the current anchor with this one, and add the current anchor as the second struct in the chain. VkDebugUtilsMessengerCreateInfoEXT tmp = *scb.get_struct(); scb.set_anchor_struct(get_debug_utils_messenger_create_info()); scb.add_struct(tmp); -#endif } void ShaderDebugPrintf::render(float delta_time)