Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion framework/core/instance.h
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ inline Instance<bindingType>::Instance(std::string const
.enabledExtensionCount = static_cast<uint32_t>(enabled_extensions_cstr.size()),
.ppEnabledExtensionNames = enabled_extensions_cstr.data()};

vkb::StructureChainBuilder<vkb::BindingType::Cpp, vk::InstanceCreateInfo> scb;
vkb::StructureChainBuilderCpp<vk::InstanceCreateInfo> scb;
scb.set_anchor_struct(create_info);
if constexpr (bindingType == vkb::BindingType::Cpp)
{
Expand Down
33 changes: 19 additions & 14 deletions framework/structure_chain_builder.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ namespace vkb
template <vkb::BindingType bindingType, typename AnchorStructType>
class StructureChainBuilder
{
public:
StructureChainBuilder();
static_assert((offsetof(AnchorStructType, sType) == 0) && (offsetof(AnchorStructType, pNext) == sizeof(void *)));

public:
template <typename T>
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)
Expand Down Expand Up @@ -66,13 +66,6 @@ T &StructureChainBuilder<bindingType, AnchorStructType>::add_chain_data(T const
return *std::any_cast<T>(chain_data.back().get());
}

template <vkb::BindingType bindingType, typename AnchorStructType>
inline StructureChainBuilder<bindingType, AnchorStructType>::StructureChainBuilder()
{
static_assert((offsetof(AnchorStructType, sType) == 0) && (offsetof(AnchorStructType, pNext) == sizeof(void *)));
structure_chain.push_back(std::make_unique<std::any>(std::make_any<AnchorStructType>()));
}

template <vkb::BindingType bindingType, typename AnchorStructType>
template <typename StructType>
inline StructType &StructureChainBuilder<bindingType, AnchorStructType>::add_struct(StructType const &struct_to_add)
Expand All @@ -92,6 +85,11 @@ template <vkb::BindingType bindingType, typename AnchorStructType>
template <typename StructType>
inline StructType &StructureChainBuilder<bindingType, AnchorStructType>::add_struct_impl(StructType const &struct_to_add)
{
if (structure_chain.empty())
{
structure_chain.push_back(std::make_unique<std::any>(std::make_any<AnchorStructType>()));
}

#if !defined(NDEBUG)
auto it = std::ranges::find_if(structure_chain, [](auto const &chain_element) {
return std::any_cast<StructType>(chain_element.get()) != nullptr;
Expand All @@ -115,7 +113,7 @@ inline StructType const *StructureChainBuilder<bindingType, AnchorStructType>::g
}
else
{
return reinterpret_cast<StructType const *>(get_struct_impl<vk::CppType<StructType>::Type>(skip));
return reinterpret_cast<StructType const *>(get_struct_impl<typename vk::CppType<StructType>::Type>(skip));
}
}

Expand Down Expand Up @@ -146,17 +144,24 @@ inline void StructureChainBuilder<bindingType, AnchorStructType>::set_anchor_str
}
else
{
return reinterpret_cast<StructureChainBuilder<vkb::BindingType::Cpp, typename vk::CppType<AnchorStructType>::Type> *>(this)->add_anchor_struct(
reinterpret_cast<StructureChainBuilder<vkb::BindingType::Cpp, typename vk::CppType<AnchorStructType>::Type> *>(this)->set_anchor_struct(
reinterpret_cast<typename vk::CppType<AnchorStructType>::Type const &>(anchor_struct));
}
}

template <vkb::BindingType bindingType, typename AnchorStructType>
inline void StructureChainBuilder<bindingType, AnchorStructType>::set_anchor_struct_impl(AnchorStructType const &anchor_struct)
{
void const *pNext = std::any_cast<AnchorStructType>(structure_chain.front().get())->pNext;
*std::any_cast<AnchorStructType>(structure_chain.front().get()) = anchor_struct;
std::any_cast<AnchorStructType>(structure_chain.front().get())->pNext = pNext;
if (structure_chain.empty())
{
structure_chain.push_back(std::make_unique<std::any>(std::make_any<AnchorStructType>(anchor_struct)));
}
else
{
void const *pNext = std::any_cast<AnchorStructType>(structure_chain.front().get())->pNext;
*std::any_cast<AnchorStructType>(structure_chain.front().get()) = anchor_struct;
std::any_cast<AnchorStructType>(structure_chain.front().get())->pNext = pNext;
}
}

} // namespace vkb
134 changes: 67 additions & 67 deletions framework/vulkan_sample.h
Original file line number Diff line number Diff line change
Expand Up @@ -203,11 +203,11 @@ class VulkanSample : public vkb::Application
*/
virtual void draw_renderpass(vkb::core::CommandBuffer<bindingType> &command_buffer, vkb::rendering::RenderTarget<bindingType> &render_target);

virtual void extend_instance_create_info(vkb::StructureChainBuilder<bindingType, InstanceCreateInfoType> &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<std::string> const &enabled_extensions) const;
virtual void extend_instance_create_info(vkb::StructureChainBuilder<bindingType, InstanceCreateInfoType> &scb) const;
virtual void extend_debug_report_callback_create_info(vkb::StructureChainBuilder<bindingType, DebugReportCallbackCreateInfoType> &scb) const;
virtual void extend_debug_utils_messenger_create_info(vkb::StructureChainBuilder<bindingType, DebugUtilsMessengerCreateInfoType> &scb) const;
virtual uint32_t get_api_version() const;
virtual InstanceCreateFlagsType get_instance_create_flags(std::vector<std::string> const &enabled_extensions) const;

