diff options
| author | assiduous <assiduous@diligentgraphics.com> | 2021-03-18 22:05:18 +0000 |
|---|---|---|
| committer | assiduous <assiduous@diligentgraphics.com> | 2021-03-19 00:38:25 +0000 |
| commit | ef1e1c02e4f44b3a37c6bb683090b4f661aadcdc (patch) | |
| tree | ab1bc97327e4596d9486fb42f3e96474edc90097 /Graphics | |
| parent | Few updates to PipelineStateD3D11Impl (diff) | |
| download | DiligentCore-ef1e1c02e4f44b3a37c6bb683090b4f661aadcdc.tar.gz DiligentCore-ef1e1c02e4f44b3a37c6bb683090b4f661aadcdc.zip | |
Removed duplicate code from unbinding incompatible signatures logic in D3D11, GL and Vk
Diffstat (limited to 'Graphics')
4 files changed, 49 insertions, 78 deletions
diff --git a/Graphics/GraphicsEngine/include/DeviceContextBase.hpp b/Graphics/GraphicsEngine/include/DeviceContextBase.hpp index 769f8f01..1e791845 100644 --- a/Graphics/GraphicsEngine/include/DeviceContextBase.hpp +++ b/Graphics/GraphicsEngine/include/DeviceContextBase.hpp @@ -105,18 +105,19 @@ template <typename EngineImplTraits> class DeviceContextBase : public ObjectBase<typename EngineImplTraits::DeviceContextInterface> { public: - using BaseInterface = typename EngineImplTraits::DeviceContextInterface; - using TObjectBase = ObjectBase<BaseInterface>; - using DeviceImplType = typename EngineImplTraits::RenderDeviceImplType; - using BufferImplType = typename EngineImplTraits::BufferImplType; - using TextureImplType = typename EngineImplTraits::TextureImplType; - using PipelineStateImplType = typename EngineImplTraits::PipelineStateImplType; - using TextureViewImplType = typename EngineImplTraits::TextureViewImplType; - using QueryImplType = typename EngineImplTraits::QueryImplType; - using FramebufferImplType = typename EngineImplTraits::FramebufferImplType; - using RenderPassImplType = typename EngineImplTraits::RenderPassImplType; - using BottomLevelASType = typename EngineImplTraits::BottomLevelASImplType; - using TopLevelASType = typename EngineImplTraits::TopLevelASImplType; + using BaseInterface = typename EngineImplTraits::DeviceContextInterface; + using TObjectBase = ObjectBase<BaseInterface>; + using DeviceImplType = typename EngineImplTraits::RenderDeviceImplType; + using BufferImplType = typename EngineImplTraits::BufferImplType; + using TextureImplType = typename EngineImplTraits::TextureImplType; + using PipelineStateImplType = typename EngineImplTraits::PipelineStateImplType; + using ShaderResourceBindingImplType = typename EngineImplTraits::ShaderResourceBindingImplType; + using TextureViewImplType = typename EngineImplTraits::TextureViewImplType; + using QueryImplType = typename EngineImplTraits::QueryImplType; + using FramebufferImplType = typename EngineImplTraits::FramebufferImplType; + using RenderPassImplType = typename EngineImplTraits::RenderPassImplType; + using BottomLevelASType = typename EngineImplTraits::BottomLevelASImplType; + using TopLevelASType = typename EngineImplTraits::TopLevelASImplType; /// \param pRefCounters - Reference counters object that controls the lifetime of this device context. /// \param pRenderDevice - Render device. @@ -311,6 +312,8 @@ protected: bool DvpVerifyBufferState (const BufferImplType& Buffer, RESOURCE_STATE RequiredState, const char* OperationName) const; bool DvpVerifyBLASState (const BottomLevelASType& BLAS, RESOURCE_STATE RequiredState, const char* OperationName) const; bool DvpVerifyTLASState (const TopLevelASType& TLAS, RESOURCE_STATE RequiredState, const char* OperationName) const; + + Uint32 DvpGetCompatibleSignatureCount(ShaderResourceBindingImplType* pBoundSRBs[])const; #else bool DvpVerifyDrawArguments (const DrawAttribs& Attribs)const {return true;} bool DvpVerifyDrawIndexedArguments (const DrawIndexedAttribs& Attribs)const {return true;} @@ -2121,6 +2124,34 @@ bool DeviceContextBase<ImplementationTraits>::DvpVerifyTLASState( return true; } +template <typename ImplementationTraits> +Uint32 DeviceContextBase<ImplementationTraits>::DvpGetCompatibleSignatureCount(ShaderResourceBindingImplType* pBoundSRBs[]) const +{ + VERIFY_EXPR(m_pPipelineState); + const auto SignCount = m_pPipelineState->GetResourceSignatureCount(); + + Uint32 sign = 0; + for (; sign < SignCount; ++sign) + { + const auto* pPSOSign = m_pPipelineState->GetResourceSignature(sign); + const auto* pSRBSign = pBoundSRBs[sign] != nullptr ? pBoundSRBs[sign]->GetSignature() : nullptr; + + if ((pPSOSign == nullptr || pPSOSign->IsEmpty()) != (pSRBSign == nullptr || pSRBSign->IsEmpty())) + { + // One signature is null or empty while the other is not - SRB is not compatible with the PSO. + break; + } + + if (pPSOSign != nullptr && pSRBSign != nullptr && pPSOSign->IsIncompatibleWith(*pSRBSign)) + { + // Signatures are incompatible + break; + } + } + + return sign; +} + #endif // DILIGENT_DEVELOPMENT } // namespace Diligent diff --git a/Graphics/GraphicsEngineD3D11/src/DeviceContextD3D11Impl.cpp b/Graphics/GraphicsEngineD3D11/src/DeviceContextD3D11Impl.cpp index 7524bdd7..c44a80dc 100755 --- a/Graphics/GraphicsEngineD3D11/src/DeviceContextD3D11Impl.cpp +++ b/Graphics/GraphicsEngineD3D11/src/DeviceContextD3D11Impl.cpp @@ -154,29 +154,9 @@ void DeviceContextD3D11Impl::SetPipelineState(IPipelineState* pPipelineState) } #ifdef DILIGENT_DEVELOPMENT - // Find the first incompatible shader resource bindings - Uint32 sign = 0; - for (; sign < SignCount; ++sign) - { - const auto* pLayoutSign = m_pPipelineState->GetResourceSignature(sign); - const auto* pSRBSign = m_BindInfo.SRBs[sign] != nullptr ? m_BindInfo.SRBs[sign]->GetSignature() : nullptr; - - if ((pLayoutSign == nullptr || pLayoutSign->GetTotalResourceCount() == 0) != (pSRBSign == nullptr || pSRBSign->GetTotalResourceCount() == 0)) - { - // One signature is null or empty while the other is not - SRB is not compatible with the layout. - break; - } - - if (pLayoutSign != nullptr && pSRBSign != nullptr && pLayoutSign->IsIncompatibleWith(*pSRBSign)) - { - // Signatures are incompatible - break; - } - } - // Unbind incompatible SRB and SRB with a higher binding index. // This is the same behavior that used in Vulkan backend. - for (; sign < SignCount; ++sign) + for (auto sign = DvpGetCompatibleSignatureCount(m_BindInfo.SRBs.data()); sign < SignCount; ++sign) { m_BindInfo.SRBs[sign] = nullptr; m_BindInfo.ClearStaleSRBBit(sign); @@ -191,9 +171,9 @@ void DeviceContextD3D11Impl::SetPipelineState(IPipelineState* pPipelineState) /// Helper macro used to create an array of device context methods to /// set particular resource for every shader stage #define DEFINE_D3D11CTX_FUNC_POINTERS(ArrayName, FuncName) \ - typedef decltype (&ID3D11DeviceContext::VS##FuncName) T##FuncName##Type; \ - static const T##FuncName##Type ArrayName[] = \ - { \ + using T##FuncName##Type = decltype (&ID3D11DeviceContext::VS##FuncName); \ + static const T##FuncName##Type ArrayName[] = \ + { \ &ID3D11DeviceContext::VS##FuncName, \ &ID3D11DeviceContext::PS##FuncName, \ &ID3D11DeviceContext::GS##FuncName, \ diff --git a/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp index 1bff455e..4895efc0 100644 --- a/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp @@ -169,29 +169,9 @@ void DeviceContextGLImpl::SetPipelineState(IPipelineState* pPipelineState) } #ifdef DILIGENT_DEVELOPMENT - // Find the first incompatible shader resource bindings - Uint32 sign = 0; - for (; sign < SignCount; ++sign) - { - const auto* pLayoutSign = m_pPipelineState->GetResourceSignature(sign); - const auto* pSRBSign = m_BindInfo.SRBs[sign] != nullptr ? m_BindInfo.SRBs[sign]->GetSignature() : nullptr; - - if ((pLayoutSign == nullptr || pLayoutSign->GetTotalResourceCount() == 0) != (pSRBSign == nullptr || pSRBSign->GetTotalResourceCount() == 0)) - { - // One signature is null or empty while the other is not - SRB is not compatible with the layout. - break; - } - - if (pLayoutSign != nullptr && pSRBSign != nullptr && pLayoutSign->IsIncompatibleWith(*pSRBSign)) - { - // Signatures are incompatible - break; - } - } - // Unbind incompatible SRB and SRB with a higher binding index. // This is the same behavior that used in Vulkan backend. - for (; sign < SignCount; ++sign) + for (auto sign = DvpGetCompatibleSignatureCount(m_BindInfo.SRBs.data()); sign < SignCount; ++sign) { m_BindInfo.SRBs[sign] = nullptr; m_BindInfo.ClearStaleSRBBit(sign); diff --git a/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp index 40cab0ad..32f68f9d 100644 --- a/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp @@ -348,31 +348,11 @@ void DeviceContextVkImpl::SetPipelineState(IPipelineState* pPipelineState) // (14.2.2. Pipeline Layouts, clause 'Pipeline Layout Compatibility') // https://www.khronos.org/registry/vulkan/specs/1.2-extensions/html/vkspec.html#descriptorsets-compatibility - // Find the first incompatible shader resource bindings - Uint32 sign = 0; - for (; sign < SignCount; ++sign) - { - const auto* pLayoutSign = pPipelineStateVk->GetResourceSignature(sign); - const auto* pSRBSign = BindInfo.SRBs[sign] != nullptr ? BindInfo.SRBs[sign]->GetSignature() : nullptr; - - if ((pLayoutSign == nullptr || pLayoutSign->GetNumDescriptorSets() == 0) != (pSRBSign == nullptr || pSRBSign->GetNumDescriptorSets() == 0)) - { - // One signature is null or empty while the other is not - SRB is not compatible with the layout. - break; - } - - if (pLayoutSign != nullptr && pSRBSign != nullptr && pLayoutSign->IsIncompatibleWith(*pSRBSign)) - { - // Signatures are incompatible - break; - } - } - // Unbind incompatible shader resources // A consequence of layout compatibility is that when the implementation compiles a pipeline // layout and maps pipeline resources to implementation resources, the mechanism for set N // should only be a function of sets [0..N]. - for (; sign < SignCount; ++sign) + for (auto sign = DvpGetCompatibleSignatureCount(BindInfo.SRBs.data()); sign < SignCount; ++sign) { BindInfo.SRBs[sign] = nullptr; |
