From 0d784c57289a80fc2a7af4bab1d41888065296ec Mon Sep 17 00:00:00 2001 From: baldurk Date: Mon, 16 Jun 2025 16:30:33 +0100 Subject: [PATCH] Only reserve descriptors once even when self-capturing * We mark to ourselves that the reserved descriptor range has been grabbed and don't try to re-create it, instead sharing/re-using it between different versions. --- renderdoc/driver/vulkan/vk_common.cpp | 8 +++++++ renderdoc/driver/vulkan/vk_common.h | 2 ++ renderdoc/driver/vulkan/vk_core.h | 6 ++++- .../vulkan/wrappers/vk_device_funcs.cpp | 13 +++++++++++ .../driver/vulkan/wrappers/vk_misc_funcs.cpp | 5 +++++ .../vulkan/wrappers/vk_resource_funcs.cpp | 22 ++++++++++++------- 6 files changed, 47 insertions(+), 9 deletions(-) diff --git a/renderdoc/driver/vulkan/vk_common.cpp b/renderdoc/driver/vulkan/vk_common.cpp index 510d09799..4d2a02246 100644 --- a/renderdoc/driver/vulkan/vk_common.cpp +++ b/renderdoc/driver/vulkan/vk_common.cpp @@ -433,6 +433,10 @@ bool VkInitParams::IsSupportedVersion(uint64_t ver) if(ver == CurrentVersion) return true; + // 0x16 -> 0x17 - added indication of reserved descriptors + if(ver == 0x16) + return true; + // 0x15 -> 0x16 - added support for acceleration structures if(ver == 0x15) return true; @@ -1012,6 +1016,10 @@ void DoSerialise(SerialiserType &ser, VkInitParams &el) SERIALISE_MEMBER(Layers); SERIALISE_MEMBER(Extensions).Important(); SERIALISE_MEMBER(InstanceID).TypedAs("VkInstance"_lit); + if(ser.VersionAtLeast(0x17)) + SERIALISE_MEMBER(DescriptorsReserved); + else + SERIALISE_MEMBER_EMPTY(DescriptorsReserved); } INSTANTIATE_SERIALISE_TYPE(VkInitParams); diff --git a/renderdoc/driver/vulkan/vk_common.h b/renderdoc/driver/vulkan/vk_common.h index 41e260af5..e055f3fbc 100644 --- a/renderdoc/driver/vulkan/vk_common.h +++ b/renderdoc/driver/vulkan/vk_common.h @@ -102,6 +102,8 @@ typedef VkPhysicalDeviceBufferDeviceAddressFeatures VkPhysicalDeviceBufferDevice // UUID shared with VR runtimes to specify which vkImage is currently presented to the screen #define VR_ThumbnailTag_UUID 0x94F5B9E495BCC552ULL +#define RENDERDOC_DescriptorsReservation_UUID 0xB908FA75193CFD52ULL + ResourceFormat MakeResourceFormat(VkFormat fmt); VkFormat MakeVkFormat(ResourceFormat fmt); Topology MakePrimitiveTopology(VkPrimitiveTopology Topo, uint32_t patchControlPoints); diff --git a/renderdoc/driver/vulkan/vk_core.h b/renderdoc/driver/vulkan/vk_core.h index 10b70b0a4..14d789c02 100644 --- a/renderdoc/driver/vulkan/vk_core.h +++ b/renderdoc/driver/vulkan/vk_core.h @@ -53,11 +53,15 @@ struct VkInitParams rdcarray Extensions; ResourceId InstanceID; + // indicates that the 'application' has pre-reserved our descriptors - for self-capture. Prevents + // us from getting into a loop of ever-increasing reservations and failing to allocate. + bool DescriptorsReserved = false; + // remember to update this function if you add more members uint64_t GetSerialiseSize(); // check if a frame capture section version is supported - static const uint64_t CurrentVersion = 0x16; + static const uint64_t CurrentVersion = 0x17; static bool IsSupportedVersion(uint64_t ver); }; diff --git a/renderdoc/driver/vulkan/wrappers/vk_device_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_device_funcs.cpp index 4809b6fb6..3a3cb1fb6 100644 --- a/renderdoc/driver/vulkan/wrappers/vk_device_funcs.cpp +++ b/renderdoc/driver/vulkan/wrappers/vk_device_funcs.cpp @@ -4409,6 +4409,19 @@ bool WrappedVulkan::Serialise_vkCreateDevice(SerialiserType &ser, VkPhysicalDevi } EstimateDescriptorFormats(); + + // indicate to any self-capture that we have reserved the descriptors + if(ObjDisp(m_Device)->SetDebugUtilsObjectTagEXT) + { + VkDebugUtilsObjectTagInfoEXT tagInfo = {VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_TAG_INFO_EXT}; + tagInfo.objectType = VK_OBJECT_TYPE_INSTANCE; + tagInfo.objectHandle = uint64_t(Unwrap(m_Instance)); + tagInfo.tagName = RENDERDOC_DescriptorsReservation_UUID; + tagInfo.tagSize = 0; + tagInfo.pTag = NULL; + + vkr = ObjDisp(m_Device)->SetDebugUtilsObjectTagEXT(Unwrap(m_Device), &tagInfo); + } } APIProps.vendor = GetDriverInfo().Vendor(); diff --git a/renderdoc/driver/vulkan/wrappers/vk_misc_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_misc_funcs.cpp index cffee70ae..de7410698 100644 --- a/renderdoc/driver/vulkan/wrappers/vk_misc_funcs.cpp +++ b/renderdoc/driver/vulkan/wrappers/vk_misc_funcs.cpp @@ -2642,6 +2642,11 @@ VkResult WrappedVulkan::vkSetDebugUtilsObjectTagEXT(VkDevice device, { m_CurrentVRBackbuffer = data.record->GetResourceID(); } + else if(pTagInfo->tagName == RENDERDOC_DescriptorsReservation_UUID && + pTagInfo->objectType == VK_OBJECT_TYPE_INSTANCE) + { + m_InitParams.DescriptorsReserved = true; + } else if(ObjDisp(device)->SetDebugUtilsObjectTagEXT) { VkDebugUtilsObjectTagInfoEXT unwrapped = *pTagInfo; diff --git a/renderdoc/driver/vulkan/wrappers/vk_resource_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_resource_funcs.cpp index ac236f16b..f12e32099 100644 --- a/renderdoc/driver/vulkan/wrappers/vk_resource_funcs.cpp +++ b/renderdoc/driver/vulkan/wrappers/vk_resource_funcs.cpp @@ -1893,11 +1893,14 @@ bool WrappedVulkan::Serialise_vkCreateBuffer(SerialiserType &ser, VkDevice devic VkBufferCreateInfo patched = CreateInfo; - // inflate all resource descriptor buffers by 2 descriptors, so that we have room for internal - // descriptors wherever they are bound - if(CreateInfo.usage & VK_BUFFER_USAGE_RESOURCE_DESCRIPTOR_BUFFER_BIT_EXT) + // inflate all resource descriptor buffers, so that we have room for internal + // descriptors wherever they are bound. We only do this once at the point of original capturing + // - one we have captured and are then self-capturing we re-use the same reservation space to + // ensure we don't keep trying to add more and more reservation + if(patchedusage & VK_BUFFER_USAGE_RESOURCE_DESCRIPTOR_BUFFER_BIT_EXT) { - patched.size += m_ResourceDescriptorBufferReserveSize; + if(!m_InitParams.DescriptorsReserved) + patched.size += m_ResourceDescriptorBufferReserveSize; } byte *tempMem = GetTempMemory(GetNextPatchSize(patched.pNext)); @@ -1987,11 +1990,14 @@ VkResult WrappedVulkan::vkCreateBuffer(VkDevice device, const VkBufferCreateInfo if(IsCaptureMode(m_State)) adjusted_info.flags |= DefaultBufferCreateFlags(); - // inflate all resource descriptor buffers by 2 descriptors, so that we have room for internal - // descriptors wherever they are bound - if(adjusted_info.usage & VK_BUFFER_USAGE_RESOURCE_DESCRIPTOR_BUFFER_BIT_EXT) + // inflate all resource descriptor buffers, so that we have room for internal + // descriptors wherever they are bound. We only do this once at the point of original capturing - + // one we have captured and are then self-capturing we re-use the same reservation space to ensure + // we don't keep trying to add more and more reservation + if(adjusted_usage & VK_BUFFER_USAGE_RESOURCE_DESCRIPTOR_BUFFER_BIT_EXT) { - adjusted_info.size += m_ResourceDescriptorBufferReserveSize; + if(!m_InitParams.DescriptorsReserved) + adjusted_info.size += m_ResourceDescriptorBufferReserveSize; } SetBufferUsageFlags(&adjusted_info, adjusted_usage);