summaryrefslogtreecommitdiffstats
path: root/Graphics/GraphicsEngineVulkan
diff options
context:
space:
mode:
authorazhirnov <zh1dron@gmail.com>2020-10-15 17:55:38 +0000
committerazhirnov <zh1dron@gmail.com>2020-10-15 17:59:25 +0000
commit259a9d5897937dcaaca1b4b294bb8d5250371e76 (patch)
treeb6123b30f228d05a7086a009cb35e2af713ed008 /Graphics/GraphicsEngineVulkan
parentA number of corrections for PSO refactoring (diff)
downloadDiligentCore-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')
-rw-r--r--Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.hpp14
-rw-r--r--Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.hpp7
-rw-r--r--Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp68
-rw-r--r--Graphics/GraphicsEngineVulkan/src/GenerateMipsVkHelper.cpp12
-rw-r--r--Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp147
-rw-r--r--Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp16
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,