diff options
| author | azhirnov <zh1dron@gmail.com> | 2020-10-15 17:55:38 +0000 |
|---|---|---|
| committer | azhirnov <zh1dron@gmail.com> | 2020-10-15 17:59:25 +0000 |
| commit | 259a9d5897937dcaaca1b4b294bb8d5250371e76 (patch) | |
| tree | b6123b30f228d05a7086a009cb35e2af713ed008 /Graphics/GraphicsEngineVulkan | |
| parent | A number of corrections for PSO refactoring (diff) | |
| download | DiligentCore-259a9d5897937dcaaca1b4b294bb8d5250371e76.tar.gz DiligentCore-259a9d5897937dcaaca1b4b294bb8d5250371e76.zip | |
Added GraphicsPipelineCreateInfo and ComputePipelineCreateInfo instead of single PipelineCreateInfo.
Some optimizations for dynamic memory allocations in PipelineState.
Diffstat (limited to 'Graphics/GraphicsEngineVulkan')
6 files changed, 170 insertions, 94 deletions
diff --git a/Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.hpp b/Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.hpp index 2185dabd..1773e743 100644 --- a/Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.hpp +++ b/Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.hpp @@ -57,7 +57,8 @@ class PipelineStateVkImpl final : public PipelineStateBase<IPipelineStateVk, Ren public: using TPipelineStateBase = PipelineStateBase<IPipelineStateVk, RenderDeviceVkImpl>; - PipelineStateVkImpl(IReferenceCounters* pRefCounters, RenderDeviceVkImpl* pDeviceVk, const PipelineStateCreateInfo& CreateInfo); + PipelineStateVkImpl(IReferenceCounters* pRefCounters, RenderDeviceVkImpl* pDeviceVk, const GraphicsPipelineStateCreateInfo& CreateInfo); + PipelineStateVkImpl(IReferenceCounters* pRefCounters, RenderDeviceVkImpl* pDeviceVk, const ComputePipelineStateCreateInfo& CreateInfo); ~PipelineStateVkImpl(); virtual void DILIGENT_CALL_TYPE QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface) override final; @@ -125,6 +126,11 @@ public: void InitializeStaticSRBResources(ShaderResourceCacheVk& ResourceCache) const; private: + using TShaderStages = ShaderResourceLayoutVk::TShaderStages; + void InitResourceLayouts(RenderDeviceVkImpl* pDeviceVk, + const PipelineStateCreateInfo& CreateInfo, + TShaderStages& ShaderStages); + const ShaderResourceLayoutVk& GetStaticShaderResLayout(Uint32 ShaderInd) const { VERIFY_EXPR(ShaderInd < GetNumShaderStages()); @@ -143,9 +149,9 @@ private: return m_StaticVarsMgrs[ShaderInd]; } - ShaderResourceLayoutVk* m_ShaderResourceLayouts = nullptr; - ShaderResourceCacheVk* m_StaticResCaches = nullptr; - ShaderVariableManagerVk* m_StaticVarsMgrs = nullptr; + ShaderResourceLayoutVk* m_ShaderResourceLayouts = nullptr; // [m_NumShaderStages * 2] + ShaderResourceCacheVk* m_StaticResCaches = nullptr; // [m_NumShaderStages] + ShaderVariableManagerVk* m_StaticVarsMgrs = nullptr; // [m_NumShaderStages] // SRB memory allocator must be declared before m_pDefaultShaderResBinding SRBMemoryAllocator m_SRBMemAllocator; diff --git a/Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.hpp b/Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.hpp index 25a9f44b..24f3345c 100644 --- a/Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.hpp +++ b/Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.hpp @@ -72,8 +72,11 @@ public: virtual void DILIGENT_CALL_TYPE QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface) override final; - /// Implementation of IRenderDevice::CreatePipelineState() in Vulkan backend. - virtual void DILIGENT_CALL_TYPE CreatePipelineState(const PipelineStateCreateInfo& PSOCreateInfo, IPipelineState** ppPipelineState) override final; + /// Implementation of IRenderDevice::CreateGraphicsPipelineState() in Vulkan backend. + virtual void DILIGENT_CALL_TYPE CreateGraphicsPipelineState(const GraphicsPipelineStateCreateInfo& PSOCreateInfo, IPipelineState** ppPipelineState) override final; + + /// Implementation of IRenderDevice::CreateComputePipelineState() in Vulkan backend. + virtual void DILIGENT_CALL_TYPE CreateComputePipelineState(const ComputePipelineStateCreateInfo& PSOCreateInfo, IPipelineState** ppPipelineState) override final; /// Implementation of IRenderDevice::CreateBuffer() in Vulkan backend. virtual void DILIGENT_CALL_TYPE CreateBuffer(const BufferDesc& BuffDesc, diff --git a/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp index 2d7b9591..c8b231c2 100644 --- a/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp @@ -257,39 +257,49 @@ void DeviceContextVkImpl::SetPipelineState(IPipelineState* pPipelineState) else { const auto& OldPSODesc = m_pPipelineState->GetDesc(); - // Commit all graphics states when switching from compute pipeline + // Commit all graphics states when switching from non-graphics pipeline // This is necessary because if the command list had been flushed // and the first PSO set on the command list was a compute pipeline, // the states would otherwise never be committed (since m_pPipelineState != nullptr) - CommitStates = OldPSODesc.IsComputePipeline(); + CommitStates = !OldPSODesc.IsAnyGraphicsPipeline(); // We also need to update scissor rect if ScissorEnable state was disabled in previous pipeline - CommitScissor = !OldPSODesc.GraphicsPipeline.RasterizerDesc.ScissorEnable; + if (OldPSODesc.IsAnyGraphicsPipeline()) + CommitScissor = !m_pPipelineState->GetGraphicsPipelineDesc().RasterizerDesc.ScissorEnable; } TDeviceContextBase::SetPipelineState(pPipelineStateVk, 0 /*Dummy*/); EnsureVkCmdBuffer(); - if (PSODesc.IsComputePipeline()) - { - auto vkPipeline = pPipelineStateVk->GetVkPipeline(); - m_CommandBuffer.BindComputePipeline(vkPipeline); - } - else - { - auto vkPipeline = pPipelineStateVk->GetVkPipeline(); - m_CommandBuffer.BindGraphicsPipeline(vkPipeline); + auto vkPipeline = pPipelineStateVk->GetVkPipeline(); - if (CommitStates) + switch (PSODesc.PipelineType) + { + case PIPELINE_TYPE_GRAPHICS: + case PIPELINE_TYPE_MESH: { - m_CommandBuffer.SetStencilReference(m_StencilRef); - m_CommandBuffer.SetBlendConstants(m_BlendFactors); - CommitViewports(); - } + auto& GraphicsPipeline = pPipelineStateVk->GetGraphicsPipelineDesc(); + m_CommandBuffer.BindGraphicsPipeline(vkPipeline); + + if (CommitStates) + { + m_CommandBuffer.SetStencilReference(m_StencilRef); + m_CommandBuffer.SetBlendConstants(m_BlendFactors); + CommitViewports(); + } - if (PSODesc.GraphicsPipeline.RasterizerDesc.ScissorEnable && (CommitStates || CommitScissor)) + if (GraphicsPipeline.RasterizerDesc.ScissorEnable && (CommitStates || CommitScissor)) + { + CommitScissorRects(); + } + break; + } + case PIPELINE_TYPE_COMPUTE: { - CommitScissorRects(); + m_CommandBuffer.BindComputePipeline(vkPipeline); + break; } + default: + UNEXPECTED("unknown pipeline type"); } m_DescrSetBindInfo.Reset(); @@ -381,8 +391,11 @@ void DeviceContextVkImpl::CommitVkVertexBuffers() void DeviceContextVkImpl::DvpLogRenderPass_PSOMismatch() { + const auto& Desc = m_pPipelineState->GetDesc(); + const auto& GrPipeline = m_pPipelineState->GetGraphicsPipelineDesc(); + std::stringstream ss; - ss << "Active render pass is incomaptible with PSO '" << m_pPipelineState->GetDesc().Name + ss << "Active render pass is incomaptible with PSO '" << Desc.Name << "'. This indicates the mismatch between the number and/or format of bound render " "targets and/or depth stencil buffer and the PSO. Vulkand requires exact match.\n" " Bound render targets (" @@ -411,7 +424,6 @@ void DeviceContextVkImpl::DvpLogRenderPass_PSOMismatch() ss << "<Not set>"; ss << "; Sample count: " << SampleCount; - const auto& GrPipeline = m_pPipelineState->GetDesc().GraphicsPipeline; ss << "\n PSO: render targets (" << Uint32{GrPipeline.NumRenderTargets} << "): "; for (Uint32 rt = 0; rt < GrPipeline.NumRenderTargets; ++rt) ss << ' ' << GetTextureFormatAttribs(GrPipeline.RTVFormats[rt]).Name; @@ -472,7 +484,7 @@ void DeviceContextVkImpl::PrepareForDraw(DRAW_FLAGS Flags) # endif #endif - if (m_pPipelineState->GetDesc().GraphicsPipeline.pRenderPass == nullptr) + if (m_pPipelineState->GetGraphicsPipelineDesc().pRenderPass == nullptr) { #ifdef DILIGENT_DEVELOPMENT if (m_pPipelineState->GetRenderPass()->GetVkRenderPass() != m_vkRenderPass) @@ -1110,7 +1122,7 @@ void DeviceContextVkImpl::SetViewports(Uint32 NumViewports, const Viewport* pVie void DeviceContextVkImpl::CommitScissorRects() { - VERIFY(m_pPipelineState && m_pPipelineState->GetDesc().GraphicsPipeline.RasterizerDesc.ScissorEnable, "Scissor test must be enabled in the graphics pipeline"); + VERIFY(m_pPipelineState && m_pPipelineState->GetGraphicsPipelineDesc().RasterizerDesc.ScissorEnable, "Scissor test must be enabled in the graphics pipeline"); if (m_NumScissorRects == 0) return; // Scissors have not been set in the context yet @@ -1136,14 +1148,10 @@ void DeviceContextVkImpl::SetScissorRects(Uint32 NumRects, const Rect* pRects, U // Only commit scissor rects if scissor test is enabled in the rasterizer state. // If scissor is currently disabled, or no PSO is bound, scissor rects will be committed by // the SetPipelineState() when a PSO with enabled scissor test is set. - if (m_pPipelineState) + if (m_pPipelineState && m_pPipelineState->GetDesc().IsAnyGraphicsPipeline() && m_pPipelineState->GetGraphicsPipelineDesc().RasterizerDesc.ScissorEnable) { - const auto& PSODesc = m_pPipelineState->GetDesc(); - if (PSODesc.IsAnyGraphicsPipeline() && PSODesc.GraphicsPipeline.RasterizerDesc.ScissorEnable) - { - VERIFY(NumRects == m_NumScissorRects, "Unexpected number of scissor rects"); - CommitScissorRects(); - } + VERIFY(NumRects == m_NumScissorRects, "Unexpected number of scissor rects"); + CommitScissorRects(); } } diff --git a/Graphics/GraphicsEngineVulkan/src/GenerateMipsVkHelper.cpp b/Graphics/GraphicsEngineVulkan/src/GenerateMipsVkHelper.cpp index 5110c873..d6f4b0be 100644 --- a/Graphics/GraphicsEngineVulkan/src/GenerateMipsVkHelper.cpp +++ b/Graphics/GraphicsEngineVulkan/src/GenerateMipsVkHelper.cpp @@ -154,12 +154,12 @@ std::array<RefCntAutoPtr<IPipelineState>, 4> GenerateMipsVkHelper::CreatePSOs(TE m_DeviceVkImpl.CreateShader(CSCreateInfo, &pCS); - PipelineStateCreateInfo PSOCreateInfo; - PipelineStateDesc& PSODesc = PSOCreateInfo.PSODesc; + ComputePipelineStateCreateInfo PSOCreateInfo; + PipelineStateDesc& PSODesc = PSOCreateInfo.PSODesc; - PSODesc.PipelineType = PIPELINE_TYPE_COMPUTE; - PSODesc.Name = name.c_str(); - PSODesc.ComputePipeline.pCS = pCS; + PSODesc.PipelineType = PIPELINE_TYPE_COMPUTE; + PSODesc.Name = name.c_str(); + PSOCreateInfo.pCS = pCS; PSODesc.ResourceLayout.DefaultVariableType = SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC; ShaderResourceVariableDesc VarDesc{SHADER_TYPE_COMPUTE, "CB", SHADER_RESOURCE_VARIABLE_TYPE_STATIC}; @@ -170,7 +170,7 @@ std::array<RefCntAutoPtr<IPipelineState>, 4> GenerateMipsVkHelper::CreatePSOs(TE PSODesc.ResourceLayout.StaticSamplers = &StaticSampler; PSODesc.ResourceLayout.NumStaticSamplers = 1; - m_DeviceVkImpl.CreatePipelineState(PSOCreateInfo, &PSOs[NonPowOfTwo]); + m_DeviceVkImpl.CreateComputePipelineState(PSOCreateInfo, &PSOs[NonPowOfTwo]); PSOs[NonPowOfTwo]->GetStaticVariableByName(SHADER_TYPE_COMPUTE, "CB")->Set(m_ConstantsCB); } #endif diff --git a/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp index fbc5fae3..3e4154be 100644 --- a/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp @@ -196,7 +196,7 @@ static void InitPipelineShaderStages(const VulkanUtilities::VulkanLogicalDevice& static void CreateComputePipeline(RenderDeviceVkImpl* pDeviceVk, std::vector<VkPipelineShaderStageCreateInfo>& Stages, const PipelineLayout& Layout, - const PipelineStateDesc& Desc, + const PipelineStateDesc& PSODesc, VulkanUtilities::PipelineWrapper& Pipeline) { const auto& LogicalDevice = pDeviceVk->GetLogicalDevice(); @@ -214,21 +214,21 @@ static void CreateComputePipeline(RenderDeviceVkImpl* PipelineCI.stage = Stages[0]; PipelineCI.layout = Layout.GetVkPipelineLayout(); - Pipeline = LogicalDevice.CreateComputePipeline(PipelineCI, VK_NULL_HANDLE, Desc.Name); + Pipeline = LogicalDevice.CreateComputePipeline(PipelineCI, VK_NULL_HANDLE, PSODesc.Name); } static void CreateGraphicsPipeline(RenderDeviceVkImpl* pDeviceVk, std::vector<VkPipelineShaderStageCreateInfo>& Stages, const PipelineLayout& Layout, - const PipelineStateDesc& Desc, + const PipelineStateDesc& PSODesc, + const GraphicsPipelineDesc& GraphicsPipeline, VulkanUtilities::PipelineWrapper& Pipeline, RefCntAutoPtr<IRenderPass>& pRenderPass) { - const auto& LogicalDevice = pDeviceVk->GetLogicalDevice(); - const auto& PhysicalDevice = pDeviceVk->GetPhysicalDevice(); - auto& GraphicsPipeline = Desc.GraphicsPipeline; - auto& RPCache = pDeviceVk->GetImplicitRenderPassCache(); + const auto& LogicalDevice = pDeviceVk->GetLogicalDevice(); + const auto& PhysicalDevice = pDeviceVk->GetPhysicalDevice(); + auto& RPCache = pDeviceVk->GetImplicitRenderPassCache(); if (pRenderPass == nullptr) { @@ -276,7 +276,7 @@ static void CreateGraphicsPipeline(RenderDeviceVkImpl* TessStateCI.flags = 0; // reserved for future use PipelineCI.pTessellationState = &TessStateCI; - if (Desc.PipelineType == PIPELINE_TYPE_MESH) + if (PSODesc.PipelineType == PIPELINE_TYPE_MESH) { // Input assembly is not used in the mesh pipeline, so topology may contain any value. // Validation layers may generate a warning if point_list topology is used, so use MAX_ENUM value. @@ -394,40 +394,19 @@ static void CreateGraphicsPipeline(RenderDeviceVkImpl* PipelineCI.renderPass = pRenderPass.RawPtr<IRenderPassVk>()->GetVkRenderPass(); - PipelineCI.subpass = Desc.GraphicsPipeline.SubpassIndex; + PipelineCI.subpass = GraphicsPipeline.SubpassIndex; PipelineCI.basePipelineHandle = VK_NULL_HANDLE; // a pipeline to derive from PipelineCI.basePipelineIndex = -1; // an index into the pCreateInfos parameter to use as a pipeline to derive from - Pipeline = LogicalDevice.CreateGraphicsPipeline(PipelineCI, VK_NULL_HANDLE, Desc.Name); + Pipeline = LogicalDevice.CreateGraphicsPipeline(PipelineCI, VK_NULL_HANDLE, PSODesc.Name); } - -PipelineStateVkImpl::PipelineStateVkImpl(IReferenceCounters* pRefCounters, - RenderDeviceVkImpl* pDeviceVk, - const PipelineStateCreateInfo& CreateInfo) : - TPipelineStateBase{pRefCounters, pDeviceVk, CreateInfo.PSODesc}, - m_SRBMemAllocator{GetRawAllocator()} +void PipelineStateVkImpl::InitResourceLayouts(RenderDeviceVkImpl* pDeviceVk, + const PipelineStateCreateInfo& CreateInfo, + TShaderStages& ShaderStages) { - m_ResourceLayoutIndex.fill(-1); - const auto& LogicalDevice = pDeviceVk->GetLogicalDevice(); - ShaderResourceLayoutVk::TShaderStages ShaderStages; - ExtractShaders<ShaderVkImpl>(ShaderStages); - - // clang-format off - static_assert((sizeof(ShaderResourceLayoutVk) % sizeof(void*)) == 0, "sizeof(ShaderResourceLayoutVk) is expected to be a multiple of sizeof(void*)"); - static_assert((sizeof(ShaderResourceCacheVk) % sizeof(void*)) == 0, "sizeof(ShaderResourceCacheVk) is expected to be a multiple of sizeof(void*)"); - static_assert((sizeof(ShaderVariableManagerVk) % sizeof(void*)) == 0, "sizeof(ShaderVariableManagerVk) is expected to be a multiple of sizeof(void*)"); - // clang-format on - const auto MemSize = (sizeof(ShaderResourceLayoutVk) * 2 + sizeof(ShaderResourceCacheVk) + sizeof(ShaderVariableManagerVk)) * GetNumShaderStages(); - auto* const pRawMem = - ALLOCATE_RAW(GetRawAllocator(), "Raw memory for ShaderResourceLayoutVk, ShaderResourceCacheVk, and ShaderVariableManagerVk arrays", MemSize); - - m_ShaderResourceLayouts = reinterpret_cast<ShaderResourceLayoutVk*>(pRawMem); - m_StaticResCaches = reinterpret_cast<ShaderResourceCacheVk*>(m_ShaderResourceLayouts + GetNumShaderStages() * 2); - m_StaticVarsMgrs = reinterpret_cast<ShaderVariableManagerVk*>(m_StaticResCaches + GetNumShaderStages()); - for (size_t s = 0; s < ShaderStages.size(); ++s) { auto& StageInfo = ShaderStages[s]; @@ -436,7 +415,6 @@ PipelineStateVkImpl::PipelineStateVkImpl(IReferenceCounters* pRefCoun new (m_ShaderResourceLayouts + s) ShaderResourceLayoutVk{LogicalDevice}; - m_ResourceLayoutIndex[ShaderTypeInd] = static_cast<Int8>(s); auto* pStaticResLayout = new (m_ShaderResourceLayouts + ShaderStages.size() + s) ShaderResourceLayoutVk{LogicalDevice}; @@ -469,22 +447,6 @@ PipelineStateVkImpl::PipelineStateVkImpl(IReferenceCounters* pRefCoun m_SRBMemAllocator.Initialize(m_Desc.SRBAllocationGranularity, GetNumShaderStages(), ShaderVariableDataSizes.data(), 1, &CacheMemorySize); } - // Create shader modules and initialize shader stages - std::vector<VkPipelineShaderStageCreateInfo> VkShaderStages; - std::vector<VulkanUtilities::ShaderModuleWrapper> ShaderModules; - InitPipelineShaderStages(LogicalDevice, ShaderStages, ShaderModules, VkShaderStages); - - // Create pipeline - switch (m_Desc.PipelineType) - { - // clang-format off - case PIPELINE_TYPE_GRAPHICS: - case PIPELINE_TYPE_MESH: CreateGraphicsPipeline( pDeviceVk, VkShaderStages, m_PipelineLayout, m_Desc, m_Pipeline, m_pRenderPass); break; - case PIPELINE_TYPE_COMPUTE: CreateComputePipeline( pDeviceVk, VkShaderStages, m_PipelineLayout, m_Desc, m_Pipeline); break; - default: UNEXPECTED("unknown pipeline type"); - // clang-format on - } - m_HasStaticResources = false; m_HasNonStaticResources = false; for (Uint32 s = 0; s < GetNumShaderStages(); ++s) @@ -501,6 +463,89 @@ PipelineStateVkImpl::PipelineStateVkImpl(IReferenceCounters* pRefCoun m_ShaderResourceLayoutHash = m_PipelineLayout.GetHash(); } + +PipelineStateVkImpl::PipelineStateVkImpl(IReferenceCounters* pRefCounters, + RenderDeviceVkImpl* pDeviceVk, + const GraphicsPipelineStateCreateInfo& CreateInfo) : + TPipelineStateBase{pRefCounters, pDeviceVk, CreateInfo.PSODesc}, + m_SRBMemAllocator{GetRawAllocator()} +{ + m_ResourceLayoutIndex.fill(-1); + + ShaderResourceLayoutVk::TShaderStages ShaderStages; + ExtractShaders<ShaderVkImpl>(CreateInfo, ShaderStages); + + // Memory must be released if an exception is thrown. + LinearAllocator MemPool{GetRawAllocator()}; + + MemPool.AddRequiredSize<ShaderResourceLayoutVk>(GetNumShaderStages() * 2); + MemPool.AddRequiredSize<ShaderResourceCacheVk>(GetNumShaderStages()); + MemPool.AddRequiredSize<ShaderVariableManagerVk>(GetNumShaderStages()); + + ValidateAndReserveSpace(CreateInfo, MemPool); + + MemPool.Reserve(); + + m_ShaderResourceLayouts = MemPool.Allocate<ShaderResourceLayoutVk>(GetNumShaderStages() * 2); + m_StaticResCaches = MemPool.Allocate<ShaderResourceCacheVk>(GetNumShaderStages()); + m_StaticVarsMgrs = MemPool.Allocate<ShaderVariableManagerVk>(GetNumShaderStages()); + + InitGraphicsPipeline(CreateInfo, MemPool); + InitResourceLayouts(pDeviceVk, CreateInfo, ShaderStages); + + // Create shader modules and initialize shader stages + std::vector<VkPipelineShaderStageCreateInfo> VkShaderStages; + std::vector<VulkanUtilities::ShaderModuleWrapper> ShaderModules; + InitPipelineShaderStages(pDeviceVk->GetLogicalDevice(), ShaderStages, ShaderModules, VkShaderStages); + + CreateGraphicsPipeline(pDeviceVk, VkShaderStages, m_PipelineLayout, m_Desc, GetGraphicsPipelineDesc(), m_Pipeline, m_pRenderPass); + + void* Ptr = MemPool.Release(); + VERIFY_EXPR(Ptr == m_ShaderResourceLayouts); +} + + +PipelineStateVkImpl::PipelineStateVkImpl(IReferenceCounters* pRefCounters, + RenderDeviceVkImpl* pDeviceVk, + const ComputePipelineStateCreateInfo& CreateInfo) : + TPipelineStateBase{pRefCounters, pDeviceVk, CreateInfo.PSODesc}, + m_SRBMemAllocator{GetRawAllocator()} +{ + m_ResourceLayoutIndex.fill(-1); + + ShaderResourceLayoutVk::TShaderStages ShaderStages; + ExtractShaders<ShaderVkImpl>(CreateInfo, ShaderStages); + + // Memory must be released if an exception is thrown. + LinearAllocator MemPool{GetRawAllocator()}; + + MemPool.AddRequiredSize<ShaderResourceLayoutVk>(GetNumShaderStages() * 2); + MemPool.AddRequiredSize<ShaderResourceCacheVk>(GetNumShaderStages()); + MemPool.AddRequiredSize<ShaderVariableManagerVk>(GetNumShaderStages()); + + ValidateAndReserveSpace(CreateInfo, MemPool); + + MemPool.Reserve(); + + m_ShaderResourceLayouts = MemPool.Allocate<ShaderResourceLayoutVk>(GetNumShaderStages() * 2); + m_StaticResCaches = MemPool.Allocate<ShaderResourceCacheVk>(GetNumShaderStages()); + m_StaticVarsMgrs = MemPool.Allocate<ShaderVariableManagerVk>(GetNumShaderStages()); + + InitComputePipeline(CreateInfo, MemPool); + InitResourceLayouts(pDeviceVk, CreateInfo, ShaderStages); + + // Create shader modules and initialize shader stages + std::vector<VkPipelineShaderStageCreateInfo> VkShaderStages; + std::vector<VulkanUtilities::ShaderModuleWrapper> ShaderModules; + InitPipelineShaderStages(pDeviceVk->GetLogicalDevice(), ShaderStages, ShaderModules, VkShaderStages); + + CreateComputePipeline(pDeviceVk, VkShaderStages, m_PipelineLayout, m_Desc, m_Pipeline); + + void* Ptr = MemPool.Release(); + VERIFY_EXPR(Ptr == m_ShaderResourceLayouts); +} + + PipelineStateVkImpl::~PipelineStateVkImpl() { m_pDevice->SafeReleaseDeviceObject(std::move(m_Pipeline), m_Desc.CommandQueueMask); diff --git a/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp index f6e337c2..ca729479 100644 --- a/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp @@ -541,7 +541,21 @@ void RenderDeviceVkImpl::TestTextureFormat(TEXTURE_FORMAT TexFormat) IMPLEMENT_QUERY_INTERFACE(RenderDeviceVkImpl, IID_RenderDeviceVk, TRenderDeviceBase) -void RenderDeviceVkImpl::CreatePipelineState(const PipelineStateCreateInfo& PSOCreateInfo, IPipelineState** ppPipelineState) +void RenderDeviceVkImpl::CreateGraphicsPipelineState(const GraphicsPipelineStateCreateInfo& PSOCreateInfo, IPipelineState** ppPipelineState) +{ + CreateDeviceObject( + "Pipeline State", PSOCreateInfo.PSODesc, ppPipelineState, + [&]() // + { + PipelineStateVkImpl* pPipelineStateVk(NEW_RC_OBJ(m_PSOAllocator, "PipelineStateVkImpl instance", PipelineStateVkImpl)(this, PSOCreateInfo)); + pPipelineStateVk->QueryInterface(IID_PipelineState, reinterpret_cast<IObject**>(ppPipelineState)); + OnCreateDeviceObject(pPipelineStateVk); + } // + ); +} + + +void RenderDeviceVkImpl::CreateComputePipelineState(const ComputePipelineStateCreateInfo& PSOCreateInfo, IPipelineState** ppPipelineState) { CreateDeviceObject( "Pipeline State", PSOCreateInfo.PSODesc, ppPipelineState, |
