From 2547e8e940d17090c109fd08af021385afdeb4b6 Mon Sep 17 00:00:00 2001 From: Johannes Schneider Date: Wed, 10 Jul 2024 20:25:44 +0200 Subject: [PATCH 1/4] Fix spelling mistake --- src/VulkanSample.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/VulkanSample.cpp b/src/VulkanSample.cpp index 08da708..949040f 100644 --- a/src/VulkanSample.cpp +++ b/src/VulkanSample.cpp @@ -86,7 +86,7 @@ static std::vector g_SwapchainImageViews; static std::vector g_Framebuffers; static VkCommandPool g_hCommandPool; static VkCommandBuffer g_MainCommandBuffers[COMMAND_BUFFER_COUNT]; -static VkFence g_MainCommandBufferExecutedFances[COMMAND_BUFFER_COUNT]; +static VkFence g_MainCommandBufferExecutedFences[COMMAND_BUFFER_COUNT]; VkFence g_ImmediateFence; static uint32_t g_NextCommandBufferIndex; // Notice we need as many semaphores as there are swapchain images @@ -2088,7 +2088,7 @@ static void InitializeApplication() fenceInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT; for(size_t i = 0; i < COMMAND_BUFFER_COUNT; ++i) { - ERR_GUARD_VULKAN( vkCreateFence(g_hDevice, &fenceInfo, g_Allocs, &g_MainCommandBufferExecutedFances[i]) ); + ERR_GUARD_VULKAN( vkCreateFence(g_hDevice, &fenceInfo, g_Allocs, &g_MainCommandBufferExecutedFences[i]) ); } ERR_GUARD_VULKAN( vkCreateFence(g_hDevice, &fenceInfo, g_Allocs, &g_ImmediateFence) ); @@ -2226,10 +2226,10 @@ static void FinalizeApplication() for(size_t i = COMMAND_BUFFER_COUNT; i--; ) { - if(g_MainCommandBufferExecutedFances[i] != VK_NULL_HANDLE) + if(g_MainCommandBufferExecutedFences[i] != VK_NULL_HANDLE) { - vkDestroyFence(g_hDevice, g_MainCommandBufferExecutedFances[i], g_Allocs); - g_MainCommandBufferExecutedFances[i] = VK_NULL_HANDLE; + vkDestroyFence(g_hDevice, g_MainCommandBufferExecutedFences[i], g_Allocs); + g_MainCommandBufferExecutedFences[i] = VK_NULL_HANDLE; } } if(g_MainCommandBuffers[0] != VK_NULL_HANDLE) @@ -2290,7 +2290,7 @@ static void DrawFrame() // Begin main command buffer size_t cmdBufIndex = (g_NextCommandBufferIndex++) % COMMAND_BUFFER_COUNT; VkCommandBuffer hCommandBuffer = g_MainCommandBuffers[cmdBufIndex]; - VkFence hCommandBufferExecutedFence = g_MainCommandBufferExecutedFances[cmdBufIndex]; + VkFence hCommandBufferExecutedFence = g_MainCommandBufferExecutedFences[cmdBufIndex]; ERR_GUARD_VULKAN( vkWaitForFences(g_hDevice, 1, &hCommandBufferExecutedFence, VK_TRUE, UINT64_MAX) ); ERR_GUARD_VULKAN( vkResetFences(g_hDevice, 1, &hCommandBufferExecutedFence) ); From b51e05e28bfab18698d9425ed9d0984741a61cb2 Mon Sep 17 00:00:00 2001 From: Johannes Schneider Date: Wed, 10 Jul 2024 20:36:07 +0200 Subject: [PATCH 2/4] 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() From a2f0a42cd9b8d1d83ed21e6754325c9736c259e8 Mon Sep 17 00:00:00 2001 From: Johannes Schneider Date: Wed, 10 Jul 2024 22:48:55 +0200 Subject: [PATCH 3/4] Use SetDebugUtilsObjectName in sample app --- src/VulkanSample.cpp | 60 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 58 insertions(+), 2 deletions(-) diff --git a/src/VulkanSample.cpp b/src/VulkanSample.cpp index b933d22..890d3ec 100644 --- a/src/VulkanSample.cpp +++ b/src/VulkanSample.cpp @@ -299,6 +299,8 @@ void EndSingleTimeCommands() { ERR_GUARD_VULKAN( vkEndCommandBuffer(g_hTemporaryCommandBuffer) ); + SetDebugUtilsObjectName(VK_OBJECT_TYPE_COMMAND_BUFFER, reinterpret_cast(g_hTemporaryCommandBuffer), "g_hTemporaryCommandBuffer"); + VkSubmitInfo submitInfo = { VK_STRUCTURE_TYPE_SUBMIT_INFO }; submitInfo.commandBufferCount = 1; submitInfo.pCommandBuffers = &g_hTemporaryCommandBuffer; @@ -715,6 +717,7 @@ static void CreateMesh() vbInfo.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT; vbAllocCreateInfo.flags = 0; ERR_GUARD_VULKAN( vmaCreateBuffer(g_hAllocator, &vbInfo, &vbAllocCreateInfo, &g_hVertexBuffer, &g_hVertexBufferAlloc, nullptr) ); + SetDebugUtilsObjectName(VK_OBJECT_TYPE_BUFFER, reinterpret_cast(g_hVertexBuffer), "g_hVertexBuffer"); // Create index buffer @@ -739,6 +742,7 @@ static void CreateMesh() ibInfo.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT; ibAllocCreateInfo.flags = 0; ERR_GUARD_VULKAN( vmaCreateBuffer(g_hAllocator, &ibInfo, &ibAllocCreateInfo, &g_hIndexBuffer, &g_hIndexBufferAlloc, nullptr) ); + SetDebugUtilsObjectName(VK_OBJECT_TYPE_BUFFER, reinterpret_cast(g_hIndexBuffer), "g_hIndexBuffer"); // Copy buffers @@ -820,7 +824,11 @@ static void CreateTexture(uint32_t sizeX, uint32_t sizeY) VmaAllocationCreateInfo imageAllocCreateInfo = {}; imageAllocCreateInfo.usage = VMA_MEMORY_USAGE_AUTO; - ERR_GUARD_VULKAN( vmaCreateImage(g_hAllocator, &imageInfo, &imageAllocCreateInfo, &g_hTextureImage, &g_hTextureImageAlloc, nullptr) ); + VmaAllocationInfo textureImageAllocInfo = {}; + + ERR_GUARD_VULKAN( vmaCreateImage(g_hAllocator, &imageInfo, &imageAllocCreateInfo, &g_hTextureImage, &g_hTextureImageAlloc, &textureImageAllocInfo) ); + SetDebugUtilsObjectName(VK_OBJECT_TYPE_IMAGE, reinterpret_cast(g_hTextureImage), "g_hTextureImage"); + SetDebugUtilsObjectName(VK_OBJECT_TYPE_DEVICE_MEMORY, reinterpret_cast(textureImageAllocInfo.deviceMemory), "textureImageAllocInfo.deviceMemory"); // Transition image layouts, copy image. @@ -889,6 +897,7 @@ static void CreateTexture(uint32_t sizeX, uint32_t sizeY) textureImageViewInfo.subresourceRange.baseArrayLayer = 0; textureImageViewInfo.subresourceRange.layerCount = 1; ERR_GUARD_VULKAN( vkCreateImageView(g_hDevice, &textureImageViewInfo, g_Allocs, &g_hTextureImageView) ); + SetDebugUtilsObjectName(VK_OBJECT_TYPE_IMAGE_VIEW, reinterpret_cast(g_hTextureImageView), "g_hTextureImageView"); } struct UniformBufferObject @@ -994,6 +1003,8 @@ static void CreateSwapchain() vkDestroySwapchainKHR(g_hDevice, g_hSwapchain, g_Allocs); g_hSwapchain = hNewSwapchain; + SetDebugUtilsObjectName(VK_OBJECT_TYPE_SWAPCHAIN_KHR, reinterpret_cast(g_hSwapchain), "g_hSwapchain"); + // Retrieve swapchain images. uint32_t swapchainImageCount = 0; @@ -1001,6 +1012,11 @@ static void CreateSwapchain() g_SwapchainImages.resize(swapchainImageCount); ERR_GUARD_VULKAN( vkGetSwapchainImagesKHR(g_hDevice, g_hSwapchain, &swapchainImageCount, g_SwapchainImages.data()) ); + for (size_t i = 0; i < swapchainImageCount; i++) { + std::string swapchainImgName = "g_SwapchainImages[" + std::to_string(i) + "]"; + SetDebugUtilsObjectName(VK_OBJECT_TYPE_IMAGE, reinterpret_cast(g_SwapchainImages[i]), swapchainImgName); + } + // Create swapchain image views. for(size_t i = g_SwapchainImageViews.size(); i--; ) @@ -1024,6 +1040,8 @@ static void CreateSwapchain() swapchainImageViewInfo.subresourceRange.baseArrayLayer = 0; swapchainImageViewInfo.subresourceRange.layerCount = 1; ERR_GUARD_VULKAN( vkCreateImageView(g_hDevice, &swapchainImageViewInfo, g_Allocs, &g_SwapchainImageViews[i]) ); + std::string imgViewName = "g_SwapchainImageViews["+ std::to_string(i) + "]"; + SetDebugUtilsObjectName(VK_OBJECT_TYPE_IMAGE_VIEW, reinterpret_cast(g_SwapchainImageViews[i]), imgViewName); } // Create depth buffer @@ -1049,7 +1067,11 @@ static void CreateSwapchain() VmaAllocationCreateInfo depthImageAllocCreateInfo = {}; depthImageAllocCreateInfo.usage = VMA_MEMORY_USAGE_AUTO; - ERR_GUARD_VULKAN( vmaCreateImage(g_hAllocator, &depthImageInfo, &depthImageAllocCreateInfo, &g_hDepthImage, &g_hDepthImageAlloc, nullptr) ); + VmaAllocationInfo depthImageAllocInfo = {}; + + ERR_GUARD_VULKAN( vmaCreateImage(g_hAllocator, &depthImageInfo, &depthImageAllocCreateInfo, &g_hDepthImage, &g_hDepthImageAlloc, &depthImageAllocInfo) ); + SetDebugUtilsObjectName(VK_OBJECT_TYPE_IMAGE, reinterpret_cast(g_hDepthImage), "g_hDepthImage"); + SetDebugUtilsObjectName(VK_OBJECT_TYPE_DEVICE_MEMORY, reinterpret_cast(depthImageAllocInfo.deviceMemory), "depthImageAllocInfo.deviceMemory"); VkImageViewCreateInfo depthImageViewInfo = { VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO }; depthImageViewInfo.image = g_hDepthImage; @@ -1062,6 +1084,7 @@ static void CreateSwapchain() depthImageViewInfo.subresourceRange.layerCount = 1; ERR_GUARD_VULKAN( vkCreateImageView(g_hDevice, &depthImageViewInfo, g_Allocs, &g_hDepthImageView) ); + SetDebugUtilsObjectName(VK_OBJECT_TYPE_IMAGE_VIEW, reinterpret_cast(g_hDepthImageView), "g_hDepthImageView"); // Create pipeline layout { @@ -1084,6 +1107,7 @@ static void CreateSwapchain() pipelineLayoutInfo.pushConstantRangeCount = 1; pipelineLayoutInfo.pPushConstantRanges = pushConstantRanges; ERR_GUARD_VULKAN( vkCreatePipelineLayout(g_hDevice, &pipelineLayoutInfo, g_Allocs, &g_hPipelineLayout) ); + SetDebugUtilsObjectName(VK_OBJECT_TYPE_PIPELINE_LAYOUT, reinterpret_cast(g_hPipelineLayout), "g_hPipelineLayout"); } // Create render pass @@ -1136,6 +1160,7 @@ static void CreateSwapchain() renderPassInfo.pSubpasses = &subpassDesc; renderPassInfo.dependencyCount = 0; ERR_GUARD_VULKAN( vkCreateRenderPass(g_hDevice, &renderPassInfo, g_Allocs, &g_hRenderPass) ); + SetDebugUtilsObjectName(VK_OBJECT_TYPE_RENDER_PASS, reinterpret_cast(g_hRenderPass), "g_hRenderPass"); } // Create pipeline @@ -1147,6 +1172,7 @@ static void CreateSwapchain() shaderModuleInfo.pCode = (const uint32_t*)vertShaderCode.data(); VkShaderModule hVertShaderModule = VK_NULL_HANDLE; ERR_GUARD_VULKAN( vkCreateShaderModule(g_hDevice, &shaderModuleInfo, g_Allocs, &hVertShaderModule) ); + SetDebugUtilsObjectName(VK_OBJECT_TYPE_SHADER_MODULE, reinterpret_cast(hVertShaderModule), "hVertShaderModule"); std::vector hFragShaderCode; LoadShader(hFragShaderCode, "Shader.frag.spv"); @@ -1154,6 +1180,7 @@ static void CreateSwapchain() shaderModuleInfo.pCode = (const uint32_t*)hFragShaderCode.data(); VkShaderModule fragShaderModule = VK_NULL_HANDLE; ERR_GUARD_VULKAN( vkCreateShaderModule(g_hDevice, &shaderModuleInfo, g_Allocs, &fragShaderModule) ); + SetDebugUtilsObjectName(VK_OBJECT_TYPE_SHADER_MODULE, reinterpret_cast(fragShaderModule), "fragShaderModule"); VkPipelineShaderStageCreateInfo vertPipelineShaderStageInfo = { VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO }; vertPipelineShaderStageInfo.stage = VK_SHADER_STAGE_VERTEX_BIT; @@ -1293,6 +1320,8 @@ static void CreateSwapchain() g_Allocs, &g_hPipeline) ); + SetDebugUtilsObjectName(VK_OBJECT_TYPE_PIPELINE, reinterpret_cast(g_hPipeline), "g_hPipeline"); + vkDestroyShaderModule(g_hDevice, fragShaderModule, g_Allocs); vkDestroyShaderModule(g_hDevice, hVertShaderModule, g_Allocs); } @@ -1316,6 +1345,8 @@ static void CreateSwapchain() framebufferInfo.height = g_Extent.height; framebufferInfo.layers = 1; ERR_GUARD_VULKAN( vkCreateFramebuffer(g_hDevice, &framebufferInfo, g_Allocs, &g_Framebuffers[i]) ); + std::string framebufName = "g_Framebuffers["+ std::to_string(i) + "]"; + SetDebugUtilsObjectName(VK_OBJECT_TYPE_FRAMEBUFFER, reinterpret_cast(g_Framebuffers[i]), framebufName); } // Destroy the old semaphores and create new ones @@ -1342,7 +1373,12 @@ static void CreateSwapchain() for (std::size_t swapchain_img_index = 0; swapchain_img_index < g_SwapchainImageCount; swapchain_img_index++) { ERR_GUARD_VULKAN(vkCreateSemaphore(g_hDevice, &semaphoreInfo, g_Allocs, &g_hImageAvailableSemaphores[swapchain_img_index])); + std::string semaphoreName = "g_hImageAvailableSemaphores[" + std::to_string(swapchain_img_index) + "]"; + SetDebugUtilsObjectName(VK_OBJECT_TYPE_SEMAPHORE, reinterpret_cast(g_hImageAvailableSemaphores[swapchain_img_index]), semaphoreName); + ERR_GUARD_VULKAN(vkCreateSemaphore(g_hDevice, &semaphoreInfo, g_Allocs, &g_hRenderFinishedSemaphores[swapchain_img_index])); + semaphoreName = "g_hRenderFinishedSemaphores[" + std::to_string(swapchain_img_index) + "]"; + SetDebugUtilsObjectName(VK_OBJECT_TYPE_SEMAPHORE, reinterpret_cast(g_hRenderFinishedSemaphores[swapchain_img_index]), semaphoreName); } } @@ -2045,6 +2081,10 @@ static void InitializeApplication() deviceCreateInfo.pQueueCreateInfos = queueCreateInfo; ERR_GUARD_VULKAN( vkCreateDevice(g_hPhysicalDevice, &deviceCreateInfo, g_Allocs, &g_hDevice) ); + SetDebugUtilsObjectName(VK_OBJECT_TYPE_DEVICE, reinterpret_cast(g_hDevice), "g_hDevice"); + // Only now that SetDebugUtilsObjectName is loaded, we can assign a name to g_hVulkanInstance as well + SetDebugUtilsObjectName(VK_OBJECT_TYPE_INSTANCE, reinterpret_cast(g_hVulkanInstance), "g_hVulkanInstance"); + SetDebugUtilsObjectName(VK_OBJECT_TYPE_PHYSICAL_DEVICE, reinterpret_cast(g_hPhysicalDevice), "g_hPhysicalDevice"); // Fetch pointers to extension functions if(VK_KHR_buffer_device_address_enabled) @@ -2079,6 +2119,8 @@ static void InitializeApplication() vkGetDeviceQueue(g_hDevice, g_PresentQueueFamilyIndex, 0, &g_hPresentQueue); assert(g_hGraphicsQueue); assert(g_hPresentQueue); + SetDebugUtilsObjectName(VK_OBJECT_TYPE_QUEUE, reinterpret_cast(g_hGraphicsQueue), "g_hGraphicsQueue"); + SetDebugUtilsObjectName(VK_OBJECT_TYPE_QUEUE, reinterpret_cast(g_hPresentQueue), "g_hPresentQueue"); if(g_SparseBindingEnabled) { @@ -2092,24 +2134,33 @@ static void InitializeApplication() commandPoolInfo.queueFamilyIndex = g_GraphicsQueueFamilyIndex; commandPoolInfo.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; ERR_GUARD_VULKAN( vkCreateCommandPool(g_hDevice, &commandPoolInfo, g_Allocs, &g_hCommandPool) ); + SetDebugUtilsObjectName(VK_OBJECT_TYPE_COMMAND_POOL, reinterpret_cast(g_hCommandPool), "g_hCommandPool"); VkCommandBufferAllocateInfo commandBufferInfo = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO }; commandBufferInfo.commandPool = g_hCommandPool; commandBufferInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; commandBufferInfo.commandBufferCount = COMMAND_BUFFER_COUNT; ERR_GUARD_VULKAN( vkAllocateCommandBuffers(g_hDevice, &commandBufferInfo, g_MainCommandBuffers) ); + for (size_t i = 0; i < COMMAND_BUFFER_COUNT; i++) { + std::string cmdBufName = "g_MainCommandBuffers[" + std::to_string(i) + "]"; + SetDebugUtilsObjectName(VK_OBJECT_TYPE_COMMAND_BUFFER, reinterpret_cast(g_MainCommandBuffers[i]), cmdBufName); + } VkFenceCreateInfo fenceInfo = { VK_STRUCTURE_TYPE_FENCE_CREATE_INFO }; fenceInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT; for(size_t i = 0; i < COMMAND_BUFFER_COUNT; ++i) { ERR_GUARD_VULKAN( vkCreateFence(g_hDevice, &fenceInfo, g_Allocs, &g_MainCommandBufferExecutedFences[i]) ); + std::string fenceName = "g_MainCommandBufferExecutedFences[" + std::to_string(i) + "]"; + SetDebugUtilsObjectName(VK_OBJECT_TYPE_FENCE, reinterpret_cast(g_MainCommandBufferExecutedFences[i]), fenceName); } ERR_GUARD_VULKAN( vkCreateFence(g_hDevice, &fenceInfo, g_Allocs, &g_ImmediateFence) ); + SetDebugUtilsObjectName(VK_OBJECT_TYPE_FENCE, reinterpret_cast(g_ImmediateFence), "g_ImmediateFence"); commandBufferInfo.commandBufferCount = 1; ERR_GUARD_VULKAN( vkAllocateCommandBuffers(g_hDevice, &commandBufferInfo, &g_hTemporaryCommandBuffer) ); + SetDebugUtilsObjectName(VK_OBJECT_TYPE_COMMAND_BUFFER, reinterpret_cast(g_hTemporaryCommandBuffer), "g_hTemporaryCommandBuffer"); // Create texture sampler @@ -2130,6 +2181,7 @@ static void InitializeApplication() samplerInfo.minLod = 0.f; samplerInfo.maxLod = FLT_MAX; ERR_GUARD_VULKAN( vkCreateSampler(g_hDevice, &samplerInfo, g_Allocs, &g_hSampler) ); + SetDebugUtilsObjectName(VK_OBJECT_TYPE_SAMPLER, reinterpret_cast(g_hSampler), "g_hSampler"); CreateTexture(128, 128); CreateMesh(); @@ -2144,6 +2196,7 @@ static void InitializeApplication() descriptorSetLayoutInfo.bindingCount = 1; descriptorSetLayoutInfo.pBindings = &samplerLayoutBinding; ERR_GUARD_VULKAN( vkCreateDescriptorSetLayout(g_hDevice, &descriptorSetLayoutInfo, g_Allocs, &g_hDescriptorSetLayout) ); + SetDebugUtilsObjectName(VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT, reinterpret_cast(g_hDescriptorSetLayout), "g_hDescriptorSetLayout"); // Create descriptor pool @@ -2159,6 +2212,7 @@ static void InitializeApplication() descriptorPoolInfo.pPoolSizes = descriptorPoolSizes; descriptorPoolInfo.maxSets = 1; ERR_GUARD_VULKAN( vkCreateDescriptorPool(g_hDevice, &descriptorPoolInfo, g_Allocs, &g_hDescriptorPool) ); + SetDebugUtilsObjectName(VK_OBJECT_TYPE_DESCRIPTOR_POOL, reinterpret_cast(g_hDescriptorPool), "g_hDescriptorPool"); // Create descriptor set layout @@ -2168,6 +2222,7 @@ static void InitializeApplication() descriptorSetInfo.descriptorSetCount = 1; descriptorSetInfo.pSetLayouts = descriptorSetLayouts; ERR_GUARD_VULKAN( vkAllocateDescriptorSets(g_hDevice, &descriptorSetInfo, &g_hDescriptorSet) ); + SetDebugUtilsObjectName(VK_OBJECT_TYPE_DESCRIPTOR_SET, reinterpret_cast(g_hDescriptorSet), "g_hDescriptorSet"); VkDescriptorImageInfo descriptorImageInfo = {}; descriptorImageInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; @@ -2313,6 +2368,7 @@ static void DrawFrame() VkCommandBufferBeginInfo commandBufferBeginInfo = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO }; commandBufferBeginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; ERR_GUARD_VULKAN( vkBeginCommandBuffer(hCommandBuffer, &commandBufferBeginInfo) ); + SetDebugUtilsObjectName(VK_OBJECT_TYPE_COMMAND_BUFFER, reinterpret_cast(hCommandBuffer), "hCommandBuffer"); // Acquire swapchain image uint32_t imageIndex = 0; From 225d157cfecb698ed6fc3c7e4c3e190ceb0ee0c1 Mon Sep 17 00:00:00 2001 From: Johannes Schneider Date: Thu, 11 Jul 2024 17:47:15 +0200 Subject: [PATCH 4/4] Add requested changes to SetDebugUtilsObjectName --- src/Tests.cpp | 2 +- src/VulkanSample.cpp | 18 ++---------------- 2 files changed, 3 insertions(+), 17 deletions(-) diff --git a/src/Tests.cpp b/src/Tests.cpp index a18d544..796b84d 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, std::string); +void SetDebugUtilsObjectName(VkObjectType type, uint64_t handle, const std::string&); #ifndef VMA_DEBUG_MARGIN #define VMA_DEBUG_MARGIN 0 diff --git a/src/VulkanSample.cpp b/src/VulkanSample.cpp index 890d3ec..1a2ebf1 100644 --- a/src/VulkanSample.cpp +++ b/src/VulkanSample.cpp @@ -262,29 +262,15 @@ struct CommandLineParameters } } g_CommandLineParameters; -void SetDebugUtilsObjectName(VkObjectType type, uint64_t handle, std::string name) +void SetDebugUtilsObjectName(VkObjectType type, uint64_t handle, const std::string &name) { - 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 = pObjectName; + info.pObjectName = name.c_str(); ERR_GUARD_VULKAN( vkSetDebugUtilsObjectNameEXT_Func(g_hDevice, &info) ); }