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 --- .../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 +- 11 files changed, 76 insertions(+), 48 deletions(-) (limited to 'Graphics/GraphicsEngineVulkan') 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