summaryrefslogtreecommitdiffstats
path: root/Graphics
diff options
context:
space:
mode:
authorEgor Yusov <egor.yusov@gmail.com>2018-03-11 19:07:09 +0000
committerEgor Yusov <egor.yusov@gmail.com>2018-03-11 19:07:09 +0000
commitbbbf3434aefd105662f9efd4bf9e7d56f9e8170b (patch)
tree42806921a62dcc82b4925927d52e9f453048e959 /Graphics
parentEnabled full optimization (/Ox) for windows release builds (diff)
downloadDiligentCore-bbbf3434aefd105662f9efd4bf9e7d56f9e8170b.tar.gz
DiligentCore-bbbf3434aefd105662f9efd4bf9e7d56f9e8170b.zip
Implemented PSO compatibility in D3D11
Diffstat (limited to 'Graphics')
-rw-r--r--Graphics/GraphicsEngine/include/DeviceContextBase.h8
-rw-r--r--Graphics/GraphicsEngine/include/PipelineStateBase.h8
-rw-r--r--Graphics/GraphicsEngine/interface/PipelineState.h16
-rw-r--r--Graphics/GraphicsEngineD3D11/include/PipelineStateD3D11Impl.h2
-rw-r--r--Graphics/GraphicsEngineD3D11/src/DeviceContextD3D11Impl.cpp4
-rw-r--r--Graphics/GraphicsEngineD3D11/src/PipelineStateD3D11Impl.cpp40
-rw-r--r--Graphics/GraphicsEngineD3D11/src/ShaderResourceLayoutD3D11.cpp10
-rw-r--r--Graphics/GraphicsEngineD3D11/src/ShaderResourcesD3D11.cpp10
-rw-r--r--Graphics/GraphicsEngineD3D12/include/PipelineStateD3D12Impl.h2
-rw-r--r--Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp7
-rw-r--r--Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp6
-rw-r--r--Graphics/GraphicsEngineD3D12/src/ShaderResourceLayoutD3D12.cpp20
-rw-r--r--Graphics/GraphicsEngineD3DBase/include/ShaderResources.h49
-rw-r--r--Graphics/GraphicsEngineD3DBase/src/ShaderResources.cpp93
-rw-r--r--Graphics/GraphicsEngineOpenGL/include/PipelineStateGLImpl.h2
-rw-r--r--Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp3
-rw-r--r--Graphics/GraphicsEngineOpenGL/src/PipelineStateGLImpl.cpp6
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);