Add support for VK_EXT_debug_utils extension

This commit is contained in:
baldurk
2018-04-30 13:52:17 +01:00
parent 9b2e515be5
commit 49ea4dd8e3
12 changed files with 947 additions and 155 deletions
+6 -1
View File
@@ -14,6 +14,12 @@
"pre_instance_functions": {
"vkEnumerateInstanceExtensionProperties": "VK_LAYER_RENDERDOC_CaptureEnumerateInstanceExtensionProperties"
},
"instance_extensions": [
{
"name": "VK_EXT_debug_utils",
"spec_version": "1"
}
],
"device_extensions": [
{
"name": "VK_EXT_debug_marker",
@@ -25,7 +31,6 @@
"vkCmdDebugMarkerInsertEXT"
]
}
],
"enable_environment": {
"ENABLE_VULKAN_RENDERDOC_CAPTURE": "1"
+9
View File
@@ -474,6 +474,13 @@ enum class VulkanChunk : uint32_t
vkBindBufferMemory2KHR,
vkBindImageMemory2KHR,
vkCmdWriteBufferMarkerAMD,
vkSetDebugUtilsObjectNameEXT,
vkQueueBeginDebugUtilsLabelEXT,
vkQueueEndDebugUtilsLabelEXT,
vkQueueInsertDebugUtilsLabelEXT,
vkCmdBeginDebugUtilsLabelEXT,
vkCmdEndDebugUtilsLabelEXT,
vkCmdInsertDebugUtilsLabelEXT,
Max,
};
@@ -628,6 +635,7 @@ DECLARE_REFLECTION_STRUCT(VkRenderPassInputAttachmentAspectCreateInfoKHR);
DECLARE_REFLECTION_STRUCT(VkVertexInputBindingDivisorDescriptionEXT);
DECLARE_REFLECTION_STRUCT(VkPipelineVertexInputDivisorStateCreateInfoEXT);
DECLARE_REFLECTION_STRUCT(VkSamplerReductionModeCreateInfoEXT);
DECLARE_REFLECTION_STRUCT(VkDebugUtilsLabelEXT);
DECLARE_DESERIALISE_TYPE(VkDeviceCreateInfo);
DECLARE_DESERIALISE_TYPE(VkBufferCreateInfo);
@@ -673,6 +681,7 @@ DECLARE_DESERIALISE_TYPE(VkImageViewUsageCreateInfoKHR);
DECLARE_DESERIALISE_TYPE(VkRenderPassInputAttachmentAspectCreateInfoKHR);
DECLARE_DESERIALISE_TYPE(VkPipelineVertexInputDivisorStateCreateInfoEXT);
DECLARE_DESERIALISE_TYPE(VkSamplerReductionModeCreateInfoEXT);
DECLARE_DESERIALISE_TYPE(VkDebugUtilsLabelEXT);
DECLARE_REFLECTION_ENUM(VkFlagWithNoBits);
DECLARE_REFLECTION_ENUM(VkQueueFlagBits);
+42
View File
@@ -540,9 +540,15 @@ static const VkExtensionProperties supportedExtensions[] = {
VK_EXT_CONSERVATIVE_RASTERIZATION_EXTENSION_NAME,
VK_EXT_CONSERVATIVE_RASTERIZATION_SPEC_VERSION,
},
{
VK_EXT_DEBUG_MARKER_EXTENSION_NAME, VK_EXT_DEBUG_MARKER_SPEC_VERSION,
},
{
VK_EXT_DEBUG_REPORT_EXTENSION_NAME, VK_EXT_DEBUG_REPORT_SPEC_VERSION,
},
{
VK_EXT_DEBUG_UTILS_EXTENSION_NAME, VK_EXT_DEBUG_UTILS_SPEC_VERSION,
},
{
VK_EXT_DIRECT_MODE_DISPLAY_EXTENSION_NAME, VK_EXT_DIRECT_MODE_DISPLAY_SPEC_VERSION,
},
@@ -737,6 +743,10 @@ static const VkExtensionProperties renderdocProvidedDeviceExtensions[] = {
{VK_EXT_DEBUG_MARKER_EXTENSION_NAME, VK_EXT_DEBUG_MARKER_SPEC_VERSION},
};
static const VkExtensionProperties renderdocProvidedInstanceExtensions[] = {
{VK_EXT_DEBUG_UTILS_EXTENSION_NAME, VK_EXT_DEBUG_UTILS_SPEC_VERSION},
};
bool WrappedVulkan::IsSupportedExtension(const char *extName)
{
for(size_t i = 0; i < ARRAY_COUNT(supportedExtensions); i++)
@@ -850,6 +860,12 @@ VkResult WrappedVulkan::FilterInstanceExtensionProperties(
FilterToSupportedExtensions(exts, filtered);
// now we can add extensions that we provide ourselves (note this isn't sorted, but we
// don't have to sort the results, the sorting was just so we could filter optimally).
filtered.insert(
filtered.end(), &renderdocProvidedInstanceExtensions[0],
&renderdocProvidedInstanceExtensions[0] + ARRAY_COUNT(renderdocProvidedInstanceExtensions));
return FillPropertyCountAndList(&filtered[0], (uint32_t)filtered.size(), pPropertyCount,
pProperties);
}
@@ -1946,6 +1962,10 @@ bool WrappedVulkan::ContextProcessChunk(ReadSerialiser &ser, VulkanChunk chunk)
{
// don't add these events - they will be handled when inserted in-line into queue submit
}
else if(chunk == VulkanChunk::vkQueueEndDebugUtilsLabelEXT)
{
// also ignore, this just pops the drawcall stack
}
else
{
if(!m_AddedDrawcall)
@@ -2315,6 +2335,28 @@ bool WrappedVulkan::ProcessChunk(ReadSerialiser &ser, VulkanChunk chunk)
ser, VK_NULL_HANDLE, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_NULL_HANDLE, 0, 0);
break;
case VulkanChunk::vkSetDebugUtilsObjectNameEXT:
return Serialise_vkSetDebugUtilsObjectNameEXT(ser, VK_NULL_HANDLE, NULL);
break;
case VulkanChunk::vkQueueBeginDebugUtilsLabelEXT:
return Serialise_vkQueueBeginDebugUtilsLabelEXT(ser, VK_NULL_HANDLE, NULL);
break;
case VulkanChunk::vkQueueEndDebugUtilsLabelEXT:
return Serialise_vkQueueEndDebugUtilsLabelEXT(ser, VK_NULL_HANDLE);
break;
case VulkanChunk::vkQueueInsertDebugUtilsLabelEXT:
return Serialise_vkQueueInsertDebugUtilsLabelEXT(ser, VK_NULL_HANDLE, NULL);
break;
case VulkanChunk::vkCmdBeginDebugUtilsLabelEXT:
return Serialise_vkCmdBeginDebugUtilsLabelEXT(ser, VK_NULL_HANDLE, NULL);
break;
case VulkanChunk::vkCmdEndDebugUtilsLabelEXT:
return Serialise_vkCmdEndDebugUtilsLabelEXT(ser, VK_NULL_HANDLE);
break;
case VulkanChunk::vkCmdInsertDebugUtilsLabelEXT:
return Serialise_vkCmdInsertDebugUtilsLabelEXT(ser, VK_NULL_HANDLE, NULL);
break;
default:
{
SystemChunk system = (SystemChunk)chunk;
+40 -2
View File
@@ -679,8 +679,8 @@ private:
bool EndFrameCapture(void *dev, void *wnd);
template <typename SerialiserType>
bool Serialise_SetShaderDebugPath(SerialiserType &ser, VkDevice device,
const VkDebugMarkerObjectTagInfoEXT *pTagInfo);
bool Serialise_SetShaderDebugPath(SerialiserType &ser, VkShaderModule ShaderObject,
std::string DebugPath);
// replay
@@ -1695,7 +1695,45 @@ public:
const VkDescriptorSetLayoutCreateInfo *pCreateInfo,
VkDescriptorSetLayoutSupport *pSupport);
// VK_AMD_buffer_marker
IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdWriteBufferMarkerAMD, VkCommandBuffer commandBuffer,
VkPipelineStageFlagBits pipelineStage, VkBuffer dstBuffer,
VkDeviceSize dstOffset, uint32_t marker);
// VK_EXT_debug_utils
IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkSetDebugUtilsObjectNameEXT, VkDevice device,
const VkDebugUtilsObjectNameInfoEXT *pNameInfo);
IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkSetDebugUtilsObjectTagEXT, VkDevice device,
const VkDebugUtilsObjectTagInfoEXT *pTagInfo);
IMPLEMENT_FUNCTION_SERIALISED(void, vkQueueBeginDebugUtilsLabelEXT, VkQueue queue,
const VkDebugUtilsLabelEXT *pLabelInfo);
IMPLEMENT_FUNCTION_SERIALISED(void, vkQueueEndDebugUtilsLabelEXT, VkQueue queue);
IMPLEMENT_FUNCTION_SERIALISED(void, vkQueueInsertDebugUtilsLabelEXT, VkQueue queue,
const VkDebugUtilsLabelEXT *pLabelInfo);
IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdBeginDebugUtilsLabelEXT, VkCommandBuffer commandBuffer,
const VkDebugUtilsLabelEXT *pLabelInfo);
IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdEndDebugUtilsLabelEXT, VkCommandBuffer commandBuffer);
IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdInsertDebugUtilsLabelEXT, VkCommandBuffer commandBuffer,
const VkDebugUtilsLabelEXT *pLabelInfo);
IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkCreateDebugUtilsMessengerEXT, VkInstance instance,
const VkDebugUtilsMessengerCreateInfoEXT *pCreateInfo,
const VkAllocationCallbacks *pAllocator,
VkDebugUtilsMessengerEXT *pMessenger);
IMPLEMENT_FUNCTION_SERIALISED(void, vkDestroyDebugUtilsMessengerEXT, VkInstance instance,
VkDebugUtilsMessengerEXT messenger,
const VkAllocationCallbacks *pAllocator);
IMPLEMENT_FUNCTION_SERIALISED(void, vkSubmitDebugUtilsMessageEXT, VkInstance instance,
VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
VkDebugUtilsMessageTypeFlagsEXT messageTypes,
const VkDebugUtilsMessengerCallbackDataEXT *pCallbackData);
};
@@ -113,6 +113,7 @@ void InitDeviceExtensionTables(VkDevice device, InstanceDeviceInfo *info)
DeviceGPA(func); \
}
CheckInstanceExts();
CheckDeviceExts();
HookInitVulkanDeviceExts();
+36 -1
View File
@@ -295,7 +295,8 @@
CheckExt(EXT_acquire_xlib_display, VKXX); \
CheckExt(KHR_external_memory_capabilities, VK11); \
CheckExt(KHR_external_semaphore_capabilities, VK11); \
CheckExt(KHR_external_fence_capabilities, VK11);
CheckExt(KHR_external_fence_capabilities, VK11); \
CheckExt(EXT_debug_utils, VKXX);
#define CheckDeviceExts() \
CheckExt(EXT_debug_marker, VKXX); \
@@ -362,6 +363,9 @@
HookInitExtension(KHR_external_semaphore_capabilities, \
GetPhysicalDeviceExternalSemaphorePropertiesKHR); \
HookInitExtension(KHR_external_fence_capabilities, GetPhysicalDeviceExternalFencePropertiesKHR); \
HookInitExtension(EXT_debug_utils, CreateDebugUtilsMessengerEXT); \
HookInitExtension(EXT_debug_utils, DestroyDebugUtilsMessengerEXT); \
HookInitExtension(EXT_debug_utils, SubmitDebugUtilsMessageEXT); \
HookInitInstance_PlatformSpecific()
#define HookInitVulkanDeviceExts() \
@@ -401,6 +405,14 @@
HookInitExtension(KHR_bind_memory2, BindImageMemory2KHR); \
HookInitExtension(KHR_maintenance3, GetDescriptorSetLayoutSupportKHR); \
HookInitExtension(AMD_buffer_marker, CmdWriteBufferMarkerAMD); \
HookInitExtension(EXT_debug_utils, SetDebugUtilsObjectNameEXT); \
HookInitExtension(EXT_debug_utils, SetDebugUtilsObjectTagEXT); \
HookInitExtension(EXT_debug_utils, QueueBeginDebugUtilsLabelEXT); \
HookInitExtension(EXT_debug_utils, QueueEndDebugUtilsLabelEXT); \
HookInitExtension(EXT_debug_utils, QueueInsertDebugUtilsLabelEXT); \
HookInitExtension(EXT_debug_utils, CmdBeginDebugUtilsLabelEXT); \
HookInitExtension(EXT_debug_utils, CmdEndDebugUtilsLabelEXT); \
HookInitExtension(EXT_debug_utils, CmdInsertDebugUtilsLabelEXT); \
HookInitDevice_PlatformSpecific()
#define DefineHooks() \
@@ -847,6 +859,29 @@
HookDefine5(void, vkCmdWriteBufferMarkerAMD, VkCommandBuffer, commandBuffer, \
VkPipelineStageFlagBits, pipelineStage, VkBuffer, dstBuffer, VkDeviceSize, \
dstOffset, uint32_t, marker); \
HookDefine2(VkResult, vkSetDebugUtilsObjectNameEXT, VkDevice, device, \
const VkDebugUtilsObjectNameInfoEXT *, pNameInfo); \
HookDefine2(VkResult, vkSetDebugUtilsObjectTagEXT, VkDevice, device, \
const VkDebugUtilsObjectTagInfoEXT *, pTagInfo); \
HookDefine2(void, vkQueueBeginDebugUtilsLabelEXT, VkQueue, queue, const VkDebugUtilsLabelEXT *, \
pLabelInfo); \
HookDefine1(void, vkQueueEndDebugUtilsLabelEXT, VkQueue, queue); \
HookDefine2(void, vkQueueInsertDebugUtilsLabelEXT, VkQueue, queue, const VkDebugUtilsLabelEXT *, \
pLabelInfo); \
HookDefine2(void, vkCmdBeginDebugUtilsLabelEXT, VkCommandBuffer, commandBuffer, \
const VkDebugUtilsLabelEXT *, pLabelInfo); \
HookDefine1(void, vkCmdEndDebugUtilsLabelEXT, VkCommandBuffer, commandBuffer); \
HookDefine2(void, vkCmdInsertDebugUtilsLabelEXT, VkCommandBuffer, commandBuffer, \
const VkDebugUtilsLabelEXT *, pLabelInfo); \
HookDefine4(VkResult, vkCreateDebugUtilsMessengerEXT, VkInstance, instance, \
const VkDebugUtilsMessengerCreateInfoEXT *, pCreateInfo, \
const VkAllocationCallbacks *, pAllocator, VkDebugUtilsMessengerEXT *, pMessenger); \
HookDefine3(void, vkDestroyDebugUtilsMessengerEXT, VkInstance, instance, \
VkDebugUtilsMessengerEXT, messenger, const VkAllocationCallbacks *, pAllocator); \
HookDefine4(void, vkSubmitDebugUtilsMessageEXT, VkInstance, instance, \
VkDebugUtilsMessageSeverityFlagBitsEXT, messageSeverity, \
VkDebugUtilsMessageTypeFlagsEXT, messageTypes, \
const VkDebugUtilsMessengerCallbackDataEXT *, pCallbackData); \
HookDefine_PlatformSpecific()
struct VkLayerInstanceDispatchTableExtended : VkLayerInstanceDispatchTable
+1
View File
@@ -293,6 +293,7 @@ VK_LAYER_RENDERDOC_CaptureGetDeviceProcAddr(VkDevice device, const char *pName)
InstanceDeviceInfo *instDevInfo = GetRecord(device)->instDevInfo;
CheckInstanceExts();
CheckDeviceExts();
HookInitVulkanDeviceExts();
+17
View File
@@ -2349,6 +2349,22 @@ void Deserialise(const VkSamplerReductionModeCreateInfoEXT &el)
DeserialiseNext(el.pNext);
}
template <typename SerialiserType>
void DoSerialise(SerialiserType &ser, VkDebugUtilsLabelEXT &el)
{
RDCASSERT(ser.IsReading() || el.sType == VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT);
SerialiseNext(ser, el.sType, el.pNext);
SERIALISE_MEMBER(pLabelName);
SERIALISE_MEMBER(color);
}
template <>
void Deserialise(const VkDebugUtilsLabelEXT &el)
{
DeserialiseNext(el.pNext);
}
INSTANTIATE_SERIALISE_TYPE(VkOffset2D);
INSTANTIATE_SERIALISE_TYPE(VkExtent2D);
INSTANTIATE_SERIALISE_TYPE(VkMemoryType);
@@ -2452,6 +2468,7 @@ INSTANTIATE_SERIALISE_TYPE(VkBindImageMemoryInfoKHR);
INSTANTIATE_SERIALISE_TYPE(VkPipelineRasterizationConservativeStateCreateInfoEXT);
INSTANTIATE_SERIALISE_TYPE(VkPipelineVertexInputDivisorStateCreateInfoEXT);
INSTANTIATE_SERIALISE_TYPE(VkSamplerReductionModeCreateInfoEXT);
INSTANTIATE_SERIALISE_TYPE(VkDebugUtilsLabelEXT);
INSTANTIATE_SERIALISE_TYPE(DescriptorSetSlot);
INSTANTIATE_SERIALISE_TYPE(ImageRegionState);
+8 -1
View File
@@ -28,7 +28,7 @@
template <>
std::string DoStringise(const VulkanChunk &el)
{
RDCCOMPILE_ASSERT((uint32_t)VulkanChunk::Max == 1105, "Chunks changed without updating names");
RDCCOMPILE_ASSERT((uint32_t)VulkanChunk::Max == 1112, "Chunks changed without updating names");
BEGIN_ENUM_STRINGISE(VulkanChunk)
{
@@ -137,6 +137,13 @@ std::string DoStringise(const VulkanChunk &el)
STRINGISE_ENUM_CLASS(vkBindBufferMemory2KHR);
STRINGISE_ENUM_CLASS(vkBindImageMemory2KHR);
STRINGISE_ENUM_CLASS(vkCmdWriteBufferMarkerAMD);
STRINGISE_ENUM_CLASS(vkSetDebugUtilsObjectNameEXT);
STRINGISE_ENUM_CLASS(vkQueueBeginDebugUtilsLabelEXT);
STRINGISE_ENUM_CLASS(vkQueueEndDebugUtilsLabelEXT);
STRINGISE_ENUM_CLASS(vkQueueInsertDebugUtilsLabelEXT);
STRINGISE_ENUM_CLASS(vkCmdBeginDebugUtilsLabelEXT);
STRINGISE_ENUM_CLASS(vkCmdEndDebugUtilsLabelEXT);
STRINGISE_ENUM_CLASS(vkCmdInsertDebugUtilsLabelEXT);
STRINGISE_ENUM_CLASS_NAMED(Max, "Max Chunk");
}
END_ENUM_STRINGISE()
@@ -3579,6 +3579,217 @@ void WrappedVulkan::vkCmdWriteBufferMarkerAMD(VkCommandBuffer commandBuffer,
}
}
template <typename SerialiserType>
bool WrappedVulkan::Serialise_vkCmdBeginDebugUtilsLabelEXT(SerialiserType &ser,
VkCommandBuffer commandBuffer,
const VkDebugUtilsLabelEXT *pLabelInfo)
{
SERIALISE_ELEMENT(commandBuffer);
SERIALISE_ELEMENT_LOCAL(Label, *pLabelInfo);
SERIALISE_CHECK_READ_ERRORS();
if(IsReplayingAndReading())
{
m_LastCmdBufferID = GetResourceManager()->GetOriginalID(GetResID(commandBuffer));
if(IsActiveReplaying(m_State))
{
if(InRerecordRange(m_LastCmdBufferID))
{
commandBuffer = RerecordCmdBuf(m_LastCmdBufferID);
m_BakedCmdBufferInfo[m_LastCmdBufferID].markerCount++;
if(ObjDisp(commandBuffer)->CmdBeginDebugUtilsLabelEXT)
ObjDisp(commandBuffer)->CmdBeginDebugUtilsLabelEXT(Unwrap(commandBuffer), &Label);
}
}
else
{
if(ObjDisp(commandBuffer)->CmdBeginDebugUtilsLabelEXT)
ObjDisp(commandBuffer)->CmdBeginDebugUtilsLabelEXT(Unwrap(commandBuffer), &Label);
DrawcallDescription draw;
draw.name = Label.pLabelName;
draw.flags |= DrawFlags::PushMarker;
draw.markerColor[0] = RDCCLAMP(Label.color[0], 0.0f, 1.0f);
draw.markerColor[1] = RDCCLAMP(Label.color[1], 0.0f, 1.0f);
draw.markerColor[2] = RDCCLAMP(Label.color[2], 0.0f, 1.0f);
draw.markerColor[3] = RDCCLAMP(Label.color[3], 0.0f, 1.0f);
AddEvent();
AddDrawcall(draw, false);
}
}
return true;
}
void WrappedVulkan::vkCmdBeginDebugUtilsLabelEXT(VkCommandBuffer commandBuffer,
const VkDebugUtilsLabelEXT *pLabelInfo)
{
if(ObjDisp(commandBuffer)->CmdBeginDebugUtilsLabelEXT)
{
SERIALISE_TIME_CALL(
ObjDisp(commandBuffer)->CmdBeginDebugUtilsLabelEXT(Unwrap(commandBuffer), pLabelInfo));
}
if(IsCaptureMode(m_State))
{
VkResourceRecord *record = GetRecord(commandBuffer);
CACHE_THREAD_SERIALISER();
ser.SetDrawChunk();
SCOPED_SERIALISE_CHUNK(VulkanChunk::vkCmdBeginDebugUtilsLabelEXT);
Serialise_vkCmdBeginDebugUtilsLabelEXT(ser, commandBuffer, pLabelInfo);
record->AddChunk(scope.Get());
}
}
template <typename SerialiserType>
bool WrappedVulkan::Serialise_vkCmdEndDebugUtilsLabelEXT(SerialiserType &ser,
VkCommandBuffer commandBuffer)
{
SERIALISE_ELEMENT(commandBuffer);
SERIALISE_CHECK_READ_ERRORS();
if(IsReplayingAndReading())
{
m_LastCmdBufferID = GetResourceManager()->GetOriginalID(GetResID(commandBuffer));
if(IsActiveReplaying(m_State))
{
if(InRerecordRange(m_LastCmdBufferID))
{
commandBuffer = RerecordCmdBuf(m_LastCmdBufferID);
int &markerCount = m_BakedCmdBufferInfo[m_LastCmdBufferID].markerCount;
markerCount = RDCMAX(0, markerCount - 1);
if(ObjDisp(commandBuffer)->CmdEndDebugUtilsLabelEXT)
ObjDisp(commandBuffer)->CmdEndDebugUtilsLabelEXT(Unwrap(commandBuffer));
}
}
else
{
if(ObjDisp(commandBuffer)->CmdEndDebugUtilsLabelEXT)
ObjDisp(commandBuffer)->CmdEndDebugUtilsLabelEXT(Unwrap(commandBuffer));
if(!m_BakedCmdBufferInfo[m_LastCmdBufferID].curEvents.empty())
{
DrawcallDescription draw;
draw.name = "API Calls";
draw.flags = DrawFlags::APICalls;
AddDrawcall(draw, true);
}
// dummy draw that is consumed when this command buffer
// is being in-lined into the call stream
DrawcallDescription draw;
draw.name = "Pop()";
draw.flags = DrawFlags::PopMarker;
AddEvent();
AddDrawcall(draw, false);
}
}
return true;
}
void WrappedVulkan::vkCmdEndDebugUtilsLabelEXT(VkCommandBuffer commandBuffer)
{
if(ObjDisp(commandBuffer)->CmdEndDebugUtilsLabelEXT)
{
SERIALISE_TIME_CALL(ObjDisp(commandBuffer)->CmdEndDebugUtilsLabelEXT(Unwrap(commandBuffer)));
}
if(IsCaptureMode(m_State))
{
VkResourceRecord *record = GetRecord(commandBuffer);
CACHE_THREAD_SERIALISER();
ser.SetDrawChunk();
SCOPED_SERIALISE_CHUNK(VulkanChunk::vkCmdEndDebugUtilsLabelEXT);
Serialise_vkCmdEndDebugUtilsLabelEXT(ser, commandBuffer);
record->AddChunk(scope.Get());
}
}
template <typename SerialiserType>
bool WrappedVulkan::Serialise_vkCmdInsertDebugUtilsLabelEXT(SerialiserType &ser,
VkCommandBuffer commandBuffer,
const VkDebugUtilsLabelEXT *pLabelInfo)
{
SERIALISE_ELEMENT(commandBuffer);
SERIALISE_ELEMENT_LOCAL(Label, *pLabelInfo);
SERIALISE_CHECK_READ_ERRORS();
if(IsReplayingAndReading())
{
m_LastCmdBufferID = GetResourceManager()->GetOriginalID(GetResID(commandBuffer));
if(IsActiveReplaying(m_State))
{
if(InRerecordRange(m_LastCmdBufferID))
{
commandBuffer = RerecordCmdBuf(m_LastCmdBufferID);
if(ObjDisp(commandBuffer)->CmdInsertDebugUtilsLabelEXT)
ObjDisp(commandBuffer)->CmdInsertDebugUtilsLabelEXT(Unwrap(commandBuffer), &Label);
}
}
else
{
if(ObjDisp(commandBuffer)->CmdInsertDebugUtilsLabelEXT)
ObjDisp(commandBuffer)->CmdInsertDebugUtilsLabelEXT(Unwrap(commandBuffer), &Label);
DrawcallDescription draw;
draw.name = Label.pLabelName;
draw.flags |= DrawFlags::SetMarker;
draw.markerColor[0] = RDCCLAMP(Label.color[0], 0.0f, 1.0f);
draw.markerColor[1] = RDCCLAMP(Label.color[1], 0.0f, 1.0f);
draw.markerColor[2] = RDCCLAMP(Label.color[2], 0.0f, 1.0f);
draw.markerColor[3] = RDCCLAMP(Label.color[3], 0.0f, 1.0f);
AddEvent();
AddDrawcall(draw, false);
}
}
return true;
}
void WrappedVulkan::vkCmdInsertDebugUtilsLabelEXT(VkCommandBuffer commandBuffer,
const VkDebugUtilsLabelEXT *pLabelInfo)
{
if(ObjDisp(commandBuffer)->CmdInsertDebugUtilsLabelEXT)
{
SERIALISE_TIME_CALL(
ObjDisp(commandBuffer)->CmdInsertDebugUtilsLabelEXT(Unwrap(commandBuffer), pLabelInfo));
}
if(IsCaptureMode(m_State))
{
VkResourceRecord *record = GetRecord(commandBuffer);
CACHE_THREAD_SERIALISER();
ser.SetDrawChunk();
SCOPED_SERIALISE_CHUNK(VulkanChunk::vkCmdInsertDebugUtilsLabelEXT);
Serialise_vkCmdInsertDebugUtilsLabelEXT(ser, commandBuffer, pLabelInfo);
record->AddChunk(scope.Get());
}
}
INSTANTIATE_FUNCTION_SERIALISED(VkResult, vkCreateCommandPool, VkDevice device,
const VkCommandPoolCreateInfo *pCreateInfo,
const VkAllocationCallbacks *pAllocator, VkCommandPool *pCommandPool);
@@ -3679,4 +3890,12 @@ INSTANTIATE_FUNCTION_SERIALISED(void, vkCmdPushDescriptorSetWithTemplateKHR,
INSTANTIATE_FUNCTION_SERIALISED(void, vkCmdWriteBufferMarkerAMD, VkCommandBuffer commandBuffer,
VkPipelineStageFlagBits pipelineStage, VkBuffer dstBuffer,
VkDeviceSize dstOffset, uint32_t marker);
VkDeviceSize dstOffset, uint32_t marker);
INSTANTIATE_FUNCTION_SERIALISED(void, vkCmdBeginDebugUtilsLabelEXT, VkCommandBuffer commandBuffer,
const VkDebugUtilsLabelEXT *pLabelInfo);
INSTANTIATE_FUNCTION_SERIALISED(void, vkCmdEndDebugUtilsLabelEXT, VkCommandBuffer commandBuffer);
INSTANTIATE_FUNCTION_SERIALISED(void, vkCmdInsertDebugUtilsLabelEXT, VkCommandBuffer commandBuffer,
const VkDebugUtilsLabelEXT *pLabelInfo);
+404 -149
View File
@@ -1011,7 +1011,7 @@ VkResult WrappedVulkan::vkGetQueryPoolResults(VkDevice device, VkQueryPool query
queryCount, dataSize, pData, stride, flags);
}
struct UserDebugCallbackData
struct UserDebugReportCallbackData
{
VkInstance wrappedInstance;
VkDebugReportCallbackCreateInfoEXT createInfo;
@@ -1020,12 +1020,13 @@ struct UserDebugCallbackData
VkDebugReportCallbackEXT realObject;
};
VkBool32 VKAPI_PTR UserDebugCallback(VkDebugReportFlagsEXT flags,
VkDebugReportObjectTypeEXT objectType, uint64_t object,
size_t location, int32_t messageCode, const char *pLayerPrefix,
const char *pMessage, void *pUserData)
VkBool32 VKAPI_PTR UserDebugReportCallback(VkDebugReportFlagsEXT flags,
VkDebugReportObjectTypeEXT objectType, uint64_t object,
size_t location, int32_t messageCode,
const char *pLayerPrefix, const char *pMessage,
void *pUserData)
{
UserDebugCallbackData *user = (UserDebugCallbackData *)pUserData;
UserDebugReportCallbackData *user = (UserDebugReportCallbackData *)pUserData;
if(RenderDoc::Inst().GetCaptureOptions().debugOutputMute)
{
@@ -1061,22 +1062,77 @@ VkBool32 VKAPI_PTR UserDebugCallback(VkDebugReportFlagsEXT flags,
return user->createInfo.pfnCallback(flags, objectType, object, location, messageCode,
pLayerPrefix, pMessage, user->createInfo.pUserData);
}
struct UserDebugUtilsCallbackData
{
VkDebugUtilsMessengerCreateInfoEXT createInfo;
bool muteWarned;
VkDebugUtilsMessengerEXT realObject;
};
VkBool32 VKAPI_PTR UserDebugUtilsCallback(VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
VkDebugUtilsMessageTypeFlagsEXT messageType,
const VkDebugUtilsMessengerCallbackDataEXT *pCallbackData,
void *pUserData)
{
UserDebugUtilsCallbackData *user = (UserDebugUtilsCallbackData *)pUserData;
if(RenderDoc::Inst().GetCaptureOptions().debugOutputMute)
{
if(user->muteWarned)
return false;
// once only insert a fake message notifying of the muting
user->muteWarned = true;
// we insert as an information message, since some trigger-happy applications might
// debugbreak/crash/messagebox/etc on even warnings. This puts us in the same pool
// as extremely spammy messages, but there's not much alternative.
if(user->createInfo.messageSeverity & (VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT |
VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT))
{
// use information type if possible, or if it's not accepted but debug is - use debug type.
messageSeverity =
(user->createInfo.messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT)
? VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT
: VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT;
VkDebugUtilsMessengerCallbackDataEXT data = {};
data.messageIdNumber = 1;
data.pMessageIdName = NULL;
data.pMessage =
"While debugging through RenderDoc, debug output through validation layers is "
"suppressed.\n"
"To show debug output look at the 'DebugOutputMute' capture option in RenderDoc's API, "
"but be aware of false positives from the validation layers.";
data.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CALLBACK_DATA_EXT;
user->createInfo.pfnUserCallback(messageSeverity, VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT,
&data, user->createInfo.pUserData);
}
return false;
}
return user->createInfo.pfnUserCallback(messageSeverity, messageType, pCallbackData,
user->createInfo.pUserData);
}
VkResult WrappedVulkan::vkCreateDebugReportCallbackEXT(
VkInstance instance, const VkDebugReportCallbackCreateInfoEXT *pCreateInfo,
const VkAllocationCallbacks *pAllocator, VkDebugReportCallbackEXT *pCallback)
{
// we create an interception object here so that we can dynamically check the state of API
// messages
// being muted, since it's quite likely that the application will initialise Vulkan (and so create
// a debug report callback) before it messes with RenderDoc's API to unmute messages.
UserDebugCallbackData *user = new UserDebugCallbackData();
// messages being muted, since it's quite likely that the application will initialise Vulkan (and
// so create a debug report callback) before it messes with RenderDoc's API to unmute messages.
UserDebugReportCallbackData *user = new UserDebugReportCallbackData();
user->wrappedInstance = instance;
user->createInfo = *pCreateInfo;
user->muteWarned = false;
VkDebugReportCallbackCreateInfoEXT wrappedCreateInfo = *pCreateInfo;
wrappedCreateInfo.pfnCallback = &UserDebugCallback;
wrappedCreateInfo.pfnCallback = &UserDebugReportCallback;
wrappedCreateInfo.pUserData = user;
VkResult vkr = ObjDisp(instance)->CreateDebugReportCallbackEXT(
@@ -1098,7 +1154,8 @@ void WrappedVulkan::vkDestroyDebugReportCallbackEXT(VkInstance instance,
VkDebugReportCallbackEXT callback,
const VkAllocationCallbacks *pAllocator)
{
UserDebugCallbackData *user = (UserDebugCallbackData *)(uintptr_t)NON_DISP_TO_UINT64(callback);
UserDebugReportCallbackData *user =
(UserDebugReportCallbackData *)(uintptr_t)NON_DISP_TO_UINT64(callback);
ObjDisp(instance)->DestroyDebugReportCallbackEXT(Unwrap(instance), user->realObject, pAllocator);
@@ -1114,82 +1171,177 @@ void WrappedVulkan::vkDebugReportMessageEXT(VkInstance instance, VkDebugReportFl
location, messageCode, pLayerPrefix, pMessage);
}
static VkResourceRecord *GetObjRecord(VkDebugReportObjectTypeEXT objType, uint64_t object)
// we use VkObjectType as the object type since it mostly overlaps with the debug report enum so in
// most cases we can upcast it. There's an overload to translate the few that might conflict.
// Likewise to re-use the switch in most cases, we return both the record and the unwrapped
// object at once. In *most* cases the unwrapped object comes from the record, but there are a few
// exceptions which don't have records, or aren't wrapped, etc.
struct ObjData
{
VkResourceRecord *record;
uint64_t unwrapped;
};
static ObjData GetObjData(VkObjectType objType, uint64_t object)
{
ObjData ret = {};
switch(objType)
{
case VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT: return GetRecord((VkInstance)object);
case VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT:
return GetRecord((VkPhysicalDevice)object);
case VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT: return GetRecord((VkDevice)object);
case VK_DEBUG_REPORT_OBJECT_TYPE_QUEUE_EXT: return GetRecord((VkQueue)object);
case VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT: return GetRecord((VkCommandBuffer)object);
case VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT: return GetRecord((VkDeviceMemory)object);
case VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT: return GetRecord((VkBuffer)object);
case VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_VIEW_EXT: return GetRecord((VkBufferView)object);
case VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT: return GetRecord((VkImage)object);
case VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_VIEW_EXT: return GetRecord((VkImageView)object);
case VK_DEBUG_REPORT_OBJECT_TYPE_SHADER_MODULE_EXT: return GetRecord((VkShaderModule)object);
case VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT: return GetRecord((VkPipeline)object);
case VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_LAYOUT_EXT:
return GetRecord((VkPipelineLayout)object);
case VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_EXT: return GetRecord((VkSampler)object);
case VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT: return GetRecord((VkDescriptorSet)object);
case VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT_EXT:
return GetRecord((VkDescriptorSetLayout)object);
case VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT:
return GetRecord((VkDescriptorPool)object);
case VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT: return GetRecord((VkFence)object);
case VK_DEBUG_REPORT_OBJECT_TYPE_SEMAPHORE_EXT: return GetRecord((VkSemaphore)object);
case VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT: return GetRecord((VkEvent)object);
case VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT: return GetRecord((VkQueryPool)object);
case VK_DEBUG_REPORT_OBJECT_TYPE_FRAMEBUFFER_EXT: return GetRecord((VkFramebuffer)object);
case VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT: return GetRecord((VkRenderPass)object);
case VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_CACHE_EXT: return GetRecord((VkPipelineCache)object);
case VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT: return GetRecord((VkSurfaceKHR)object);
case VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT: return GetRecord((VkSwapchainKHR)object);
case VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_POOL_EXT: return GetRecord((VkCommandPool)object);
case VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_EXT:
return GetRecord((VkDescriptorUpdateTemplateKHR)object);
case VK_DEBUG_REPORT_OBJECT_TYPE_DISPLAY_KHR_EXT:
case VK_DEBUG_REPORT_OBJECT_TYPE_DISPLAY_MODE_KHR_EXT:
case VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT:
case VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_EXT:
case VK_DEBUG_REPORT_OBJECT_TYPE_RANGE_SIZE_EXT:
case VK_DEBUG_REPORT_OBJECT_TYPE_OBJECT_TABLE_NVX_EXT:
case VK_DEBUG_REPORT_OBJECT_TYPE_VALIDATION_CACHE_EXT:
case VK_DEBUG_REPORT_OBJECT_TYPE_INDIRECT_COMMANDS_LAYOUT_NVX_EXT:
case VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION_KHR_EXT:
case VK_DEBUG_REPORT_OBJECT_TYPE_MAX_ENUM_EXT: break;
case VK_OBJECT_TYPE_INSTANCE: ret.record = GetRecord((VkInstance)object); break;
case VK_OBJECT_TYPE_PHYSICAL_DEVICE: ret.record = GetRecord((VkPhysicalDevice)object); break;
case VK_OBJECT_TYPE_DEVICE: ret.record = GetRecord((VkDevice)object); break;
case VK_OBJECT_TYPE_QUEUE: ret.record = GetRecord((VkQueue)object); break;
case VK_OBJECT_TYPE_SEMAPHORE: ret.record = GetRecord((VkSemaphore)object); break;
case VK_OBJECT_TYPE_COMMAND_BUFFER: ret.record = GetRecord((VkCommandBuffer)object); break;
case VK_OBJECT_TYPE_FENCE: ret.record = GetRecord((VkFence)object); break;
case VK_OBJECT_TYPE_DEVICE_MEMORY: ret.record = GetRecord((VkDeviceMemory)object); break;
case VK_OBJECT_TYPE_BUFFER: ret.record = GetRecord((VkBuffer)object); break;
case VK_OBJECT_TYPE_IMAGE: ret.record = GetRecord((VkImage)object); break;
case VK_OBJECT_TYPE_EVENT: ret.record = GetRecord((VkEvent)object); break;
case VK_OBJECT_TYPE_QUERY_POOL: ret.record = GetRecord((VkQueryPool)object); break;
case VK_OBJECT_TYPE_BUFFER_VIEW: ret.record = GetRecord((VkBufferView)object); break;
case VK_OBJECT_TYPE_IMAGE_VIEW: ret.record = GetRecord((VkImageView)object); break;
case VK_OBJECT_TYPE_SHADER_MODULE: ret.record = GetRecord((VkShaderModule)object); break;
case VK_OBJECT_TYPE_PIPELINE_CACHE: ret.record = GetRecord((VkPipelineCache)object); break;
case VK_OBJECT_TYPE_PIPELINE_LAYOUT: ret.record = GetRecord((VkPipelineLayout)object); break;
case VK_OBJECT_TYPE_RENDER_PASS: ret.record = GetRecord((VkRenderPass)object); break;
case VK_OBJECT_TYPE_PIPELINE: ret.record = GetRecord((VkPipeline)object); break;
case VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT:
ret.record = GetRecord((VkDescriptorSetLayout)object);
break;
case VK_OBJECT_TYPE_SAMPLER: ret.record = GetRecord((VkSampler)object); break;
case VK_OBJECT_TYPE_DESCRIPTOR_POOL: ret.record = GetRecord((VkDescriptorPool)object); break;
case VK_OBJECT_TYPE_DESCRIPTOR_SET: ret.record = GetRecord((VkDescriptorSet)object); break;
case VK_OBJECT_TYPE_FRAMEBUFFER: ret.record = GetRecord((VkFramebuffer)object); break;
case VK_OBJECT_TYPE_COMMAND_POOL: ret.record = GetRecord((VkCommandPool)object); break;
case VK_OBJECT_TYPE_SWAPCHAIN_KHR: ret.record = GetRecord((VkSwapchainKHR)object); break;
case VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE:
ret.record = GetRecord((VkDescriptorUpdateTemplateKHR)object);
break;
/////////////////////////////
// special cases
// VkSurfaceKHR doesn't have a record
case VK_OBJECT_TYPE_SURFACE_KHR:
ret.unwrapped = GetWrapped((VkSurfaceKHR)object)->real.handle;
break;
// VkDisplayKHR and VkDisplayModeKHR are not wrapped
case VK_OBJECT_TYPE_DISPLAY_KHR:
case VK_OBJECT_TYPE_DISPLAY_MODE_KHR:
ret.unwrapped = object;
break;
// debug report callback and messenger are not wrapped in the conventional way
case VK_OBJECT_TYPE_DEBUG_REPORT_CALLBACK_EXT:
{
UserDebugReportCallbackData *user = (UserDebugReportCallbackData *)(uintptr_t)object;
ret.unwrapped = NON_DISP_TO_UINT64(user->realObject);
break;
}
case VK_OBJECT_TYPE_DEBUG_UTILS_MESSENGER_EXT:
{
UserDebugUtilsCallbackData *user = (UserDebugUtilsCallbackData *)(uintptr_t)object;
ret.unwrapped = NON_DISP_TO_UINT64(user->realObject);
break;
}
// these objects are not supported
case VK_OBJECT_TYPE_OBJECT_TABLE_NVX:
case VK_OBJECT_TYPE_VALIDATION_CACHE_EXT:
case VK_OBJECT_TYPE_INDIRECT_COMMANDS_LAYOUT_NVX:
case VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION:
case VK_OBJECT_TYPE_UNKNOWN:
case VK_OBJECT_TYPE_RANGE_SIZE:
case VK_OBJECT_TYPE_MAX_ENUM: break;
}
return NULL;
RDCCOMPILE_ASSERT(VK_OBJECT_TYPE_END_RANGE == VK_OBJECT_TYPE_COMMAND_POOL,
"Enum added to object type");
// if we have a record and no unwrapped object, fetch it out of the record
if(ret.record && ret.unwrapped == 0)
{
switch(objType)
{
// dispatchable objects
case VK_OBJECT_TYPE_INSTANCE:
case VK_OBJECT_TYPE_PHYSICAL_DEVICE:
case VK_OBJECT_TYPE_QUEUE:
case VK_OBJECT_TYPE_DEVICE:
case VK_OBJECT_TYPE_COMMAND_BUFFER:
{
WrappedVkDispRes *res = (WrappedVkDispRes *)ret.record->Resource;
ret.unwrapped = res->real.handle;
break;
}
// non-dispatchable objects
default:
{
WrappedVkNonDispRes *res = (WrappedVkNonDispRes *)ret.record->Resource;
ret.unwrapped = res->real.handle;
break;
}
}
}
return ret;
}
// overload to silently cast
static ObjData GetObjData(VkDebugReportObjectTypeEXT objType, uint64_t object)
{
VkObjectType castType = (VkObjectType)objType;
// a few special cases don't overlap and will conflict when more core objects are added to
// VkObjectType so we don't cast them.
if(objType == VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT)
castType = VK_OBJECT_TYPE_SWAPCHAIN_KHR;
else if(objType == VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT)
castType = VK_OBJECT_TYPE_SURFACE_KHR;
else if(objType == VK_DEBUG_REPORT_OBJECT_TYPE_DISPLAY_KHR_EXT)
castType = VK_OBJECT_TYPE_DISPLAY_KHR;
else if(objType == VK_DEBUG_REPORT_OBJECT_TYPE_DISPLAY_MODE_KHR_EXT)
castType = VK_OBJECT_TYPE_DISPLAY_MODE_KHR;
else if(objType == VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_EXT)
castType = VK_OBJECT_TYPE_DEBUG_REPORT_CALLBACK_EXT;
else if(objType == VK_DEBUG_REPORT_OBJECT_TYPE_OBJECT_TABLE_NVX_EXT)
castType = VK_OBJECT_TYPE_OBJECT_TABLE_NVX;
else if(objType == VK_DEBUG_REPORT_OBJECT_TYPE_INDIRECT_COMMANDS_LAYOUT_NVX_EXT)
castType = VK_OBJECT_TYPE_INDIRECT_COMMANDS_LAYOUT_NVX;
else if(objType == VK_DEBUG_REPORT_OBJECT_TYPE_VALIDATION_CACHE_EXT)
castType = VK_OBJECT_TYPE_VALIDATION_CACHE_EXT;
else if(objType == VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION_EXT)
castType = VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION;
else if(objType == VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_EXT)
castType = VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE;
RDCCOMPILE_ASSERT(VK_DEBUG_REPORT_OBJECT_TYPE_END_RANGE_EXT ==
VK_DEBUG_REPORT_OBJECT_TYPE_VALIDATION_CACHE_EXT_EXT,
"Enum added to debug report object type");
return GetObjData((VkObjectType)objType, object);
}
template <typename SerialiserType>
bool WrappedVulkan::Serialise_SetShaderDebugPath(SerialiserType &ser, VkDevice device,
const VkDebugMarkerObjectTagInfoEXT *pTagInfo)
bool WrappedVulkan::Serialise_SetShaderDebugPath(SerialiserType &ser, VkShaderModule ShaderObject,
std::string DebugPath)
{
SERIALISE_ELEMENT_LOCAL(ShaderObject,
GetObjRecord(pTagInfo->objectType, pTagInfo->object)->GetResourceID())
.TypedAs("VkShaderModule");
std::string DebugPath;
if(IsCaptureMode(m_State))
{
char *tag = (char *)pTagInfo->pTag;
DebugPath = std::string(tag, tag + pTagInfo->tagSize);
}
SERIALISE_ELEMENT(ShaderObject);
SERIALISE_ELEMENT(DebugPath);
SERIALISE_CHECK_READ_ERRORS();
if(IsReplayingAndReading())
{
m_CreationInfo.m_ShaderModule[GetResourceManager()->GetLiveID(ShaderObject)].unstrippedPath =
DebugPath;
m_CreationInfo.m_ShaderModule[GetResID(ShaderObject)].unstrippedPath = DebugPath;
AddResourceCurChunk(ShaderObject);
AddResourceCurChunk(GetResourceManager()->GetOriginalID(GetResID(ShaderObject)));
}
return true;
@@ -1200,50 +1352,25 @@ VkResult WrappedVulkan::vkDebugMarkerSetObjectTagEXT(VkDevice device,
{
if(IsCaptureMode(m_State) && pTagInfo)
{
VkResourceRecord *record = GetObjRecord(pTagInfo->objectType, pTagInfo->object);
ObjData data = GetObjData(pTagInfo->objectType, pTagInfo->object);
if(!record)
{
RDCERR("Unrecognised object %d %llu", pTagInfo->objectType, pTagInfo->object);
return VK_SUCCESS;
}
if(pTagInfo->tagName == RENDERDOC_ShaderDebugMagicValue_truncated &&
if(data.record && pTagInfo->tagName == RENDERDOC_ShaderDebugMagicValue_truncated &&
pTagInfo->objectType == VK_DEBUG_REPORT_OBJECT_TYPE_SHADER_MODULE_EXT)
{
CACHE_THREAD_SERIALISER();
char *tag = (char *)pTagInfo->pTag;
std::string DebugPath = std::string(tag, tag + pTagInfo->tagSize);
SCOPED_SERIALISE_CHUNK(VulkanChunk::SetShaderDebugPath);
Serialise_SetShaderDebugPath(ser, device, pTagInfo);
record->AddChunk(scope.Get());
Serialise_SetShaderDebugPath(ser, (VkShaderModule)data.record->Resource, DebugPath);
data.record->AddChunk(scope.Get());
}
else if(ObjDisp(device)->DebugMarkerSetObjectTagEXT)
{
VkDebugMarkerObjectTagInfoEXT unwrapped = *pTagInfo;
// special case for VkSurfaceKHR - the record pointer is actually just the underlying native
// window handle, so instead we unwrap and call through.
if(unwrapped.objectType == VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT)
{
unwrapped.object = GetWrapped((VkSurfaceKHR)unwrapped.object)->real.handle;
return ObjDisp(device)->DebugMarkerSetObjectTagEXT(device, &unwrapped);
}
if(unwrapped.objectType == VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT ||
unwrapped.objectType == VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT ||
unwrapped.objectType == VK_DEBUG_REPORT_OBJECT_TYPE_QUEUE_EXT ||
unwrapped.objectType == VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT ||
unwrapped.objectType == VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT)
{
WrappedVkDispRes *res = (WrappedVkDispRes *)record->Resource;
unwrapped.object = res->real.handle;
}
else
{
WrappedVkNonDispRes *res = (WrappedVkNonDispRes *)record->Resource;
unwrapped.object = res->real.handle;
}
unwrapped.object = data.unwrapped;
return ObjDisp(device)->DebugMarkerSetObjectTagEXT(device, &unwrapped);
}
@@ -1256,8 +1383,8 @@ template <typename SerialiserType>
bool WrappedVulkan::Serialise_vkDebugMarkerSetObjectNameEXT(
SerialiserType &ser, VkDevice device, const VkDebugMarkerObjectNameInfoEXT *pNameInfo)
{
SERIALISE_ELEMENT_LOCAL(Object,
GetObjRecord(pNameInfo->objectType, pNameInfo->object)->GetResourceID());
SERIALISE_ELEMENT_LOCAL(
Object, GetObjData(pNameInfo->objectType, pNameInfo->object).record->GetResourceID());
SERIALISE_ELEMENT_LOCAL(ObjectName, pNameInfo->pObjectName);
SERIALISE_CHECK_READ_ERRORS();
@@ -1286,58 +1413,166 @@ VkResult WrappedVulkan::vkDebugMarkerSetObjectNameEXT(VkDevice device,
{
if(IsCaptureMode(m_State) && pNameInfo)
{
Chunk *chunk = NULL;
VkResourceRecord *record = GetObjRecord(pNameInfo->objectType, pNameInfo->object);
if(!record)
{
RDCERR("Unrecognised object %d %llu", pNameInfo->objectType, pNameInfo->object);
return VK_SUCCESS;
}
ObjData data = GetObjData(pNameInfo->objectType, pNameInfo->object);
VkDebugMarkerObjectNameInfoEXT unwrapped = *pNameInfo;
// special case for VkSurfaceKHR - the record pointer is actually just the underlying native
// window handle, so instead we unwrap and call through.
if(unwrapped.objectType == VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT)
{
unwrapped.object = GetWrapped((VkSurfaceKHR)unwrapped.object)->real.handle;
if(ObjDisp(device)->DebugMarkerSetObjectNameEXT)
return ObjDisp(device)->DebugMarkerSetObjectNameEXT(device, &unwrapped);
return VK_SUCCESS;
}
if(unwrapped.objectType == VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT ||
unwrapped.objectType == VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT ||
unwrapped.objectType == VK_DEBUG_REPORT_OBJECT_TYPE_QUEUE_EXT ||
unwrapped.objectType == VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT ||
unwrapped.objectType == VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT)
{
WrappedVkDispRes *res = (WrappedVkDispRes *)record->Resource;
unwrapped.object = res->real.handle;
}
else
{
WrappedVkNonDispRes *res = (WrappedVkNonDispRes *)record->Resource;
unwrapped.object = res->real.handle;
}
unwrapped.object = data.unwrapped;
if(ObjDisp(device)->DebugMarkerSetObjectNameEXT)
ObjDisp(device)->DebugMarkerSetObjectNameEXT(device, &unwrapped);
if(data.record)
{
CACHE_THREAD_SERIALISER();
SCOPED_SERIALISE_CHUNK(VulkanChunk::vkDebugMarkerSetObjectNameEXT);
Serialise_vkDebugMarkerSetObjectNameEXT(ser, device, pNameInfo);
chunk = scope.Get();
}
Chunk *chunk = scope.Get();
record->AddChunk(chunk);
data.record->AddChunk(chunk);
}
}
return VK_SUCCESS;
}
VkResult WrappedVulkan::vkCreateDebugUtilsMessengerEXT(
VkInstance instance, const VkDebugUtilsMessengerCreateInfoEXT *pCreateInfo,
const VkAllocationCallbacks *pAllocator, VkDebugUtilsMessengerEXT *pMessenger)
{
// we create an interception object here so that we can dynamically check the state of API
// messages being muted, since it's quite likely that the application will initialise Vulkan (and
// so create a debug report callback) before it messes with RenderDoc's API to unmute messages.
UserDebugUtilsCallbackData *user = new UserDebugUtilsCallbackData();
user->createInfo = *pCreateInfo;
user->muteWarned = false;
VkDebugUtilsMessengerCreateInfoEXT wrappedCreateInfo = *pCreateInfo;
wrappedCreateInfo.pfnUserCallback = &UserDebugUtilsCallback;
wrappedCreateInfo.pUserData = user;
VkResult vkr = ObjDisp(instance)->CreateDebugUtilsMessengerEXT(
Unwrap(instance), &wrappedCreateInfo, pAllocator, &user->realObject);
if(vkr != VK_SUCCESS)
{
*pMessenger = VK_NULL_HANDLE;
delete user;
return vkr;
}
*pMessenger = (VkDebugUtilsMessengerEXT)(uint64_t)user;
return vkr;
}
void WrappedVulkan::vkDestroyDebugUtilsMessengerEXT(VkInstance instance,
VkDebugUtilsMessengerEXT messenger,
const VkAllocationCallbacks *pAllocator)
{
UserDebugReportCallbackData *user =
(UserDebugReportCallbackData *)(uintptr_t)NON_DISP_TO_UINT64(messenger);
ObjDisp(instance)->DestroyDebugReportCallbackEXT(Unwrap(instance), user->realObject, pAllocator);
delete user;
}
void WrappedVulkan::vkSubmitDebugUtilsMessageEXT(
VkInstance instance, VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
VkDebugUtilsMessageTypeFlagsEXT messageTypes,
const VkDebugUtilsMessengerCallbackDataEXT *pCallbackData)
{
return ObjDisp(instance)->SubmitDebugUtilsMessageEXT(Unwrap(instance), messageSeverity,
messageTypes, pCallbackData);
}
template <typename SerialiserType>
bool WrappedVulkan::Serialise_vkSetDebugUtilsObjectNameEXT(
SerialiserType &ser, VkDevice device, const VkDebugUtilsObjectNameInfoEXT *pNameInfo)
{
SERIALISE_ELEMENT_LOCAL(
Object, GetObjData(pNameInfo->objectType, pNameInfo->objectHandle).record->GetResourceID());
SERIALISE_ELEMENT_LOCAL(ObjectName, pNameInfo->pObjectName);
SERIALISE_CHECK_READ_ERRORS();
if(IsReplayingAndReading())
{
// if we don't have a live resource, this is probably a command buffer being named on the
// virtual non-existant parent, not any of the baked IDs. Just save the name on the original ID
// and we'll propagate it in Serialise_vkBeginCommandBuffer
if(!GetResourceManager()->HasLiveResource(Object) || GetResourceManager()->HasReplacement(Object))
m_CreationInfo.m_Names[Object] = ObjectName;
else
m_CreationInfo.m_Names[GetResourceManager()->GetLiveID(Object)] = ObjectName;
ResourceDescription &descr = GetReplay()->GetResourceDesc(Object);
AddResourceCurChunk(descr);
descr.SetCustomName(ObjectName);
}
return true;
}
VkResult WrappedVulkan::vkSetDebugUtilsObjectNameEXT(VkDevice device,
const VkDebugUtilsObjectNameInfoEXT *pNameInfo)
{
if(IsCaptureMode(m_State) && pNameInfo)
{
ObjData data = GetObjData(pNameInfo->objectType, pNameInfo->objectHandle);
VkDebugUtilsObjectNameInfoEXT unwrapped = *pNameInfo;
unwrapped.objectHandle = data.unwrapped;
if(ObjDisp(device)->SetDebugUtilsObjectNameEXT)
ObjDisp(device)->SetDebugUtilsObjectNameEXT(device, &unwrapped);
if(data.record)
{
CACHE_THREAD_SERIALISER();
SCOPED_SERIALISE_CHUNK(VulkanChunk::vkSetDebugUtilsObjectNameEXT);
Serialise_vkSetDebugUtilsObjectNameEXT(ser, device, pNameInfo);
Chunk *chunk = scope.Get();
data.record->AddChunk(chunk);
}
}
return VK_SUCCESS;
}
VkResult WrappedVulkan::vkSetDebugUtilsObjectTagEXT(VkDevice device,
const VkDebugUtilsObjectTagInfoEXT *pTagInfo)
{
if(IsCaptureMode(m_State) && pTagInfo)
{
ObjData data = GetObjData(pTagInfo->objectType, pTagInfo->objectHandle);
if(data.record && pTagInfo->tagName == RENDERDOC_ShaderDebugMagicValue_truncated &&
pTagInfo->objectType == VK_OBJECT_TYPE_SHADER_MODULE)
{
CACHE_THREAD_SERIALISER();
char *tag = (char *)pTagInfo->pTag;
std::string DebugPath = std::string(tag, tag + pTagInfo->tagSize);
SCOPED_SERIALISE_CHUNK(VulkanChunk::SetShaderDebugPath);
Serialise_SetShaderDebugPath(ser, (VkShaderModule)data.record->Resource, DebugPath);
data.record->AddChunk(scope.Get());
}
else if(ObjDisp(device)->SetDebugUtilsObjectTagEXT)
{
VkDebugUtilsObjectTagInfoEXT unwrapped = *pTagInfo;
unwrapped.objectHandle = data.unwrapped;
return ObjDisp(device)->SetDebugUtilsObjectTagEXT(device, &unwrapped);
}
}
return VK_SUCCESS;
@@ -1359,8 +1594,28 @@ INSTANTIATE_FUNCTION_SERIALISED(VkResult, vkCreateQueryPool, VkDevice device,
const VkQueryPoolCreateInfo *pCreateInfo,
const VkAllocationCallbacks *pAllocator, VkQueryPool *pQueryPool);
INSTANTIATE_FUNCTION_SERIALISED(void, SetShaderDebugPath, VkDevice device,
const VkDebugMarkerObjectTagInfoEXT *pTagInfo);
INSTANTIATE_FUNCTION_SERIALISED(void, SetShaderDebugPath, VkShaderModule ShaderObject,
std::string DebugPath);
INSTANTIATE_FUNCTION_SERIALISED(VkResult, vkDebugMarkerSetObjectNameEXT, VkDevice device,
const VkDebugMarkerObjectNameInfoEXT *pNameInfo);
INSTANTIATE_FUNCTION_SERIALISED(VkResult, vkSetDebugUtilsObjectNameEXT, VkDevice device,
const VkDebugUtilsObjectNameInfoEXT *pNameInfo);
INSTANTIATE_FUNCTION_SERIALISED(VkResult, vkSetDebugUtilsObjectTagEXT, VkDevice device,
const VkDebugUtilsObjectTagInfoEXT *pTagInfo);
INSTANTIATE_FUNCTION_SERIALISED(VkResult, vkCreateDebugUtilsMessengerEXT, VkInstance instance,
const VkDebugUtilsMessengerCreateInfoEXT *pCreateInfo,
const VkAllocationCallbacks *pAllocator,
VkDebugUtilsMessengerEXT *pMessenger);
INSTANTIATE_FUNCTION_SERIALISED(void, vkDestroyDebugUtilsMessengerEXT, VkInstance instance,
VkDebugUtilsMessengerEXT messenger,
const VkAllocationCallbacks *pAllocator);
INSTANTIATE_FUNCTION_SERIALISED(void, vkSubmitDebugUtilsMessageEXT, VkInstance instance,
VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
VkDebugUtilsMessageTypeFlagsEXT messageTypes,
const VkDebugUtilsMessengerCallbackDataEXT *pCallbackData);
@@ -1105,6 +1105,161 @@ VkResult WrappedVulkan::vkQueueWaitIdle(VkQueue queue)
return ret;
}
template <typename SerialiserType>
bool WrappedVulkan::Serialise_vkQueueBeginDebugUtilsLabelEXT(SerialiserType &ser, VkQueue queue,
const VkDebugUtilsLabelEXT *pLabelInfo)
{
SERIALISE_ELEMENT(queue);
SERIALISE_ELEMENT_LOCAL(Label, *pLabelInfo);
SERIALISE_CHECK_READ_ERRORS();
if(IsReplayingAndReading())
{
if(ObjDisp(queue)->QueueBeginDebugUtilsLabelEXT)
ObjDisp(queue)->QueueBeginDebugUtilsLabelEXT(Unwrap(queue), &Label);
if(IsLoading(m_State))
{
DrawcallDescription draw;
draw.name = Label.pLabelName;
draw.flags |= DrawFlags::PushMarker;
draw.markerColor[0] = RDCCLAMP(Label.color[0], 0.0f, 1.0f);
draw.markerColor[1] = RDCCLAMP(Label.color[1], 0.0f, 1.0f);
draw.markerColor[2] = RDCCLAMP(Label.color[2], 0.0f, 1.0f);
draw.markerColor[3] = RDCCLAMP(Label.color[3], 0.0f, 1.0f);
AddEvent();
m_RootEventID++;
AddDrawcall(draw, false);
// now push the drawcall stack
GetDrawcallStack().push_back(&GetDrawcallStack().back()->children.back());
}
else
{
m_RootEventID++;
}
}
return true;
}
void WrappedVulkan::vkQueueBeginDebugUtilsLabelEXT(VkQueue queue,
const VkDebugUtilsLabelEXT *pLabelInfo)
{
if(ObjDisp(queue)->QueueBeginDebugUtilsLabelEXT)
{
SERIALISE_TIME_CALL(ObjDisp(queue)->QueueBeginDebugUtilsLabelEXT(Unwrap(queue), pLabelInfo));
}
if(IsActiveCapturing(m_State))
{
CACHE_THREAD_SERIALISER();
ser.SetDrawChunk();
SCOPED_SERIALISE_CHUNK(VulkanChunk::vkQueueBeginDebugUtilsLabelEXT);
Serialise_vkQueueBeginDebugUtilsLabelEXT(ser, queue, pLabelInfo);
m_FrameCaptureRecord->AddChunk(scope.Get());
GetResourceManager()->MarkResourceFrameReferenced(GetResID(queue), eFrameRef_Read);
}
}
template <typename SerialiserType>
bool WrappedVulkan::Serialise_vkQueueEndDebugUtilsLabelEXT(SerialiserType &ser, VkQueue queue)
{
SERIALISE_ELEMENT(queue);
SERIALISE_CHECK_READ_ERRORS();
if(IsReplayingAndReading())
{
if(ObjDisp(queue)->QueueEndDebugUtilsLabelEXT)
ObjDisp(queue)->QueueEndDebugUtilsLabelEXT(Unwrap(queue));
if(IsLoading(m_State))
{
if(GetDrawcallStack().size() > 1)
GetDrawcallStack().pop_back();
}
}
return true;
}
void WrappedVulkan::vkQueueEndDebugUtilsLabelEXT(VkQueue queue)
{
if(ObjDisp(queue)->QueueEndDebugUtilsLabelEXT)
{
SERIALISE_TIME_CALL(ObjDisp(queue)->QueueEndDebugUtilsLabelEXT(Unwrap(queue)));
}
if(IsActiveCapturing(m_State))
{
CACHE_THREAD_SERIALISER();
ser.SetDrawChunk();
SCOPED_SERIALISE_CHUNK(VulkanChunk::vkQueueEndDebugUtilsLabelEXT);
Serialise_vkQueueEndDebugUtilsLabelEXT(ser, queue);
m_FrameCaptureRecord->AddChunk(scope.Get());
GetResourceManager()->MarkResourceFrameReferenced(GetResID(queue), eFrameRef_Read);
}
}
template <typename SerialiserType>
bool WrappedVulkan::Serialise_vkQueueInsertDebugUtilsLabelEXT(SerialiserType &ser, VkQueue queue,
const VkDebugUtilsLabelEXT *pLabelInfo)
{
SERIALISE_ELEMENT(queue);
SERIALISE_ELEMENT_LOCAL(Label, *pLabelInfo);
SERIALISE_CHECK_READ_ERRORS();
if(IsReplayingAndReading())
{
if(ObjDisp(queue)->QueueInsertDebugUtilsLabelEXT)
ObjDisp(queue)->QueueInsertDebugUtilsLabelEXT(Unwrap(queue), &Label);
if(IsLoading(m_State))
{
DrawcallDescription draw;
draw.name = Label.pLabelName;
draw.flags |= DrawFlags::SetMarker;
draw.markerColor[0] = RDCCLAMP(Label.color[0], 0.0f, 1.0f);
draw.markerColor[1] = RDCCLAMP(Label.color[1], 0.0f, 1.0f);
draw.markerColor[2] = RDCCLAMP(Label.color[2], 0.0f, 1.0f);
draw.markerColor[3] = RDCCLAMP(Label.color[3], 0.0f, 1.0f);
AddEvent();
AddDrawcall(draw, false);
}
}
return true;
}
void WrappedVulkan::vkQueueInsertDebugUtilsLabelEXT(VkQueue queue,
const VkDebugUtilsLabelEXT *pLabelInfo)
{
if(ObjDisp(queue)->QueueInsertDebugUtilsLabelEXT)
{
SERIALISE_TIME_CALL(ObjDisp(queue)->QueueInsertDebugUtilsLabelEXT(Unwrap(queue), pLabelInfo));
}
if(IsActiveCapturing(m_State))
{
CACHE_THREAD_SERIALISER();
ser.SetDrawChunk();
SCOPED_SERIALISE_CHUNK(VulkanChunk::vkQueueInsertDebugUtilsLabelEXT);
Serialise_vkQueueInsertDebugUtilsLabelEXT(ser, queue, pLabelInfo);
m_FrameCaptureRecord->AddChunk(scope.Get());
GetResourceManager()->MarkResourceFrameReferenced(GetResID(queue), eFrameRef_Read);
}
}
INSTANTIATE_FUNCTION_SERIALISED(void, vkGetDeviceQueue, VkDevice device, uint32_t queueFamilyIndex,
uint32_t queueIndex, VkQueue *pQueue);
@@ -1115,3 +1270,11 @@ INSTANTIATE_FUNCTION_SERIALISED(VkResult, vkQueueBindSparse, VkQueue queue, uint
const VkBindSparseInfo *pBindInfo, VkFence fence);
INSTANTIATE_FUNCTION_SERIALISED(VkResult, vkQueueWaitIdle, VkQueue queue);
INSTANTIATE_FUNCTION_SERIALISED(void, vkQueueBeginDebugUtilsLabelEXT, VkQueue queue,
const VkDebugUtilsLabelEXT *pLabelInfo);
INSTANTIATE_FUNCTION_SERIALISED(void, vkQueueEndDebugUtilsLabelEXT, VkQueue queue);
INSTANTIATE_FUNCTION_SERIALISED(void, vkQueueInsertDebugUtilsLabelEXT, VkQueue queue,
const VkDebugUtilsLabelEXT *pLabelInfo);