From 95ef6bc4003ca9ec71c5ea293fbc14d4a829cc8a Mon Sep 17 00:00:00 2001 From: baldurk Date: Fri, 4 Jul 2025 17:17:51 +0100 Subject: [PATCH] Handle mutable descriptor types in descriptor buffers --- renderdoc/driver/vulkan/vk_info.cpp | 43 ++++++++++++++----- renderdoc/driver/vulkan/vk_info.h | 3 ++ renderdoc/driver/vulkan/vk_replay.cpp | 10 ++++- .../driver/vulkan/vk_shader_feedback.cpp | 4 +- 4 files changed, 47 insertions(+), 13 deletions(-) diff --git a/renderdoc/driver/vulkan/vk_info.cpp b/renderdoc/driver/vulkan/vk_info.cpp index d00622019..385558d52 100644 --- a/renderdoc/driver/vulkan/vk_info.cpp +++ b/renderdoc/driver/vulkan/vk_info.cpp @@ -832,10 +832,31 @@ bool CreateDescriptorWritesForSlotData(WrappedVulkan *vk, rdcarray &descriptorAccess, - rdcarray setLayoutInfos) +uint32_t GetDescriptorSizeOfBind(VulkanResourceManager *resourceMan, + const rdcarray &bindings, + const rdcarray &mutableBitmasks, uint32_t fixedBindNumber) +{ + if(bindings[fixedBindNumber].layoutDescType != VK_DESCRIPTOR_TYPE_MUTABLE_EXT) + return resourceMan->DescriptorDataSize(bindings[fixedBindNumber].layoutDescType); + + uint64_t bitmask = mutableBitmasks[fixedBindNumber]; + uint32_t ret = 0; + + for(uint64_t m = 0; m < (uint64_t)DescriptorSlotType::Count; m++) + { + if(bitmask & (1ULL << m)) + { + ret = RDCMAX(ret, resourceMan->DescriptorDataSize(convert(DescriptorSlotType(m)))); + } + } + + return ret; +} + +static void ProcessStaticDescriptorAccess(VulkanResourceManager *resourceMan, + ShaderReflection *refl, ResourceId specStorage, + rdcarray &descriptorAccess, + rdcarray setLayoutInfos) { if(!refl) return; @@ -912,7 +933,8 @@ void ProcessStaticDescriptorAccess(VulkanResourceManager *resourceMan, ShaderRef { access.descriptorStore = VulkanCreationInfo::descriptorBufferStorage[bind.fixedBindSetOrSpace]; - access.byteSize = resourceMan->DescriptorDataSize(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER); + access.byteSize = GetDescriptorSizeOfBind( + resourceMan, setLayout->bindings, setLayout->mutableBitmasks, bind.fixedBindNumber); } // we are only handling non-arrays here @@ -963,7 +985,8 @@ void ProcessStaticDescriptorAccess(VulkanResourceManager *resourceMan, ShaderRef VK_DESCRIPTOR_SET_LAYOUT_CREATE_DESCRIPTOR_BUFFER_BIT_EXT) { access.descriptorStore = VulkanCreationInfo::descriptorBufferStorage[bind.fixedBindSetOrSpace]; - access.byteSize = resourceMan->DescriptorDataSize(VK_DESCRIPTOR_TYPE_SAMPLER); + access.byteSize = GetDescriptorSizeOfBind(resourceMan, setLayout->bindings, + setLayout->mutableBitmasks, bind.fixedBindNumber); // we are only handling non-arrays here access.byteOffset = setLayout->bindings[bind.fixedBindNumber].elemOffset; @@ -1016,8 +1039,8 @@ void ProcessStaticDescriptorAccess(VulkanResourceManager *resourceMan, ShaderRef VK_DESCRIPTOR_SET_LAYOUT_CREATE_DESCRIPTOR_BUFFER_BIT_EXT) { access.descriptorStore = VulkanCreationInfo::descriptorBufferStorage[bind.fixedBindSetOrSpace]; - access.byteSize = resourceMan->DescriptorDataSize( - MakeVkDescriptorType(bind.descriptorType, bind.isInputAttachment)); + access.byteSize = GetDescriptorSizeOfBind(resourceMan, setLayout->bindings, + setLayout->mutableBitmasks, bind.fixedBindNumber); // we are only handling non-arrays here access.byteOffset = setLayout->bindings[bind.fixedBindNumber].elemOffset; @@ -1064,8 +1087,8 @@ void ProcessStaticDescriptorAccess(VulkanResourceManager *resourceMan, ShaderRef VK_DESCRIPTOR_SET_LAYOUT_CREATE_DESCRIPTOR_BUFFER_BIT_EXT) { access.descriptorStore = VulkanCreationInfo::descriptorBufferStorage[bind.fixedBindSetOrSpace]; - access.byteSize = - resourceMan->DescriptorDataSize(MakeVkDescriptorType(bind.descriptorType, false)); + access.byteSize = GetDescriptorSizeOfBind(resourceMan, setLayout->bindings, + setLayout->mutableBitmasks, bind.fixedBindNumber); // we are only handling non-arrays here access.byteOffset = setLayout->bindings[bind.fixedBindNumber].elemOffset; diff --git a/renderdoc/driver/vulkan/vk_info.h b/renderdoc/driver/vulkan/vk_info.h index b875b5da8..e2e83e136 100644 --- a/renderdoc/driver/vulkan/vk_info.h +++ b/renderdoc/driver/vulkan/vk_info.h @@ -142,6 +142,9 @@ struct DescSetLayout bool isCompatible(const DescSetLayout &other) const; }; +uint32_t GetDescriptorSizeOfBind(VulkanResourceManager *resourceMan, + const rdcarray &bindings, + const rdcarray &mutableBitmasks, uint32_t fixedBindNumber); bool IsValid(bool allowNULLDescriptors, const VkWriteDescriptorSet &write, uint32_t arrayElement); bool CreateDescriptorWritesForSlotData(WrappedVulkan *vk, rdcarray &writes, VkDescriptorBufferInfo *&writeScratch, diff --git a/renderdoc/driver/vulkan/vk_replay.cpp b/renderdoc/driver/vulkan/vk_replay.cpp index 2b217c7a6..1b919d48c 100644 --- a/renderdoc/driver/vulkan/vk_replay.cpp +++ b/renderdoc/driver/vulkan/vk_replay.cpp @@ -2627,7 +2627,10 @@ rdcarray VulkanReplay::GetDescriptors(ResourceId descriptorStore, } else { - m_pDriver->LookupDescriptor(descriptor, r.descriptorSize, r.type, tmp); + uint32_t size = m_pDriver->DescriptorDataSize(MakeVkDescriptorType(r.type, false)); + // should not be larger, only smaller with mutable descriptors + RDCASSERT(size <= r.descriptorSize); + m_pDriver->LookupDescriptor(descriptor, size, r.type, tmp); FillDescriptor(ret[dst], tmp); } @@ -2763,7 +2766,10 @@ rdcarray VulkanReplay::GetSamplerDescriptors(ResourceId descr } else { - m_pDriver->LookupDescriptor(descriptor, r.descriptorSize, r.type, tmp); + uint32_t size = m_pDriver->DescriptorDataSize(MakeVkDescriptorType(r.type, false)); + // should not be larger, only smaller with mutable descriptors + RDCASSERT(size <= r.descriptorSize); + m_pDriver->LookupDescriptor(descriptor, size, r.type, tmp); FillSamplerDescriptor(ret[dst], tmp); } diff --git a/renderdoc/driver/vulkan/vk_shader_feedback.cpp b/renderdoc/driver/vulkan/vk_shader_feedback.cpp index ad034d546..80ca5014f 100644 --- a/renderdoc/driver/vulkan/vk_shader_feedback.cpp +++ b/renderdoc/driver/vulkan/vk_shader_feedback.cpp @@ -1611,7 +1611,9 @@ bool VulkanReplay::FetchShaderFeedback(uint32_t eventId) access.descriptorStore = m_pDriver->GetResourceManager()->GetOriginalID(id); access.byteOffset += uint32_t(offs + descSets[bindset].descBufferOffset) + descLayouts[bindset]->bindings[bind].elemOffset; - access.byteSize = m_pDriver->DescriptorDataSize(MakeVkDescriptorType(type, inputAttachment)); + access.byteSize = + GetDescriptorSizeOfBind(m_pDriver->GetResourceManager(), descLayouts[bindset]->bindings, + descLayouts[bindset]->mutableBitmasks, bind); if(descLayouts[bindset]->bindings[bind].variableSize || arraySize == ~0U) {