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/GraphicsEngine | |
| 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/GraphicsEngine')
| -rw-r--r-- | Graphics/GraphicsEngine/include/DeviceContextBase.h | 8 | ||||
| -rw-r--r-- | Graphics/GraphicsEngine/include/PipelineStateBase.h | 8 | ||||
| -rw-r--r-- | Graphics/GraphicsEngine/interface/PipelineState.h | 16 |
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; }; } |
