From 51d5250fd4c322e212684200d13af8f9e9027294 Mon Sep 17 00:00:00 2001 From: baldurk Date: Thu, 17 Dec 2020 15:23:45 +0000 Subject: [PATCH] Reuse root elements array in D3D12 pipeline state * This means if there's a large view array, selecting between draws with the same root signature doesn't free & reallocate the array, it can re-use the existing memory. --- renderdoc/driver/d3d12/d3d12_replay.cpp | 54 ++++++++++++++++++------- 1 file changed, 40 insertions(+), 14 deletions(-) diff --git a/renderdoc/driver/d3d12/d3d12_replay.cpp b/renderdoc/driver/d3d12/d3d12_replay.cpp index b9eb62fee..f2a54113b 100644 --- a/renderdoc/driver/d3d12/d3d12_replay.cpp +++ b/renderdoc/driver/d3d12/d3d12_replay.cpp @@ -930,23 +930,28 @@ void D3D12Replay::FillRootElements(const D3D12RenderState::RootSignature &rootSi WrappedID3D12RootSignature *sig = m_pDevice->GetResourceManager()->GetCurrentAs(rootSig.rootsig); - rootElements.clear(); rootElements.reserve(sig->sig.Parameters.size() + sig->sig.StaticSamplers.size()); + size_t ridx = 0; + for(size_t rootEl = 0; rootEl < sig->sig.Parameters.size(); rootEl++) { const D3D12RootSignatureParameter &p = sig->sig.Parameters[rootEl]; if(p.ParameterType == D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS) { - rootElements.push_back(D3D12Pipe::RootSignatureRange()); - D3D12Pipe::RootSignatureRange &element = rootElements.back(); + rootElements.resize_for_index(ridx); + D3D12Pipe::RootSignatureRange &element = rootElements[ridx++]; element.immediate = true; element.rootElement = (uint32_t)rootEl; element.type = BindType::ConstantBuffer; element.registerSpace = p.Constants.RegisterSpace; element.visibility = ToShaderStageMask(p.ShaderVisibility); + element.samplers.clear(); + element.constantBuffers.clear(); + element.views.clear(); + element.constantBuffers.push_back(D3D12Pipe::ConstantBuffer(p.Constants.ShaderRegister)); D3D12Pipe::ConstantBuffer &cb = element.constantBuffers.back(); cb.byteSize = uint32_t(sizeof(uint32_t) * p.Constants.Num32BitValues); @@ -964,14 +969,18 @@ void D3D12Replay::FillRootElements(const D3D12RenderState::RootSignature &rootSi } else if(p.ParameterType == D3D12_ROOT_PARAMETER_TYPE_CBV) { - rootElements.push_back(D3D12Pipe::RootSignatureRange()); - D3D12Pipe::RootSignatureRange &element = rootElements.back(); + rootElements.resize_for_index(ridx); + D3D12Pipe::RootSignatureRange &element = rootElements[ridx++]; element.immediate = true; element.rootElement = (uint32_t)rootEl; element.type = BindType::ConstantBuffer; element.registerSpace = p.Descriptor.RegisterSpace; element.visibility = ToShaderStageMask(p.ShaderVisibility); + element.samplers.clear(); + element.constantBuffers.clear(); + element.views.clear(); + element.constantBuffers.push_back(D3D12Pipe::ConstantBuffer(p.Descriptor.ShaderRegister)); D3D12Pipe::ConstantBuffer &cb = element.constantBuffers.back(); @@ -993,14 +1002,18 @@ void D3D12Replay::FillRootElements(const D3D12RenderState::RootSignature &rootSi } else if(p.ParameterType == D3D12_ROOT_PARAMETER_TYPE_SRV) { - rootElements.push_back(D3D12Pipe::RootSignatureRange()); - D3D12Pipe::RootSignatureRange &element = rootElements.back(); + rootElements.resize_for_index(ridx); + D3D12Pipe::RootSignatureRange &element = rootElements[ridx++]; element.immediate = true; element.rootElement = (uint32_t)rootEl; element.type = BindType::ReadOnlyResource; element.registerSpace = p.Descriptor.RegisterSpace; element.visibility = ToShaderStageMask(p.ShaderVisibility); + element.samplers.clear(); + element.constantBuffers.clear(); + element.views.clear(); + element.views.push_back(D3D12Pipe::View(p.Descriptor.ShaderRegister)); D3D12Pipe::View &view = element.views.back(); @@ -1027,14 +1040,18 @@ void D3D12Replay::FillRootElements(const D3D12RenderState::RootSignature &rootSi } else if(p.ParameterType == D3D12_ROOT_PARAMETER_TYPE_UAV) { - rootElements.push_back(D3D12Pipe::RootSignatureRange()); - D3D12Pipe::RootSignatureRange &element = rootElements.back(); + rootElements.resize_for_index(ridx); + D3D12Pipe::RootSignatureRange &element = rootElements[ridx++]; element.immediate = true; element.rootElement = (uint32_t)rootEl; element.type = BindType::ReadWriteResource; element.registerSpace = p.Descriptor.RegisterSpace; element.visibility = ToShaderStageMask(p.ShaderVisibility); + element.samplers.clear(); + element.constantBuffers.clear(); + element.views.clear(); + element.views.push_back(D3D12Pipe::View(p.Descriptor.ShaderRegister)); D3D12Pipe::View &view = element.views.back(); @@ -1080,13 +1097,18 @@ void D3D12Replay::FillRootElements(const D3D12RenderState::RootSignature &rootSi // Here we diverge slightly from how root signatures store data. A descriptor table can // contain multiple ranges which can each contain different types. D3D12Pipe treats // each range as a separate RootElement - rootElements.push_back(D3D12Pipe::RootSignatureRange()); - D3D12Pipe::RootSignatureRange &element = rootElements.back(); + rootElements.resize_for_index(ridx); + D3D12Pipe::RootSignatureRange &element = rootElements[ridx++]; + element.immediate = false; element.rootElement = (uint32_t)rootEl; element.registerSpace = range.RegisterSpace; element.visibility = ToShaderStageMask(p.ShaderVisibility); + element.samplers.clear(); + element.constantBuffers.clear(); + element.views.clear(); + UINT shaderReg = range.BaseShaderRegister; D3D12Descriptor *desc = NULL; @@ -1248,16 +1270,20 @@ void D3D12Replay::FillRootElements(const D3D12RenderState::RootSignature &rootSi { D3D12_STATIC_SAMPLER_DESC &sampDesc = sig->sig.StaticSamplers[i]; - rootElements.push_back(D3D12Pipe::RootSignatureRange()); - D3D12Pipe::RootSignatureRange &element = rootElements.back(); + rootElements.resize_for_index(ridx); + D3D12Pipe::RootSignatureRange &element = rootElements[ridx++]; element.immediate = true; element.rootElement = (uint32_t)i; element.type = BindType::Sampler; element.registerSpace = sampDesc.RegisterSpace; element.visibility = ToShaderStageMask(sampDesc.ShaderVisibility); + element.samplers.clear(); + element.constantBuffers.clear(); + element.views.clear(); + element.samplers.push_back(D3D12Pipe::Sampler(sampDesc.ShaderRegister)); - D3D12Pipe::Sampler &samp = element.samplers.back(); + D3D12Pipe::Sampler &samp = element.samplers[0]; samp.addressU = MakeAddressMode(sampDesc.AddressU); samp.addressV = MakeAddressMode(sampDesc.AddressV);