From 2b1d5cbd90a55a9b8d3fd5ea855f2a0e8712d77d Mon Sep 17 00:00:00 2001 From: Egor Yusov Date: Wed, 23 Oct 2019 21:05:17 -0700 Subject: D3D12 backend: optimized CommitRootViews method to process dynamic and non-dynamic buffers separately --- .../GraphicsEngineD3D12/include/BufferD3D12Impl.h | 15 ++++- .../include/PipelineStateD3D12Impl.h | 18 ++++-- .../GraphicsEngineD3D12/include/RootSignature.h | 73 ++++++++++++++++++---- .../include/ShaderResourceCacheD3D12.h | 22 +++++-- .../include/ShaderResourceLayoutD3D12.h | 3 +- .../GraphicsEngineD3D12/src/BufferD3D12Impl.cpp | 16 ----- .../src/DeviceContextD3D12Impl.cpp | 67 +++++++++++++++----- .../src/PipelineStateD3D12Impl.cpp | 56 +++++++++++------ Graphics/GraphicsEngineD3D12/src/RootSignature.cpp | 4 +- .../src/ShaderResourceBindingD3D12Impl.cpp | 7 +++ .../src/ShaderResourceCacheD3D12.cpp | 19 ++++++ .../src/ShaderResourceLayoutD3D12.cpp | 35 ++++++++--- 12 files changed, 252 insertions(+), 83 deletions(-) (limited to 'Graphics/GraphicsEngineD3D12') diff --git a/Graphics/GraphicsEngineD3D12/include/BufferD3D12Impl.h b/Graphics/GraphicsEngineD3D12/include/BufferD3D12Impl.h index 1b92a511..6e976537 100644 --- a/Graphics/GraphicsEngineD3D12/include/BufferD3D12Impl.h +++ b/Graphics/GraphicsEngineD3D12/include/BufferD3D12Impl.h @@ -79,7 +79,20 @@ public: virtual D3D12_RESOURCE_STATES GetD3D12ResourceState()const override final; - D3D12_GPU_VIRTUAL_ADDRESS GetGPUAddress(class DeviceContextD3D12Impl* pCtx); + __forceinline D3D12_GPU_VIRTUAL_ADDRESS GetGPUAddress(Uint32 ContextId, class DeviceContextD3D12Impl* pCtx) + { + if(m_Desc.Usage == USAGE_DYNAMIC) + { +#ifdef DEVELOPMENT + DvpVerifyDynamicAllocation(pCtx); +#endif + return m_DynamicData[ContextId].GPUAddress; + } + else + { + return GetD3D12Resource()->GetGPUVirtualAddress(); + } + } D3D12_CPU_DESCRIPTOR_HANDLE GetCBVHandle(){return m_CBVDescriptorAllocation.GetCpuHandle();} diff --git a/Graphics/GraphicsEngineD3D12/include/PipelineStateD3D12Impl.h b/Graphics/GraphicsEngineD3D12/include/PipelineStateD3D12Impl.h index d7f61929..f61b53db 100644 --- a/Graphics/GraphicsEngineD3D12/include/PipelineStateD3D12Impl.h +++ b/Graphics/GraphicsEngineD3D12/include/PipelineStateD3D12Impl.h @@ -66,11 +66,17 @@ public: virtual ID3D12RootSignature *GetD3D12RootSignature()const override final{return m_RootSig.GetD3D12RootSignature(); } - ShaderResourceCacheD3D12* CommitAndTransitionShaderResources(IShaderResourceBinding* pShaderResourceBinding, - class CommandContext& Ctx, - bool CommitResources, - bool TransitionResources, - bool ValidateStates)const; + struct CommitAndTransitionResourcesAttribs + { + Uint32 CtxId = 0; + IShaderResourceBinding* pShaderResourceBinding = nullptr; + bool CommitResources = false; + bool TransitionResources = false; + bool ValidateStates = false; + }; + ShaderResourceCacheD3D12* CommitAndTransitionShaderResources(class DeviceContextD3D12Impl* pDeviceCtx, + class CommandContext& CmdCtx, + CommitAndTransitionResourcesAttribs& Attrib)const; const RootSignature& GetRootSignature()const{return m_RootSig;} @@ -92,7 +98,7 @@ public: return m_pStaticResourceCaches[ShaderInd]; } - bool dbgContainsShaderResources()const; + bool ContainsShaderResources()const; SRBMemoryAllocator& GetSRBMemoryAllocator() { diff --git a/Graphics/GraphicsEngineD3D12/include/RootSignature.h b/Graphics/GraphicsEngineD3D12/include/RootSignature.h index 988cabd2..59f2102e 100644 --- a/Graphics/GraphicsEngineD3D12/include/RootSignature.h +++ b/Graphics/GraphicsEngineD3D12/include/RootSignature.h @@ -328,9 +328,15 @@ public: class CommandContext& Ctx)const; __forceinline void CommitRootViews(ShaderResourceCacheD3D12& ResourceCache, - class CommandContext& Ctx, + class CommandContext& CmdCtx, bool IsCompute, - class DeviceContextD3D12Impl* pCtx)const; + Uint32 DeviceCtxId, + class DeviceContextD3D12Impl* pDeviceCtx, + bool CommitViews, + bool ProcessDynamicBuffers, + bool ProcessNonDynamicBuffers, + bool TransitionStates, + bool ValidateStates)const; Uint32 GetTotalSrvCbvUavSlots(SHADER_RESOURCE_VARIABLE_TYPE VarType)const { @@ -358,6 +364,11 @@ private: #ifdef _DEBUG void dbgVerifyRootParameters()const; #endif + +#ifdef DEVELOPMENT + static void DvpVerifyResourceState(const ShaderResourceCacheD3D12::Resource& Res, + D3D12_DESCRIPTOR_RANGE_TYPE RangeType); +#endif std::vector > GetCacheTableSizes()const; @@ -490,9 +501,15 @@ private: }; void RootSignature::CommitRootViews(ShaderResourceCacheD3D12& ResourceCache, - CommandContext& Ctx, + CommandContext& CmdCtx, bool IsCompute, - DeviceContextD3D12Impl* pCtx)const + Uint32 DeviceCtxId, + DeviceContextD3D12Impl* pDeviceCtx, + bool CommitViews, + bool ProcessDynamicBuffers, + bool ProcessNonDynamicBuffers, + bool TransitionStates, + bool ValidateStates)const { for (Uint32 rv = 0; rv < m_RootParams.GetNumRootViews(); ++rv) { @@ -511,14 +528,46 @@ void RootSignature::CommitRootViews(ShaderResourceCacheD3D12& ResourceCache, auto& Res = ResourceCache.GetRootTable(RootInd).GetResource(0, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, dbgShaderType); if (auto* pBuffToTransition = Res.pObject.RawPtr()) { - if (pBuffToTransition->IsInKnownState() && !pBuffToTransition->CheckState(RESOURCE_STATE_CONSTANT_BUFFER) ) - Ctx.TransitionResource(pBuffToTransition, RESOURCE_STATE_CONSTANT_BUFFER); - - D3D12_GPU_VIRTUAL_ADDRESS CBVAddress = pBuffToTransition->GetGPUAddress(pCtx); - if(IsCompute) - Ctx.GetCommandList()->SetComputeRootConstantBufferView(RootInd, CBVAddress); - else - Ctx.GetCommandList()->SetGraphicsRootConstantBufferView(RootInd, CBVAddress); + bool IsDynamic = pBuffToTransition->GetDesc().Usage == USAGE_DYNAMIC; + if (IsDynamic && ProcessDynamicBuffers || !IsDynamic && ProcessNonDynamicBuffers) + { + if (IsDynamic) + { +#ifdef _DEBUG + if (pBuffToTransition->IsInKnownState()) + { + VERIFY(pBuffToTransition->CheckState(RESOURCE_STATE_CONSTANT_BUFFER), + "Dynamic buffers must always have RESOURCE_STATE_CONSTANT_BUFFER state flag set"); + } +#endif + } + else + { + if (TransitionStates) + { + if (pBuffToTransition->IsInKnownState() && !pBuffToTransition->CheckState(RESOURCE_STATE_CONSTANT_BUFFER)) + { + CmdCtx.TransitionResource(pBuffToTransition, RESOURCE_STATE_CONSTANT_BUFFER); + } + } +#ifdef DEVELOPMENT + else if (ValidateStates) + { + + DvpVerifyResourceState(Res, D3D12_DESCRIPTOR_RANGE_TYPE_CBV); + } +#endif + } + + if (CommitViews) + { + D3D12_GPU_VIRTUAL_ADDRESS CBVAddress = pBuffToTransition->GetGPUAddress(DeviceCtxId, pDeviceCtx); + if(IsCompute) + CmdCtx.GetCommandList()->SetComputeRootConstantBufferView(RootInd, CBVAddress); + else + CmdCtx.GetCommandList()->SetGraphicsRootConstantBufferView(RootInd, CBVAddress); + } + } } } } diff --git a/Graphics/GraphicsEngineD3D12/include/ShaderResourceCacheD3D12.h b/Graphics/GraphicsEngineD3D12/include/ShaderResourceCacheD3D12.h index 1c65fb66..4f210d2c 100644 --- a/Graphics/GraphicsEngineD3D12/include/ShaderResourceCacheD3D12.h +++ b/Graphics/GraphicsEngineD3D12/include/ShaderResourceCacheD3D12.h @@ -142,6 +142,12 @@ public: m_pResources {pResources } {} + inline const Resource& GetResource(Uint32 OffsetFromTableStart)const + { + VERIFY(OffsetFromTableStart < m_NumResources, "Root table is not large enough to store descriptor at offset ", OffsetFromTableStart ); + return m_pResources[OffsetFromTableStart]; + } + inline const Resource& GetResource(Uint32 OffsetFromTableStart, const D3D12_DESCRIPTOR_HEAP_TYPE dbgDescriptorHeapType, const SHADER_TYPE dbgRefShaderType)const @@ -178,8 +184,8 @@ public: #endif const Uint32 m_NumResources = 0; + private: - #ifdef _DEBUG D3D12_DESCRIPTOR_HEAP_TYPE m_dbgHeapType = D3D12_DESCRIPTOR_HEAP_TYPE_NUM_TYPES; SHADER_TYPE m_dbgShaderType = SHADER_TYPE_UNKNOWN; @@ -295,9 +301,15 @@ public: return GPUDescriptorHandle; } + Uint32& GetBoundDynamicCBsCounter() {return m_NumDynamicCBsBound;} + + // Returns the number of dynamic constant buffers bound in the cache regardless of their variable types + Uint32 GetNumDynamicCBsBound()const{return m_NumDynamicCBsBound;} + #ifdef _DEBUG // Only for debug purposes: indicates what types of resources are stored in the cache DbgCacheContentType DbgGetContentType()const{return m_DbgContentType;} + void DbgVerifyBoundDynamicCBsCounter()const; #endif private: @@ -312,9 +324,11 @@ private: // Allocation in a GPU-visible CBV/SRV/UAV descriptor heap DescriptorHeapAllocation m_CbvSrvUavHeapSpace; - IMemoryAllocator *m_pAllocator=nullptr; - void *m_pMemory = nullptr; - Uint32 m_NumTables = 0; + IMemoryAllocator* m_pAllocator = nullptr; + void* m_pMemory = nullptr; + Uint32 m_NumTables = 0; + // The number of the dynamic buffers bound in the resource cache regardless of their variable type + Uint32 m_NumDynamicCBsBound = 0; #ifdef _DEBUG // Only for debug purposes: indicates what types of resources are stored in the cache diff --git a/Graphics/GraphicsEngineD3D12/include/ShaderResourceLayoutD3D12.h b/Graphics/GraphicsEngineD3D12/include/ShaderResourceLayoutD3D12.h index 53f7bb01..6a251a24 100644 --- a/Graphics/GraphicsEngineD3D12/include/ShaderResourceLayoutD3D12.h +++ b/Graphics/GraphicsEngineD3D12/include/ShaderResourceLayoutD3D12.h @@ -203,7 +203,8 @@ public: void CacheCB(IDeviceObject* pBuffer, ShaderResourceCacheD3D12::Resource& DstRes, Uint32 ArrayInd, - D3D12_CPU_DESCRIPTOR_HANDLE ShdrVisibleHeapCPUDescriptorHandle)const; + D3D12_CPU_DESCRIPTOR_HANDLE ShdrVisibleHeapCPUDescriptorHandle, + Uint32& BoundDynamicCBsCounter)const; templateGetContextId(); - return m_DynamicData[ContextId].GPUAddress; - } - else - { - return GetD3D12Resource()->GetGPUVirtualAddress(); - } -} - #ifdef DEVELOPMENT void BufferD3D12Impl::DvpVerifyDynamicAllocation(DeviceContextD3D12Impl* pCtx)const { diff --git a/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp index cac5178d..645bc2b4 100644 --- a/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp @@ -238,7 +238,13 @@ namespace Diligent auto& Ctx = GetCmdContext(); auto* pPipelineStateD3D12 = ValidatedCast(pPipelineState); - pPipelineStateD3D12->CommitAndTransitionShaderResources(pShaderResourceBinding, Ctx, false, true, false); + PipelineStateD3D12Impl::CommitAndTransitionResourcesAttribs Attribs; + Attribs.CtxId = m_ContextId; + Attribs.pShaderResourceBinding = pShaderResourceBinding; + Attribs.CommitResources = false; + Attribs.TransitionResources = true; + Attribs.ValidateStates = false; + pPipelineStateD3D12->CommitAndTransitionShaderResources(this, Ctx, Attribs); } void DeviceContextD3D12Impl::CommitShaderResources(IShaderResourceBinding* pShaderResourceBinding, RESOURCE_STATE_TRANSITION_MODE StateTransitionMode) @@ -247,10 +253,13 @@ namespace Diligent return; auto& Ctx = GetCmdContext(); - m_State.pCommittedResourceCache = - m_pPipelineState->CommitAndTransitionShaderResources(pShaderResourceBinding, Ctx, true, - StateTransitionMode == RESOURCE_STATE_TRANSITION_MODE_TRANSITION, - StateTransitionMode == RESOURCE_STATE_TRANSITION_MODE_VERIFY); + PipelineStateD3D12Impl::CommitAndTransitionResourcesAttribs Attribs; + Attribs.CtxId = m_ContextId; + Attribs.pShaderResourceBinding = pShaderResourceBinding; + Attribs.CommitResources = true; + Attribs.TransitionResources = StateTransitionMode == RESOURCE_STATE_TRANSITION_MODE_TRANSITION; + Attribs.ValidateStates = StateTransitionMode == RESOURCE_STATE_TRANSITION_MODE_VERIFY; + m_State.pCommittedResourceCache = m_pPipelineState->CommitAndTransitionShaderResources(this, Ctx, Attribs); m_State.bRootViewsCommitted = false; } @@ -275,7 +284,7 @@ namespace Diligent VERIFY( m_pIndexBuffer != nullptr, "Index buffer is not set up for indexed draw command" ); D3D12_INDEX_BUFFER_VIEW IBView; - IBView.BufferLocation = m_pIndexBuffer->GetGPUAddress(this) + m_IndexDataStartOffset; + IBView.BufferLocation = m_pIndexBuffer->GetGPUAddress(m_ContextId, this) + m_IndexDataStartOffset; if( IndexType == VT_UINT32 ) IBView.Format = DXGI_FORMAT_R32_UINT; else @@ -344,7 +353,7 @@ namespace Diligent // so there is no need to reference the resource here //GraphicsCtx.AddReferencedObject(pd3d12Resource); - VBView.BufferLocation = pBufferD3D12->GetGPUAddress(this) + CurrStream.Offset; + VBView.BufferLocation = pBufferD3D12->GetGPUAddress(m_ContextId, this) + CurrStream.Offset; VBView.StrideInBytes = m_pPipelineState->GetBufferStride(Buff); // Note that for a dynamic buffer, what we use here is the size of the buffer itself, not the upload heap buffer! VBView.SizeInBytes = pBufferD3D12->GetDesc().uiSizeInBytes - CurrStream.Offset; @@ -394,16 +403,31 @@ namespace Diligent if (m_State.pCommittedResourceCache != nullptr) { - if (!m_State.bRootViewsCommitted || (Flags & DRAW_FLAG_DYNAMIC_RESOURCE_BUFFERS_INTACT) == 0) + if (m_State.pCommittedResourceCache->GetNumDynamicCBsBound() > 0) { - m_pPipelineState->GetRootSignature().CommitRootViews(*m_State.pCommittedResourceCache, GraphCtx, false, this); - m_State.bRootViewsCommitted = true; + if (!m_State.bRootViewsCommitted || (Flags & DRAW_FLAG_DYNAMIC_RESOURCE_BUFFERS_INTACT) == 0) + { + // Only process dynamic buffers. Non-dynamic buffers are committed by CommitShaderResources + m_pPipelineState->GetRootSignature(). + CommitRootViews(*m_State.pCommittedResourceCache, + GraphCtx, + false, // IsCompute + m_ContextId, + this, + true, // CommitViews + true, // ProcessDynamicBuffers + false, // ProcessNonDynamicBuffers + false, // TransitionStates + false // ValidateStates + ); + m_State.bRootViewsCommitted = true; + } } } #ifdef DEVELOPMENT else { - if (m_pPipelineState->dbgContainsShaderResources()) + if (m_pPipelineState->ContainsShaderResources()) LOG_ERROR_MESSAGE("Pipeline state '", m_pPipelineState->GetDesc().Name, "' contains shader resources, but IDeviceContext::CommitShaderResources() was not called with non-null SRB" ); } #endif @@ -506,12 +530,27 @@ namespace Diligent ComputeCtx.SetRootSignature(m_pPipelineState->GetD3D12RootSignature()); if (m_State.pCommittedResourceCache != nullptr) { - m_pPipelineState->GetRootSignature().CommitRootViews(*m_State.pCommittedResourceCache, ComputeCtx, true, this); + if (m_State.pCommittedResourceCache->GetNumDynamicCBsBound() > 0) + { + // Only process dynamic buffers. Non-dynamic buffers are committed by CommitShaderResources + m_pPipelineState->GetRootSignature(). + CommitRootViews(*m_State.pCommittedResourceCache, + ComputeCtx, + true, // IsCompute + m_ContextId, + this, + true, // CommitViews + true, // ProcessDynamicBuffers + false, // ProcessNonDynamicBuffers + false, // TransitionStates + false // ValidateStates + ); + } } -#ifdef _DEBUG +#ifdef DEVELOPMENT else { - if (m_pPipelineState->dbgContainsShaderResources()) + if (m_pPipelineState->ContainsShaderResources()) LOG_ERROR_MESSAGE("Pipeline state '", m_pPipelineState->GetDesc().Name, "' contains shader resources, but IDeviceContext::CommitShaderResources() was not called with non-null SRB" ); } #endif diff --git a/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp index f6e576dc..1a0f2186 100644 --- a/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp @@ -363,29 +363,27 @@ bool PipelineStateD3D12Impl::IsCompatibleWith(const IPipelineState* pPSO)const return IsSameRootSignature; } -ShaderResourceCacheD3D12* PipelineStateD3D12Impl::CommitAndTransitionShaderResources(IShaderResourceBinding* pShaderResourceBinding, - CommandContext& Ctx, - bool CommitResources, - bool TransitionResources, - bool ValidateStates)const +ShaderResourceCacheD3D12* PipelineStateD3D12Impl::CommitAndTransitionShaderResources(class DeviceContextD3D12Impl* pDeviceCtx, + class CommandContext& CmdCtx, + CommitAndTransitionResourcesAttribs& Attrib)const { #ifdef DEVELOPMENT - if (pShaderResourceBinding == nullptr && dbgContainsShaderResources()) + if (Attrib.pShaderResourceBinding == nullptr && ContainsShaderResources()) { LOG_ERROR_MESSAGE("Pipeline state '", m_Desc.Name, "' requires shader resource binding object to ", - (CommitResources ? "commit" : "transition"), " resources, but none is provided."); + (Attrib.CommitResources ? "commit" : "transition"), " resources, but none is provided."); } #endif - auto* pResBindingD3D12Impl = ValidatedCast(pShaderResourceBinding); + auto* pResBindingD3D12Impl = ValidatedCast(Attrib.pShaderResourceBinding); if (pResBindingD3D12Impl == nullptr) { - if (CommitResources) + if (Attrib.CommitResources) { if(m_Desc.IsComputePipeline) - Ctx.AsComputeContext().SetRootSignature( GetD3D12RootSignature() ); + CmdCtx.AsComputeContext().SetRootSignature( GetD3D12RootSignature() ); else - Ctx.AsGraphicsContext().SetRootSignature( GetD3D12RootSignature() ); + CmdCtx.AsGraphicsContext().SetRootSignature( GetD3D12RootSignature() ); } return nullptr; } @@ -408,28 +406,46 @@ ShaderResourceCacheD3D12* PipelineStateD3D12Impl::CommitAndTransitionShaderResou #endif auto& ResourceCache = pResBindingD3D12Impl->GetResourceCache(); - if(CommitResources) + if(Attrib.CommitResources) { if(m_Desc.IsComputePipeline) - Ctx.AsComputeContext().SetRootSignature( GetD3D12RootSignature() ); + CmdCtx.AsComputeContext().SetRootSignature( GetD3D12RootSignature() ); else - Ctx.AsGraphicsContext().SetRootSignature( GetD3D12RootSignature() ); + CmdCtx.AsGraphicsContext().SetRootSignature( GetD3D12RootSignature() ); - if(TransitionResources) - (m_RootSig.*m_RootSig.TransitionAndCommitDescriptorHandles)(m_pDevice, ResourceCache, Ctx, m_Desc.IsComputePipeline, ValidateStates); + if(Attrib.TransitionResources) + { + (m_RootSig.*m_RootSig.TransitionAndCommitDescriptorHandles)(m_pDevice, ResourceCache, CmdCtx, m_Desc.IsComputePipeline, Attrib.ValidateStates); + } else - (m_RootSig.*m_RootSig.CommitDescriptorHandles)(m_pDevice, ResourceCache, Ctx, m_Desc.IsComputePipeline, ValidateStates); + { + (m_RootSig.*m_RootSig.CommitDescriptorHandles)(m_pDevice, ResourceCache, CmdCtx, m_Desc.IsComputePipeline, Attrib.ValidateStates); + } } else { - VERIFY(TransitionResources, "Resources should be transitioned or committed or both"); - m_RootSig.TransitionResources(ResourceCache, Ctx); + VERIFY(Attrib.TransitionResources, "Resources should be transitioned or committed or both"); + m_RootSig.TransitionResources(ResourceCache, CmdCtx); } + + // Process only non-dynamic buffers at this point. Dynamic buffers will be handled by the Draw/Dispatch command. + m_RootSig.CommitRootViews(ResourceCache, + CmdCtx, + m_Desc.IsComputePipeline, + Attrib.CtxId, + pDeviceCtx, + Attrib.CommitResources, // CommitViews + false, // ProcessDynamicBuffers + true, // ProcessNonDynamicBuffers + Attrib.TransitionResources, + Attrib.ValidateStates + ); + return &ResourceCache; } -bool PipelineStateD3D12Impl::dbgContainsShaderResources()const +bool PipelineStateD3D12Impl::ContainsShaderResources()const { for(auto VarType = SHADER_RESOURCE_VARIABLE_TYPE_STATIC; VarType < SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES; VarType = static_cast(VarType+1)) { diff --git a/Graphics/GraphicsEngineD3D12/src/RootSignature.cpp b/Graphics/GraphicsEngineD3D12/src/RootSignature.cpp index d432042c..147fd72e 100644 --- a/Graphics/GraphicsEngineD3D12/src/RootSignature.cpp +++ b/Graphics/GraphicsEngineD3D12/src/RootSignature.cpp @@ -751,8 +751,8 @@ void TransitionResource(CommandContext& Ctx, #ifdef DEVELOPMENT -void DvpVerifyResourceState(const ShaderResourceCacheD3D12::Resource& Res, - D3D12_DESCRIPTOR_RANGE_TYPE RangeType) +void RootSignature::DvpVerifyResourceState(const ShaderResourceCacheD3D12::Resource& Res, + D3D12_DESCRIPTOR_RANGE_TYPE RangeType) { switch (Res.Type) { diff --git a/Graphics/GraphicsEngineD3D12/src/ShaderResourceBindingD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/ShaderResourceBindingD3D12Impl.cpp index b5c465a8..3a088ec8 100644 --- a/Graphics/GraphicsEngineD3D12/src/ShaderResourceBindingD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/ShaderResourceBindingD3D12Impl.cpp @@ -164,6 +164,9 @@ void ShaderResourceBindingD3D12Impl::dvpVerifyResourceBindings(const PipelineSta const auto& ShaderResLayout = pRefPSO->GetShaderResLayout(l); ShaderResLayout.dvpVerifyBindings(m_ShaderResourceCache); } +#ifdef _DEBUG + m_ShaderResourceCache.DbgVerifyBoundDynamicCBsCounter(); +#endif } #endif @@ -206,6 +209,10 @@ void ShaderResourceBindingD3D12Impl::InitializeStaticResources(const IPipelineSt StaticResLayout.CopyStaticResourceDesriptorHandles(StaticResCache, ShaderResLayout, m_ShaderResourceCache); } +#ifdef _DEBUG + m_ShaderResourceCache.DbgVerifyBoundDynamicCBsCounter(); +#endif + m_bStaticResourcesInitialized = true; } diff --git a/Graphics/GraphicsEngineD3D12/src/ShaderResourceCacheD3D12.cpp b/Graphics/GraphicsEngineD3D12/src/ShaderResourceCacheD3D12.cpp index 385e3bc4..b5a54e2e 100644 --- a/Graphics/GraphicsEngineD3D12/src/ShaderResourceCacheD3D12.cpp +++ b/Graphics/GraphicsEngineD3D12/src/ShaderResourceCacheD3D12.cpp @@ -24,6 +24,7 @@ #include "pch.h" #include "ShaderResourceCacheD3D12.h" +#include "BufferD3D12Impl.h" namespace Diligent { @@ -92,4 +93,22 @@ namespace Diligent m_pAllocator->Free(m_pMemory); } } + +#ifdef _DEBUG + void ShaderResourceCacheD3D12::DbgVerifyBoundDynamicCBsCounter()const + { + Uint32 NumDynamicCBsBound = 0; + for (Uint32 t = 0; t < m_NumTables; ++t) + { + const auto& RT = GetRootTable(t); + for (Uint32 res=0; res < RT.GetSize(); ++res) + { + const auto& Res = RT.GetResource(res); + if (Res.Type == CachedResourceType::CBV && Res.pObject && Res.pObject.RawPtr()->GetDesc().Usage == USAGE_DYNAMIC) + ++NumDynamicCBsBound; + } + } + VERIFY(NumDynamicCBsBound == m_NumDynamicCBsBound, "The number of dynamic CBs bound is invalid"); + } +#endif } diff --git a/Graphics/GraphicsEngineD3D12/src/ShaderResourceLayoutD3D12.cpp b/Graphics/GraphicsEngineD3D12/src/ShaderResourceLayoutD3D12.cpp index 364ae46f..39e003f0 100644 --- a/Graphics/GraphicsEngineD3D12/src/ShaderResourceLayoutD3D12.cpp +++ b/Graphics/GraphicsEngineD3D12/src/ShaderResourceLayoutD3D12.cpp @@ -362,7 +362,8 @@ ShaderResourceLayoutD3D12::ShaderResourceLayoutD3D12(IObject& void ShaderResourceLayoutD3D12::D3D12Resource::CacheCB(IDeviceObject* pBuffer, ShaderResourceCacheD3D12::Resource& DstRes, Uint32 ArrayInd, - D3D12_CPU_DESCRIPTOR_HANDLE ShdrVisibleHeapCPUDescriptorHandle)const + D3D12_CPU_DESCRIPTOR_HANDLE ShdrVisibleHeapCPUDescriptorHandle, + Uint32& BoundDynamicCBsCounter)const { // http://diligentgraphics.com/diligent-engine/architecture/d3d12/shader-resource-cache#Binding-Objects-to-Shader-Variables @@ -395,6 +396,13 @@ void ShaderResourceLayoutD3D12::D3D12Resource::CacheCB(IDeviceObject* pd3d12Device->CopyDescriptorsSimple(1, ShdrVisibleHeapCPUDescriptorHandle, DstRes.CPUDescriptorHandle, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); } + if (DstRes.pObject != nullptr && DstRes.pObject.RawPtr()->GetDesc().Usage == USAGE_DYNAMIC) + { + VERIFY(BoundDynamicCBsCounter > 0, "There is a dynamic CB bound in the resource cache, but the dynamic CB counter is zero"); + --BoundDynamicCBsCounter; + } + if (pBuffD3D12->GetDesc().Usage == USAGE_DYNAMIC) + ++BoundDynamicCBsCounter; DstRes.pObject = std::move(pBuffD3D12); } } @@ -573,7 +581,7 @@ void ShaderResourceLayoutD3D12::D3D12Resource::BindResource(IDeviceObject* switch (GetResType()) { case CachedResourceType::CBV: - CacheCB(pObj, DstRes, ArrayIndex, ShdrVisibleHeapCPUDescriptorHandle); + CacheCB(pObj, DstRes, ArrayIndex, ShdrVisibleHeapCPUDescriptorHandle, ResourceCache.GetBoundDynamicCBsCounter()); break; case CachedResourceType::TexSRV: @@ -693,7 +701,7 @@ void ShaderResourceLayoutD3D12::CopyStaticResourceDesriptorHandles(const ShaderR auto CbvSrvUavCount = DstLayout.GetCbvSrvUavCount(SHADER_RESOURCE_VARIABLE_TYPE_STATIC); VERIFY(GetCbvSrvUavCount(SHADER_RESOURCE_VARIABLE_TYPE_STATIC) == CbvSrvUavCount, "Number of static resources in the source cache (", GetCbvSrvUavCount(SHADER_RESOURCE_VARIABLE_TYPE_STATIC), ") is not consistent with the number of static resources in destination cache (", CbvSrvUavCount, ")" ); - + auto& DstBoundDynamicCBsCounter = DstCache.GetBoundDynamicCBsCounter(); for(Uint32 r=0; r < CbvSrvUavCount; ++r) { // Get resource attributes @@ -716,8 +724,21 @@ void ShaderResourceLayoutD3D12::CopyStaticResourceDesriptorHandles(const ShaderR { VERIFY(DstRes.pObject == nullptr, "Static resource has already been initialized, and the resource to be assigned from the shader does not match previously assigned resource"); - DstRes.pObject = SrcRes.pObject; - DstRes.Type = SrcRes.Type; + if (SrcRes.Type == CachedResourceType::CBV) + { + if (DstRes.pObject && DstRes.pObject.RawPtr()->GetDesc().Usage == USAGE_DYNAMIC) + { + VERIFY_EXPR(DstBoundDynamicCBsCounter > 0); + --DstBoundDynamicCBsCounter; + } + if (SrcRes.pObject && SrcRes.pObject.RawPtr()->GetDesc().Usage == USAGE_DYNAMIC) + { + ++DstBoundDynamicCBsCounter; + } + } + + DstRes.pObject = SrcRes.pObject; + DstRes.Type = SrcRes.Type; DstRes.CPUDescriptorHandle = SrcRes.CPUDescriptorHandle; auto ShdrVisibleHeapCPUDescriptorHandle = DstCache.GetShaderVisibleTableCPUDescriptorHandle(res.RootIndex, res.OffsetFromTableStart + ArrInd); @@ -766,8 +787,8 @@ void ShaderResourceLayoutD3D12::CopyStaticResourceDesriptorHandles(const ShaderR { VERIFY(DstSampler.pObject == nullptr, "Static-type sampler has already been initialized, and the sampler to be assigned from the shader does not match previously assigned resource"); - DstSampler.pObject = SrcSampler.pObject; - DstSampler.Type = SrcSampler.Type; + DstSampler.pObject = SrcSampler.pObject; + DstSampler.Type = SrcSampler.Type; DstSampler.CPUDescriptorHandle = SrcSampler.CPUDescriptorHandle; auto ShdrVisibleSamplerHeapCPUDescriptorHandle = DstCache.GetShaderVisibleTableCPUDescriptorHandle(SamInfo.RootIndex, SamInfo.OffsetFromTableStart + ArrInd); -- cgit v1.2.3