/**
* @brief Override this to customise the creation of the swapchain and render_context
Expand Down Expand Up @@ -346,6 +346,11 @@ class VulkanSample : public vkb::Application
void request_layer_settings_impl(std::vector<vk::LayerSettingEXT> &requested_layer_settings, vkb::StructureChainBuilderCpp<vk::InstanceCreateInfo> &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)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if it's a good idea to hide these behind those defines. What about samples like debugprintf that are supposed to work without validation layers (to be used with e.g. RenderDoc)?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Those two functions hidden by those defines are private helper functions of the VulkanSample class. They are not virtual, and nobody out of this class actually need to know about them.

In contrast to that, extend_instance_create_info and extend_debug_utils_messenger_create_info are protected virtual functions in VulkanSample, not hidden by any defines. The shader_debugprintf sample, for example, overrides them and calls it own local helper function get_debug_utils_messenger_create_info, which is not hidden behind any defines.

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.
*
Expand Down Expand Up @@ -786,16 +791,11 @@ inline void VulkanSample<bindingType>::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

Expand Down Expand Up @@ -842,48 +842,17 @@ inline void VulkanSample<bindingType>::extend_instance_create_info_impl(vkb::Str
}

template <vkb::BindingType bindingType>
inline uint32_t VulkanSample<bindingType>::get_api_version() const
{
return VK_API_VERSION_1_1;
}
inline void VulkanSample<bindingType>::extend_debug_report_callback_create_info(vkb::StructureChainBuilder<bindingType, DebugReportCallbackCreateInfoType> &scb) const
{}

template <vkb::BindingType bindingType>
inline typename VulkanSample<bindingType>::DebugReportCallbackCreateInfoType const *VulkanSample<bindingType>::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<VkDebugReportCallbackCreateInfoEXT *>(&debug_report_callback_create_info);
}
#else
return nullptr;
#endif
}
inline void VulkanSample<bindingType>::extend_debug_utils_messenger_create_info(vkb::StructureChainBuilder<bindingType, DebugUtilsMessengerCreateInfoType> &scb) const
{}

template <vkb::BindingType bindingType>
inline typename VulkanSample<bindingType>::DebugUtilsMessengerCreateInfoType const *VulkanSample<bindingType>::get_debug_utils_messenger_create_info() const
inline uint32_t VulkanSample<bindingType>::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<VkDebugUtilsMessengerCreateInfoEXT *>(&debug_utils_messenger_create_info);
}
#else
return nullptr;
#endif
return VK_API_VERSION_1_1;
}

template <vkb::BindingType bindingType>
Expand Down Expand Up @@ -939,6 +908,23 @@ inline vkb::core::Device<bindingType> &VulkanSample<bindingType>::get_device()
}
}

#if defined(VKB_DEBUG) || defined(VKB_VALIDATION_LAYERS)
template <vkb::BindingType bindingType>
inline vk::DebugReportCallbackCreateInfoEXT VulkanSample<bindingType>::get_debug_report_callback_create_info() const
{
return {.flags = vk::DebugReportFlagBitsEXT::eError | vk::DebugReportFlagBitsEXT::eWarning | vk::DebugReportFlagBitsEXT::ePerformanceWarning,
.pfnCallback = vkb::core::debug_callback};
}

template <vkb::BindingType bindingType>
inline vk::DebugUtilsMessengerCreateInfoEXT VulkanSample<bindingType>::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 <vkb::BindingType bindingType>
inline std::unordered_map<const char *, bool> const &VulkanSample<bindingType>::get_device_extensions() const
{
Expand Down Expand Up @@ -1259,32 +1245,46 @@ inline bool VulkanSample<bindingType>::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<vk::DebugUtilsMessengerCreateInfoEXT> 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<vkb::StructureChainBuilderC<VkDebugUtilsMessengerCreateInfoEXT> &>(scb));
}

vk::DebugUtilsMessengerCreateInfoEXT const *debug_utils_messenger_create_info = scb.get_struct<vk::DebugUtilsMessengerCreateInfoEXT>();
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<vk::DebugUtilsMessengerCreateInfoEXT const *>(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<vk::DebugReportCallbackCreateInfoEXT> 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<vkb::StructureChainBuilderC<VkDebugReportCallbackCreateInfoEXT> &>(scb));
}

vk::DebugReportCallbackCreateInfoEXT const *debug_report_callback_create_info = scb.get_struct<vk::DebugReportCallbackCreateInfoEXT>();
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<vk::DebugReportCallbackCreateInfoEXT const *>(debug_report_callback_create_info));
}
debug_report_callback = instance->get_handle().createDebugReportCallbackEXT(*debug_report_callback_create_info);
}
}

Expand Down
31 changes: 19 additions & 12 deletions samples/extensions/shader_debugprintf/shader_debugprintf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -458,27 +458,34 @@ 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<VkInstanceCreateInfo> &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());

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a fan of this. Samples like this are supposed to explicitly show how to set up things. Moving them to the framework and making things implicit makes it harder to follow and/or adopt such samples.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a fan of this.

What exactly don't you like here?
The usage of the StructureChainBuilder to ease structure chaining? Or the use of a local helper function to get the very same VkDebugUtilsMessengerCreateInfoEXT in two separate functions?

}

VkDebugUtilsMessengerCreateInfoEXT const *ShaderDebugPrintf::get_debug_utils_messenger_create_info() const
void ShaderDebugPrintf::extend_debug_utils_messenger_create_info(vkb::StructureChainBuilderC<VkDebugUtilsMessengerCreateInfoEXT> &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;
// 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<VkDebugUtilsMessengerCreateInfoEXT>();
scb.set_anchor_struct(get_debug_utils_messenger_create_info());
scb.add_struct(tmp);
}

void ShaderDebugPrintf::render(float delta_time)
Expand Down
Loading
Loading