From c2dac14dbb95c9a458c0f524b11ceee08d9b2071 Mon Sep 17 00:00:00 2001 From: azhirnov Date: Tue, 16 Feb 2021 00:29:54 +0300 Subject: optimize root view updates --- .../include/DeviceContextD3D12Impl.hpp | 15 +++--- .../include/PipelineResourceSignatureD3D12Impl.hpp | 30 ++++++++++- .../src/DeviceContextD3D12Impl.cpp | 63 +++++++++++----------- .../src/PipelineResourceSignatureD3D12Impl.cpp | 29 ---------- 4 files changed, 70 insertions(+), 67 deletions(-) (limited to 'Graphics/GraphicsEngineD3D12') diff --git a/Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.hpp b/Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.hpp index 5ed3a1dc..333dc912 100644 --- a/Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.hpp +++ b/Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.hpp @@ -391,27 +391,30 @@ private: using Bitfield = Uint8; static_assert(sizeof(Bitfield) * 8 >= MAX_RESOURCE_SIGNATURES, "not enought space to store MAX_RESOURCE_SIGNATURES bits"); - //Bitfield ActiveSRBMask ; // Indicates which SRBs are active in current PSO - bool bRootViewsCommitted; // Indicates if root views have been committed since the time SRB has been committed. + Bitfield ActiveSRBMask = 0; // Indicates which SRBs are active in current PSO + Bitfield DynamicBuffersMask = 0; // Indicates which SRBs have dynamic buffers + bool bRootViewsCommitted; // Indicates if root views have been committed since the time SRB has been committed. bool bRootTablesCommited; - bool IsCompute : 1; ID3D12RootSignature* pRootSig; std::array SRBs; - RootTableInfo(bool _IsCompute) + RootTableInfo() { memset(this, 0, sizeof(*this)); - IsCompute = _IsCompute; } __forceinline bool RequireUpdate(bool DynamicBuffersIntact = false) const { - return true; //(StaleSRBMask & ActiveSRBMask) != 0 || ((DynamicBuffersMask & ActiveSRBMask) != 0 && !DynamicBuffersIntact); + return !bRootViewsCommitted || !bRootTablesCommited || ((DynamicBuffersMask & ActiveSRBMask) != 0 && !DynamicBuffersIntact); } + + void SetDynamicBufferBit(Uint32 Index) { DynamicBuffersMask |= static_cast(1u << Index); } + void ClearDynamicBufferBit(Uint32 Index) { DynamicBuffersMask &= static_cast(~(1u << Index)); } }; __forceinline RootTableInfo& GetRootTableInfo(PIPELINE_TYPE PipelineType); + template __forceinline void CommitRootTables(RootTableInfo& RootInfo); #ifdef DILIGENT_DEVELOPMENT void DvpValidateCommittedShaderResources(); diff --git a/Graphics/GraphicsEngineD3D12/include/PipelineResourceSignatureD3D12Impl.hpp b/Graphics/GraphicsEngineD3D12/include/PipelineResourceSignatureD3D12Impl.hpp index 8fd7ee7d..c747dda2 100644 --- a/Graphics/GraphicsEngineD3D12/include/PipelineResourceSignatureD3D12Impl.hpp +++ b/Graphics/GraphicsEngineD3D12/include/PipelineResourceSignatureD3D12Impl.hpp @@ -273,11 +273,11 @@ public: bool IsCompute, Uint32 FirstRootIndex); + template void CommitRootViews(ShaderResourceCacheD3D12& ResourceCache, CommandContext& Ctx, DeviceContextD3D12Impl* pDeviceCtx, Uint32 DeviceCtxId, - bool IsCompute, Uint32 FirstRootIndex); private: @@ -307,4 +307,32 @@ private: SRBMemoryAllocator m_SRBMemAllocator; }; +template +__forceinline void PipelineResourceSignatureD3D12Impl::CommitRootViews(ShaderResourceCacheD3D12& ResourceCache, + CommandContext& CmdCtx, + DeviceContextD3D12Impl* pDeviceCtx, + Uint32 DeviceCtxId, + Uint32 FirstRootIndex) +{ + for (Uint32 rv = 0; rv < m_RootParams.GetNumRootViews(); ++rv) + { + auto& RootView = m_RootParams.GetRootView(rv); + auto RootInd = RootView.RootIndex; + + auto& Res = ResourceCache.GetRootTable(RootInd).GetResource(0, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); + if (auto* pBuffToTransition = Res.pObject.RawPtr()) + { + bool IsDynamic = pBuffToTransition->GetDesc().Usage == USAGE_DYNAMIC; + if (IsDynamic) + { + D3D12_GPU_VIRTUAL_ADDRESS CBVAddress = pBuffToTransition->GetGPUAddress(DeviceCtxId, pDeviceCtx); + if (IsCompute) + CmdCtx.GetCommandList()->SetComputeRootConstantBufferView(FirstRootIndex + RootInd, CBVAddress); + else + CmdCtx.GetCommandList()->SetGraphicsRootConstantBufferView(FirstRootIndex + RootInd, CBVAddress); + } + } + } +} + } // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp index 58e3262f..db878dd9 100644 --- a/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp @@ -75,8 +75,6 @@ DeviceContextD3D12Impl::DeviceContextD3D12Impl(IReferenceCounters* pRef bIsDeferred ? std::numeric_limits::max() : EngineCI.NumCommandsToFlushCmdList, bIsDeferred }, - m_GraphicsResources{false}, - m_ComputeResources {true }, m_DynamicHeap { pDeviceD3D12Impl->GetDynamicMemoryManager(), @@ -236,6 +234,14 @@ void DeviceContextD3D12Impl::SetPipelineState(IPipelineState* pPipelineState) RootInfo.pRootSig = pd3d12RootSig; RootInfo.bRootTablesCommited = false; RootInfo.bRootViewsCommitted = false; + RootInfo.ActiveSRBMask = 0; + + for (Uint32 i = 0, SignCount = pPipelineStateD3D12->GetSignatureCount(); i < SignCount; ++i) + { + auto* pSignature = pPipelineStateD3D12->GetSignature(i); + if (pSignature != nullptr) + RootInfo.ActiveSRBMask |= 1u << i; + } } switch (PSODesc.PipelineType) @@ -293,6 +299,7 @@ void DeviceContextD3D12Impl::SetPipelineState(IPipelineState* pPipelineState) } } +template void DeviceContextD3D12Impl::CommitRootTables(RootTableInfo& RootInfo) { const auto& RootSig = *m_pPipelineState->GetRootSignature(); @@ -301,7 +308,6 @@ void DeviceContextD3D12Impl::CommitRootTables(RootTableInfo& RootInfo) if (!RootInfo.bRootTablesCommited) { RootInfo.bRootTablesCommited = true; - for (Uint32 s = 0; s < RootSig.GetSignatureCount(); ++s) { auto* pSignature = RootSig.GetSignature(s); @@ -311,25 +317,21 @@ void DeviceContextD3D12Impl::CommitRootTables(RootTableInfo& RootInfo) continue; VERIFY_EXPR(pSRB != nullptr); - pSignature->CommitRootTables(pSRB->GetResourceCache(), CmdCtx, this, GetContextId(), RootInfo.IsCompute, RootSig.GetFirstRootIndex(s)); + pSignature->CommitRootTables(pSRB->GetResourceCache(), CmdCtx, this, GetContextId(), IsCompute, RootSig.GetFirstRootIndex(s)); } } - //if (!RootInfo.bRootViewsCommitted) + RootInfo.bRootViewsCommitted = true; + for (Uint32 s = 0; s < RootSig.GetSignatureCount(); ++s) { - RootInfo.bRootViewsCommitted = true; - - for (Uint32 s = 0; s < RootSig.GetSignatureCount(); ++s) - { - auto* pSignature = RootSig.GetSignature(s); - auto* pSRB = RootInfo.SRBs[s]; + auto* pSignature = RootSig.GetSignature(s); + auto* pSRB = RootInfo.SRBs[s]; - if (pSignature == nullptr || pSignature->GetNumRootViews() == 0) - continue; + if (pSignature == nullptr || pSignature->GetNumRootViews() == 0) + continue; - VERIFY_EXPR(pSRB != nullptr); - pSignature->CommitRootViews(pSRB->GetResourceCache(), CmdCtx, this, GetContextId(), RootInfo.IsCompute, RootSig.GetFirstRootIndex(s)); - } + VERIFY_EXPR(pSRB != nullptr); + pSignature->CommitRootViews(pSRB->GetResourceCache(), CmdCtx, this, GetContextId(), RootSig.GetFirstRootIndex(s)); } } @@ -359,12 +361,6 @@ void DeviceContextD3D12Impl::CommitShaderResources(IShaderResourceBinding* pShad auto& CmdCtx = GetCmdContext(); auto* pSignature = pResBindingD3D12Impl->GetSignature(); - //if (pSignature->GetTotalRootCount() == 0) - //{ - // Ignore SRBs that contain no resources - // return; - //} - #ifdef DILIGENT_DEBUG //ResourceCache.DbgVerifyDynamicBuffersCounter(); #endif @@ -380,9 +376,15 @@ void DeviceContextD3D12Impl::CommitShaderResources(IShaderResourceBinding* pShad } #endif - auto& RootInfo = GetRootTableInfo(pSignature->GetPipelineType()); + const auto SRBIndex = pResBindingD3D12Impl->GetBindingIndex(); + auto& RootInfo = GetRootTableInfo(pSignature->GetPipelineType()); - RootInfo.SRBs[pSignature->GetDesc().BindingIndex] = pResBindingD3D12Impl; + RootInfo.SRBs[SRBIndex] = pResBindingD3D12Impl; + + if (ResourceCache.GetNumDynamicCBsBound() > 0) + RootInfo.SetDynamicBufferBit(SRBIndex); + else + RootInfo.ClearDynamicBufferBit(SRBIndex); RootInfo.bRootTablesCommited = false; RootInfo.bRootViewsCommitted = false; @@ -581,7 +583,7 @@ void DeviceContextD3D12Impl::PrepareForDraw(GraphicsContext& GraphCtx, DRAW_FLAG auto& RootInfo = GetRootTableInfo(PIPELINE_TYPE_GRAPHICS); if (RootInfo.RequireUpdate(Flags & DRAW_FLAG_DYNAMIC_RESOURCE_BUFFERS_INTACT)) { - CommitRootTables(RootInfo); + CommitRootTables(RootInfo); } #ifdef DILIGENT_DEVELOPMENT @@ -714,7 +716,7 @@ void DeviceContextD3D12Impl::PrepareForDispatchCompute(ComputeContext& ComputeCt auto& RootInfo = GetRootTableInfo(PIPELINE_TYPE_COMPUTE); if (RootInfo.RequireUpdate()) { - CommitRootTables(RootInfo); + CommitRootTables(RootInfo); } #ifdef DILIGENT_DEVELOPMENT @@ -727,7 +729,7 @@ void DeviceContextD3D12Impl::PrepareForDispatchRays(GraphicsContext& GraphCtx) auto& RootInfo = GetRootTableInfo(PIPELINE_TYPE_RAY_TRACING); if (RootInfo.RequireUpdate()) { - CommitRootTables(RootInfo); + CommitRootTables(RootInfo); } #ifdef DILIGENT_DEVELOPMENT @@ -894,10 +896,9 @@ void DeviceContextD3D12Impl::Flush(bool RequestNewCmdCtx, if (RequestNewCmdCtx) RequestCommandContext(m_pDevice); - m_State = State{}; - - m_GraphicsResources = RootTableInfo{false}; - m_ComputeResources = RootTableInfo{true}; + m_State = State{}; + m_GraphicsResources = RootTableInfo{}; + m_ComputeResources = RootTableInfo{}; // Setting pipeline state to null makes sure that render targets and other // states will be restored in the command list next time a PSO is bound. diff --git a/Graphics/GraphicsEngineD3D12/src/PipelineResourceSignatureD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/PipelineResourceSignatureD3D12Impl.cpp index 7cab8a5d..243cf9c0 100644 --- a/Graphics/GraphicsEngineD3D12/src/PipelineResourceSignatureD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/PipelineResourceSignatureD3D12Impl.cpp @@ -1060,7 +1060,6 @@ void PipelineResourceSignatureD3D12Impl::CommitRootTables(ShaderResourceCacheD3D Uint32 NumDynamicCbvSrvUavDescriptors = m_RootParams.GetTotalSrvCbvUavSlots(ROOT_PARAMETER_GROUP_DYNAMIC); Uint32 NumDynamicSamplerDescriptors = m_RootParams.GetTotalSamplerSlots(ROOT_PARAMETER_GROUP_DYNAMIC); - //VERIFY_EXPR(NumDynamicCbvSrvUavDescriptors > 0 || NumDynamicSamplerDescriptors > 0); DescriptorHeapAllocation DynamicCbvSrvUavDescriptors, DynamicSamplerDescriptors; if (NumDynamicCbvSrvUavDescriptors > 0) @@ -1204,34 +1203,6 @@ void PipelineResourceSignatureD3D12Impl::CommitRootTables(ShaderResourceCacheD3D } } -void PipelineResourceSignatureD3D12Impl::CommitRootViews(ShaderResourceCacheD3D12& ResourceCache, - CommandContext& CmdCtx, - DeviceContextD3D12Impl* pDeviceCtx, - Uint32 DeviceCtxId, - bool IsCompute, - Uint32 FirstRootIndex) -{ - for (Uint32 rv = 0; rv < m_RootParams.GetNumRootViews(); ++rv) - { - auto& RootView = m_RootParams.GetRootView(rv); - auto RootInd = RootView.RootIndex; - - auto& Res = ResourceCache.GetRootTable(RootInd).GetResource(0, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); - if (auto* pBuffToTransition = Res.pObject.RawPtr()) - { - bool IsDynamic = pBuffToTransition->GetDesc().Usage == USAGE_DYNAMIC; - if (IsDynamic) - { - D3D12_GPU_VIRTUAL_ADDRESS CBVAddress = pBuffToTransition->GetGPUAddress(DeviceCtxId, pDeviceCtx); - if (IsCompute) - CmdCtx.GetCommandList()->SetComputeRootConstantBufferView(FirstRootIndex + RootInd, CBVAddress); - else - CmdCtx.GetCommandList()->SetGraphicsRootConstantBufferView(FirstRootIndex + RootInd, CBVAddress); - } - } - } -} - namespace { -- cgit v1.2.3