diff --git a/base/vulkandebug.cpp b/base/vulkandebug.cpp index 9e38c673..26caac61 100644 --- a/base/vulkandebug.cpp +++ b/base/vulkandebug.cpp @@ -87,4 +87,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); + } } diff --git a/base/vulkanexamplebase.cpp b/base/vulkanexamplebase.cpp index f300fd6c..5b8945b5 100644 --- a/base/vulkanexamplebase.cpp +++ b/base/vulkanexamplebase.cpp @@ -61,6 +61,13 @@ VkResult VulkanExampleBase::createDevice(VkDeviceQueueCreateInfo requestedQueues deviceCreateInfo.pQueueCreateInfos = &requestedQueues; deviceCreateInfo.pEnabledFeatures = NULL; + // enable the debug marker extension if it is present (likely meaning a debugging tool is present) + if (vkTools::checkDeviceExtensionPresent(physicalDevice, VK_EXT_DEBUG_MARKER_EXTENSION_NAME)) + { + enabledExtensions.push_back(VK_EXT_DEBUG_MARKER_EXTENSION_NAME); + enableDebugMarkers = true; + } + if (enabledExtensions.size() > 0) { deviceCreateInfo.enabledExtensionCount = (uint32_t)enabledExtensions.size(); @@ -249,6 +256,10 @@ void VulkanExampleBase::prepare() { vkDebug::setupDebugging(instance, VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_NULL_HANDLE); } + if (enableDebugMarkers) + { + vkDebug::setupDebugMarkers(device); + } createCommandPool(); createSetupCommandBuffer(); setupSwapChain(); @@ -1539,6 +1550,8 @@ void VulkanExampleBase::setupDepthStencil() getMemoryType(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &mem_alloc.memoryTypeIndex); err = vkAllocateMemory(device, &mem_alloc, nullptr, &depthStencil.mem); assert(!err); + + vkDebug::SetObjectName(device, depthStencil.image, "Backbuffer depth-stencil"); err = vkBindImageMemory(device, depthStencil.image, depthStencil.mem, 0); assert(!err); diff --git a/base/vulkanexamplebase.h b/base/vulkanexamplebase.h index 1a7a1974..8d11f222 100644 --- a/base/vulkanexamplebase.h +++ b/base/vulkanexamplebase.h @@ -54,6 +54,8 @@ class VulkanExampleBase private: // Set to true when example is created with enabled validation layers bool enableValidation = false; + // Set to true when the debug marker extension is detected + bool enableDebugMarkers = false; // fps timer (one second interval) float fpsTimer = 0.0f; // Create application wide Vulkan instance diff --git a/external/vulkan/vulkan.h b/external/vulkan/vulkan.h index eb8343e2..741da4ce 100644 --- a/external/vulkan/vulkan.h +++ b/external/vulkan/vulkan.h @@ -43,7 +43,7 @@ extern "C" { #define VK_VERSION_MINOR(version) (((uint32_t)(version) >> 12) & 0x3ff) #define VK_VERSION_PATCH(version) ((uint32_t)(version) & 0xfff) // Version of this file -#define VK_HEADER_VERSION 11 +#define VK_HEADER_VERSION 12 #define VK_NULL_HANDLE 0 @@ -210,6 +210,10 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR = 1000008000, VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR = 1000009000, VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT = 1000011000, + VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_RASTERIZATION_ORDER_AMD = 1000018000, + VK_STRUCTURE_TYPE_DEBUG_MARKER_OBJECT_NAME_INFO_EXT = 1000022000, + VK_STRUCTURE_TYPE_DEBUG_MARKER_OBJECT_TAG_INFO_EXT = 1000022001, + VK_STRUCTURE_TYPE_DEBUG_MARKER_MARKER_INFO_EXT = 1000022002, VK_STRUCTURE_TYPE_BEGIN_RANGE = VK_STRUCTURE_TYPE_APPLICATION_INFO, VK_STRUCTURE_TYPE_END_RANGE = VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO, VK_STRUCTURE_TYPE_RANGE_SIZE = (VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO - VK_STRUCTURE_TYPE_APPLICATION_INFO + 1), @@ -3828,6 +3832,85 @@ VKAPI_ATTR void VKAPI_CALL vkDebugReportMessageEXT( #define VK_IMG_FILTER_CUBIC_EXTENSION_NAME "VK_IMG_filter_cubic" +#define VK_AMD_rasterization_order 1 +#define VK_AMD_RASTERIZATION_ORDER_SPEC_VERSION 1 +#define VK_AMD_RASTERIZATION_ORDER_EXTENSION_NAME "VK_AMD_rasterization_order" + + +typedef enum VkRasterizationOrderAMD { + VK_RASTERIZATION_ORDER_STRICT_AMD = 0, + VK_RASTERIZATION_ORDER_RELAXED_AMD = 1, + VK_RASTERIZATION_ORDER_BEGIN_RANGE_AMD = VK_RASTERIZATION_ORDER_STRICT_AMD, + VK_RASTERIZATION_ORDER_END_RANGE_AMD = VK_RASTERIZATION_ORDER_RELAXED_AMD, + VK_RASTERIZATION_ORDER_RANGE_SIZE_AMD = (VK_RASTERIZATION_ORDER_RELAXED_AMD - VK_RASTERIZATION_ORDER_STRICT_AMD + 1), + VK_RASTERIZATION_ORDER_MAX_ENUM_AMD = 0x7FFFFFFF +} VkRasterizationOrderAMD; + +typedef struct VkPipelineRasterizationStateRasterizationOrderAMD { + VkStructureType sType; + const void* pNext; + VkRasterizationOrderAMD rasterizationOrder; +} VkPipelineRasterizationStateRasterizationOrderAMD; + + + +#define VK_EXT_debug_marker 1 +#define VK_EXT_DEBUG_MARKER_SPEC_VERSION 3 +#define VK_EXT_DEBUG_MARKER_EXTENSION_NAME "VK_EXT_debug_marker" + +typedef struct VkDebugMarkerObjectNameInfoEXT { + VkStructureType sType; + const void* pNext; + VkDebugReportObjectTypeEXT objectType; + uint64_t object; + const char* pObjectName; +} VkDebugMarkerObjectNameInfoEXT; + +typedef struct VkDebugMarkerObjectTagInfoEXT { + VkStructureType sType; + const void* pNext; + VkDebugReportObjectTypeEXT objectType; + uint64_t object; + uint64_t tagName; + size_t tagSize; + const void* pTag; +} VkDebugMarkerObjectTagInfoEXT; + +typedef struct VkDebugMarkerMarkerInfoEXT { + VkStructureType sType; + const void* pNext; + const char* pMarkerName; + float color[4]; +} VkDebugMarkerMarkerInfoEXT; + + +typedef VkResult (VKAPI_PTR *PFN_vkDebugMarkerSetObjectTagEXT)(VkDevice device, VkDebugMarkerObjectTagInfoEXT* pTagInfo); +typedef VkResult (VKAPI_PTR *PFN_vkDebugMarkerSetObjectNameEXT)(VkDevice device, VkDebugMarkerObjectNameInfoEXT* pNameInfo); +typedef void (VKAPI_PTR *PFN_vkCmdDebugMarkerBeginEXT)(VkCommandBuffer commandBuffer, VkDebugMarkerMarkerInfoEXT* pMarkerInfo); +typedef void (VKAPI_PTR *PFN_vkCmdDebugMarkerEndEXT)(VkCommandBuffer commandBuffer); +typedef void (VKAPI_PTR *PFN_vkCmdDebugMarkerInsertEXT)(VkCommandBuffer commandBuffer, VkDebugMarkerMarkerInfoEXT* pMarkerInfo); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkDebugMarkerSetObjectTagEXT( + VkDevice device, + VkDebugMarkerObjectTagInfoEXT* pTagInfo); + +VKAPI_ATTR VkResult VKAPI_CALL vkDebugMarkerSetObjectNameEXT( + VkDevice device, + VkDebugMarkerObjectNameInfoEXT* pNameInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdDebugMarkerBeginEXT( + VkCommandBuffer commandBuffer, + VkDebugMarkerMarkerInfoEXT* pMarkerInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdDebugMarkerEndEXT( + VkCommandBuffer commandBuffer); + +VKAPI_ATTR void VKAPI_CALL vkCmdDebugMarkerInsertEXT( + VkCommandBuffer commandBuffer, + VkDebugMarkerMarkerInfoEXT* pMarkerInfo); +#endif + #ifdef __cplusplus } #endif