From bbbf3434aefd105662f9efd4bf9e7d56f9e8170b Mon Sep 17 00:00:00 2001 From: Egor Yusov Date: Sun, 11 Mar 2018 12:07:09 -0700 Subject: Implemented PSO compatibility in D3D11 --- Graphics/GraphicsEngine/include/DeviceContextBase.h | 8 +++++--- Graphics/GraphicsEngine/include/PipelineStateBase.h | 8 ++++++++ Graphics/GraphicsEngine/interface/PipelineState.h | 16 ++++++++++++++++ 3 files changed, 29 insertions(+), 3 deletions(-) (limited to 'Graphics/GraphicsEngine') 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 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 :: SetPipelineState(IPipelineState } template +template inline bool DeviceContextBase :: CommitShaderResources(IShaderResourceBinding *pShaderResourceBinding, Uint32 Flags, int) { #ifdef _DEBUG @@ -260,10 +262,10 @@ inline bool DeviceContextBase :: CommitShaderResources(IShaderRes if (pShaderResourceBinding) { - auto *pPSO = pShaderResourceBinding->GetPipelineState(); - if (pPSO != m_pPipelineState) + auto *pPSOImpl = ValidatedCast(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(pPSO)->m_ShaderResourceLayoutHash; + } + protected: std::vector > m_LayoutElements; @@ -189,6 +196,7 @@ protected: RefCntAutoPtr 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; }; } -- cgit v1.2.3