From 43302d5fc3b3978952dd4215eea8f3f5668b95dd Mon Sep 17 00:00:00 2001 From: Egor Yusov Date: Wed, 27 Feb 2019 20:45:24 -0800 Subject: Working on resource binding API refactor --- .../include/PipelineStateVkImpl.h | 42 +++++++- .../src/GenerateMipsVkHelper.cpp | 23 ++-- .../src/PipelineStateVkImpl.cpp | 120 +++++++++++++++++---- .../src/RenderDeviceVkImpl.cpp | 6 +- .../src/ShaderResourceBindingVkImpl.cpp | 19 +--- 5 files changed, 155 insertions(+), 55 deletions(-) (limited to 'Graphics/GraphicsEngineVulkan') diff --git a/Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.h b/Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.h index cd7d1cab..07b0f414 100644 --- a/Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.h +++ b/Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.h @@ -33,6 +33,7 @@ #include "PipelineStateBase.h" #include "PipelineLayout.h" #include "ShaderResourceLayoutVk.h" +#include "ShaderVariableVk.h" #include "FixedBlockMemoryAllocator.h" #include "SRBMemoryAllocator.h" #include "VulkanUtilities/VulkanObjectWrappers.h" @@ -44,6 +45,7 @@ namespace Diligent { class FixedBlockMemoryAllocator; +class ShaderVariableManagerVk; /// Implementation of the Diligent::IRenderDeviceVk interface class PipelineStateVkImpl final : public PipelineStateBase @@ -54,9 +56,9 @@ public: PipelineStateVkImpl( IReferenceCounters* pRefCounters, RenderDeviceVkImpl* pDeviceVk, const PipelineStateDesc &PipelineDesc ); ~PipelineStateVkImpl(); - virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject** ppInterface )override final; + virtual void QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface)override final; - virtual void CreateShaderResourceBinding( IShaderResourceBinding **ppShaderResourceBinding, bool InitStaticResources )override final; + virtual void CreateShaderResourceBinding(IShaderResourceBinding** ppShaderResourceBinding, bool InitStaticResources)override final; virtual bool IsCompatibleWith(const IPipelineState* pPSO)const override final; @@ -64,6 +66,14 @@ public: virtual VkPipeline GetVkPipeline()const override final { return m_Pipeline; } + virtual void BindStaticResources(IResourceMapping* pResourceMapping, Uint32 Flags)override final; + + virtual Uint32 GetStaticVariableCount(SHADER_TYPE ShaderType) const override final; + + virtual IShaderResourceVariable* GetStaticShaderVariable(SHADER_TYPE ShaderType, const Char* Name) override final; + + virtual IShaderResourceVariable* GetStaticShaderVariable(SHADER_TYPE ShaderType, Uint32 Index) override final; + void CommitAndTransitionShaderResources(IShaderResourceBinding* pShaderResourceBinding, DeviceContextVkImpl* pCtxVkImpl, bool CommitResources, @@ -98,9 +108,31 @@ public: VkSubpassDescription& SubpassDesc); + void InitializeStaticSRBResources(ShaderResourceCacheVk& ResourceCache)const; + private: - ShaderResourceLayoutVk* m_ShaderResourceLayouts = nullptr; - + const ShaderResourceLayoutVk& GetStaticShaderResLayout(Uint32 ShaderInd)const + { + VERIFY_EXPR(ShaderInd < m_NumShaders); + return m_ShaderResourceLayouts[m_NumShaders + ShaderInd]; + } + + const ShaderResourceCacheVk& GetStaticResCache(Uint32 ShaderInd)const + { + VERIFY_EXPR(ShaderInd < m_NumShaders); + return m_StaticResCaches[ShaderInd]; + } + + ShaderVariableManagerVk& GetStaticVarMgr(Uint32 ShaderInd)const + { + VERIFY_EXPR(ShaderInd < m_NumShaders); + return m_StaticVarsMgrs[ShaderInd]; + } + + ShaderResourceLayoutVk* m_ShaderResourceLayouts = nullptr; + ShaderResourceCacheVk* m_StaticResCaches = nullptr; + ShaderVariableManagerVk* m_StaticVarsMgrs = nullptr; + // SRB memory allocator must be declared before m_pDefaultShaderResBinding SRBMemoryAllocator m_SRBMemAllocator; @@ -109,6 +141,8 @@ private: VkRenderPass m_RenderPass = VK_NULL_HANDLE; // Render passes are managed by the render device VulkanUtilities::PipelineWrapper m_Pipeline; PipelineLayout m_PipelineLayout; + + Int8 m_ResourceLayoutIndex[6] = {-1, -1, -1, -1, -1, -1}; bool m_HasStaticResources = false; bool m_HasNonStaticResources = false; }; diff --git a/Graphics/GraphicsEngineVulkan/src/GenerateMipsVkHelper.cpp b/Graphics/GraphicsEngineVulkan/src/GenerateMipsVkHelper.cpp index 793aea80..d177ca46 100644 --- a/Graphics/GraphicsEngineVulkan/src/GenerateMipsVkHelper.cpp +++ b/Graphics/GraphicsEngineVulkan/src/GenerateMipsVkHelper.cpp @@ -109,17 +109,8 @@ namespace Diligent CSCreateAttribs.Source = g_GenerateMipsCSSource; CSCreateAttribs.EntryPoint = "main"; - CSCreateAttribs.SourceLanguage = SHADER_SOURCE_LANGUAGE_GLSL; + CSCreateAttribs.SourceLanguage = SHADER_SOURCE_LANGUAGE_GLSL; CSCreateAttribs.Desc.ShaderType = SHADER_TYPE_COMPUTE; - CSCreateAttribs.Desc.DefaultVariableType = SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC; - - ShaderResourceVariableDesc VarDesc{"CB", SHADER_RESOURCE_VARIABLE_TYPE_STATIC}; - CSCreateAttribs.Desc.VariableDesc = &VarDesc; - CSCreateAttribs.Desc.NumVariables = 1; - - const StaticSamplerDesc StaticSampler("SrcMip", Sam_LinearClamp); - CSCreateAttribs.Desc.StaticSamplers = &StaticSampler; - CSCreateAttribs.Desc.NumStaticSamplers = 1; const auto& FmtAttribs = GetTextureFormatAttribs(Fmt); bool IsGamma = FmtAttribs.ComponentType == COMPONENT_TYPE_UNORM_SRGB; @@ -155,8 +146,18 @@ namespace Diligent PSODesc.IsComputePipeline = true; PSODesc.Name = name.c_str(); PSODesc.ComputePipeline.pCS = pCS; - pCS->GetShaderVariable("CB")->Set(m_ConstantsCB); + + PSODesc.Layout.DefaultVariableType = SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC; + ShaderResourceVariableDesc VarDesc{SHADER_TYPE_COMPUTE, "CB", SHADER_RESOURCE_VARIABLE_TYPE_STATIC}; + PSODesc.Layout.Variables = &VarDesc; + PSODesc.Layout.NumVariables = 1; + + const StaticSamplerDesc StaticSampler(SHADER_TYPE_COMPUTE, "SrcMip", Sam_LinearClamp); + PSODesc.Layout.StaticSamplers = &StaticSampler; + PSODesc.Layout.NumStaticSamplers = 1; + m_DeviceVkImpl.CreatePipelineState(PSODesc, &PSOs[NonPowOfTwo]); + PSOs[NonPowOfTwo]->GetStaticShaderVariable(SHADER_TYPE_COMPUTE, "CB")->Set(m_ConstantsCB); } return PSOs; diff --git a/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp index 8fd4583c..2a60ce96 100644 --- a/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp @@ -60,12 +60,12 @@ VkRenderPassCreateInfo PipelineStateVkImpl::GetRenderPassCreateInfo( { auto& DepthAttachment = Attachments[AttachmentInd]; - DepthAttachment.flags = 0; // Allowed value VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT - DepthAttachment.format = TexFormatToVkFormat(DSVFormat); + DepthAttachment.flags = 0; // Allowed value VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT + DepthAttachment.format = TexFormatToVkFormat(DSVFormat); DepthAttachment.samples = SampleCountFlags; - DepthAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; // previous contents of the image within the render area - // will be preserved. For attachments with a depth/stencil format, - // this uses the access type VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT. + DepthAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; // previous contents of the image within the render area + // will be preserved. For attachments with a depth/stencil format, + // this uses the access type VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT. DepthAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE; // the contents generated during the render pass and within the render // area are written to memory. For attachments with a depth/stencil format, // this uses the access type VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT. @@ -113,12 +113,12 @@ VkRenderPassCreateInfo PipelineStateVkImpl::GetRenderPassCreateInfo( // dependencies between pairs of subpasses, or NULL if dependencyCount is zero. - SubpassDesc.flags = 0; // All bits for this type are defined by extensions - SubpassDesc.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; // Currently, only graphics subpasses are supported. - SubpassDesc.inputAttachmentCount = 0; - SubpassDesc.pInputAttachments = nullptr; - SubpassDesc.colorAttachmentCount = NumRenderTargets; - SubpassDesc.pColorAttachments = pColorAttachmentsReference; + SubpassDesc.flags = 0; // All bits for this type are defined by extensions + SubpassDesc.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; // Currently, only graphics subpasses are supported. + SubpassDesc.inputAttachmentCount = 0; + SubpassDesc.pInputAttachments = nullptr; + SubpassDesc.colorAttachmentCount = NumRenderTargets; + SubpassDesc.pColorAttachments = pColorAttachmentsReference; SubpassDesc.pResolveAttachments = nullptr; SubpassDesc.pDepthStencilAttachment = pDepthAttachmentReference; SubpassDesc.preserveAttachmentCount = 0; @@ -147,7 +147,7 @@ PipelineStateVkImpl :: PipelineStateVkImpl(IReferenceCounters* pRefCounters RenderDeviceVkImpl* pDeviceVk, const PipelineStateDesc& PipelineDesc) : TPipelineStateBase(pRefCounters, pDeviceVk, PipelineDesc), - m_SRBMemAllocator(GetRawAllocator()) + m_SRBMemAllocator (GetRawAllocator()) { const auto& LogicalDevice = pDeviceVk->GetLogicalDevice(); @@ -155,16 +155,32 @@ PipelineStateVkImpl :: PipelineStateVkImpl(IReferenceCounters* pRefCounters auto& ShaderResLayoutAllocator = GetRawAllocator(); std::array, MaxShadersInPipeline> ShaderResources; std::array, MaxShadersInPipeline> ShaderSPIRVs; - auto* pResLayoutRawMem = ALLOCATE(ShaderResLayoutAllocator, "Raw memory for ShaderResourceLayoutVk", sizeof(ShaderResourceLayoutVk) * m_NumShaders); + auto* pResLayoutRawMem = ALLOCATE(ShaderResLayoutAllocator, "Raw memory for ShaderResourceLayoutVk", sizeof(ShaderResourceLayoutVk) * m_NumShaders * 2); + auto* pStaticResCacheRawMem = ALLOCATE(GetRawAllocator(), "Raw memory for ShaderResourceCacheVk", sizeof(ShaderResourceCacheVk) * m_NumShaders); + auto* pStaticVarMgrRawMem = ALLOCATE(GetRawAllocator(), "Raw memory for ShaderVariableManagerVk", sizeof(ShaderVariableManagerVk) * m_NumShaders); m_ShaderResourceLayouts = reinterpret_cast(pResLayoutRawMem); + m_StaticResCaches = reinterpret_cast(pStaticResCacheRawMem); + m_StaticVarsMgrs = reinterpret_cast(pStaticVarMgrRawMem); for (Uint32 s=0; s < m_NumShaders; ++s) { new (m_ShaderResourceLayouts + s) ShaderResourceLayoutVk(*this, LogicalDevice); auto* pShaderVk = GetShader(s); ShaderResources[s] = pShaderVk->GetShaderResources(); ShaderSPIRVs[s] = pShaderVk->GetSPIRV(); + + const auto ShaderType = pShaderVk->GetDesc().ShaderType; + const auto ShaderTypeInd = GetShaderTypeIndex(ShaderType); + m_ResourceLayoutIndex[ShaderTypeInd] = static_cast(s); + + auto* pStaticResLayout = new (m_ShaderResourceLayouts + m_NumShaders + s) ShaderResourceLayoutVk(*this, LogicalDevice); + auto* pStaticResCache = new (m_StaticResCaches + s) ShaderResourceCacheVk(ShaderResourceCacheVk::DbgCacheContentType::StaticShaderResources); + pStaticResLayout->InitializeStaticResourceLayout(ShaderResources[s], ShaderResLayoutAllocator, PipelineDesc.Layout, m_StaticResCaches[s]); + + auto* pStaticVarMgr = new (m_StaticVarsMgrs + s) ShaderVariableManagerVk(*this); + pStaticVarMgr->Initialize(*pStaticResLayout, GetRawAllocator(), nullptr, 0, *pStaticResCache); } - ShaderResourceLayoutVk::Initialize(m_NumShaders, m_ShaderResourceLayouts, ShaderResources.data(), GetRawAllocator(), ShaderSPIRVs.data(), m_PipelineLayout); + ShaderResourceLayoutVk::Initialize(pDeviceVk, m_NumShaders, m_ShaderResourceLayouts, ShaderResources.data(), GetRawAllocator(), + PipelineDesc.Layout, ShaderSPIRVs.data(), m_PipelineLayout); m_PipelineLayout.Finalize(LogicalDevice); if (PipelineDesc.SRBAllocationGranularity > 1) @@ -172,7 +188,7 @@ PipelineStateVkImpl :: PipelineStateVkImpl(IReferenceCounters* pRefCounters std::array ShaderVariableDataSizes = {}; for (Uint32 s = 0; s < m_NumShaders; ++s) { - std::array AllowedVarTypes = { {SHADER_VARIABLE_TYPE_MUTABLE, SHADER_VARIABLE_TYPE_DYNAMIC} }; + std::array AllowedVarTypes = { {SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE, SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC} }; Uint32 UnusedNumVars = 0; ShaderVariableDataSizes[s] = ShaderVariableManagerVk::GetRequiredMemorySize(m_ShaderResourceLayouts[s], AllowedVarTypes.data(), static_cast(AllowedVarTypes.size()), UnusedNumVars); } @@ -412,11 +428,11 @@ PipelineStateVkImpl :: PipelineStateVkImpl(IReferenceCounters* pRefCounters for (Uint32 s=0; s < m_NumShaders; ++s) { const auto& Layout = m_ShaderResourceLayouts[s]; - if (Layout.GetResourceCount(SHADER_VARIABLE_TYPE_STATIC) != 0) + if (Layout.GetResourceCount(SHADER_RESOURCE_VARIABLE_TYPE_STATIC) != 0) m_HasStaticResources = true; - if (Layout.GetResourceCount(SHADER_VARIABLE_TYPE_MUTABLE) != 0 || - Layout.GetResourceCount(SHADER_VARIABLE_TYPE_DYNAMIC) != 0) + if (Layout.GetResourceCount(SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE) != 0 || + Layout.GetResourceCount(SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC) != 0) m_HasNonStaticResources = true; } @@ -440,8 +456,13 @@ PipelineStateVkImpl::~PipelineStateVkImpl() for (Uint32 s=0; s < m_NumShaders; ++s) { m_ShaderResourceLayouts[s].~ShaderResourceLayoutVk(); + m_StaticResCaches[s].~ShaderResourceCacheVk(); + m_StaticVarsMgrs[s].Destroy(GetRawAllocator()); + m_StaticVarsMgrs[s].~ShaderVariableManagerVk(); } RawAllocator.Free(m_ShaderResourceLayouts); + RawAllocator.Free(m_StaticResCaches); + RawAllocator.Free(m_StaticVarsMgrs); } IMPLEMENT_QUERY_INTERFACE( PipelineStateVkImpl, IID_PipelineStateVk, TPipelineStateBase ) @@ -581,7 +602,7 @@ void PipelineStateVkImpl::CommitAndTransitionShaderResources(IShaderResourceBind for (Uint32 s=0; s < m_NumShaders; ++s) { const auto& Layout = m_ShaderResourceLayouts[s]; - if (Layout.GetResourceCount(SHADER_VARIABLE_TYPE_DYNAMIC) != 0) + if (Layout.GetResourceCount(SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC) != 0) Layout.CommitDynamicResources(ResourceCache, DynamicDescrSet); } } @@ -593,4 +614,65 @@ void PipelineStateVkImpl::CommitAndTransitionShaderResources(IShaderResourceBind } } +void PipelineStateVkImpl::BindStaticResources(IResourceMapping* pResourceMapping, Uint32 Flags) +{ + for (Uint32 s=0; s < m_NumShaders; ++s) + { + auto& StaticVarMgr = GetStaticVarMgr(s); + StaticVarMgr.BindResources(pResourceMapping, Flags); + } +} + +Uint32 PipelineStateVkImpl::GetStaticVariableCount(SHADER_TYPE ShaderType) const +{ + const auto ShaderTypeInd = GetShaderTypeIndex(ShaderType); + if (ShaderTypeInd < 0) + return 0; + + auto& StaticVarMgr = GetStaticVarMgr(ShaderTypeInd); + return StaticVarMgr.GetVariableCount(); +} + +IShaderResourceVariable* PipelineStateVkImpl::GetStaticShaderVariable(SHADER_TYPE ShaderType, const Char* Name) +{ + const auto ShaderTypeInd = GetShaderTypeIndex(ShaderType); + if (ShaderTypeInd < 0) + return nullptr; + + auto& StaticVarMgr = GetStaticVarMgr(ShaderTypeInd); + return StaticVarMgr.GetVariable(Name); +} + +IShaderResourceVariable* PipelineStateVkImpl::GetStaticShaderVariable(SHADER_TYPE ShaderType, Uint32 Index) +{ + const auto ShaderTypeInd = GetShaderTypeIndex(ShaderType); + if (ShaderTypeInd < 0) + return nullptr; + + auto& StaticVarMgr = GetStaticVarMgr(ShaderTypeInd); + return StaticVarMgr.GetVariable(Index); +} + + +void PipelineStateVkImpl::InitializeStaticSRBResources(ShaderResourceCacheVk& ResourceCache)const +{ + for (Uint32 s = 0; s < m_NumShaders; ++s) + { + const auto& StaticResLayout = GetStaticShaderResLayout(s); +#ifdef DEVELOPMENT + if (!StaticResLayout.dvpVerifyBindings(ResourceCache)) + { + const auto* pShaderVk = GetShader(s); + LOG_ERROR_MESSAGE("Static resources in SRB of PSO '", GetDesc().Name, "' will not be successfully initialized " + "because not all static resource bindings in shader '", pShaderVk->GetDesc().Name, "' are valid. " + "Please make sure you bind all static resources to the shader before calling InitializeStaticResources() " + "directly or indirectly by passing InitStaticResources=true to CreateShaderResourceBinding() method."); + } +#endif + const auto& StaticResCache = GetStaticResCache(s); + const auto& ShaderResourceLayouts = GetShaderResLayout(s); + ShaderResourceLayouts.InitializeStaticResources(StaticResLayout, StaticResCache, ResourceCache); + } +} + } diff --git a/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp index dbf2893f..89ed5d01 100644 --- a/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp @@ -433,12 +433,12 @@ void RenderDeviceVkImpl :: CreateBuffer(const BufferDesc& BuffDesc, const Buffer } -void RenderDeviceVkImpl :: CreateShader(const ShaderCreationAttribs &ShaderCreationAttribs, IShader **ppShader) +void RenderDeviceVkImpl :: CreateShader(const ShaderCreateInfo& ShaderCI, IShader **ppShader) { - CreateDeviceObject( "shader", ShaderCreationAttribs.Desc, ppShader, + CreateDeviceObject( "shader", ShaderCI.Desc, ppShader, [&]() { - ShaderVkImpl *pShaderVk( NEW_RC_OBJ(m_ShaderObjAllocator, "ShaderVkImpl instance", ShaderVkImpl)(this, ShaderCreationAttribs ) ); + ShaderVkImpl *pShaderVk( NEW_RC_OBJ(m_ShaderObjAllocator, "ShaderVkImpl instance", ShaderVkImpl)(this, ShaderCI) ); pShaderVk->QueryInterface( IID_Shader, reinterpret_cast(ppShader) ); OnCreateDeviceObject( pShaderVk ); diff --git a/Graphics/GraphicsEngineVulkan/src/ShaderResourceBindingVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/ShaderResourceBindingVkImpl.cpp index 342f5ae6..3077a5dd 100644 --- a/Graphics/GraphicsEngineVulkan/src/ShaderResourceBindingVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/ShaderResourceBindingVkImpl.cpp @@ -155,24 +155,7 @@ void ShaderResourceBindingVkImpl::InitializeStaticResources(const IPipelineState } auto* pPSOVK = ValidatedCast(pPipelineState); - for (Uint32 s = 0; s < m_NumShaders; ++s) - { - const auto* pShaderVk = pPSOVK->GetShader(s); -#ifdef DEVELOPMENT - if (!pShaderVk->DvpVerifyStaticResourceBindings()) - { - LOG_ERROR_MESSAGE("Static resources in SRB of PSO '", pPSOVK->GetDesc().Name, "' will not be successfully initialized " - "because not all static resource bindings in shader '", pShaderVk->GetDesc().Name, "' are valid. " - "Please make sure you bind all static resources to the shader before calling InitializeStaticResources() " - "directly or indirectly by passing InitStaticResources=true to CreateShaderResourceBinding() method."); - } -#endif - const auto& StaticResLayout = pShaderVk->GetStaticResLayout(); - const auto& StaticResCache = pShaderVk->GetStaticResCache(); - const auto& ShaderResourceLayouts = pPSOVK->GetShaderResLayout(s); - ShaderResourceLayouts.InitializeStaticResources(StaticResLayout, StaticResCache, m_ShaderResourceCache); - } - + pPSOVK->InitializeStaticSRBResources(m_ShaderResourceCache); m_bStaticResourcesInitialized = true; } -- cgit v1.2.3