From 84d8fedc201a66835f5c234160bda63bbc40f682 Mon Sep 17 00:00:00 2001 From: Egor Yusov Date: Fri, 23 Nov 2018 16:07:34 -0800 Subject: Added IShaderResourceBinding::InitializeStaticResources() method to allow explicit initialization of static shader resources in a SRB --- Graphics/GraphicsEngine/interface/PipelineState.h | 5 +++- .../interface/ShaderResourceBinding.h | 20 ++++++++++++- .../include/PipelineStateD3D11Impl.h | 2 +- .../include/ShaderResourceBindingD3D11Impl.h | 3 +- .../src/DeviceContextD3D11Impl.cpp | 13 ++++++--- .../src/PipelineStateD3D11Impl.cpp | 5 +++- .../src/ShaderResourceBindingD3D11Impl.cpp | 15 ++++++++-- .../include/PipelineStateD3D12Impl.h | 2 +- .../include/ShaderResourceBindingD3D12Impl.h | 3 +- .../src/PipelineStateD3D12Impl.cpp | 15 ++++++---- Graphics/GraphicsEngineD3D12/src/RootSignature.cpp | 18 ++++++------ .../src/ShaderResourceBindingD3D12Impl.cpp | 25 ++++++++++++---- .../include/PipelineStateGLImpl.h | 2 +- .../include/ShaderResourceBindingGLImpl.h | 2 ++ .../src/PipelineStateGLImpl.cpp | 4 ++- .../src/ShaderResourceBindingGLImpl.cpp | 5 ++++ .../GraphicsEngineVulkan/include/PipelineLayout.h | 14 ++++----- .../include/PipelineStateVkImpl.h | 2 +- .../include/ShaderResourceBindingVkImpl.h | 7 +++-- .../include/ShaderResourceLayoutVk.h | 2 +- .../GraphicsEngineVulkan/include/ShaderVkImpl.h | 6 ++-- .../GraphicsEngineVulkan/src/PipelineLayout.cpp | 10 +++---- .../src/PipelineStateVkImpl.cpp | 26 ++++++----------- .../src/ShaderResourceBindingVkImpl.cpp | 33 ++++++++++++++++++++++ .../src/ShaderResourceCacheVk.cpp | 16 +++++------ .../src/ShaderResourceLayoutVk.cpp | 6 ++-- Graphics/GraphicsEngineVulkan/src/ShaderVkImpl.cpp | 2 +- 27 files changed, 179 insertions(+), 84 deletions(-) (limited to 'Graphics') diff --git a/Graphics/GraphicsEngine/interface/PipelineState.h b/Graphics/GraphicsEngine/interface/PipelineState.h index ca12dda4..2169eefb 100644 --- a/Graphics/GraphicsEngine/interface/PipelineState.h +++ b/Graphics/GraphicsEngine/interface/PipelineState.h @@ -190,7 +190,10 @@ public: /// \param [out] ppShaderResourceBinding - memory location where pointer to the new shader resource /// binding object is written. - virtual void CreateShaderResourceBinding( IShaderResourceBinding **ppShaderResourceBinding ) = 0; + /// \param [in] InitStaticResources - if set to true, the method will initialize static resources in + /// the created object, which has the exact same effect as calling + /// IShaderResourceBinding::InitializeStaticResources(). + virtual void CreateShaderResourceBinding( IShaderResourceBinding **ppShaderResourceBinding, bool InitStaticResources = false ) = 0; /// Checks if this pipeline state object is compatible with another PSO diff --git a/Graphics/GraphicsEngine/interface/ShaderResourceBinding.h b/Graphics/GraphicsEngine/interface/ShaderResourceBinding.h index 2c177926..9b71f06c 100644 --- a/Graphics/GraphicsEngine/interface/ShaderResourceBinding.h +++ b/Graphics/GraphicsEngine/interface/ShaderResourceBinding.h @@ -58,7 +58,7 @@ public: /// Any combination of Diligent::SHADER_TYPE may be specified. /// \param [in] pResMapping - Shader resource mapping, where required resources will be looked up /// \param [in] Flags - Additional flags. See Diligent::BIND_SHADER_RESOURCES_FLAGS. - virtual void BindResources(Uint32 ShaderFlags, IResourceMapping *pResMapping, Uint32 Flags) = 0; + virtual void BindResources(Uint32 ShaderFlags, IResourceMapping* pResMapping, Uint32 Flags) = 0; /// Returns variable @@ -84,6 +84,24 @@ public: /// \remark Only mutable and dynamic variables can be accessed through this method. /// Static variables are accessed through the Shader object. virtual IShaderVariable* GetVariable(SHADER_TYPE ShaderType, Uint32 Index) = 0; + + + /// Initializes static resources + + /// If shaders in the pipeline state contain static resources + /// (see Diligent::SHADER_VARIABLE_TYPE_STATIC), this method must be called + /// once to initialize static resources in this shader resource binding object. + /// The method must be called after all static variables are initialized + /// in the shaders. + /// \param [in] pPipelineState - Pipeline state to copy static shader resource + /// bindings from. The pipeline state must be compatible + /// with this shader resource binding object. + /// If null pointer is provided, the pipeline state + /// that this SRB object was created from is used. + /// \note The method must be called exactly once. If static resources have + /// already been initialized and the method is called again, it will have + /// no effect and a warning messge will be displayed. + virtual void InitializeStaticResources(const IPipelineState* pPipelineState = nullptr) = 0; }; } diff --git a/Graphics/GraphicsEngineD3D11/include/PipelineStateD3D11Impl.h b/Graphics/GraphicsEngineD3D11/include/PipelineStateD3D11Impl.h index 2ea2d8da..4d3776c8 100644 --- a/Graphics/GraphicsEngineD3D11/include/PipelineStateD3D11Impl.h +++ b/Graphics/GraphicsEngineD3D11/include/PipelineStateD3D11Impl.h @@ -68,7 +68,7 @@ public: virtual ID3D11HullShader* GetD3D11HullShader()override final; virtual ID3D11ComputeShader* GetD3D11ComputeShader()override final; - virtual void CreateShaderResourceBinding( IShaderResourceBinding **ppShaderResourceBinding )override final; + virtual void CreateShaderResourceBinding( IShaderResourceBinding **ppShaderResourceBinding, bool InitStaticResources )override final; virtual bool IsCompatibleWith(const IPipelineState *pPSO)const override final; diff --git a/Graphics/GraphicsEngineD3D11/include/ShaderResourceBindingD3D11Impl.h b/Graphics/GraphicsEngineD3D11/include/ShaderResourceBindingD3D11Impl.h index 479ec282..9c6c354d 100755 --- a/Graphics/GraphicsEngineD3D11/include/ShaderResourceBindingD3D11Impl.h +++ b/Graphics/GraphicsEngineD3D11/include/ShaderResourceBindingD3D11Impl.h @@ -58,10 +58,11 @@ public: virtual IShaderVariable* GetVariable(SHADER_TYPE ShaderType, Uint32 Index)override final; + virtual void InitializeStaticResources(const IPipelineState* pPipelineState)override final; + ShaderResourceCacheD3D11& GetResourceCache (Uint32 Ind){VERIFY_EXPR(Ind < m_NumActiveShaders); return m_pBoundResourceCaches[Ind];} ShaderResourceLayoutD3D11& GetResourceLayout(Uint32 Ind){VERIFY_EXPR(Ind < m_NumActiveShaders); return m_pResourceLayouts[Ind];} - void BindStaticShaderResources(); inline bool IsStaticResourcesBound(){return m_bIsStaticResourcesBound;} Uint32 GetNumActiveShaders() diff --git a/Graphics/GraphicsEngineD3D11/src/DeviceContextD3D11Impl.cpp b/Graphics/GraphicsEngineD3D11/src/DeviceContextD3D11Impl.cpp index 3456ee47..f64409cc 100755 --- a/Graphics/GraphicsEngineD3D11/src/DeviceContextD3D11Impl.cpp +++ b/Graphics/GraphicsEngineD3D11/src/DeviceContextD3D11Impl.cpp @@ -175,17 +175,22 @@ namespace Diligent } #endif - if(!pShaderResBindingD3D11->IsStaticResourcesBound()) - pShaderResBindingD3D11->BindStaticShaderResources(); - auto NumShaders = pShaderResBindingD3D11->GetNumActiveShaders(); VERIFY(NumShaders == pdbgPipelineStateD3D11->GetNumShaders(), "Number of active shaders in shader resource binding is not consistent with the number of shaders in the pipeline state"); #ifdef DEVELOPMENT + bool StaticResourcesPresent = false; for (Uint32 s = 0; s < NumShaders; ++s) { pShaderResBindingD3D11->GetResourceLayout(s).dvpVerifyBindings(); // Static resource bindings are verified in BindStaticShaderResources() + auto* pShaderD3D11 = ValidatedCast(ppdbgShaders[s]); + if (pShaderD3D11->GetStaticResourceLayout().GetTotalResourceCount() > 0) + StaticResourcesPresent = true; + } + if (StaticResourcesPresent && !pShaderResBindingD3D11->IsStaticResourcesBound()) + { + LOG_ERROR_MESSAGE("Static resources have not been initialized in the shader resource binding object. Please call IShaderResourceBinding::InitializeStaticResources()."); } #endif @@ -767,7 +772,7 @@ namespace Diligent auto* pd3d11InputLayout = m_pPipelineState->GetD3D11InputLayout(); if (pd3d11InputLayout != nullptr && !m_bCommittedD3D11VBsUpToDate) { - VERIFY( m_NumVertexStreams >= m_pPipelineState->GetNumBufferSlotsUsed(), "Currently bound pipeline state '", m_pPipelineState->GetDesc().Name, "' expects ", m_pPipelineState->GetNumBufferSlotsUsed(), " input buffer slots, but only ", m_NumVertexStreams, " is bound"); + DEV_CHECK_ERR( m_NumVertexStreams >= m_pPipelineState->GetNumBufferSlotsUsed(), "Currently bound pipeline state '", m_pPipelineState->GetDesc().Name, "' expects ", m_pPipelineState->GetNumBufferSlotsUsed(), " input buffer slots, but only ", m_NumVertexStreams, " is bound"); CommitD3D11VertexBuffers(m_pPipelineState, drawAttribs.Flags & DRAW_FLAG_TRANSITION_VERTEX_BUFFERS); } diff --git a/Graphics/GraphicsEngineD3D11/src/PipelineStateD3D11Impl.cpp b/Graphics/GraphicsEngineD3D11/src/PipelineStateD3D11Impl.cpp index d61c85e1..f3a37ddc 100644 --- a/Graphics/GraphicsEngineD3D11/src/PipelineStateD3D11Impl.cpp +++ b/Graphics/GraphicsEngineD3D11/src/PipelineStateD3D11Impl.cpp @@ -129,6 +129,7 @@ PipelineStateD3D11Impl::PipelineStateD3D11Impl(IReferenceCounters* pRefCoun auto &SRBAllocator = pRenderDeviceD3D11->GetSRBAllocator(); m_pDefaultShaderResBinding.reset( NEW_RC_OBJ(SRBAllocator, "ShaderResourceBindingD3D11Impl instance", ShaderResourceBindingD3D11Impl, this)(this, true) ); + m_pDefaultShaderResBinding->InitializeStaticResources(nullptr); } @@ -159,11 +160,13 @@ ID3D11InputLayout* PipelineStateD3D11Impl::GetD3D11InputLayout() return m_pd3d11InputLayout; } -void PipelineStateD3D11Impl::CreateShaderResourceBinding(IShaderResourceBinding** ppShaderResourceBinding) +void PipelineStateD3D11Impl::CreateShaderResourceBinding(IShaderResourceBinding** ppShaderResourceBinding, bool InitStaticResources) { auto* pRenderDeviceD3D11 = ValidatedCast( GetDevice() ); auto &SRBAllocator = pRenderDeviceD3D11->GetSRBAllocator(); auto pShaderResBinding = NEW_RC_OBJ(SRBAllocator, "ShaderResourceBindingD3D11Impl instance", ShaderResourceBindingD3D11Impl)(this, false); + if (InitStaticResources) + pShaderResBinding->InitializeStaticResources(nullptr); pShaderResBinding->QueryInterface(IID_ShaderResourceBinding, reinterpret_cast(static_cast(ppShaderResourceBinding))); } diff --git a/Graphics/GraphicsEngineD3D11/src/ShaderResourceBindingD3D11Impl.cpp b/Graphics/GraphicsEngineD3D11/src/ShaderResourceBindingD3D11Impl.cpp index 83f0dac1..f63e64f0 100644 --- a/Graphics/GraphicsEngineD3D11/src/ShaderResourceBindingD3D11Impl.cpp +++ b/Graphics/GraphicsEngineD3D11/src/ShaderResourceBindingD3D11Impl.cpp @@ -111,15 +111,24 @@ void ShaderResourceBindingD3D11Impl::BindResources(Uint32 ShaderFlags, IResource } } -void ShaderResourceBindingD3D11Impl::BindStaticShaderResources() +void ShaderResourceBindingD3D11Impl::InitializeStaticResources(const IPipelineState* pPipelineState) { if (m_bIsStaticResourcesBound) { - LOG_ERROR("Static resources already bound"); + LOG_WARNING_MESSAGE("Static resources have already been initialized in this shader resource binding object. The operation will be ignored."); return; } - auto *pPSOD3D11 = ValidatedCast(GetPipelineState()); + if (pPipelineState == nullptr) + { + pPipelineState = GetPipelineState(); + } + else + { + DEV_CHECK_ERR(pPipelineState->IsCompatibleWith(GetPipelineState()), "The pipeline state is not compatible with this SRB"); + } + + const auto *pPSOD3D11 = ValidatedCast(pPipelineState); auto ppShaders = pPSOD3D11->GetShaders(); auto NumShaders = pPSOD3D11->GetNumShaders(); VERIFY_EXPR(NumShaders == m_NumActiveShaders); diff --git a/Graphics/GraphicsEngineD3D12/include/PipelineStateD3D12Impl.h b/Graphics/GraphicsEngineD3D12/include/PipelineStateD3D12Impl.h index a0f9ab76..0ecda4a1 100644 --- a/Graphics/GraphicsEngineD3D12/include/PipelineStateD3D12Impl.h +++ b/Graphics/GraphicsEngineD3D12/include/PipelineStateD3D12Impl.h @@ -51,7 +51,7 @@ public: virtual ID3D12PipelineState *GetD3D12PipelineState()const override final{return m_pd3d12PSO;} - virtual void CreateShaderResourceBinding( IShaderResourceBinding **ppShaderResourceBinding )override final; + virtual void CreateShaderResourceBinding( IShaderResourceBinding **ppShaderResourceBinding, bool InitStaticResources )override final; virtual bool IsCompatibleWith(const IPipelineState *pPSO)const override final; diff --git a/Graphics/GraphicsEngineD3D12/include/ShaderResourceBindingD3D12Impl.h b/Graphics/GraphicsEngineD3D12/include/ShaderResourceBindingD3D12Impl.h index 5a237414..2685dde2 100644 --- a/Graphics/GraphicsEngineD3D12/include/ShaderResourceBindingD3D12Impl.h +++ b/Graphics/GraphicsEngineD3D12/include/ShaderResourceBindingD3D12Impl.h @@ -58,6 +58,8 @@ public: virtual Uint32 GetVariableCount(SHADER_TYPE ShaderType) const override final; virtual IShaderVariable* GetVariable(SHADER_TYPE ShaderType, Uint32 Index)override final; + + virtual void InitializeStaticResources(const IPipelineState* pPipelineState)override final; ShaderResourceCacheD3D12& GetResourceCache(){return m_ShaderResourceCache;} @@ -66,7 +68,6 @@ public: #endif bool StaticResourcesInitialized()const{return m_bStaticResourcesInitialized;} - void InitializeStaticResources(const PipelineStateD3D12Impl* pPSO); private: diff --git a/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp index 85d8ee0a..8fc17cb2 100644 --- a/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp @@ -224,6 +224,7 @@ PipelineStateD3D12Impl :: PipelineStateD3D12Impl(IReferenceCounters* pRefCo auto& SRBAllocator = pDeviceD3D12->GetSRBAllocator(); // Default shader resource binding must be initialized after resource layouts are parsed! m_pDefaultShaderResBinding.reset( NEW_RC_OBJ(SRBAllocator, "ShaderResourceBindingD3D12Impl instance", ShaderResourceBindingD3D12Impl, this)(this, true) ); + m_pDefaultShaderResBinding->InitializeStaticResources(this); } m_ShaderResourceLayoutHash = m_RootSig.GetHash(); @@ -245,10 +246,12 @@ PipelineStateD3D12Impl::~PipelineStateD3D12Impl() IMPLEMENT_QUERY_INTERFACE( PipelineStateD3D12Impl, IID_PipelineStateD3D12, TPipelineStateBase ) -void PipelineStateD3D12Impl::CreateShaderResourceBinding(IShaderResourceBinding** ppShaderResourceBinding) +void PipelineStateD3D12Impl::CreateShaderResourceBinding(IShaderResourceBinding** ppShaderResourceBinding, bool InitStaticResources ) { auto& SRBAllocator = m_pDevice->GetSRBAllocator(); auto pResBindingD3D12 = NEW_RC_OBJ(SRBAllocator, "ShaderResourceBindingD3D12Impl instance", ShaderResourceBindingD3D12Impl)(this, false); + if (InitStaticResources) + pResBindingD3D12->InitializeStaticResources(nullptr); pResBindingD3D12->QueryInterface(IID_ShaderResourceBinding, reinterpret_cast(ppShaderResourceBinding)); } @@ -341,13 +344,13 @@ ShaderResourceCacheD3D12* PipelineStateD3D12Impl::CommitAndTransitionShaderResou return nullptr; } } -#endif - // First time only, copy static shader resources to the cache - if(!pResBindingD3D12Impl->StaticResourcesInitialized()) - pResBindingD3D12Impl->InitializeStaticResources(this); + if( (m_RootSig.GetTotalSrvCbvUavSlots(SHADER_VARIABLE_TYPE_STATIC) != 0 || + m_RootSig.GetTotalRootViews(SHADER_VARIABLE_TYPE_STATIC) != 0) && !pResBindingD3D12Impl->StaticResourcesInitialized() ) + { + LOG_ERROR_MESSAGE("Static resources have not been initialized in the shader resource binding object. Please call IShaderResourceBinding::InitializeStaticResources()."); + } -#ifdef DEVELOPMENT pResBindingD3D12Impl->dvpVerifyResourceBindings(this); #endif diff --git a/Graphics/GraphicsEngineD3D12/src/RootSignature.cpp b/Graphics/GraphicsEngineD3D12/src/RootSignature.cpp index d874d45e..67369355 100644 --- a/Graphics/GraphicsEngineD3D12/src/RootSignature.cpp +++ b/Graphics/GraphicsEngineD3D12/src/RootSignature.cpp @@ -1055,15 +1055,17 @@ void RootSignature::CommitRootViews(ShaderResourceCacheD3D12& ResourceCache, #endif auto& Res = ResourceCache.GetRootTable(RootInd).GetResource(0, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, dbgShaderType); - auto *pBuffToTransition = Res.pObject.RawPtr(); - if (pBuffToTransition->IsInKnownState() && !pBuffToTransition->CheckState(RESOURCE_STATE_CONSTANT_BUFFER) ) - Ctx.TransitionResource(pBuffToTransition, RESOURCE_STATE_CONSTANT_BUFFER); + if (auto* pBuffToTransition = Res.pObject.RawPtr()) + { + if (pBuffToTransition->IsInKnownState() && !pBuffToTransition->CheckState(RESOURCE_STATE_CONSTANT_BUFFER) ) + Ctx.TransitionResource(pBuffToTransition, RESOURCE_STATE_CONSTANT_BUFFER); - D3D12_GPU_VIRTUAL_ADDRESS CBVAddress = pBuffToTransition->GetGPUAddress(pCtx); - if(IsCompute) - Ctx.GetCommandList()->SetComputeRootConstantBufferView(RootInd, CBVAddress); - else - Ctx.GetCommandList()->SetGraphicsRootConstantBufferView(RootInd, CBVAddress); + D3D12_GPU_VIRTUAL_ADDRESS CBVAddress = pBuffToTransition->GetGPUAddress(pCtx); + if(IsCompute) + Ctx.GetCommandList()->SetComputeRootConstantBufferView(RootInd, CBVAddress); + else + Ctx.GetCommandList()->SetGraphicsRootConstantBufferView(RootInd, CBVAddress); + } } } diff --git a/Graphics/GraphicsEngineD3D12/src/ShaderResourceBindingD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/ShaderResourceBindingD3D12Impl.cpp index cec03f11..ff569364 100644 --- a/Graphics/GraphicsEngineD3D12/src/ShaderResourceBindingD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/ShaderResourceBindingD3D12Impl.cpp @@ -154,13 +154,26 @@ void ShaderResourceBindingD3D12Impl::dvpVerifyResourceBindings(const PipelineSta #endif -void ShaderResourceBindingD3D12Impl::InitializeStaticResources(const PipelineStateD3D12Impl* pPSO) +void ShaderResourceBindingD3D12Impl::InitializeStaticResources(const IPipelineState* pPSO) { - VERIFY(!StaticResourcesInitialized(), "Static resources have already been initialized"); - VERIFY(pPSO->IsCompatibleWith(GetPipelineState()), "Currently bound pipeline state is not compatible with this SRB"); + if (StaticResourcesInitialized()) + { + LOG_WARNING_MESSAGE("Static resources have already been initialized in this shader resource binding object. The operation will be ignored."); + return; + } + + if (pPSO == nullptr) + { + pPSO = GetPipelineState(); + } + else + { + DEV_CHECK_ERR(pPSO->IsCompatibleWith(GetPipelineState()), "The pipeline state is not compatible with this SRB"); + } - auto NumShaders = pPSO->GetNumShaders(); - auto ppShaders = pPSO->GetShaders(); + auto* pPSO12 = ValidatedCast(pPSO); + auto NumShaders = pPSO12->GetNumShaders(); + auto ppShaders = pPSO12->GetShaders(); // Copy static resources for (Uint32 s = 0; s < NumShaders; ++s) { @@ -168,7 +181,7 @@ void ShaderResourceBindingD3D12Impl::InitializeStaticResources(const PipelineSta #ifdef DEVELOPMENT pShader->DvpVerifyStaticResourceBindings(); #endif - const auto& ShaderResLayout = pPSO->GetShaderResLayout(s); + const auto& ShaderResLayout = pPSO12->GetShaderResLayout(s); auto& StaticResLayout = pShader->GetStaticResLayout(); auto& StaticResCache = pShader->GetStaticResCache(); StaticResLayout.CopyStaticResourceDesriptorHandles(StaticResCache, ShaderResLayout, m_ShaderResourceCache); diff --git a/Graphics/GraphicsEngineOpenGL/include/PipelineStateGLImpl.h b/Graphics/GraphicsEngineOpenGL/include/PipelineStateGLImpl.h index c6f54964..6e03df2e 100644 --- a/Graphics/GraphicsEngineOpenGL/include/PipelineStateGLImpl.h +++ b/Graphics/GraphicsEngineOpenGL/include/PipelineStateGLImpl.h @@ -50,7 +50,7 @@ public: virtual void BindShaderResources( IResourceMapping *pResourceMapping, Uint32 Flags )override final; - virtual void CreateShaderResourceBinding( IShaderResourceBinding **ppShaderResourceBinding )override final; + virtual void CreateShaderResourceBinding( IShaderResourceBinding **ppShaderResourceBinding, bool InitStaticResources )override final; virtual bool IsCompatibleWith(const IPipelineState *pPSO)const override final; diff --git a/Graphics/GraphicsEngineOpenGL/include/ShaderResourceBindingGLImpl.h b/Graphics/GraphicsEngineOpenGL/include/ShaderResourceBindingGLImpl.h index 6500ad29..02193dd9 100644 --- a/Graphics/GraphicsEngineOpenGL/include/ShaderResourceBindingGLImpl.h +++ b/Graphics/GraphicsEngineOpenGL/include/ShaderResourceBindingGLImpl.h @@ -55,6 +55,8 @@ public: virtual IShaderVariable* GetVariable(SHADER_TYPE ShaderType, Uint32 Index)override final; + virtual void InitializeStaticResources(const IPipelineState* pPipelineState)override final; + GLProgramResources &GetProgramResources(SHADER_TYPE ShaderType, PipelineStateGLImpl *pdbgPSO); private: diff --git a/Graphics/GraphicsEngineOpenGL/src/PipelineStateGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/PipelineStateGLImpl.cpp index 19503efb..57c2e4a4 100644 --- a/Graphics/GraphicsEngineOpenGL/src/PipelineStateGLImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/PipelineStateGLImpl.cpp @@ -152,11 +152,13 @@ void PipelineStateGLImpl::BindShaderResources(IResourceMapping *pResourceMapping } } -void PipelineStateGLImpl::CreateShaderResourceBinding(IShaderResourceBinding **ppShaderResourceBinding) +void PipelineStateGLImpl::CreateShaderResourceBinding(IShaderResourceBinding **ppShaderResourceBinding, bool InitStaticResources) { auto *pRenderDeviceGL = ValidatedCast( GetDevice() ); auto &SRBAllocator = pRenderDeviceGL->GetSRBAllocator(); auto pResBinding = NEW_RC_OBJ( SRBAllocator, "ShaderResourceBindingGLImpl instance", ShaderResourceBindingGLImpl)(this); + if (InitStaticResources) + pResBinding->InitializeStaticResources(nullptr); pResBinding->QueryInterface(IID_ShaderResourceBinding, reinterpret_cast(ppShaderResourceBinding)); } diff --git a/Graphics/GraphicsEngineOpenGL/src/ShaderResourceBindingGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/ShaderResourceBindingGLImpl.cpp index 4041afed..d6cae215 100644 --- a/Graphics/GraphicsEngineOpenGL/src/ShaderResourceBindingGLImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/ShaderResourceBindingGLImpl.cpp @@ -113,4 +113,9 @@ GLProgramResources &ShaderResourceBindingGLImpl::GetProgramResources(SHADER_TYPE return m_DynamicProgResources[ShaderInd]; } +void ShaderResourceBindingGLImpl::InitializeStaticResources(const IPipelineState* pPipelineState) +{ + +} + } diff --git a/Graphics/GraphicsEngineVulkan/include/PipelineLayout.h b/Graphics/GraphicsEngineVulkan/include/PipelineLayout.h index a2ebd353..fbe0ea20 100644 --- a/Graphics/GraphicsEngineVulkan/include/PipelineLayout.h +++ b/Graphics/GraphicsEngineVulkan/include/PipelineLayout.h @@ -86,8 +86,8 @@ public: { std::vector vkSets; std::vector DynamicOffsets; - ShaderResourceCacheVk* pResourceCache = nullptr; - VkPipelineBindPoint BindPoint = VK_PIPELINE_BIND_POINT_MAX_ENUM; + const ShaderResourceCacheVk* pResourceCache = nullptr; + VkPipelineBindPoint BindPoint = VK_PIPELINE_BIND_POINT_MAX_ENUM; Uint32 SetCout = 0; Uint32 DynamicOffsetCount = 0; #ifdef _DEBUG @@ -120,11 +120,11 @@ public: // may not be possible until draw command time because dynamic offsets are // set by the same Vulkan command. If there are no dynamic descriptors, this // function also binds descriptor sets rightaway. - void PrepareDescriptorSets(DeviceContextVkImpl* pCtxVkImpl, - bool IsCompute, - ShaderResourceCacheVk& ResourceCache, - DescriptorSetBindInfo& BindInfo, - VkDescriptorSet VkDynamicDescrSet)const; + void PrepareDescriptorSets(DeviceContextVkImpl* pCtxVkImpl, + bool IsCompute, + const ShaderResourceCacheVk& ResourceCache, + DescriptorSetBindInfo& BindInfo, + VkDescriptorSet VkDynamicDescrSet)const; // Computes dynamic offsets and binds descriptor sets void BindDescriptorSetsWithDynamicOffsets(DeviceContextVkImpl* pCtxVkImpl, diff --git a/Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.h b/Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.h index 1475c9ff..0d2988c7 100644 --- a/Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.h +++ b/Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.h @@ -56,7 +56,7 @@ public: virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject** ppInterface ); - virtual void CreateShaderResourceBinding( IShaderResourceBinding **ppShaderResourceBinding )override final; + virtual void CreateShaderResourceBinding( IShaderResourceBinding **ppShaderResourceBinding, bool InitStaticResources )override final; virtual bool IsCompatibleWith(const IPipelineState* pPSO)const override final; diff --git a/Graphics/GraphicsEngineVulkan/include/ShaderResourceBindingVkImpl.h b/Graphics/GraphicsEngineVulkan/include/ShaderResourceBindingVkImpl.h index 6ebea962..d61a04cf 100644 --- a/Graphics/GraphicsEngineVulkan/include/ShaderResourceBindingVkImpl.h +++ b/Graphics/GraphicsEngineVulkan/include/ShaderResourceBindingVkImpl.h @@ -58,10 +58,11 @@ public: virtual IShaderVariable* GetVariable(SHADER_TYPE ShaderType, Uint32 Index)override final; - ShaderResourceCacheVk& GetResourceCache(){return m_ShaderResourceCache;} + virtual void InitializeStaticResources(const IPipelineState* pPipelineState)override final; - bool StaticResourcesInitialized()const{return m_bStaticResourcesInitialized;} - void SetStaticResourcesInitialized(){m_bStaticResourcesInitialized = true;} + ShaderResourceCacheVk& GetResourceCache() { return m_ShaderResourceCache; } + + bool StaticResourcesInitialized() const { return m_bStaticResourcesInitialized; } private: diff --git a/Graphics/GraphicsEngineVulkan/include/ShaderResourceLayoutVk.h b/Graphics/GraphicsEngineVulkan/include/ShaderResourceLayoutVk.h index 2bfc65ca..c53d4d1f 100644 --- a/Graphics/GraphicsEngineVulkan/include/ShaderResourceLayoutVk.h +++ b/Graphics/GraphicsEngineVulkan/include/ShaderResourceLayoutVk.h @@ -226,7 +226,7 @@ public: // Copies static resources from SrcResourceCache defined by SrcLayout // to DstResourceCache defined by this layout void InitializeStaticResources(const ShaderResourceLayoutVk& SrcLayout, - ShaderResourceCacheVk& SrcResourceCache, + const ShaderResourceCacheVk& SrcResourceCache, ShaderResourceCacheVk& DstResourceCache)const; #ifdef DEVELOPMENT diff --git a/Graphics/GraphicsEngineVulkan/include/ShaderVkImpl.h b/Graphics/GraphicsEngineVulkan/include/ShaderVkImpl.h index d42973c2..ca0373bf 100644 --- a/Graphics/GraphicsEngineVulkan/include/ShaderVkImpl.h +++ b/Graphics/GraphicsEngineVulkan/include/ShaderVkImpl.h @@ -77,13 +77,13 @@ public: } const std::shared_ptr& GetShaderResources()const{return m_pShaderResources;} - const ShaderResourceLayoutVk& GetStaticResLayout()const{return m_StaticResLayout;} - ShaderResourceCacheVk& GetStaticResCache(){return m_StaticResCache;} + const ShaderResourceLayoutVk& GetStaticResLayout()const { return m_StaticResLayout; } + const ShaderResourceCacheVk& GetStaticResCache() const { return m_StaticResCache; } const char* GetEntryPoint() const { return m_EntryPoint.c_str(); } #ifdef DEVELOPMENT - void DvpVerifyStaticResourceBindings(); + void DvpVerifyStaticResourceBindings()const; #endif private: diff --git a/Graphics/GraphicsEngineVulkan/src/PipelineLayout.cpp b/Graphics/GraphicsEngineVulkan/src/PipelineLayout.cpp index 04503613..9260450b 100644 --- a/Graphics/GraphicsEngineVulkan/src/PipelineLayout.cpp +++ b/Graphics/GraphicsEngineVulkan/src/PipelineLayout.cpp @@ -421,11 +421,11 @@ void PipelineLayout::InitResourceCache(RenderDeviceVkImpl* pDeviceVkImpl, Shader } } -void PipelineLayout::PrepareDescriptorSets(DeviceContextVkImpl* pCtxVkImpl, - bool IsCompute, - ShaderResourceCacheVk& ResourceCache, - DescriptorSetBindInfo& BindInfo, - VkDescriptorSet VkDynamicDescrSet)const +void PipelineLayout::PrepareDescriptorSets(DeviceContextVkImpl* pCtxVkImpl, + bool IsCompute, + const ShaderResourceCacheVk& ResourceCache, + DescriptorSetBindInfo& BindInfo, + VkDescriptorSet VkDynamicDescrSet)const { #ifdef _DEBUG BindInfo.vkSets.clear(); diff --git a/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp index 537411aa..dbdbd63c 100644 --- a/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp @@ -427,6 +427,7 @@ PipelineStateVkImpl :: PipelineStateVkImpl(IReferenceCounters* pRefCounters auto& SRBAllocator = pDeviceVk->GetSRBAllocator(); // Default shader resource binding must be initialized after resource layouts are parsed! m_pDefaultShaderResBinding.reset( NEW_RC_OBJ(SRBAllocator, "ShaderResourceBindingVkImpl instance", ShaderResourceBindingVkImpl, this)(this, true) ); + m_pDefaultShaderResBinding->InitializeStaticResources(this); } m_ShaderResourceLayoutHash = m_PipelineLayout.GetHash(); @@ -460,10 +461,12 @@ PipelineStateVkImpl::~PipelineStateVkImpl() IMPLEMENT_QUERY_INTERFACE( PipelineStateVkImpl, IID_PipelineStateVk, TPipelineStateBase ) -void PipelineStateVkImpl::CreateShaderResourceBinding(IShaderResourceBinding **ppShaderResourceBinding) +void PipelineStateVkImpl::CreateShaderResourceBinding(IShaderResourceBinding **ppShaderResourceBinding, bool InitStaticResources) { auto& SRBAllocator = m_pDevice->GetSRBAllocator(); auto pResBindingVk = NEW_RC_OBJ(SRBAllocator, "ShaderResourceBindingVkImpl instance", ShaderResourceBindingVkImpl)(this, false); + if (InitStaticResources) + pResBindingVk->InitializeStaticResources(nullptr); pResBindingVk->QueryInterface(IID_ShaderResourceBinding, reinterpret_cast(ppShaderResourceBinding)); } @@ -545,25 +548,14 @@ void PipelineStateVkImpl::CommitAndTransitionShaderResources(IShaderResourceBind return; } } -#endif - - auto& ResourceCache = pResBindingVkImpl->GetResourceCache(); - // First time only, copy static shader resources to the cache - if (!pResBindingVkImpl->StaticResourcesInitialized()) + if (m_HasStaticResources && !pResBindingVkImpl->StaticResourcesInitialized()) { - for (Uint32 s = 0; s < m_NumShaders; ++s) - { - auto* pShaderVk = GetShader(s); -#ifdef DEVELOPMENT - pShaderVk->DvpVerifyStaticResourceBindings(); -#endif - auto& StaticResLayout = pShaderVk->GetStaticResLayout(); - auto& StaticResCache = pShaderVk->GetStaticResCache(); - m_ShaderResourceLayouts[s].InitializeStaticResources(StaticResLayout, StaticResCache, ResourceCache); - } - pResBindingVkImpl->SetStaticResourcesInitialized(); + LOG_ERROR_MESSAGE("Static resources have not been initialized in the shader resource binding object. Please call IShaderResourceBinding::InitializeStaticResources()."); } +#endif + + auto& ResourceCache = pResBindingVkImpl->GetResourceCache(); #ifdef DEVELOPMENT for (Uint32 s = 0; s < m_NumShaders; ++s) diff --git a/Graphics/GraphicsEngineVulkan/src/ShaderResourceBindingVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/ShaderResourceBindingVkImpl.cpp index b531493e..d3f885a3 100644 --- a/Graphics/GraphicsEngineVulkan/src/ShaderResourceBindingVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/ShaderResourceBindingVkImpl.cpp @@ -137,4 +137,37 @@ IShaderVariable* ShaderResourceBindingVkImpl::GetVariable(SHADER_TYPE ShaderType return m_pShaderVarMgrs[ResLayoutInd].GetVariable(Index); } +void ShaderResourceBindingVkImpl::InitializeStaticResources(const IPipelineState* pPipelineState) +{ + if (StaticResourcesInitialized()) + { + LOG_WARNING_MESSAGE("Static resources have already been initialized in this shader resource binding object. The operation will be ignored."); + return; + } + + if (pPipelineState == nullptr) + { + pPipelineState = GetPipelineState(); + } + else + { + DEV_CHECK_ERR(pPipelineState->IsCompatibleWith(GetPipelineState()), "The pipeline state is not compatible with this SRB"); + } + + auto* pPSOVK = ValidatedCast(pPipelineState); + for (Uint32 s = 0; s < m_NumShaders; ++s) + { + const auto* pShaderVk = pPSOVK->GetShader(s); +#ifdef DEVELOPMENT + pShaderVk->DvpVerifyStaticResourceBindings(); +#endif + const auto& StaticResLayout = pShaderVk->GetStaticResLayout(); + const auto& StaticResCache = pShaderVk->GetStaticResCache(); + const auto& ShaderResourceLayouts = pPSOVK->GetShaderResLayout(s); + ShaderResourceLayouts.InitializeStaticResources(StaticResLayout, StaticResCache, m_ShaderResourceCache); + } + + m_bStaticResourcesInitialized = true; +} + } diff --git a/Graphics/GraphicsEngineVulkan/src/ShaderResourceCacheVk.cpp b/Graphics/GraphicsEngineVulkan/src/ShaderResourceCacheVk.cpp index 9e1fb7ca..888e4d00 100644 --- a/Graphics/GraphicsEngineVulkan/src/ShaderResourceCacheVk.cpp +++ b/Graphics/GraphicsEngineVulkan/src/ShaderResourceCacheVk.cpp @@ -111,7 +111,7 @@ void ShaderResourceCacheVk::TransitionResources(DeviceContextVkImpl *pCtxVkImpl) case SPIRVShaderResourceAttribs::ResourceType::UniformBuffer: { auto* pBufferVk = Res.pObject.RawPtr(); - if (pBufferVk->IsInKnownState()) + if (pBufferVk != nullptr && pBufferVk->IsInKnownState()) { RESOURCE_STATE RequiredState = RESOURCE_STATE_CONSTANT_BUFFER; VERIFY_EXPR((ResourceStateFlagsToVkAccessFlags(RequiredState) & VK_ACCESS_UNIFORM_READ_BIT) == VK_ACCESS_UNIFORM_READ_BIT); @@ -139,8 +139,8 @@ void ShaderResourceCacheVk::TransitionResources(DeviceContextVkImpl *pCtxVkImpl) case SPIRVShaderResourceAttribs::ResourceType::StorageTexelBuffer: { auto* pBuffViewVk = Res.pObject.RawPtr(); - auto* pBufferVk = ValidatedCast(pBuffViewVk->GetBuffer()); - if (pBufferVk->IsInKnownState()) + auto* pBufferVk = pBuffViewVk != nullptr ? ValidatedCast(pBuffViewVk->GetBuffer()) : nullptr; + if (pBufferVk != nullptr && pBufferVk->IsInKnownState()) { RESOURCE_STATE RequiredState = (Res.Type == SPIRVShaderResourceAttribs::ResourceType::UniformTexelBuffer) ? RESOURCE_STATE_SHADER_RESOURCE : RESOURCE_STATE_UNORDERED_ACCESS; @@ -173,8 +173,8 @@ void ShaderResourceCacheVk::TransitionResources(DeviceContextVkImpl *pCtxVkImpl) case SPIRVShaderResourceAttribs::ResourceType::StorageImage: { auto* pTextureViewVk = Res.pObject.RawPtr(); - auto* pTextureVk = ValidatedCast(pTextureViewVk->GetTexture()); - if (pTextureVk->IsInKnownState()) + auto* pTextureVk = pTextureViewVk != nullptr ? ValidatedCast(pTextureViewVk->GetTexture()) : nullptr; + if (pTextureVk != nullptr && pTextureVk->IsInKnownState()) { // The image subresources for a storage image must be in the VK_IMAGE_LAYOUT_GENERAL layout in // order to access its data in a shader (13.1.1) @@ -390,7 +390,7 @@ Uint32 ShaderResourceCacheVk::GetDynamicBufferOffsets(DeviceContextVkImpl *pCtxV break; const auto* pBufferVk = Res.pObject.RawPtr(); - auto Offset = pBufferVk->GetDynamicOffset(CtxId, pCtxVkImpl); + auto Offset = pBufferVk != nullptr ? pBufferVk->GetDynamicOffset(CtxId, pCtxVkImpl) : 0; Offsets[OffsetInd++] = Offset; ++res; @@ -403,8 +403,8 @@ Uint32 ShaderResourceCacheVk::GetDynamicBufferOffsets(DeviceContextVkImpl *pCtxV break; const auto* pBufferVkView = Res.pObject.RawPtr(); - const auto* pBufferVk = pBufferVkView->GetBufferVk(); - auto Offset = pBufferVk->GetDynamicOffset(CtxId, pCtxVkImpl); + const auto* pBufferVk = pBufferVkView != nullptr ? pBufferVkView->GetBufferVk() : 0; + auto Offset = pBufferVk != nullptr ? pBufferVk->GetDynamicOffset(CtxId, pCtxVkImpl) : 0; Offsets[OffsetInd++] = Offset; ++res; diff --git a/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp b/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp index b9a5a346..d0ba2d3d 100644 --- a/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp +++ b/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp @@ -683,7 +683,7 @@ bool ShaderResourceLayoutVk::VkResource::IsBound(Uint32 ArrayIndex, const Shader void ShaderResourceLayoutVk::InitializeStaticResources(const ShaderResourceLayoutVk& SrcLayout, - ShaderResourceCacheVk& SrcResourceCache, + const ShaderResourceCacheVk& SrcResourceCache, ShaderResourceCacheVk& DstResourceCache)const { auto NumStaticResources = m_NumResources[SHADER_VARIABLE_TYPE_STATIC]; @@ -706,7 +706,9 @@ void ShaderResourceLayoutVk::InitializeStaticResources(const ShaderResourceLayou for (Uint32 ArrInd = 0; ArrInd < DstRes.SpirvAttribs.ArraySize; ++ArrInd) { auto SrcOffset = SrcRes.CacheOffset + ArrInd; - IDeviceObject* pObject = SrcResourceCache.GetDescriptorSet(SrcRes.DescriptorSet).GetResource(SrcOffset).pObject; + const auto& SrcCachedSet = SrcResourceCache.GetDescriptorSet(SrcRes.DescriptorSet); + const auto& SrcCachedRes = SrcCachedSet.GetResource(SrcOffset); + IDeviceObject* pObject = SrcCachedRes.pObject.RawPtr(); if (!pObject) LOG_ERROR_MESSAGE("No resource assigned to static shader variable '", SrcRes.SpirvAttribs.GetPrintName(ArrInd), "' in shader '", GetShaderName(), "'."); diff --git a/Graphics/GraphicsEngineVulkan/src/ShaderVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/ShaderVkImpl.cpp index 54ce0030..a0a76499 100644 --- a/Graphics/GraphicsEngineVulkan/src/ShaderVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/ShaderVkImpl.cpp @@ -129,7 +129,7 @@ ShaderVkImpl::~ShaderVkImpl() } #ifdef DEVELOPMENT -void ShaderVkImpl::DvpVerifyStaticResourceBindings() +void ShaderVkImpl::DvpVerifyStaticResourceBindings()const { m_StaticResLayout.dvpVerifyBindings(m_StaticResCache); } -- cgit v1.2.3