diff options
| author | Egor Yusov <egor.yusov@gmail.com> | 2018-03-11 19:07:09 +0000 |
|---|---|---|
| committer | Egor Yusov <egor.yusov@gmail.com> | 2018-03-11 19:07:09 +0000 |
| commit | bbbf3434aefd105662f9efd4bf9e7d56f9e8170b (patch) | |
| tree | 42806921a62dcc82b4925927d52e9f453048e959 /Graphics | |
| parent | Enabled full optimization (/Ox) for windows release builds (diff) | |
| download | DiligentCore-bbbf3434aefd105662f9efd4bf9e7d56f9e8170b.tar.gz DiligentCore-bbbf3434aefd105662f9efd4bf9e7d56f9e8170b.zip | |
Implemented PSO compatibility in D3D11
Diffstat (limited to 'Graphics')
17 files changed, 234 insertions, 52 deletions
diff --git a/Graphics/GraphicsEngine/include/DeviceContextBase.h b/Graphics/GraphicsEngine/include/DeviceContextBase.h index 75e2c109..8099afc7 100644 --- a/Graphics/GraphicsEngine/include/DeviceContextBase.h +++ b/Graphics/GraphicsEngine/include/DeviceContextBase.h @@ -97,6 +97,7 @@ public: inline virtual void SetPipelineState(IPipelineState *pPipelineState)override = 0; /// Base implementation of IDeviceContext::CommitShaderResources(); validates parameters. + template<typename PSOImplType> inline bool CommitShaderResources(IShaderResourceBinding *pShaderResourceBinding, Uint32 Flags, int); /// Base implementation of IDeviceContext::SetIndexBuffer(); caches the strong reference to the index buffer @@ -249,6 +250,7 @@ inline void DeviceContextBase<BaseInterface> :: SetPipelineState(IPipelineState } template<typename BaseInterface> +template<typename PSOImplType> inline bool DeviceContextBase<BaseInterface> :: CommitShaderResources(IShaderResourceBinding *pShaderResourceBinding, Uint32 Flags, int) { #ifdef _DEBUG @@ -260,10 +262,10 @@ inline bool DeviceContextBase<BaseInterface> :: CommitShaderResources(IShaderRes if (pShaderResourceBinding) { - auto *pPSO = pShaderResourceBinding->GetPipelineState(); - if (pPSO != m_pPipelineState) + auto *pPSOImpl = ValidatedCast<PSOImplType>(m_pPipelineState.RawPtr()); + if (pPSOImpl->IsIncompatibleWith(pShaderResourceBinding->GetPipelineState())) { - LOG_ERROR_MESSAGE("Shader resource binding object does not match currently bound pipeline state"); + LOG_ERROR_MESSAGE("Shader resource binding object is not compatible with the currently bound pipeline state"); return false; } } diff --git a/Graphics/GraphicsEngine/include/PipelineStateBase.h b/Graphics/GraphicsEngine/include/PipelineStateBase.h index a293d575..7348c32c 100644 --- a/Graphics/GraphicsEngine/include/PipelineStateBase.h +++ b/Graphics/GraphicsEngine/include/PipelineStateBase.h @@ -173,6 +173,13 @@ public: IShader* const* GetShaders()const{return m_ppShaders;} Uint32 GetNumShaders()const{return m_NumShaders;} + // This function only compares shader resource layout hashes, so + // it can potentially give false negatives + bool IsIncompatibleWith(IPipelineState *pPSO)const + { + return m_ShaderResourceLayoutHash != ValidatedCast<PipelineStateBase>(pPSO)->m_ShaderResourceLayoutHash; + } + protected: std::vector<LayoutElement, STDAllocatorRawMem<LayoutElement> > m_LayoutElements; @@ -189,6 +196,7 @@ protected: RefCntAutoPtr<IShader> m_pCS; ///< Strong reference to the compute shader IShader *m_ppShaders[5]; ///< Array of pointers to shaders that this PSO uses Uint32 m_NumShaders; ///< Number of shaders that this PSO uses + size_t m_ShaderResourceLayoutHash = 0;///< Hash computed from the shader resource layout }; } diff --git a/Graphics/GraphicsEngine/interface/PipelineState.h b/Graphics/GraphicsEngine/interface/PipelineState.h index 7e31b49a..58f05f7f 100644 --- a/Graphics/GraphicsEngine/interface/PipelineState.h +++ b/Graphics/GraphicsEngine/interface/PipelineState.h @@ -220,6 +220,22 @@ public: /// \param [out] ppShaderResourceBinding - memory location where pointer to the new shader resource /// binding object is written. virtual void CreateShaderResourceBinding( IShaderResourceBinding **ppShaderResourceBinding ) = 0; + + /// Checks if this pipeline state object is compatible with another PSO + + /// If two pipeline state objects are compatible, they can use shader resource binding + /// objects interchangebly, i.e. SRBs created by one PSO can be committed + /// when another PSO is bound. + /// \param [in] pPSO - Pointer to the pipeline state object to check compatibility with + /// \return true if this PSO is compatbile with pPSO. false otherwise. + /// \remarks The function only checks that shader resource layouts are compatible, but + /// does not check if resource types match. For instance, if a pixel shader in one PSO + /// uses a texture at slot 0, and a pixel shader in another PSO uses texture array at slot 0, + /// the pipelines will be compatible. However, if you try to use SRB object from the first pipeline + /// to commit resources for the second pipeline, a runtime error will occur.\n + /// The function only checks compatibility of shader resource layouts. It does not take + /// into account vertex shader input layout, number of outputs, etc. + virtual bool IsCompatibleWith(const IPipelineState *pPSO)const = 0; }; } diff --git a/Graphics/GraphicsEngineD3D11/include/PipelineStateD3D11Impl.h b/Graphics/GraphicsEngineD3D11/include/PipelineStateD3D11Impl.h index e8cc719a..0a5897f2 100644 --- a/Graphics/GraphicsEngineD3D11/include/PipelineStateD3D11Impl.h +++ b/Graphics/GraphicsEngineD3D11/include/PipelineStateD3D11Impl.h @@ -69,6 +69,8 @@ public: virtual void CreateShaderResourceBinding( IShaderResourceBinding **ppShaderResourceBinding )override final; + virtual bool IsCompatibleWith(const IPipelineState *pPSO)const override final; + class ShaderResourceBindingD3D11Impl* GetDefaultResourceBinding(){return m_pDefaultShaderResBinding.get();} IMemoryAllocator &GetResourceCacheDataAllocator(Uint32 ActiveShaderInd) { diff --git a/Graphics/GraphicsEngineD3D11/src/DeviceContextD3D11Impl.cpp b/Graphics/GraphicsEngineD3D11/src/DeviceContextD3D11Impl.cpp index 803fab7f..fd8e58f1 100644 --- a/Graphics/GraphicsEngineD3D11/src/DeviceContextD3D11Impl.cpp +++ b/Graphics/GraphicsEngineD3D11/src/DeviceContextD3D11Impl.cpp @@ -170,7 +170,7 @@ namespace Diligent #ifdef _DEBUG else { - if (pdbgPipelineStateD3D11 != pShaderResourceBinding->GetPipelineState()) + if (pdbgPipelineStateD3D11->IsIncompatibleWith(pShaderResourceBinding->GetPipelineState())) { LOG_ERROR_MESSAGE("Shader resource binding does not match Pipeline State"); return; @@ -526,7 +526,7 @@ namespace Diligent void DeviceContextD3D11Impl::CommitShaderResources(IShaderResourceBinding *pShaderResourceBinding, Uint32 Flags) { - if( !DeviceContextBase::CommitShaderResources(pShaderResourceBinding, Flags, 0 /*Dummy*/) ) + if( !DeviceContextBase::CommitShaderResources<PipelineStateD3D11Impl>(pShaderResourceBinding, Flags, 0 /*Dummy*/) ) return; if(Flags & COMMIT_SHADER_RESOURCES_FLAG_TRANSITION_RESOURCES) diff --git a/Graphics/GraphicsEngineD3D11/src/PipelineStateD3D11Impl.cpp b/Graphics/GraphicsEngineD3D11/src/PipelineStateD3D11Impl.cpp index 964614e6..c4e60dfe 100644 --- a/Graphics/GraphicsEngineD3D11/src/PipelineStateD3D11Impl.cpp +++ b/Graphics/GraphicsEngineD3D11/src/PipelineStateD3D11Impl.cpp @@ -37,27 +37,32 @@ PipelineStateD3D11Impl::PipelineStateD3D11Impl(IReferenceCounters *pRefCounters, { if (PipelineDesc.IsComputePipeline) { - m_pCS = ValidatedCast<ShaderD3D11Impl>( PipelineDesc.ComputePipeline.pCS ); + auto *pCS = ValidatedCast<ShaderD3D11Impl>(PipelineDesc.ComputePipeline.pCS); + m_pCS = pCS; if (m_pCS == nullptr) { LOG_ERROR_AND_THROW("Compute shader is null"); } if (m_pCS && m_pCS->GetDesc().ShaderType != SHADER_TYPE_COMPUTE) - { - LOG_ERROR_AND_THROW( GetShaderTypeLiteralName(SHADER_TYPE_COMPUTE), " shader is expeceted while ", GetShaderTypeLiteralName(m_pCS->GetDesc().ShaderType)," provided" ); + { + LOG_ERROR_AND_THROW(GetShaderTypeLiteralName(SHADER_TYPE_COMPUTE), " shader is expeceted while ", GetShaderTypeLiteralName(m_pCS->GetDesc().ShaderType), " provided"); } + m_ShaderResourceLayoutHash = pCS->GetResources()->GetHash(); } else { #define INIT_SHADER(ShortName, ExpectedType)\ { \ - m_p##ShortName = ValidatedCast<ShaderD3D11Impl>( PipelineDesc.GraphicsPipeline.p##ShortName ); \ + auto *pShader = ValidatedCast<ShaderD3D11Impl>(PipelineDesc.GraphicsPipeline.p##ShortName); \ + m_p##ShortName = pShader; \ if (m_p##ShortName && m_p##ShortName->GetDesc().ShaderType != ExpectedType) \ { \ LOG_ERROR_AND_THROW( GetShaderTypeLiteralName(ExpectedType), " shader is expeceted while ", GetShaderTypeLiteralName(m_p##ShortName->GetDesc().ShaderType)," provided" ); \ } \ + if(pShader!=nullptr) \ + HashCombine(m_ShaderResourceLayoutHash, pShader->GetResources()->GetHash() ); \ } INIT_SHADER(VS, SHADER_TYPE_VERTEX); @@ -186,6 +191,33 @@ void PipelineStateD3D11Impl::CreateShaderResourceBinding(IShaderResourceBinding pShaderResBinding->QueryInterface(IID_ShaderResourceBinding, reinterpret_cast<IObject**>(static_cast<IShaderResourceBinding**>(ppShaderResourceBinding))); } +bool PipelineStateD3D11Impl::IsCompatibleWith(const IPipelineState *pPSO)const +{ + if (pPSO == this) + return true; + + VERIFY_EXPR(pPSO != nullptr); + const PipelineStateD3D11Impl *pPSOD3D11 = ValidatedCast<const PipelineStateD3D11Impl>(pPSO); + if (m_ShaderResourceLayoutHash != pPSOD3D11->m_ShaderResourceLayoutHash) + return false; + + if (m_NumShaders != pPSOD3D11->m_NumShaders) + return false; + + for (Uint32 s = 0; s < m_NumShaders; ++s) + { + auto *pShader0 = ValidatedCast<ShaderD3D11Impl>(m_ppShaders[s]); + auto *pShader1 = ValidatedCast<ShaderD3D11Impl>(pPSOD3D11->m_ppShaders[s]); + if (pShader0->GetShaderTypeIndex() != pShader1->GetShaderTypeIndex()) + return false; + const ShaderResourcesD3D11 *pRes0 = pShader0->GetResources().get(); + const ShaderResourcesD3D11 *pRes1 = pShader1->GetResources().get(); + if (!pRes0->IsCompatibleWith(*pRes1)) + return false; + } + + return true; +} ID3D11VertexShader* PipelineStateD3D11Impl::GetD3D11VertexShader() { diff --git a/Graphics/GraphicsEngineD3D11/src/ShaderResourceLayoutD3D11.cpp b/Graphics/GraphicsEngineD3D11/src/ShaderResourceLayoutD3D11.cpp index 47274ba2..e653fa3a 100644 --- a/Graphics/GraphicsEngineD3D11/src/ShaderResourceLayoutD3D11.cpp +++ b/Graphics/GraphicsEngineD3D11/src/ShaderResourceLayoutD3D11.cpp @@ -143,7 +143,7 @@ void ShaderResourceLayoutD3D11::Initialize(const std::shared_ptr<const ShaderRes pSrcResources->ProcessResources( VarTypes, NumVarTypes, - [&](const D3DShaderResourceAttribs &CB) + [&](const D3DShaderResourceAttribs &CB, Uint32) { VERIFY_EXPR( IsAllowedType(CB.GetVariableType(), AllowedTypeBits) ); // Initialize current CB in place, increment CB counter @@ -151,7 +151,7 @@ void ShaderResourceLayoutD3D11::Initialize(const std::shared_ptr<const ShaderRes NumCBSlots = std::max(NumCBSlots, static_cast<Uint32>(CB.BindPoint + CB.BindCount)); }, - [&](const D3DShaderResourceAttribs& TexSRV) + [&](const D3DShaderResourceAttribs& TexSRV, Uint32) { VERIFY_EXPR( IsAllowedType(TexSRV.GetVariableType(), AllowedTypeBits) ); // Set reference to a special static instance representing invalid sampler @@ -165,7 +165,7 @@ void ShaderResourceLayoutD3D11::Initialize(const std::shared_ptr<const ShaderRes NumSamplerSlots = std::max(NumSamplerSlots, static_cast<Uint32>(SamplerAttribs.BindPoint + SamplerAttribs.BindCount)); }, - [&](const D3DShaderResourceAttribs &TexUAV) + [&](const D3DShaderResourceAttribs &TexUAV, Uint32) { VERIFY_EXPR( IsAllowedType(TexUAV.GetVariableType(), AllowedTypeBits) ); @@ -174,7 +174,7 @@ void ShaderResourceLayoutD3D11::Initialize(const std::shared_ptr<const ShaderRes NumUAVSlots = std::max(NumUAVSlots, static_cast<Uint32>(TexUAV.BindPoint + TexUAV.BindCount)); }, - [&](const D3DShaderResourceAttribs &BuffSRV) + [&](const D3DShaderResourceAttribs &BuffSRV, Uint32) { VERIFY_EXPR(IsAllowedType(BuffSRV.GetVariableType(), AllowedTypeBits)); @@ -183,7 +183,7 @@ void ShaderResourceLayoutD3D11::Initialize(const std::shared_ptr<const ShaderRes NumSRVSlots = std::max(NumSRVSlots, static_cast<Uint32>(BuffSRV.BindPoint + BuffSRV.BindCount)); }, - [&](const D3DShaderResourceAttribs &BuffUAV) + [&](const D3DShaderResourceAttribs &BuffUAV, Uint32) { VERIFY_EXPR(IsAllowedType(BuffUAV.GetVariableType(), AllowedTypeBits)); diff --git a/Graphics/GraphicsEngineD3D11/src/ShaderResourcesD3D11.cpp b/Graphics/GraphicsEngineD3D11/src/ShaderResourcesD3D11.cpp index cfc93de5..74149c5e 100644 --- a/Graphics/GraphicsEngineD3D11/src/ShaderResourcesD3D11.cpp +++ b/Graphics/GraphicsEngineD3D11/src/ShaderResourcesD3D11.cpp @@ -195,7 +195,7 @@ void ShaderResourcesD3D11::dbgVerifyCommittedResources(ID3D11Buffer* ProcessResources( nullptr, 0, - [&](const D3DShaderResourceAttribs &cb) + [&](const D3DShaderResourceAttribs &cb, Uint32) { for(auto BindPoint = cb.BindPoint; BindPoint < cb.BindPoint + cb.BindCount; ++BindPoint) { @@ -233,7 +233,7 @@ void ShaderResourcesD3D11::dbgVerifyCommittedResources(ID3D11Buffer* } }, - [&](const D3DShaderResourceAttribs& tex) + [&](const D3DShaderResourceAttribs& tex, Uint32) { for(auto BindPoint = tex.BindPoint; BindPoint < tex.BindPoint + tex.BindCount; ++BindPoint) { @@ -308,7 +308,7 @@ void ShaderResourcesD3D11::dbgVerifyCommittedResources(ID3D11Buffer* } }, - [&](const D3DShaderResourceAttribs &uav) + [&](const D3DShaderResourceAttribs &uav, Uint32) { for(auto BindPoint = uav.BindPoint; BindPoint < uav.BindPoint + uav.BindCount; ++BindPoint) { @@ -349,7 +349,7 @@ void ShaderResourcesD3D11::dbgVerifyCommittedResources(ID3D11Buffer* }, - [&](const D3DShaderResourceAttribs &buf) + [&](const D3DShaderResourceAttribs &buf, Uint32) { for(auto BindPoint = buf.BindPoint; BindPoint < buf.BindPoint + buf.BindCount; ++BindPoint) { @@ -389,7 +389,7 @@ void ShaderResourcesD3D11::dbgVerifyCommittedResources(ID3D11Buffer* } }, - [&](const D3DShaderResourceAttribs &uav) + [&](const D3DShaderResourceAttribs &uav, Uint32) { for(auto BindPoint = uav.BindPoint; BindPoint < uav.BindPoint + uav.BindCount; ++BindPoint) { diff --git a/Graphics/GraphicsEngineD3D12/include/PipelineStateD3D12Impl.h b/Graphics/GraphicsEngineD3D12/include/PipelineStateD3D12Impl.h index 9af62ee0..9813ed59 100644 --- a/Graphics/GraphicsEngineD3D12/include/PipelineStateD3D12Impl.h +++ b/Graphics/GraphicsEngineD3D12/include/PipelineStateD3D12Impl.h @@ -55,6 +55,8 @@ public: virtual void CreateShaderResourceBinding( IShaderResourceBinding **ppShaderResourceBinding )override; + virtual bool IsCompatibleWith(const IPipelineState *pPSO)const override final; + virtual ID3D12RootSignature *GetD3D12RootSignature()const override final{return m_RootSig.GetD3D12RootSignature(); } ShaderResourceCacheD3D12* CommitAndTransitionShaderResources(IShaderResourceBinding *pShaderResourceBinding, diff --git a/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp index 6c9a41be..7470424f 100644 --- a/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp @@ -184,13 +184,8 @@ namespace Diligent void DeviceContextD3D12Impl::CommitShaderResources(IShaderResourceBinding *pShaderResourceBinding, Uint32 Flags) { -#ifdef _DEBUG - if (!m_pPipelineState) - { - LOG_ERROR("No pipeline state is bound"); + if (!DeviceContextBase::CommitShaderResources<PipelineStateD3D12Impl>(pShaderResourceBinding, Flags, 0 /*Dummy*/)) return; - } -#endif auto *pCtx = RequestCmdContext(); auto *pPipelineStateD3D12 = ValidatedCast<PipelineStateD3D12Impl>(m_pPipelineState.RawPtr()); diff --git a/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp index 4c9442e4..7fe35e92 100644 --- a/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp @@ -265,6 +265,12 @@ void PipelineStateD3D12Impl::CreateShaderResourceBinding(IShaderResourceBinding pResBindingD3D12->QueryInterface(IID_ShaderResourceBinding, reinterpret_cast<IObject**>(ppShaderResourceBinding)); } +bool PipelineStateD3D12Impl::IsCompatibleWith(const IPipelineState *pPSO)const +{ + UNSUPPORTED("Not yet implemented"); + return false; +} + const ShaderResourceLayoutD3D12& PipelineStateD3D12Impl::GetShaderResLayout(SHADER_TYPE ShaderType)const { auto ShaderInd = GetShaderTypeIndex(ShaderType); diff --git a/Graphics/GraphicsEngineD3D12/src/ShaderResourceLayoutD3D12.cpp b/Graphics/GraphicsEngineD3D12/src/ShaderResourceLayoutD3D12.cpp index e94ab1d8..5fc8d9b5 100644 --- a/Graphics/GraphicsEngineD3D12/src/ShaderResourceLayoutD3D12.cpp +++ b/Graphics/GraphicsEngineD3D12/src/ShaderResourceLayoutD3D12.cpp @@ -192,12 +192,12 @@ void ShaderResourceLayoutD3D12::Initialize(ID3D12Device *pd3d12Device, m_pResources->ProcessResources( AllowedVarTypes, NumAllowedTypes, - [&](const D3DShaderResourceAttribs &CB) + [&](const D3DShaderResourceAttribs &CB, Uint32) { VERIFY_EXPR(IsAllowedType(CB.GetVariableType(), AllowedTypeBits)); ++m_NumCbvSrvUav[CB.GetVariableType()]; }, - [&](const D3DShaderResourceAttribs& TexSRV) + [&](const D3DShaderResourceAttribs& TexSRV, Uint32) { auto VarType = TexSRV.GetVariableType(); VERIFY_EXPR(IsAllowedType(VarType, AllowedTypeBits)); @@ -213,17 +213,17 @@ void ShaderResourceLayoutD3D12::Initialize(ID3D12Device *pd3d12Device, } } }, - [&](const D3DShaderResourceAttribs &TexUAV) + [&](const D3DShaderResourceAttribs &TexUAV, Uint32) { VERIFY_EXPR(IsAllowedType(TexUAV.GetVariableType(), AllowedTypeBits)); ++m_NumCbvSrvUav[TexUAV.GetVariableType()]; }, - [&](const D3DShaderResourceAttribs &BufSRV) + [&](const D3DShaderResourceAttribs &BufSRV, Uint32) { VERIFY_EXPR(IsAllowedType(BufSRV.GetVariableType(), AllowedTypeBits)); ++m_NumCbvSrvUav[BufSRV.GetVariableType()]; }, - [&](const D3DShaderResourceAttribs &BufUAV) + [&](const D3DShaderResourceAttribs &BufUAV, Uint32) { VERIFY_EXPR(IsAllowedType(BufUAV.GetVariableType(), AllowedTypeBits)); ++m_NumCbvSrvUav[BufUAV.GetVariableType()]; @@ -277,12 +277,12 @@ void ShaderResourceLayoutD3D12::Initialize(ID3D12Device *pd3d12Device, m_pResources->ProcessResources( AllowedVarTypes, NumAllowedTypes, - [&](const D3DShaderResourceAttribs &CB) + [&](const D3DShaderResourceAttribs &CB, Uint32) { VERIFY_EXPR( IsAllowedType(CB.GetVariableType(), AllowedTypeBits) ); AddResource(CB, CachedResourceType::CBV); }, - [&](const D3DShaderResourceAttribs& TexSRV) + [&](const D3DShaderResourceAttribs& TexSRV, Uint32) { auto VarType = TexSRV.GetVariableType(); VERIFY_EXPR(IsAllowedType(VarType, AllowedTypeBits) ); @@ -335,17 +335,17 @@ void ShaderResourceLayoutD3D12::Initialize(ID3D12Device *pd3d12Device, } AddResource(TexSRV, CachedResourceType::TexSRV, SamplerId); }, - [&](const D3DShaderResourceAttribs &TexUAV) + [&](const D3DShaderResourceAttribs &TexUAV, Uint32) { VERIFY_EXPR( IsAllowedType(TexUAV.GetVariableType(), AllowedTypeBits) ); AddResource(TexUAV, CachedResourceType::TexUAV); }, - [&](const D3DShaderResourceAttribs &BufSRV) + [&](const D3DShaderResourceAttribs &BufSRV, Uint32) { VERIFY_EXPR( IsAllowedType(BufSRV.GetVariableType(), AllowedTypeBits) ); AddResource(BufSRV, CachedResourceType::BufSRV); }, - [&](const D3DShaderResourceAttribs &BufUAV) + [&](const D3DShaderResourceAttribs &BufUAV, Uint32) { VERIFY_EXPR( IsAllowedType(BufUAV.GetVariableType(), AllowedTypeBits) ); AddResource(BufUAV, CachedResourceType::BufUAV); diff --git a/Graphics/GraphicsEngineD3DBase/include/ShaderResources.h b/Graphics/GraphicsEngineD3DBase/include/ShaderResources.h index 8972e2be..57e395ed 100644 --- a/Graphics/GraphicsEngineD3DBase/include/ShaderResources.h +++ b/Graphics/GraphicsEngineD3DBase/include/ShaderResources.h @@ -58,6 +58,7 @@ #include "Shader.h" #include "STDAllocator.h" +#include "HashUtils.h" namespace Diligent { @@ -218,6 +219,19 @@ struct D3DShaderResourceAttribs else return Name; } + + bool IsCompatibleWith(const D3DShaderResourceAttribs& Attibs)const + { + return BindPoint == Attibs.BindPoint && + BindCount == Attibs.BindCount && + PackedAttribs == Attibs.PackedAttribs; + } + + size_t GetHash()const + { + return ComputeHash(BindPoint, BindCount, PackedAttribs); + } + private: static constexpr Uint16 MaxBindPoint = InvalidBindPoint-1; static constexpr Uint16 MaxBindCount = std::numeric_limits<Uint16>::max(); @@ -327,38 +341,42 @@ public: { const auto& CB = GetCB(n); if( IsAllowedType(CB.GetVariableType(), AllowedTypeBits) ) - HandleCB(CB); + HandleCB(CB, n); } for(Uint32 n=0; n < GetNumTexSRV(); ++n) { const auto &TexSRV = GetTexSRV(n); if( IsAllowedType(TexSRV.GetVariableType(), AllowedTypeBits) ) - HandleTexSRV(TexSRV); + HandleTexSRV(TexSRV, n); } for(Uint32 n=0; n < GetNumTexUAV(); ++n) { const auto &TexUAV = GetTexUAV(n); if( IsAllowedType(TexUAV.GetVariableType(), AllowedTypeBits) ) - HandleTexUAV(TexUAV); + HandleTexUAV(TexUAV, n); } for(Uint32 n=0; n < GetNumBufSRV(); ++n) { const auto &BufSRV = GetBufSRV(n); if( IsAllowedType(BufSRV.GetVariableType(), AllowedTypeBits) ) - HandleBufSRV(BufSRV); + HandleBufSRV(BufSRV, n); } for(Uint32 n=0; n < GetNumBufUAV(); ++n) { const auto& BufUAV = GetBufUAV(n); if( IsAllowedType(BufUAV.GetVariableType(), AllowedTypeBits) ) - HandleBufUAV(BufUAV); + HandleBufUAV(BufUAV, n); } } + bool IsCompatibleWith(const ShaderResources &Resources)const; + + size_t GetHash()const; + protected: void Initialize(IMemoryAllocator &Allocator, Uint32 NumCBs, Uint32 NumTexSRVs, Uint32 NumTexUAVs, Uint32 NumBufSRVs, Uint32 NumBufUAVs, Uint32 NumSamplers); @@ -403,3 +421,24 @@ private: }; } + +namespace std +{ + template<> + struct hash<Diligent::D3DShaderResourceAttribs> + { + size_t operator()(const Diligent::D3DShaderResourceAttribs &Attribs) const + { + return Attribs.GetHash(); + } + }; + + template<> + struct hash<Diligent::ShaderResources> + { + size_t operator()(const Diligent::ShaderResources &Res) const + { + return Res.GetHash(); + } + }; +} diff --git a/Graphics/GraphicsEngineD3DBase/src/ShaderResources.cpp b/Graphics/GraphicsEngineD3DBase/src/ShaderResources.cpp index 6cedfa41..3d09b233 100644 --- a/Graphics/GraphicsEngineD3DBase/src/ShaderResources.cpp +++ b/Graphics/GraphicsEngineD3DBase/src/ShaderResources.cpp @@ -25,6 +25,7 @@ #include "EngineMemory.h" #include "StringTools.h" #include "ShaderResources.h" +#include "HashUtils.h" namespace Diligent { @@ -116,28 +117,28 @@ void ShaderResources::CountResources(const SHADER_VARIABLE_TYPE *AllowedVarTypes ProcessResources( AllowedVarTypes, NumAllowedTypes, - [&](const D3DShaderResourceAttribs &CB) + [&](const D3DShaderResourceAttribs &CB, Uint32) { VERIFY_EXPR(IsAllowedType(CB.GetVariableType(), AllowedTypeBits)); ++NumCBs; }, - [&](const D3DShaderResourceAttribs& TexSRV) + [&](const D3DShaderResourceAttribs& TexSRV, Uint32) { VERIFY_EXPR(IsAllowedType(TexSRV.GetVariableType(), AllowedTypeBits)); ++NumTexSRVs; NumSamplers += TexSRV.IsValidSampler() ? 1 : 0; }, - [&](const D3DShaderResourceAttribs &TexUAV) + [&](const D3DShaderResourceAttribs &TexUAV, Uint32) { VERIFY_EXPR(IsAllowedType(TexUAV.GetVariableType(), AllowedTypeBits)); ++NumTexUAVs; }, - [&](const D3DShaderResourceAttribs &BufSRV) + [&](const D3DShaderResourceAttribs &BufSRV, Uint32) { VERIFY_EXPR(IsAllowedType(BufSRV.GetVariableType(), AllowedTypeBits)); ++NumBufSRVs; }, - [&](const D3DShaderResourceAttribs &BufUAV) + [&](const D3DShaderResourceAttribs &BufUAV, Uint32) { VERIFY_EXPR(IsAllowedType(BufUAV.GetVariableType(), AllowedTypeBits)); ++NumBufUAVs; @@ -169,12 +170,12 @@ ShaderResources::ShaderResources(IMemoryAllocator &Allocator, ProcessResources( AllowedVarTypes, NumAllowedTypes, - [&](const D3DShaderResourceAttribs &CB) + [&](const D3DShaderResourceAttribs &CB, Uint32) { VERIFY_EXPR( IsAllowedType(CB.GetVariableType(), AllowedTypeBits) ); new (&GetCB(CurrCB++)) D3DShaderResourceAttribs(CB); }, - [&](const D3DShaderResourceAttribs& TexSRV) + [&](const D3DShaderResourceAttribs& TexSRV, Uint32) { VERIFY_EXPR(IsAllowedType(TexSRV.GetVariableType(), AllowedTypeBits)); @@ -187,17 +188,17 @@ ShaderResources::ShaderResources(IMemoryAllocator &Allocator, new (&GetTexSRV(CurrTexSRV++)) D3DShaderResourceAttribs(TexSRV, SamplerId); }, - [&](const D3DShaderResourceAttribs &TexUAV) + [&](const D3DShaderResourceAttribs &TexUAV, Uint32) { VERIFY_EXPR( IsAllowedType(TexUAV.GetVariableType(), AllowedTypeBits) ); new (&GetTexUAV(CurrTexUAV++)) D3DShaderResourceAttribs(TexUAV); }, - [&](const D3DShaderResourceAttribs &BufSRV) + [&](const D3DShaderResourceAttribs &BufSRV, Uint32) { VERIFY_EXPR( IsAllowedType(BufSRV.GetVariableType(), AllowedTypeBits) ); new (&GetBufSRV(CurrBufSRV++)) D3DShaderResourceAttribs(BufSRV); }, - [&](const D3DShaderResourceAttribs &BufUAV) + [&](const D3DShaderResourceAttribs &BufUAV, Uint32) { VERIFY_EXPR( IsAllowedType(BufUAV.GetVariableType(), AllowedTypeBits) ); new (&GetBufUAV(CurrBufUAV++)) D3DShaderResourceAttribs(BufUAV); @@ -229,4 +230,76 @@ Uint32 ShaderResources::FindAssignedSamplerId(const D3DShaderResourceAttribs& Te return D3DShaderResourceAttribs::InvalidSamplerId; } +bool ShaderResources::IsCompatibleWith(const ShaderResources &Res)const +{ + if (GetNumCBs() != Res.GetNumCBs() || + GetNumTexSRV() != Res.GetNumTexSRV() || + GetNumTexUAV() != Res.GetNumTexUAV() || + GetNumBufSRV() != Res.GetNumBufSRV() || + GetNumBufUAV() != Res.GetNumBufUAV()) + return false; + + bool IsCompatible = true; + ProcessResources( + nullptr, 0, + + [&](const D3DShaderResourceAttribs &CB, Uint32 n) + { + if(!CB.IsCompatibleWith(Res.GetCB(n))) + IsCompatible = false; + }, + [&](const D3DShaderResourceAttribs& TexSRV, Uint32 n) + { + if(!TexSRV.IsCompatibleWith(Res.GetTexSRV(n))) + IsCompatible = false; + }, + [&](const D3DShaderResourceAttribs &TexUAV, Uint32 n) + { + if(!TexUAV.IsCompatibleWith(Res.GetTexUAV(n))) + IsCompatible = false; + }, + [&](const D3DShaderResourceAttribs &BufSRV, Uint32 n) + { + if(!BufSRV.IsCompatibleWith(Res.GetBufSRV(n))) + IsCompatible = false; + }, + [&](const D3DShaderResourceAttribs &BufUAV, Uint32 n) + { + if(!BufUAV.IsCompatibleWith(Res.GetBufUAV(n))) + IsCompatible = false; + } + ); + return IsCompatible; +} + +size_t ShaderResources::GetHash()const +{ + size_t hash = ComputeHash(GetNumCBs(), GetNumTexSRV(), GetNumTexUAV(), GetNumBufSRV(), GetNumBufUAV()); + ProcessResources( + nullptr, 0, + [&](const D3DShaderResourceAttribs &CB, Uint32 n) + { + HashCombine(hash, CB); + }, + [&](const D3DShaderResourceAttribs& TexSRV, Uint32 n) + { + HashCombine(hash, TexSRV); + }, + [&](const D3DShaderResourceAttribs &TexUAV, Uint32 n) + { + HashCombine(hash, TexUAV); + }, + [&](const D3DShaderResourceAttribs &BufSRV, Uint32 n) + { + HashCombine(hash, BufSRV); + }, + [&](const D3DShaderResourceAttribs &BufUAV, Uint32 n) + { + HashCombine(hash, BufUAV); + } + ); + + return hash; +} + } diff --git a/Graphics/GraphicsEngineOpenGL/include/PipelineStateGLImpl.h b/Graphics/GraphicsEngineOpenGL/include/PipelineStateGLImpl.h index f7b6193c..c8c70731 100644 --- a/Graphics/GraphicsEngineOpenGL/include/PipelineStateGLImpl.h +++ b/Graphics/GraphicsEngineOpenGL/include/PipelineStateGLImpl.h @@ -51,6 +51,8 @@ public: virtual void CreateShaderResourceBinding( IShaderResourceBinding **ppShaderResourceBinding )override; + virtual bool IsCompatibleWith(const IPipelineState *pPSO)const override final; + GLProgram &GetGLProgram(){return m_GLProgram;} GLObjectWrappers::GLPipelineObj &GetGLProgramPipeline(GLContext::NativeGLContextType Context); diff --git a/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp index cd691f1f..7a0dfafc 100644 --- a/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp @@ -130,10 +130,9 @@ namespace Diligent void DeviceContextGLImpl::CommitShaderResources(IShaderResourceBinding *pShaderResourceBinding, Uint32 Flags) { - if(!DeviceContextBase::CommitShaderResources(pShaderResourceBinding, Flags, 0)) + if(!DeviceContextBase::CommitShaderResources<PipelineStateGLImpl>(pShaderResourceBinding, Flags, 0)) return; - if(m_CommitedResourcesTentativeBarriers != 0) LOG_INFO_MESSAGE("Not all tentative resource barriers have been executed since the last call to CommitShaderResources(). Did you forget to call Draw()/DispatchCompute() ?"); diff --git a/Graphics/GraphicsEngineOpenGL/src/PipelineStateGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/PipelineStateGLImpl.cpp index 360e21c0..90dbef39 100644 --- a/Graphics/GraphicsEngineOpenGL/src/PipelineStateGLImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/PipelineStateGLImpl.cpp @@ -155,6 +155,12 @@ void PipelineStateGLImpl::CreateShaderResourceBinding(IShaderResourceBinding **p pResBinding->QueryInterface(IID_ShaderResourceBinding, reinterpret_cast<IObject**>(ppShaderResourceBinding)); } +bool PipelineStateGLImpl::IsCompatibleWith(const IPipelineState *pPSO)const +{ + UNSUPPORTED("Not yet implemented"); + return false; +} + GLObjectWrappers::GLPipelineObj &PipelineStateGLImpl::GetGLProgramPipeline(GLContext::NativeGLContextType Context) { ThreadingTools::LockHelper Lock(m_ProgPipelineLockFlag); |
