summaryrefslogtreecommitdiffstats
path: root/Graphics/GraphicsEngine
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/GraphicsEngine
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/GraphicsEngine')
-rw-r--r--Graphics/GraphicsEngine/include/DeviceContextBase.h8
-rw-r--r--Graphics/GraphicsEngine/include/PipelineStateBase.h8
-rw-r--r--Graphics/GraphicsEngine/interface/PipelineState.h16
3 files changed, 29 insertions, 3 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;
};
}