diff --git a/base/vulkandebug.cpp b/base/vulkandebug.cpp index 25cb6d12..45bfe3ec 100644 --- a/base/vulkandebug.cpp +++ b/base/vulkandebug.cpp @@ -88,4 +88,138 @@ namespace vkDebug // DestroyDebugReportCallback(instance, msgCallback, nullptr); } } + + PFN_vkDebugMarkerSetObjectNameEXT DebugMarkerSetObjectName = NULL; + PFN_vkCmdDebugMarkerBeginEXT CmdDebugMarkerBegin = NULL; + PFN_vkCmdDebugMarkerEndEXT CmdDebugMarkerEnd = NULL; + PFN_vkCmdDebugMarkerInsertEXT CmdDebugMarkerInsert = NULL; + + // Set up the debug marker function pointers + void setupDebugMarkers(VkDevice device) + { + DebugMarkerSetObjectName = (PFN_vkDebugMarkerSetObjectNameEXT)vkGetDeviceProcAddr(device, "vkDebugMarkerSetObjectNameEXT"); + CmdDebugMarkerBegin = (PFN_vkCmdDebugMarkerBeginEXT)vkGetDeviceProcAddr(device, "vkCmdDebugMarkerBeginEXT"); + CmdDebugMarkerEnd = (PFN_vkCmdDebugMarkerEndEXT)vkGetDeviceProcAddr(device, "vkCmdDebugMarkerEndEXT"); + CmdDebugMarkerInsert = (PFN_vkCmdDebugMarkerInsertEXT)vkGetDeviceProcAddr(device, "vkCmdDebugMarkerInsertEXT"); + } + + void insertDebugMarker( + VkCommandBuffer cmdbuffer, + const char* pMarkerName, + float color[4]) + { + // need to check if the function pointer is valid - extension might not be present + if (CmdDebugMarkerInsert) + { + VkDebugMarkerMarkerInfoEXT markerInfo = {}; + markerInfo.sType = VK_STRUCTURE_TYPE_DEBUG_MARKER_MARKER_INFO_EXT; + memcpy(markerInfo.color, color, sizeof(float)*4); + markerInfo.pMarkerName = pMarkerName; + CmdDebugMarkerInsert(cmdbuffer, &markerInfo); + } + } + + void insertDebugMarker( + VkCommandBuffer cmdbuffer, + const char* pMarkerName) + { + // need to check if the function pointer is valid - extension might not be present + if (CmdDebugMarkerInsert) + { + VkDebugMarkerMarkerInfoEXT markerInfo = {}; + markerInfo.sType = VK_STRUCTURE_TYPE_DEBUG_MARKER_MARKER_INFO_EXT; + markerInfo.pMarkerName = pMarkerName; + CmdDebugMarkerInsert(cmdbuffer, &markerInfo); + } + } + + DebugMarkerRegion::DebugMarkerRegion(VkCommandBuffer cmdbuffer, + const char* pMarkerName, + float color[4]) + { + cmd = cmdbuffer; + // need to check if the function pointer is valid - extension might not be present + if (CmdDebugMarkerBegin) + { + VkDebugMarkerMarkerInfoEXT markerInfo = {}; + markerInfo.sType = VK_STRUCTURE_TYPE_DEBUG_MARKER_MARKER_INFO_EXT; + memcpy(markerInfo.color, color, sizeof(float)*4); + markerInfo.pMarkerName = pMarkerName; + CmdDebugMarkerBegin(cmd, &markerInfo); + } + } + + DebugMarkerRegion::DebugMarkerRegion(VkCommandBuffer cmdbuffer, + const char* pMarkerName) + { + cmd = cmdbuffer; + // need to check if the function pointer is valid - extension might not be present + if (CmdDebugMarkerBegin) + { + VkDebugMarkerMarkerInfoEXT markerInfo = {}; + markerInfo.sType = VK_STRUCTURE_TYPE_DEBUG_MARKER_MARKER_INFO_EXT; + markerInfo.pMarkerName = pMarkerName; + CmdDebugMarkerBegin(cmd, &markerInfo); + } + } + + DebugMarkerRegion::~DebugMarkerRegion() + { + // need to check if the function pointer is valid - extension might not be present + if (CmdDebugMarkerEnd) + CmdDebugMarkerEnd(cmd); + } + + // we specialise this template for each object type + template + VkDebugReportObjectTypeEXT GetObjectTypeEnum(VulkanType object); + +#define OBJECT_TYPE(enumName, objectType) template<> VkDebugReportObjectTypeEXT GetObjectTypeEnum(objectType o) { (void)o; return VK_DEBUG_REPORT_OBJECT_TYPE_ ##enumName ##_EXT; } + OBJECT_TYPE(INSTANCE, VkInstance); + OBJECT_TYPE(PHYSICAL_DEVICE, VkPhysicalDevice); + OBJECT_TYPE(DEVICE, VkDevice); + OBJECT_TYPE(QUEUE, VkQueue); + OBJECT_TYPE(SEMAPHORE, VkSemaphore); + OBJECT_TYPE(COMMAND_BUFFER, VkCommandBuffer); + OBJECT_TYPE(FENCE, VkFence); + OBJECT_TYPE(DEVICE_MEMORY, VkDeviceMemory); + OBJECT_TYPE(BUFFER, VkBuffer); + OBJECT_TYPE(IMAGE, VkImage); + OBJECT_TYPE(EVENT, VkEvent); + OBJECT_TYPE(QUERY_POOL, VkQueryPool); + OBJECT_TYPE(BUFFER_VIEW, VkBufferView); + OBJECT_TYPE(IMAGE_VIEW, VkImageView); + OBJECT_TYPE(SHADER_MODULE, VkShaderModule); + OBJECT_TYPE(PIPELINE_CACHE, VkPipelineCache); + OBJECT_TYPE(PIPELINE_LAYOUT, VkPipelineLayout); + OBJECT_TYPE(RENDER_PASS, VkRenderPass); + OBJECT_TYPE(PIPELINE, VkPipeline); + OBJECT_TYPE(DESCRIPTOR_SET_LAYOUT, VkDescriptorSetLayout); + OBJECT_TYPE(SAMPLER, VkSampler); + OBJECT_TYPE(DESCRIPTOR_POOL, VkDescriptorPool); + OBJECT_TYPE(DESCRIPTOR_SET, VkDescriptorSet); + OBJECT_TYPE(FRAMEBUFFER, VkFramebuffer); + OBJECT_TYPE(COMMAND_POOL, VkCommandPool); + OBJECT_TYPE(SURFACE_KHR, VkSurfaceKHR); + OBJECT_TYPE(SWAPCHAIN_KHR, VkSwapchainKHR); + OBJECT_TYPE(DEBUG_REPORT, VkDebugReportCallbackEXT); +#undef OBJECT_TYPE + + void SetObjectName( + VkDevice device, + VkDebugReportObjectTypeEXT objectType, + uint64_t object, + const char* pObjectName) + { + // need to check if the function pointer is valid - extension might not be present + if (DebugMarkerSetObjectName) + { + VkDebugMarkerObjectNameInfoEXT nameInfo = {}; + nameInfo.sType = VK_STRUCTURE_TYPE_DEBUG_MARKER_OBJECT_NAME_INFO_EXT; + nameInfo.objectType = objectType; + nameInfo.object = object; + nameInfo.pObjectName = pObjectName; + DebugMarkerSetObjectName(device, &nameInfo); + } + } } \ No newline at end of file diff --git a/base/vulkandebug.h b/base/vulkandebug.h index 6b722a85..b41fdfe9 100644 --- a/base/vulkandebug.h +++ b/base/vulkandebug.h @@ -44,4 +44,52 @@ namespace vkDebug VkDebugReportCallbackEXT callBack); // Clear debug callback void freeDebugCallback(VkInstance instance); + + // Set up the debug marker function pointers + void setupDebugMarkers(VkDevice device); + + // insert a debug label into the command buffer, with or + // without a color + void insertDebugMarker( + VkCommandBuffer cmdbuffer, + const char* pMarkerName, + float color[4]); + void insertDebugMarker( + VkCommandBuffer cmdbuffer, + const char* pMarkerName); + + // helper class for pushing and popping a debug region + // around some section of code. + struct DebugMarkerRegion + { + DebugMarkerRegion(VkCommandBuffer cmdbuffer, + const char* pMarkerName, + float color[4]); + DebugMarkerRegion(VkCommandBuffer cmdbuffer, + const char* pMarkerName); + ~DebugMarkerRegion(); + + VkCommandBuffer cmd; + }; + + // associate a friendly name with an object + void SetObjectName( + VkDevice device, + VkDebugReportObjectTypeEXT objectType, + uint64_t object, + const char* pObjectName); + + // specialised in vulkandebug.cpp for each object type + template + VkDebugReportObjectTypeEXT GetObjectTypeEnum(VulkanType object); + + // templated helper function for SetObjectName + template + void SetObjectName( + VkDevice device, + VulkanType object, + const char* pObjectName) + { + SetObjectName(device, GetObjectTypeEnum(object), (uint64_t)object, pObjectName); + } }