From b51e05e28bfab18698d9425ed9d0984741a61cb2 Mon Sep 17 00:00:00 2001 From: Johannes Schneider Date: Wed, 10 Jul 2024 20:36:07 +0200 Subject: [PATCH] Improve SetDebugUtilsObjectName --- src/Tests.cpp | 2 +- src/VulkanSample.cpp | 23 +++++++++++++++++++---- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/src/Tests.cpp b/src/Tests.cpp index 5a6f63b..a18d544 100644 --- a/src/Tests.cpp +++ b/src/Tests.cpp @@ -42,7 +42,7 @@ extern bool VK_KHR_maintenance5_enabled; extern PFN_vkGetBufferDeviceAddressKHR g_vkGetBufferDeviceAddressKHR; void BeginSingleTimeCommands(); void EndSingleTimeCommands(); -void SetDebugUtilsObjectName(VkObjectType type, uint64_t handle, const char* name); +void SetDebugUtilsObjectName(VkObjectType type, uint64_t handle, std::string); #ifndef VMA_DEBUG_MARGIN #define VMA_DEBUG_MARGIN 0 diff --git a/src/VulkanSample.cpp b/src/VulkanSample.cpp index 949040f..b933d22 100644 --- a/src/VulkanSample.cpp +++ b/src/VulkanSample.cpp @@ -28,6 +28,7 @@ #include "Common.h" #include #include +#include #pragma comment(lib, "shlwapi.lib") @@ -261,16 +262,30 @@ struct CommandLineParameters } } g_CommandLineParameters; -void SetDebugUtilsObjectName(VkObjectType type, uint64_t handle, const char* name) +void SetDebugUtilsObjectName(VkObjectType type, uint64_t handle, std::string name) { - if(vkSetDebugUtilsObjectNameEXT_Func == nullptr) + TEST(!name.empty()); + + // We must make sure the std::string we pass as name is still valid memory until the program ends. + // Since Vulkan is a C-Style API, it only accepts const char* as pObjectName parameter. + // Naming objects with unformatted names like "g_hTemporaryCommandBuffer" is no problem because + // this string ends up in the read-only data section of the program. However, if we for example want to + // name every item in a dynamic array of items (swapchain images for example), we can only use a std::string, + // and we must make sure the object lifetime of that string does not end before it's read as pObjectName. + // Therefore, we store the strings as a static unordered_set here just to be sure. + // Do not use a std::vector because it would continue to grow, eventually running out of memory. + static std::unordered_set debug_names; + auto result = debug_names.insert(name); + const char* pObjectName = result.first->c_str(); + + if (vkSetDebugUtilsObjectNameEXT_Func == nullptr) return; VkDebugUtilsObjectNameInfoEXT info = { VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT }; info.objectType = type; info.objectHandle = handle; - info.pObjectName = name; - vkSetDebugUtilsObjectNameEXT_Func(g_hDevice, &info); + info.pObjectName = pObjectName; + ERR_GUARD_VULKAN( vkSetDebugUtilsObjectNameEXT_Func(g_hDevice, &info) ); } void BeginSingleTimeCommands()