From b9787606ea3846061edd3ef0cec9ac7356bd3297 Mon Sep 17 00:00:00 2001 From: baldurk Date: Mon, 11 Mar 2024 18:04:32 +0000 Subject: [PATCH] Add reported descriptor access from vulkan and D3D12 bindless feedback --- renderdoc/api/replay/renderdoc_tostr.inl | 14 ++ renderdoc/api/replay/replay_enums.h | 87 +++++++++++-- renderdoc/core/image_viewer.cpp | 2 +- renderdoc/core/replay_proxy.cpp | 12 +- renderdoc/core/replay_proxy.h | 2 +- renderdoc/driver/d3d11/d3d11_replay.cpp | 2 +- renderdoc/driver/d3d11/d3d11_replay.h | 2 +- renderdoc/driver/d3d12/d3d12_replay.cpp | 159 ++++++++++++++++++++++- renderdoc/driver/d3d12/d3d12_replay.h | 2 +- renderdoc/driver/gl/gl_replay.cpp | 2 +- renderdoc/driver/gl/gl_replay.h | 2 +- renderdoc/driver/vulkan/vk_info.cpp | 1 + renderdoc/driver/vulkan/vk_replay.cpp | 117 ++++++++++++++++- renderdoc/driver/vulkan/vk_replay.h | 2 +- renderdoc/replay/dummy_driver.cpp | 2 +- renderdoc/replay/dummy_driver.h | 2 +- renderdoc/replay/replay_controller.cpp | 2 +- renderdoc/replay/replay_driver.h | 2 +- 18 files changed, 387 insertions(+), 27 deletions(-) diff --git a/renderdoc/api/replay/renderdoc_tostr.inl b/renderdoc/api/replay/renderdoc_tostr.inl index 8cd4824c4..cbe774505 100644 --- a/renderdoc/api/replay/renderdoc_tostr.inl +++ b/renderdoc/api/replay/renderdoc_tostr.inl @@ -738,6 +738,20 @@ rdcstr DoStringise(const DescriptorType &el) END_ENUM_STRINGISE(); } +template <> +rdcstr DoStringise(const DescriptorCategory &el) +{ + BEGIN_ENUM_STRINGISE(DescriptorCategory) + { + STRINGISE_ENUM_CLASS_NAMED(Unknown, "Unknown"); + STRINGISE_ENUM_CLASS_NAMED(ConstantBlock, "Constant Block"); + STRINGISE_ENUM_CLASS_NAMED(Sampler, "Sampler"); + STRINGISE_ENUM_CLASS_NAMED(ReadOnlyResource, "Read-only Resource"); + STRINGISE_ENUM_CLASS_NAMED(ReadWriteResource, "Read-write Resource"); + } + END_ENUM_STRINGISE(); +} + template <> rdcstr DoStringise(const MessageSource &el) { diff --git a/renderdoc/api/replay/replay_enums.h b/renderdoc/api/replay/replay_enums.h index 3a9754ff7..94c151610 100644 --- a/renderdoc/api/replay/replay_enums.h +++ b/renderdoc/api/replay/replay_enums.h @@ -907,36 +907,107 @@ enum class DescriptorType : uint8_t DECLARE_REFLECTION_ENUM(DescriptorType); -DOCUMENT("Checks if a descriptor type corresponds to a constant buffer in shader reflection."); -constexpr bool IsConstantBufferDescriptor(DescriptorType type) +DOCUMENT(R"(The category of a descriptor, corresponding to the interfaces in :class:`ShaderReflection`. + +.. data:: Unknown + + An unknown or uninitialised type of descriptor. + +.. data:: ConstantBlock + + A constant block. + +.. data:: Sampler + + A sampler object. + +.. data:: ReadOnlyResource + + A read-only resource. + +.. data:: ReadWriteResource + + A read-write resource. +)"); +enum class DescriptorCategory : uint8_t { - return type == DescriptorType::ConstantBuffer; + Unknown = 0, + ConstantBlock, + Sampler, + ReadOnlyResource, + ReadWriteResource, +}; + +DECLARE_REFLECTION_ENUM(DescriptorCategory); + +DOCUMENT(R"(Get the shader interface category for a given type of descriptor. + +:param DescriptorType type: The type of descriptor +:return: The descriptor category. +:rtype: DescriptorCategory +)"); +constexpr DescriptorCategory CategoryForDescriptorType(DescriptorType type) +{ + return type == DescriptorType::ConstantBuffer ? DescriptorCategory::ConstantBlock + + : type == DescriptorType::Sampler ? DescriptorCategory::Sampler + + : (type == DescriptorType::ImageSampler || type == DescriptorType::Image || + type == DescriptorType::TypedBuffer || type == DescriptorType::Buffer) + ? DescriptorCategory::ReadOnlyResource + + : (type == DescriptorType::ReadWriteBuffer || type == DescriptorType::ReadWriteImage || + type == DescriptorType::ReadWriteTypedBuffer) + ? DescriptorCategory::ReadWriteResource + + : DescriptorCategory::Unknown; +} + +DOCUMENT(R"(Checks if a descriptor type corresponds to a constant block in shader reflection. + +:param DescriptorType type: The type of descriptor +:return: ``True`` if the descriptor type is a constant block descriptor. +:rtype: bool +)"); +constexpr bool IsConstantBlockDescriptor(DescriptorType type) +{ + return CategoryForDescriptorType(type) == DescriptorCategory::ConstantBlock; } DOCUMENT(R"(Checks if a descriptor type corresponds to a sampler in shader reflection. Only dedicated sampler types are sampler descriptors, combined image/samplers are reported only as read only resources. + +:param DescriptorType type: The type of descriptor +:return: ``True`` if the descriptor type is a sampler descriptor. +:rtype: bool )"); constexpr bool IsSamplerDescriptor(DescriptorType type) { - return type == DescriptorType::Sampler; + return CategoryForDescriptorType(type) == DescriptorCategory::Sampler; } DOCUMENT(R"(Checks if a descriptor type corresponds to a read only resource in shader reflection. Combined image/samplers are reported as read only resources. + +:param DescriptorType type: The type of descriptor +:return: ``True`` if the descriptor type is a read-only resource descriptor. +:rtype: bool )"); constexpr bool IsReadOnlyDescriptor(DescriptorType type) { - return type == DescriptorType::ImageSampler || type == DescriptorType::Image || - type == DescriptorType::TypedBuffer; + return CategoryForDescriptorType(type) == DescriptorCategory::ReadOnlyResource; } DOCUMENT(R"(Checks if a descriptor type corresponds to a read write resource in shader reflection. + +:param DescriptorType type: The type of descriptor +:return: ``True`` if the descriptor type is a read-write resource descriptor. +:rtype: bool )"); constexpr bool IsReadWriteDescriptor(DescriptorType type) { - return type == DescriptorType::ReadWriteBuffer || type == DescriptorType::ReadWriteImage || - type == DescriptorType::ReadWriteTypedBuffer; + return CategoryForDescriptorType(type) == DescriptorCategory::ReadWriteResource; } DOCUMENT3(R"(Annotates a particular built-in input or output from a shader with a special meaning to diff --git a/renderdoc/core/image_viewer.cpp b/renderdoc/core/image_viewer.cpp index 6add0d974..825f65cae 100644 --- a/renderdoc/core/image_viewer.cpp +++ b/renderdoc/core/image_viewer.cpp @@ -279,7 +279,7 @@ public: ret.resize(count); return ret; } - rdcarray GetDescriptorAccess() { return {}; } + rdcarray GetDescriptorAccess(uint32_t eventId) { return {}; } DriverInformation GetDriverInfo() { DriverInformation ret = {}; diff --git a/renderdoc/core/replay_proxy.cpp b/renderdoc/core/replay_proxy.cpp index 82a12bb11..ac345a214 100644 --- a/renderdoc/core/replay_proxy.cpp +++ b/renderdoc/core/replay_proxy.cpp @@ -1909,7 +1909,8 @@ rdcarray ReplayProxy::GetSamplerDescriptors(ResourceId descri template rdcarray ReplayProxy::Proxied_GetDescriptorAccess(ParamSerialiser ¶mser, - ReturnSerialiser &retser) + ReturnSerialiser &retser, + uint32_t eventId) { const ReplayProxyPacket expectedPacket = eReplayProxy_GetDescriptorAccess; ReplayProxyPacket packet = eReplayProxy_GetDescriptorAccess; @@ -1917,13 +1918,14 @@ rdcarray ReplayProxy::Proxied_GetDescriptorAccess(ParamSeriali { BEGIN_PARAMS(); + SERIALISE_ELEMENT(eventId); END_PARAMS(); } { REMOTE_EXECUTION(); if(paramser.IsReading() && !paramser.IsErrored() && !m_IsErrored) - ret = m_Remote->GetDescriptorAccess(); + ret = m_Remote->GetDescriptorAccess(eventId); } SERIALISE_RETURN(ret); @@ -1931,9 +1933,9 @@ rdcarray ReplayProxy::Proxied_GetDescriptorAccess(ParamSeriali return ret; } -rdcarray ReplayProxy::GetDescriptorAccess() +rdcarray ReplayProxy::GetDescriptorAccess(uint32_t eventId) { - PROXY_FUNCTION(GetDescriptorAccess); + PROXY_FUNCTION(GetDescriptorAccess, eventId); } template @@ -3008,7 +3010,7 @@ bool ReplayProxy::Tick(int type) case eReplayProxy_SavePipelineState: SavePipelineState(0); break; case eReplayProxy_GetDescriptors: GetDescriptors(ResourceId(), {}); break; case eReplayProxy_GetSamplerDescriptors: GetSamplerDescriptors(ResourceId(), {}); break; - case eReplayProxy_GetDescriptorAccess: GetDescriptorAccess(); break; + case eReplayProxy_GetDescriptorAccess: GetDescriptorAccess(0); break; case eReplayProxy_GetUsage: GetUsage(ResourceId()); break; case eReplayProxy_GetLiveID: GetLiveID(ResourceId()); break; case eReplayProxy_GetFrameRecord: GetFrameRecord(); break; diff --git a/renderdoc/core/replay_proxy.h b/renderdoc/core/replay_proxy.h index fa1a2e524..5f92e1a9e 100644 --- a/renderdoc/core/replay_proxy.h +++ b/renderdoc/core/replay_proxy.h @@ -486,7 +486,7 @@ public: const rdcarray &ranges); IMPLEMENT_FUNCTION_PROXIED(rdcarray, GetSamplerDescriptors, ResourceId descriptorStore, const rdcarray &ranges); - IMPLEMENT_FUNCTION_PROXIED(rdcarray, GetDescriptorAccess); + IMPLEMENT_FUNCTION_PROXIED(rdcarray, GetDescriptorAccess, uint32_t eventId); IMPLEMENT_FUNCTION_PROXIED(rdcarray, GetPassEvents, uint32_t eventId); diff --git a/renderdoc/driver/d3d11/d3d11_replay.cpp b/renderdoc/driver/d3d11/d3d11_replay.cpp index e95afaf62..80079b96e 100644 --- a/renderdoc/driver/d3d11/d3d11_replay.cpp +++ b/renderdoc/driver/d3d11/d3d11_replay.cpp @@ -1982,7 +1982,7 @@ rdcarray D3D11Replay::GetSamplerDescriptors(ResourceId descri return ret; } -rdcarray D3D11Replay::GetDescriptorAccess() +rdcarray D3D11Replay::GetDescriptorAccess(uint32_t eventId) { D3D11RenderState *rs = m_pDevice->GetImmediateContext()->GetCurrentPipelineState(); diff --git a/renderdoc/driver/d3d11/d3d11_replay.h b/renderdoc/driver/d3d11/d3d11_replay.h index 00c67ebed..e9a9fe97f 100644 --- a/renderdoc/driver/d3d11/d3d11_replay.h +++ b/renderdoc/driver/d3d11/d3d11_replay.h @@ -186,7 +186,7 @@ public: const rdcarray &ranges); rdcarray GetSamplerDescriptors(ResourceId descriptorStore, const rdcarray &ranges); - rdcarray GetDescriptorAccess(); + rdcarray GetDescriptorAccess(uint32_t eventId); void FreeTargetResource(ResourceId id); void FreeCustomShader(ResourceId id); diff --git a/renderdoc/driver/d3d12/d3d12_replay.cpp b/renderdoc/driver/d3d12/d3d12_replay.cpp index 06c556774..4bbb28a89 100644 --- a/renderdoc/driver/d3d12/d3d12_replay.cpp +++ b/renderdoc/driver/d3d12/d3d12_replay.cpp @@ -2575,7 +2575,7 @@ rdcarray D3D12Replay::GetSamplerDescriptors(ResourceId descri return ret; } -rdcarray D3D12Replay::GetDescriptorAccess() +rdcarray D3D12Replay::GetDescriptorAccess(uint32_t eventId) { const D3D12RenderState &rs = m_pDevice->GetQueue()->GetCommandData()->m_RenderState; @@ -2648,6 +2648,163 @@ rdcarray D3D12Replay::GetDescriptorAccess() access.byteOffset += (uint32_t)rootEl.offset; } } + + const D3D12DynamicShaderFeedback &usage = m_BindlessFeedback.Usage[eventId]; + + // decode dynamic usage by reverse looking up shader bindpoint mappings. This is a temporary + // measure, once the old style bindings reporting are removed we can refactor the shader + // feedback to provide our data more directly in the format we want + if(usage.valid) + { + const D3D12RenderState::RootSignature &rootSigBind = + pipe->IsGraphics() ? rs.graphics : rs.compute; + WrappedID3D12RootSignature *rootSig = + rm->GetCurrentAs(rootSigBind.rootsig); + + for(const D3D12FeedbackBindIdentifier &bind : usage.used) + { + DescriptorAccess access; + + if(bind.directAccess) + { + access.index = DescriptorAccess::NoShaderBinding; + access.arrayElement = bind.descIndex; + + switch(bind.bindType) + { + case BindType::Unknown: + case BindType::ImageSampler: + case BindType::InputAttachment: + default: + RDCERR("Unexpected current descriptor type referenced"); + access.type = DescriptorType::Unknown; + break; + case BindType::ConstantBuffer: access.type = DescriptorType::ConstantBuffer; break; + case BindType::Sampler: access.type = DescriptorType::Sampler; break; + case BindType::ReadOnlyImage: access.type = DescriptorType::Image; break; + case BindType::ReadWriteImage: access.type = DescriptorType::ReadWriteImage; break; + case BindType::ReadOnlyTBuffer: access.type = DescriptorType::TypedBuffer; break; + case BindType::ReadWriteTBuffer: + access.type = DescriptorType::ReadWriteTypedBuffer; + break; + case BindType::ReadOnlyBuffer: access.type = DescriptorType::Buffer; + case BindType::ReadWriteBuffer: access.type = DescriptorType::ReadWriteBuffer; break; + case BindType::ReadOnlyResource: access.type = DescriptorType::Image; break; + case BindType::ReadWriteResource: access.type = DescriptorType::ReadWriteImage; break; + } + + // don't have stage-access information here yet + access.stage = pipe->IsGraphics() ? ShaderStage::Pixel : ShaderStage::Compute; + + access.byteOffset = bind.descIndex; + } + else + { + if(bind.rootEl >= rootSig->sig.Parameters.size() || + bind.rangeIndex >= rootSig->sig.Parameters[bind.rootEl].ranges.size()) + { + RDCERR("Out-of-bounds root element referenced in dynamic usage"); + continue; + } + + const D3D12_DESCRIPTOR_RANGE1 &range = + rootSig->sig.Parameters[bind.rootEl].ranges[bind.rangeIndex]; + UINT space = range.RegisterSpace; + UINT reg = range.BaseShaderRegister + bind.descIndex; + + uint32_t prevRangeOffset = 0; + for(uint32_t prevRange = 0; prevRange < bind.rangeIndex; prevRange) + { + uint32_t rangeOffset = + rootSig->sig.Parameters[bind.rootEl].ranges[prevRange].OffsetInDescriptorsFromTableStart; + if(rangeOffset == D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND) + rangeOffset = prevRangeOffset; + prevRangeOffset += rootSig->sig.Parameters[bind.rootEl].ranges[prevRange].NumDescriptors; + } + + bool found = false; + // this could have come from any stage, so we just find the first match + for(WrappedID3D12PipelineState::ShaderEntry *stage : + {pipe->VS(), pipe->HS(), pipe->DS(), pipe->GS(), pipe->PS(), pipe->CS(), pipe->AS(), + pipe->MS()}) + { + if(!stage) + continue; + + const rdcarray *iface = NULL; + switch(range.RangeType) + { + default: + case D3D12_DESCRIPTOR_RANGE_TYPE_SRV: + iface = &stage->GetMapping().readOnlyResources; + access.type = DescriptorType::Image; // hack + break; + case D3D12_DESCRIPTOR_RANGE_TYPE_UAV: + iface = &stage->GetMapping().readWriteResources; + access.type = DescriptorType::ReadWriteBuffer; // hack + break; + case D3D12_DESCRIPTOR_RANGE_TYPE_CBV: + iface = &stage->GetMapping().constantBlocks; + access.type = DescriptorType::ConstantBuffer; + break; + case D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER: + iface = &stage->GetMapping().samplers; + access.type = DescriptorType::Sampler; + break; + } + + if(iface) + { + access.index = 0; + for(const Bindpoint &searchBind : (*iface)) + { + if((uint32_t)searchBind.bindset == space && (uint32_t)searchBind.bind <= reg && + reg < uint32_t(searchBind.bind + searchBind.arraySize)) + { + access.stage = stage->GetDetails().stage; + access.arrayElement = reg - searchBind.bind; + access.byteOffset = range.OffsetInDescriptorsFromTableStart; + if(range.OffsetInDescriptorsFromTableStart == D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND) + access.byteOffset = prevRangeOffset; + access.byteOffset += searchBind.bind - range.BaseShaderRegister; + access.byteOffset += access.arrayElement; + found = true; + break; + } + access.index++; + } + + if(found) + break; + } + } + } + + if(access.type == DescriptorType::Sampler) + access.descriptorStore = + samplerHeap ? rm->GetOriginalID(samplerHeap->GetResourceID()) : ResourceId(); + else + access.descriptorStore = + resourceHeap ? rm->GetOriginalID(resourceHeap->GetResourceID()) : ResourceId(); + access.byteSize = 1; + + // don't add any duplicates if there's already static descriptor access listed for this + // register - currently we report duplicates of static accesses in the dynamic feedback + bool found = false; + for(const DescriptorAccess &a : ret) + { + if(access.stage == a.stage && + CategoryForDescriptorType(access.type) == CategoryForDescriptorType(a.type) && + access.index == a.index && access.arrayElement == a.arrayElement) + { + found = true; + break; + } + } + if(!found) + ret.push_back(access); + } + } } return ret; diff --git a/renderdoc/driver/d3d12/d3d12_replay.h b/renderdoc/driver/d3d12/d3d12_replay.h index 1b4ebec2f..f7435d8e1 100644 --- a/renderdoc/driver/d3d12/d3d12_replay.h +++ b/renderdoc/driver/d3d12/d3d12_replay.h @@ -142,7 +142,7 @@ public: const rdcarray &ranges); rdcarray GetSamplerDescriptors(ResourceId descriptorStore, const rdcarray &ranges); - rdcarray GetDescriptorAccess(); + rdcarray GetDescriptorAccess(uint32_t eventId); void FreeTargetResource(ResourceId id); void FreeCustomShader(ResourceId id); diff --git a/renderdoc/driver/gl/gl_replay.cpp b/renderdoc/driver/gl/gl_replay.cpp index f628db339..13df14432 100644 --- a/renderdoc/driver/gl/gl_replay.cpp +++ b/renderdoc/driver/gl/gl_replay.cpp @@ -2860,7 +2860,7 @@ rdcarray GLReplay::GetSamplerDescriptors(ResourceId descripto return ret; } -rdcarray GLReplay::GetDescriptorAccess() +rdcarray GLReplay::GetDescriptorAccess(uint32_t eventId) { return m_Access; } diff --git a/renderdoc/driver/gl/gl_replay.h b/renderdoc/driver/gl/gl_replay.h index 0579a9717..52c7173ac 100644 --- a/renderdoc/driver/gl/gl_replay.h +++ b/renderdoc/driver/gl/gl_replay.h @@ -164,7 +164,7 @@ public: const rdcarray &ranges); rdcarray GetSamplerDescriptors(ResourceId descriptorStore, const rdcarray &ranges); - rdcarray GetDescriptorAccess(); + rdcarray GetDescriptorAccess(uint32_t eventId); void FreeTargetResource(ResourceId id); RDResult ReadLogInitialisation(RDCFile *rdc, bool storeStructuredBuffers); diff --git a/renderdoc/driver/vulkan/vk_info.cpp b/renderdoc/driver/vulkan/vk_info.cpp index c61ead8da..293f8917a 100644 --- a/renderdoc/driver/vulkan/vk_info.cpp +++ b/renderdoc/driver/vulkan/vk_info.cpp @@ -1634,6 +1634,7 @@ void VulkanCreationInfo::Pipeline::Init(VulkanResourceManager *resourceMan, Vulk shad.module = shadid; shad.entryPoint = pCreateInfo->stage.pName; + shad.stage = ShaderStage::Compute; ShaderModuleReflectionKey key(ShaderStage::Compute, shad.entryPoint, ResourceId()); diff --git a/renderdoc/driver/vulkan/vk_replay.cpp b/renderdoc/driver/vulkan/vk_replay.cpp index d37be6d40..269372f10 100644 --- a/renderdoc/driver/vulkan/vk_replay.cpp +++ b/renderdoc/driver/vulkan/vk_replay.cpp @@ -2840,7 +2840,7 @@ rdcarray VulkanReplay::GetSamplerDescriptors(ResourceId descr return ret; } -rdcarray VulkanReplay::GetDescriptorAccess() +rdcarray VulkanReplay::GetDescriptorAccess(uint32_t eventId) { VulkanResourceManager *rm = m_pDriver->GetResourceManager(); @@ -2889,6 +2889,121 @@ rdcarray VulkanReplay::GetDescriptorAccess() access = DescriptorAccess(); } + const VKDynamicShaderFeedback &usage = m_BindlessFeedback.Usage[eventId]; + + // decode dynamic usage by reverse looking up shader bindpoint mappings. This is a temporary + // measure, once the old style bindings reporting are removed we can refactor the shader feedback + // to provide our data more directly in the format we want + if(usage.valid) + { + ResourceId pipeline = usage.compute ? state.compute.pipeline : state.graphics.pipeline; + const VulkanCreationInfo::Pipeline &pipeInfo = m_pDriver->m_CreationInfo.m_Pipeline[pipeline]; + const rdcarray &descSetLayouts = pipeInfo.descSetLayouts; + const rdcarray &descSets = + usage.compute ? state.compute.descSets : state.graphics.descSets; + for(const BindpointIndex &bind : usage.used) + { + if(bind.bindset >= descSetLayouts.count() || bind.bindset >= descSets.count()) + { + RDCERR("Out-of-bounds descriptor set referenced in dynamic usage"); + continue; + } + + const DescSetLayout &setLayoutInfo = + m_pDriver->m_CreationInfo.m_DescSetLayout[descSetLayouts[bind.bindset]]; + const DescSetLayout::Binding &bindInfo = setLayoutInfo.bindings[bind.bind]; + + DescriptorAccess access; + + if(bind.bind >= + m_pDriver->m_DescriptorSetState[descSets[bind.bindset].descSet].data.binds.count()) + { + RDCERR("Out-of-bounds binding referenced in dynamic usage in set %u", bind.bindset); + continue; + } + + // once we refactor the shader feedback this type will be provided directly by the access + switch(m_pDriver->m_DescriptorSetState[descSets[bind.bindset].descSet] + .data.binds[bind.bind][bind.arrayIndex] + .type) + { + case DescriptorSlotType::Unwritten: + default: + RDCERR("Unexpected current descriptor type referenced"); + access.type = DescriptorType::Unknown; + break; + case DescriptorSlotType::Sampler: access.type = DescriptorType::Sampler; break; + case DescriptorSlotType::CombinedImageSampler: + access.type = DescriptorType::ImageSampler; + break; + case DescriptorSlotType::SampledImage: access.type = DescriptorType::Image; break; + case DescriptorSlotType::StorageImage: access.type = DescriptorType::ReadWriteImage; break; + case DescriptorSlotType::UniformTexelBuffer: + access.type = DescriptorType::TypedBuffer; + break; + case DescriptorSlotType::StorageTexelBuffer: + access.type = DescriptorType::ReadWriteTypedBuffer; + break; + case DescriptorSlotType::UniformBuffer: access.type = DescriptorType::ConstantBuffer; break; + case DescriptorSlotType::StorageBuffer: + access.type = DescriptorType::ReadWriteBuffer; + break; + case DescriptorSlotType::UniformBufferDynamic: + access.type = DescriptorType::ConstantBuffer; + break; + case DescriptorSlotType::StorageBufferDynamic: + access.type = DescriptorType::ReadWriteBuffer; + break; + case DescriptorSlotType::InputAttachment: access.type = DescriptorType::Image; break; + case DescriptorSlotType::InlineBlock: access.type = DescriptorType::ConstantBuffer; break; + } + + bool found = false; + // this could have come from any stage, so we just find the first match + for(size_t s = 0; !found && s < NumShaderStages; s++) + { + // only look at candidate stages + if((usage.compute && (ShaderStage)s != ShaderStage::Compute) || + (!usage.compute && (ShaderStage)s == ShaderStage::Compute)) + continue; + + if(!pipeInfo.shaders[s].refl) + continue; + + for(const rdcarray &iface : { + pipeInfo.shaders[s].mapping->constantBlocks, + pipeInfo.shaders[s].mapping->samplers, + pipeInfo.shaders[s].mapping->readOnlyResources, + pipeInfo.shaders[s].mapping->readWriteResources, + }) + { + access.index = 0; + for(const Bindpoint &searchBind : iface) + { + if(searchBind == bind) + { + access.stage = pipeInfo.shaders[s].stage; + found = true; + break; + } + access.index++; + } + + if(found) + break; + } + } + + access.arrayElement = bind.arrayIndex; + + access.descriptorStore = rm->GetOriginalID(descSets[bind.bindset].descSet); + access.byteOffset = bindInfo.elemOffset + setLayoutInfo.inlineByteSize + bind.arrayIndex; + access.byteSize = 1; + + ret.push_back(access); + } + } + return ret; } diff --git a/renderdoc/driver/vulkan/vk_replay.h b/renderdoc/driver/vulkan/vk_replay.h index 6b4162f18..3192a7738 100644 --- a/renderdoc/driver/vulkan/vk_replay.h +++ b/renderdoc/driver/vulkan/vk_replay.h @@ -353,7 +353,7 @@ public: const rdcarray &ranges); rdcarray GetSamplerDescriptors(ResourceId descriptorStore, const rdcarray &ranges); - rdcarray GetDescriptorAccess(); + rdcarray GetDescriptorAccess(uint32_t eventId); void FreeTargetResource(ResourceId id); RDResult ReadLogInitialisation(RDCFile *rdc, bool storeStructuredBuffers); diff --git a/renderdoc/replay/dummy_driver.cpp b/renderdoc/replay/dummy_driver.cpp index 2a1e38afa..4fa469138 100644 --- a/renderdoc/replay/dummy_driver.cpp +++ b/renderdoc/replay/dummy_driver.cpp @@ -165,7 +165,7 @@ rdcarray DummyDriver::GetSamplerDescriptors(ResourceId descri return ret; } -rdcarray DummyDriver::GetDescriptorAccess() +rdcarray DummyDriver::GetDescriptorAccess(uint32_t eventId) { return {}; } diff --git a/renderdoc/replay/dummy_driver.h b/renderdoc/replay/dummy_driver.h index 1b709af75..1149b5e7b 100644 --- a/renderdoc/replay/dummy_driver.h +++ b/renderdoc/replay/dummy_driver.h @@ -64,7 +64,7 @@ public: const rdcarray &ranges); rdcarray GetSamplerDescriptors(ResourceId descriptorStore, const rdcarray &ranges); - rdcarray GetDescriptorAccess(); + rdcarray GetDescriptorAccess(uint32_t eventId); FrameRecord GetFrameRecord(); diff --git a/renderdoc/replay/replay_controller.cpp b/renderdoc/replay/replay_controller.cpp index e806e70c2..e2875401c 100644 --- a/renderdoc/replay/replay_controller.cpp +++ b/renderdoc/replay/replay_controller.cpp @@ -135,7 +135,7 @@ rdcarray ReplayController::GetDescriptorAccess() { CHECK_REPLAY_THREAD(); - return m_pDevice->GetDescriptorAccess(); + return m_pDevice->GetDescriptorAccess(m_EventID); } rdcarray ReplayController::GetSamplerDescriptors( diff --git a/renderdoc/replay/replay_driver.h b/renderdoc/replay/replay_driver.h index 730748ada..845ef4656 100644 --- a/renderdoc/replay/replay_driver.h +++ b/renderdoc/replay/replay_driver.h @@ -166,7 +166,7 @@ public: const rdcarray &ranges) = 0; virtual rdcarray GetSamplerDescriptors( ResourceId descriptorStore, const rdcarray &ranges) = 0; - virtual rdcarray GetDescriptorAccess() = 0; + virtual rdcarray GetDescriptorAccess(uint32_t eventId) = 0; virtual FrameRecord GetFrameRecord() = 0;