From 5b5e4f9bbb438aeb2a89e9b4e75c1047117dd6bd Mon Sep 17 00:00:00 2001 From: baldurk Date: Mon, 9 Jun 2025 13:28:53 +0100 Subject: [PATCH] Insert serialisation of opaque capture data for resources as needed --- renderdoc/driver/vulkan/vk_common.cpp | 107 ++++++++++++++++++ renderdoc/driver/vulkan/vk_common.h | 26 +++++ .../driver/vulkan/wrappers/vk_misc_funcs.cpp | 12 +- .../vulkan/wrappers/vk_resource_funcs.cpp | 40 ++++++- 4 files changed, 182 insertions(+), 3 deletions(-) diff --git a/renderdoc/driver/vulkan/vk_common.cpp b/renderdoc/driver/vulkan/vk_common.cpp index 8261cd824..cf5765e12 100644 --- a/renderdoc/driver/vulkan/vk_common.cpp +++ b/renderdoc/driver/vulkan/vk_common.cpp @@ -1016,6 +1016,113 @@ void DoSerialise(SerialiserType &ser, VkInitParams &el) INSTANTIATE_SERIALISE_TYPE(VkInitParams); +void OpaqueDataForSerialising::fill(VkDevice wrappedDevice, VkSampler wrappedSampler, + VkPhysicalDeviceDescriptorBufferPropertiesEXT &props) +{ + VkSamplerCaptureDescriptorDataInfoEXT getInfo = { + VK_STRUCTURE_TYPE_SAMPLER_CAPTURE_DESCRIPTOR_DATA_INFO_EXT, + NULL, + Unwrap(wrappedSampler), + }; + + sz = props.samplerCaptureReplayDescriptorDataSize; + + VkResult opaqueQuery = + ObjDisp(wrappedDevice) + ->GetSamplerOpaqueCaptureDescriptorDataEXT(Unwrap(wrappedDevice), &getInfo, data); + if(opaqueQuery != VK_SUCCESS) + RDCERR("Couldn't get opaque capture/replay data: %s", ToStr(opaqueQuery).c_str()); +} + +void OpaqueDataForSerialising::fill(VkDevice wrappedDevice, VkBuffer wrappedBuffer, + VkPhysicalDeviceDescriptorBufferPropertiesEXT &props) +{ + VkBufferCaptureDescriptorDataInfoEXT getInfo = { + VK_STRUCTURE_TYPE_BUFFER_CAPTURE_DESCRIPTOR_DATA_INFO_EXT, + NULL, + Unwrap(wrappedBuffer), + }; + + sz = props.bufferCaptureReplayDescriptorDataSize; + + VkResult opaqueQuery = + ObjDisp(wrappedDevice) + ->GetBufferOpaqueCaptureDescriptorDataEXT(Unwrap(wrappedDevice), &getInfo, data); + if(opaqueQuery != VK_SUCCESS) + RDCERR("Couldn't get opaque capture/replay data: %s", ToStr(opaqueQuery).c_str()); +} + +void OpaqueDataForSerialising::fill(VkDevice wrappedDevice, VkImage wrappedImage, + VkPhysicalDeviceDescriptorBufferPropertiesEXT &props) +{ + VkImageCaptureDescriptorDataInfoEXT getInfo = { + VK_STRUCTURE_TYPE_IMAGE_CAPTURE_DESCRIPTOR_DATA_INFO_EXT, + NULL, + Unwrap(wrappedImage), + }; + + sz = props.imageCaptureReplayDescriptorDataSize; + + VkResult opaqueQuery = + ObjDisp(wrappedDevice) + ->GetImageOpaqueCaptureDescriptorDataEXT(Unwrap(wrappedDevice), &getInfo, data); + if(opaqueQuery != VK_SUCCESS) + RDCERR("Couldn't get opaque capture/replay data: %s", ToStr(opaqueQuery).c_str()); +} + +void OpaqueDataForSerialising::fill(VkDevice wrappedDevice, VkImageView wrappedView, + VkPhysicalDeviceDescriptorBufferPropertiesEXT &props) +{ + VkImageViewCaptureDescriptorDataInfoEXT getInfo = { + VK_STRUCTURE_TYPE_IMAGE_VIEW_CAPTURE_DESCRIPTOR_DATA_INFO_EXT, + NULL, + Unwrap(wrappedView), + }; + + sz = props.imageViewCaptureReplayDescriptorDataSize; + + VkResult opaqueQuery = + ObjDisp(wrappedDevice) + ->GetImageViewOpaqueCaptureDescriptorDataEXT(Unwrap(wrappedDevice), &getInfo, data); + if(opaqueQuery != VK_SUCCESS) + RDCERR("Couldn't get opaque capture/replay data: %s", ToStr(opaqueQuery).c_str()); +} + +void OpaqueDataForSerialising::fill(VkDevice wrappedDevice, VkAccelerationStructureKHR wrappedAS, + VkPhysicalDeviceDescriptorBufferPropertiesEXT &props) +{ + VkAccelerationStructureCaptureDescriptorDataInfoEXT getInfo = { + VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CAPTURE_DESCRIPTOR_DATA_INFO_EXT, + NULL, + Unwrap(wrappedAS), + }; + + sz = props.accelerationStructureCaptureReplayDescriptorDataSize; + + VkResult opaqueQuery = ObjDisp(wrappedDevice) + ->GetAccelerationStructureOpaqueCaptureDescriptorDataEXT( + Unwrap(wrappedDevice), &getInfo, data); + if(opaqueQuery != VK_SUCCESS) + RDCERR("Couldn't get opaque capture/replay data: %s", ToStr(opaqueQuery).c_str()); +} + +void OpaqueDataForSerialising::addForSerialising(VkBaseInStructure *serialisedCreateInfo) +{ + VkOpaqueCaptureDescriptorDataCreateInfoEXT *existing = + (VkOpaqueCaptureDescriptorDataCreateInfoEXT *)FindNextStruct( + serialisedCreateInfo, VK_STRUCTURE_TYPE_OPAQUE_CAPTURE_DESCRIPTOR_DATA_CREATE_INFO_EXT); + + if(existing) + { + RDCASSERT(memcmp(data, existing->opaqueCaptureDescriptorData, sz) == 0); + } + else + { + pNext = serialisedCreateInfo->pNext; + serialisedCreateInfo->pNext = (VkBaseInStructure *)this; + } +} + void GetPhysicalDeviceDriverProperties(VkInstDispatchTable *instDispatchTable, VkPhysicalDevice unwrappedPhysicalDevice, VkPhysicalDeviceDriverProperties &driverProps) diff --git a/renderdoc/driver/vulkan/vk_common.h b/renderdoc/driver/vulkan/vk_common.h index a903cc0d1..9b5e5e7ec 100644 --- a/renderdoc/driver/vulkan/vk_common.h +++ b/renderdoc/driver/vulkan/vk_common.h @@ -912,6 +912,32 @@ DECLARE_REFLECTION_STRUCT(DescriptorSetSlot); constexpr uint64_t FixedOpaqueDescriptorCaptureSize = 16; constexpr uint64_t MaxDescriptorSize = 256; +struct OpaqueDataForSerialising : VkOpaqueCaptureDescriptorDataCreateInfoEXT +{ + OpaqueDataForSerialising() + { + sType = VK_STRUCTURE_TYPE_OPAQUE_CAPTURE_DESCRIPTOR_DATA_CREATE_INFO_EXT; + pNext = NULL; + opaqueCaptureDescriptorData = data; + } + + void fill(VkDevice wrappedDevice, VkSampler wrappedSampler, + VkPhysicalDeviceDescriptorBufferPropertiesEXT &props); + void fill(VkDevice wrappedDevice, VkBuffer wrappedBuffer, + VkPhysicalDeviceDescriptorBufferPropertiesEXT &props); + void fill(VkDevice wrappedDevice, VkImage wrappedImage, + VkPhysicalDeviceDescriptorBufferPropertiesEXT &props); + void fill(VkDevice wrappedDevice, VkImageView wrappedView, + VkPhysicalDeviceDescriptorBufferPropertiesEXT &props); + void fill(VkDevice wrappedDevice, VkAccelerationStructureKHR wrappedAS, + VkPhysicalDeviceDescriptorBufferPropertiesEXT &props); + + void addForSerialising(VkBaseInStructure *serialisedCreateInfo); + + byte data[FixedOpaqueDescriptorCaptureSize] = {}; + size_t sz = 0; +}; + // pointers are considered to be 48-bit only, as some descriptors only store those and no-one // uses the upper bits relevantly // diff --git a/renderdoc/driver/vulkan/wrappers/vk_misc_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_misc_funcs.cpp index dc09264c7..3dd7d4f58 100644 --- a/renderdoc/driver/vulkan/wrappers/vk_misc_funcs.cpp +++ b/renderdoc/driver/vulkan/wrappers/vk_misc_funcs.cpp @@ -734,11 +734,21 @@ VkResult WrappedVulkan::vkCreateSampler(VkDevice device, const VkSamplerCreateIn { Chunk *chunk = NULL; + VkSamplerCreateInfo serialisedCreateInfo = *pCreateInfo; + + OpaqueDataForSerialising opaqueData; + + if(DescriptorBuffers()) + { + opaqueData.fill(device, *pSampler, m_DescriptorBufferProperties); + opaqueData.addForSerialising((VkBaseInStructure *)&serialisedCreateInfo); + } + { CACHE_THREAD_SERIALISER(); SCOPED_SERIALISE_CHUNK(VulkanChunk::vkCreateSampler); - Serialise_vkCreateSampler(ser, device, pCreateInfo, NULL, pSampler); + Serialise_vkCreateSampler(ser, device, &serialisedCreateInfo, NULL, pSampler); chunk = scope.Get(); } diff --git a/renderdoc/driver/vulkan/wrappers/vk_resource_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_resource_funcs.cpp index dc10b2e6e..e0cd82a63 100644 --- a/renderdoc/driver/vulkan/wrappers/vk_resource_funcs.cpp +++ b/renderdoc/driver/vulkan/wrappers/vk_resource_funcs.cpp @@ -1996,6 +1996,8 @@ VkResult WrappedVulkan::vkCreateBuffer(VkDevice device, const VkBufferCreateInfo serialisedUsage |= VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT; SetBufferUsageFlags(&serialisedCreateInfo, serialisedUsage); + OpaqueDataForSerialising opaqueData; + // if we're using VK_[KHR|EXT]_buffer_device_address, we fetch the device address that's been // allocated and insert it into the next chain and patch the flags so that it replays // naturally. @@ -2061,6 +2063,12 @@ VkResult WrappedVulkan::vkCreateBuffer(VkDevice device, const VkBufferCreateInfo SCOPED_LOCK(m_DeviceAddressResourcesLock); m_DeviceAddressResources.IDs.push_back(record->GetResourceID()); } + + if(DescriptorBuffers()) + { + opaqueData.fill(device, *pBuffer, m_DescriptorBufferProperties); + opaqueData.addForSerialising((VkBaseInStructure *)&serialisedCreateInfo); + } } { @@ -2698,11 +2706,21 @@ VkResult WrappedVulkan::vkCreateImage(VkDevice device, const VkImageCreateInfo * { Chunk *chunk = NULL; + VkImageCreateInfo serialisedCreateInfo = *pCreateInfo; + + OpaqueDataForSerialising opaqueData; + + if(DescriptorBuffers()) + { + opaqueData.fill(device, *pImage, m_DescriptorBufferProperties); + opaqueData.addForSerialising((VkBaseInStructure *)&serialisedCreateInfo); + } + { CACHE_THREAD_SERIALISER(); SCOPED_SERIALISE_CHUNK(VulkanChunk::vkCreateImage); - Serialise_vkCreateImage(ser, device, pCreateInfo, NULL, pImage); + Serialise_vkCreateImage(ser, device, &serialisedCreateInfo, NULL, pImage); chunk = scope.Get(); } @@ -3104,11 +3122,21 @@ VkResult WrappedVulkan::vkCreateImageView(VkDevice device, const VkImageViewCrea { Chunk *chunk = NULL; + VkImageViewCreateInfo serialisedCreateInfo = *pCreateInfo; + + OpaqueDataForSerialising opaqueData; + + if(DescriptorBuffers()) + { + opaqueData.fill(device, *pView, m_DescriptorBufferProperties); + opaqueData.addForSerialising((VkBaseInStructure *)&serialisedCreateInfo); + } + { CACHE_THREAD_SERIALISER(); SCOPED_SERIALISE_CHUNK(VulkanChunk::vkCreateImageView); - Serialise_vkCreateImageView(ser, device, pCreateInfo, NULL, pView); + Serialise_vkCreateImageView(ser, device, &serialisedCreateInfo, NULL, pView); chunk = scope.Get(); } @@ -3718,6 +3746,14 @@ VkResult WrappedVulkan::vkCreateAccelerationStructureKHR( ObjDisp(device)->GetAccelerationStructureDeviceAddressKHR(Unwrap(device), &getInfo); serialisedCreateInfo.deviceAddress = addr; + OpaqueDataForSerialising opaqueData; + + if(DescriptorBuffers()) + { + opaqueData.fill(device, *pAccelerationStructure, m_DescriptorBufferProperties); + opaqueData.addForSerialising((VkBaseInStructure *)&serialisedCreateInfo); + } + Chunk *chunk = NULL; {