summaryrefslogtreecommitdiffstats
path: root/Graphics
diff options
context:
space:
mode:
authorassiduous <assiduous@diligentgraphics.com>2020-10-20 20:26:21 +0000
committerassiduous <assiduous@diligentgraphics.com>2020-10-20 20:26:21 +0000
commit13b0b54987db2684e46e337d2e5be5b81366083b (patch)
tree40f2f3c7b180c7728bc8676cd32614e16fac17a0 /Graphics
parentRenamed USAGE_STATIC to USAGE_IMMUTABLE (API240077) (diff)
downloadDiligentCore-13b0b54987db2684e46e337d2e5be5b81366083b.tar.gz
DiligentCore-13b0b54987db2684e46e337d2e5be5b81366083b.zip
Improved exception safety of pipeline state object construction
Diffstat (limited to 'Graphics')
-rw-r--r--Graphics/GraphicsEngine/include/PipelineStateBase.hpp8
-rw-r--r--Graphics/GraphicsEngineD3D11/include/PipelineStateD3D11Impl.hpp4
-rw-r--r--Graphics/GraphicsEngineD3D11/include/ShaderResourceCacheD3D11.hpp2
-rw-r--r--Graphics/GraphicsEngineD3D11/include/ShaderResourceLayoutD3D11.hpp23
-rw-r--r--Graphics/GraphicsEngineD3D11/src/PipelineStateD3D11Impl.cpp210
-rw-r--r--Graphics/GraphicsEngineD3D11/src/ShaderResourceBindingD3D11Impl.cpp23
-rwxr-xr-xGraphics/GraphicsEngineD3D11/src/ShaderResourceCacheD3D11.cpp93
-rwxr-xr-xGraphics/GraphicsEngineD3D11/src/ShaderResourceLayoutD3D11.cpp23
-rw-r--r--Graphics/GraphicsEngineD3D12/include/PipelineStateD3D12Impl.hpp4
-rw-r--r--Graphics/GraphicsEngineD3D12/include/ShaderResourceCacheD3D12.hpp2
-rw-r--r--Graphics/GraphicsEngineD3D12/include/ShaderResourceLayoutD3D12.hpp25
-rw-r--r--Graphics/GraphicsEngineD3D12/include/ShaderVariableD3D12.hpp18
-rw-r--r--Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp501
-rw-r--r--Graphics/GraphicsEngineD3D12/src/ShaderResourceBindingD3D12Impl.cpp17
-rw-r--r--Graphics/GraphicsEngineD3D12/src/ShaderResourceLayoutD3D12.cpp27
-rw-r--r--Graphics/GraphicsEngineD3D12/src/ShaderVariableD3D12.cpp23
-rw-r--r--Graphics/GraphicsEngineD3DBase/include/ShaderResources.hpp2
-rw-r--r--Graphics/GraphicsEngineD3DBase/src/ShaderResources.cpp2
-rw-r--r--Graphics/GraphicsEngineOpenGL/include/GLProgramResourceCache.hpp2
-rw-r--r--Graphics/GraphicsEngineOpenGL/include/PipelineStateGLImpl.hpp2
-rw-r--r--Graphics/GraphicsEngineOpenGL/src/GLProgramResourceCache.cpp4
-rw-r--r--Graphics/GraphicsEngineOpenGL/src/PipelineStateGLImpl.cpp130
-rw-r--r--Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.hpp10
-rw-r--r--Graphics/GraphicsEngineVulkan/include/ShaderResourceCacheVk.hpp2
-rw-r--r--Graphics/GraphicsEngineVulkan/include/ShaderResourceLayoutVk.hpp2
-rw-r--r--Graphics/GraphicsEngineVulkan/include/ShaderVariableVk.hpp24
-rw-r--r--Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp123
-rw-r--r--Graphics/GraphicsEngineVulkan/src/ShaderResourceBindingVkImpl.cpp3
-rw-r--r--Graphics/GraphicsEngineVulkan/src/ShaderVariableVk.cpp29
29 files changed, 738 insertions, 600 deletions
diff --git a/Graphics/GraphicsEngine/include/PipelineStateBase.hpp b/Graphics/GraphicsEngine/include/PipelineStateBase.hpp
index c108f663..1effd32f 100644
--- a/Graphics/GraphicsEngine/include/PipelineStateBase.hpp
+++ b/Graphics/GraphicsEngine/include/PipelineStateBase.hpp
@@ -222,7 +222,7 @@ protected:
void ReserveSpaceForPipelineDesc(const GraphicsPipelineStateCreateInfo& CreateInfo,
- LinearAllocator& MemPool)
+ LinearAllocator& MemPool) noexcept
{
MemPool.AddSpace<GraphicsPipelineDesc>();
ReserveResourceLayout(CreateInfo.PSODesc.ResourceLayout, MemPool);
@@ -240,7 +240,7 @@ protected:
}
void ReserveSpaceForPipelineDesc(const ComputePipelineStateCreateInfo& CreateInfo,
- LinearAllocator& MemPool) const
+ LinearAllocator& MemPool) const noexcept
{
ReserveResourceLayout(CreateInfo.PSODesc.ResourceLayout, MemPool);
}
@@ -448,7 +448,7 @@ protected:
}
private:
- void ReserveResourceLayout(const PipelineResourceLayoutDesc& SrcLayout, LinearAllocator& MemPool) const
+ static void ReserveResourceLayout(const PipelineResourceLayoutDesc& SrcLayout, LinearAllocator& MemPool) noexcept
{
if (SrcLayout.Variables != nullptr)
{
@@ -471,7 +471,7 @@ private:
}
}
- void CopyResourceLayout(const PipelineResourceLayoutDesc& SrcLayout, PipelineResourceLayoutDesc& DstLayout, LinearAllocator& MemPool) const
+ static void CopyResourceLayout(const PipelineResourceLayoutDesc& SrcLayout, PipelineResourceLayoutDesc& DstLayout, LinearAllocator& MemPool)
{
if (SrcLayout.Variables != nullptr)
{
diff --git a/Graphics/GraphicsEngineD3D11/include/PipelineStateD3D11Impl.hpp b/Graphics/GraphicsEngineD3D11/include/PipelineStateD3D11Impl.hpp
index 0fa62606..520e9bb0 100644
--- a/Graphics/GraphicsEngineD3D11/include/PipelineStateD3D11Impl.hpp
+++ b/Graphics/GraphicsEngineD3D11/include/PipelineStateD3D11Impl.hpp
@@ -138,11 +138,13 @@ public:
private:
template <typename PSOCreateInfoType>
- LinearAllocator InitInternalObjects(const PSOCreateInfoType& CreateInfo);
+ void InitInternalObjects(const PSOCreateInfoType& CreateInfo);
void InitResourceLayouts(const PipelineStateCreateInfo& CreateInfo,
const std::vector<std::pair<SHADER_TYPE, ShaderD3D11Impl*>>& ShaderStages);
+ void Destruct();
+
CComPtr<ID3D11BlendState> m_pd3d11BlendState;
CComPtr<ID3D11RasterizerState> m_pd3d11RasterizerState;
CComPtr<ID3D11DepthStencilState> m_pd3d11DepthStencilState;
diff --git a/Graphics/GraphicsEngineD3D11/include/ShaderResourceCacheD3D11.hpp b/Graphics/GraphicsEngineD3D11/include/ShaderResourceCacheD3D11.hpp
index dc70eec1..7aa7126d 100644
--- a/Graphics/GraphicsEngineD3D11/include/ShaderResourceCacheD3D11.hpp
+++ b/Graphics/GraphicsEngineD3D11/include/ShaderResourceCacheD3D11.hpp
@@ -51,7 +51,7 @@ namespace Diligent
class ShaderResourceCacheD3D11
{
public:
- ShaderResourceCacheD3D11()
+ ShaderResourceCacheD3D11() noexcept
{}
~ShaderResourceCacheD3D11();
diff --git a/Graphics/GraphicsEngineD3D11/include/ShaderResourceLayoutD3D11.hpp b/Graphics/GraphicsEngineD3D11/include/ShaderResourceLayoutD3D11.hpp
index 4b4d13b2..9b2c2d9b 100644
--- a/Graphics/GraphicsEngineD3D11/include/ShaderResourceLayoutD3D11.hpp
+++ b/Graphics/GraphicsEngineD3D11/include/ShaderResourceLayoutD3D11.hpp
@@ -47,14 +47,19 @@ namespace Diligent
class ShaderResourceLayoutD3D11
{
public:
- ShaderResourceLayoutD3D11(IObject& Owner,
- std::shared_ptr<const ShaderResourcesD3D11> pSrcResources,
- const PipelineResourceLayoutDesc& ResourceLayout,
- const SHADER_RESOURCE_VARIABLE_TYPE* VarTypes,
- Uint32 NumVarTypes,
- ShaderResourceCacheD3D11& ResourceCache,
- IMemoryAllocator& ResCacheDataAllocator,
- IMemoryAllocator& ResLayoutDataAllocator);
+ ShaderResourceLayoutD3D11(IObject& Owner,
+ ShaderResourceCacheD3D11& ResourceCache) noexcept :
+ m_Owner{Owner},
+ m_ResourceCache{ResourceCache}
+ {
+ }
+
+ void Initialize(std::shared_ptr<const ShaderResourcesD3D11> pSrcResources,
+ const PipelineResourceLayoutDesc& ResourceLayout,
+ const SHADER_RESOURCE_VARIABLE_TYPE* VarTypes,
+ Uint32 NumVarTypes,
+ IMemoryAllocator& ResCacheDataAllocator,
+ IMemoryAllocator& ResLayoutDataAllocator);
~ShaderResourceLayoutD3D11();
// clang-format off
@@ -68,7 +73,7 @@ public:
static size_t GetRequiredMemorySize(const ShaderResourcesD3D11& SrcResources,
const PipelineResourceLayoutDesc& ResourceLayout,
const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes,
- Uint32 NumAllowedTypes);
+ Uint32 NumAllowedTypes) noexcept;
void CopyResources(ShaderResourceCacheD3D11& DstCache) const;
diff --git a/Graphics/GraphicsEngineD3D11/src/PipelineStateD3D11Impl.cpp b/Graphics/GraphicsEngineD3D11/src/PipelineStateD3D11Impl.cpp
index 722318f2..108f149c 100644
--- a/Graphics/GraphicsEngineD3D11/src/PipelineStateD3D11Impl.cpp
+++ b/Graphics/GraphicsEngineD3D11/src/PipelineStateD3D11Impl.cpp
@@ -36,30 +36,42 @@ namespace Diligent
{
template <typename PSOCreateInfoType>
-LinearAllocator PipelineStateD3D11Impl::InitInternalObjects(const PSOCreateInfoType& CreateInfo)
+void PipelineStateD3D11Impl::InitInternalObjects(const PSOCreateInfoType& CreateInfo)
{
m_ResourceLayoutIndex.fill(-1);
std::vector<std::pair<SHADER_TYPE, ShaderD3D11Impl*>> ShaderStages;
ExtractShaders<ShaderD3D11Impl>(CreateInfo, ShaderStages);
- // Memory must be released if an exception is thrown.
+ const auto NumShaderStages = GetNumShaderStages();
+ VERIFY_EXPR(NumShaderStages > 0 && NumShaderStages == ShaderStages.size());
+
LinearAllocator MemPool{GetRawAllocator()};
- MemPool.AddSpace<ShaderResourceLayoutD3D11>(GetNumShaderStages());
- MemPool.AddSpace<ShaderResourceCacheD3D11>(GetNumShaderStages());
+ MemPool.AddSpace<ShaderResourceCacheD3D11>(NumShaderStages);
+ MemPool.AddSpace<ShaderResourceLayoutD3D11>(NumShaderStages);
ReserveSpaceForPipelineDesc(CreateInfo, MemPool);
MemPool.Reserve();
- m_pStaticResourceLayouts = MemPool.Allocate<ShaderResourceLayoutD3D11>(GetNumShaderStages());
- m_pStaticResourceCaches = MemPool.Allocate<ShaderResourceCacheD3D11>(GetNumShaderStages());
+ m_pStaticResourceCaches = MemPool.ConstructArray<ShaderResourceCacheD3D11>(NumShaderStages);
+
+ // The memory is now owned by PipelineStateD3D11Impl and will be freed by Destruct().
+ auto* Ptr = MemPool.ReleaseOwnership();
+ VERIFY_EXPR(Ptr == m_pStaticResourceCaches);
+ (void)Ptr;
+
+ m_pStaticResourceLayouts = MemPool.Allocate<ShaderResourceLayoutD3D11>(NumShaderStages);
+ for (Uint32 i = 0; i < NumShaderStages; ++i)
+ new (m_pStaticResourceLayouts + i) ShaderResourceLayoutD3D11{*this, m_pStaticResourceCaches[i]}; // noexcept
InitializePipelineDesc(CreateInfo, MemPool);
- InitResourceLayouts(CreateInfo, ShaderStages);
- return MemPool;
+ // It is important to construct all objects before initializing them because if an exception is thrown,
+ // destructors will be called for all objects
+
+ InitResourceLayouts(CreateInfo, ShaderStages);
}
@@ -77,9 +89,11 @@ PipelineStateD3D11Impl::PipelineStateD3D11Impl(IReferenceCounters*
m_ImmutableSamplers (STD_ALLOCATOR_RAW_MEM(ImmutableSamplerInfo, GetRawAllocator(), "Allocator for vector<ImmutableSamplerInfo>"))
// clang-format on
{
- auto MemPool = InitInternalObjects(CreateInfo);
+ try
+ {
+ InitInternalObjects(CreateInfo);
- auto& GraphicsPipeline = GetGraphicsPipelineDesc();
+ auto& GraphicsPipeline = GetGraphicsPipelineDesc();
#define INIT_SHADER(ShortName, ExpectedType) \
do \
@@ -94,52 +108,55 @@ PipelineStateD3D11Impl::PipelineStateD3D11Impl(IReferenceCounters*
HashCombine(m_ShaderResourceLayoutHash, pShader->GetD3D11Resources()->GetHash()); \
} while (false)
- INIT_SHADER(VS, SHADER_TYPE_VERTEX);
- INIT_SHADER(PS, SHADER_TYPE_PIXEL);
- INIT_SHADER(GS, SHADER_TYPE_GEOMETRY);
- INIT_SHADER(DS, SHADER_TYPE_DOMAIN);
- INIT_SHADER(HS, SHADER_TYPE_HULL);
+ INIT_SHADER(VS, SHADER_TYPE_VERTEX);
+ INIT_SHADER(PS, SHADER_TYPE_PIXEL);
+ INIT_SHADER(GS, SHADER_TYPE_GEOMETRY);
+ INIT_SHADER(DS, SHADER_TYPE_DOMAIN);
+ INIT_SHADER(HS, SHADER_TYPE_HULL);
#undef INIT_SHADER
- if (m_pVS == nullptr)
- {
- LOG_ERROR_AND_THROW("Vertex shader is null");
- }
+ if (m_pVS == nullptr)
+ {
+ LOG_ERROR_AND_THROW("Vertex shader is null");
+ }
- auto* pDeviceD3D11 = pRenderDeviceD3D11->GetD3D11Device();
+ auto* pDeviceD3D11 = pRenderDeviceD3D11->GetD3D11Device();
- D3D11_BLEND_DESC D3D11BSDesc = {};
- BlendStateDesc_To_D3D11_BLEND_DESC(GraphicsPipeline.BlendDesc, D3D11BSDesc);
- CHECK_D3D_RESULT_THROW(pDeviceD3D11->CreateBlendState(&D3D11BSDesc, &m_pd3d11BlendState),
- "Failed to create D3D11 blend state object");
+ D3D11_BLEND_DESC D3D11BSDesc = {};
+ BlendStateDesc_To_D3D11_BLEND_DESC(GraphicsPipeline.BlendDesc, D3D11BSDesc);
+ CHECK_D3D_RESULT_THROW(pDeviceD3D11->CreateBlendState(&D3D11BSDesc, &m_pd3d11BlendState),
+ "Failed to create D3D11 blend state object");
- D3D11_RASTERIZER_DESC D3D11RSDesc = {};
- RasterizerStateDesc_To_D3D11_RASTERIZER_DESC(GraphicsPipeline.RasterizerDesc, D3D11RSDesc);
- CHECK_D3D_RESULT_THROW(pDeviceD3D11->CreateRasterizerState(&D3D11RSDesc, &m_pd3d11RasterizerState),
- "Failed to create D3D11 rasterizer state");
+ D3D11_RASTERIZER_DESC D3D11RSDesc = {};
+ RasterizerStateDesc_To_D3D11_RASTERIZER_DESC(GraphicsPipeline.RasterizerDesc, D3D11RSDesc);
+ CHECK_D3D_RESULT_THROW(pDeviceD3D11->CreateRasterizerState(&D3D11RSDesc, &m_pd3d11RasterizerState),
+ "Failed to create D3D11 rasterizer state");
- D3D11_DEPTH_STENCIL_DESC D3D11DSSDesc = {};
- DepthStencilStateDesc_To_D3D11_DEPTH_STENCIL_DESC(GraphicsPipeline.DepthStencilDesc, D3D11DSSDesc);
- CHECK_D3D_RESULT_THROW(pDeviceD3D11->CreateDepthStencilState(&D3D11DSSDesc, &m_pd3d11DepthStencilState),
- "Failed to create D3D11 depth stencil state");
+ D3D11_DEPTH_STENCIL_DESC D3D11DSSDesc = {};
+ DepthStencilStateDesc_To_D3D11_DEPTH_STENCIL_DESC(GraphicsPipeline.DepthStencilDesc, D3D11DSSDesc);
+ CHECK_D3D_RESULT_THROW(pDeviceD3D11->CreateDepthStencilState(&D3D11DSSDesc, &m_pd3d11DepthStencilState),
+ "Failed to create D3D11 depth stencil state");
- // Create input layout
- const auto& InputLayout = GraphicsPipeline.InputLayout;
- if (InputLayout.NumElements > 0)
- {
- std::vector<D3D11_INPUT_ELEMENT_DESC, STDAllocatorRawMem<D3D11_INPUT_ELEMENT_DESC>> d311InputElements(STD_ALLOCATOR_RAW_MEM(D3D11_INPUT_ELEMENT_DESC, GetRawAllocator(), "Allocator for vector<D3D11_INPUT_ELEMENT_DESC>"));
- LayoutElements_To_D3D11_INPUT_ELEMENT_DESCs(InputLayout, d311InputElements);
+ // Create input layout
+ const auto& InputLayout = GraphicsPipeline.InputLayout;
+ if (InputLayout.NumElements > 0)
+ {
+ std::vector<D3D11_INPUT_ELEMENT_DESC, STDAllocatorRawMem<D3D11_INPUT_ELEMENT_DESC>> d311InputElements(STD_ALLOCATOR_RAW_MEM(D3D11_INPUT_ELEMENT_DESC, GetRawAllocator(), "Allocator for vector<D3D11_INPUT_ELEMENT_DESC>"));
+ LayoutElements_To_D3D11_INPUT_ELEMENT_DESCs(InputLayout, d311InputElements);
- ID3DBlob* pVSByteCode = m_pVS.RawPtr<ShaderD3D11Impl>()->GetBytecode();
- if (!pVSByteCode)
- LOG_ERROR_AND_THROW("Vertex Shader byte code does not exist");
+ ID3DBlob* pVSByteCode = m_pVS.RawPtr<ShaderD3D11Impl>()->GetBytecode();
+ if (!pVSByteCode)
+ LOG_ERROR_AND_THROW("Vertex Shader byte code does not exist");
- CHECK_D3D_RESULT_THROW(pDeviceD3D11->CreateInputLayout(d311InputElements.data(), static_cast<UINT>(d311InputElements.size()), pVSByteCode->GetBufferPointer(), pVSByteCode->GetBufferSize(), &m_pd3d11InputLayout),
- "Failed to create the Direct3D11 input layout");
+ CHECK_D3D_RESULT_THROW(pDeviceD3D11->CreateInputLayout(d311InputElements.data(), static_cast<UINT>(d311InputElements.size()), pVSByteCode->GetBufferPointer(), pVSByteCode->GetBufferSize(), &m_pd3d11InputLayout),
+ "Failed to create the Direct3D11 input layout");
+ }
+ }
+ catch (...)
+ {
+ Destruct();
+ throw;
}
-
- auto* Ptr = MemPool.Release();
- VERIFY_EXPR(Ptr == m_pStaticResourceLayouts);
}
PipelineStateD3D11Impl::PipelineStateD3D11Impl(IReferenceCounters* pRefCounters,
@@ -156,38 +173,55 @@ PipelineStateD3D11Impl::PipelineStateD3D11Impl(IReferenceCounters*
m_ImmutableSamplers(STD_ALLOCATOR_RAW_MEM(ImmutableSamplerInfo, GetRawAllocator(), "Allocator for vector<ImmutableSamplerInfo>"))
// clang-format on
{
- auto MemPool = InitInternalObjects(CreateInfo);
-
- m_pCS = ValidatedCast<ShaderD3D11Impl>(CreateInfo.pCS);
- if (m_pCS == nullptr)
+ try
{
- LOG_ERROR_AND_THROW("Compute shader is null");
- }
+ InitInternalObjects(CreateInfo);
- if (m_pCS->GetDesc().ShaderType != SHADER_TYPE_COMPUTE)
+ m_pCS = ValidatedCast<ShaderD3D11Impl>(CreateInfo.pCS);
+ if (m_pCS == nullptr)
+ {
+ LOG_ERROR_AND_THROW("Compute shader is null");
+ }
+
+ if (m_pCS->GetDesc().ShaderType != SHADER_TYPE_COMPUTE)
+ {
+ LOG_ERROR_AND_THROW(GetShaderTypeLiteralName(SHADER_TYPE_COMPUTE), " shader is expeceted while ", GetShaderTypeLiteralName(m_pCS->GetDesc().ShaderType), " provided");
+ }
+ m_ShaderResourceLayoutHash = m_pCS->GetD3D11Resources()->GetHash();
+ }
+ catch (...)
{
- LOG_ERROR_AND_THROW(GetShaderTypeLiteralName(SHADER_TYPE_COMPUTE), " shader is expeceted while ", GetShaderTypeLiteralName(m_pCS->GetDesc().ShaderType), " provided");
+ Destruct();
+ throw;
}
- m_ShaderResourceLayoutHash = m_pCS->GetD3D11Resources()->GetHash();
-
- auto* Ptr = MemPool.Release();
- VERIFY_EXPR(Ptr == m_pStaticResourceLayouts);
}
PipelineStateD3D11Impl::~PipelineStateD3D11Impl()
{
- for (Uint32 s = 0; s < GetNumShaderStages(); ++s)
+ Destruct();
+}
+
+void PipelineStateD3D11Impl::Destruct()
+{
+ if (m_pStaticResourceLayouts != nullptr)
{
- m_pStaticResourceCaches[s].Destroy(GetRawAllocator());
- m_pStaticResourceCaches[s].~ShaderResourceCacheD3D11();
+ for (Uint32 l = 0; l < GetNumShaderStages(); ++l)
+ {
+ m_pStaticResourceLayouts[l].~ShaderResourceLayoutD3D11();
+ }
}
- for (Uint32 l = 0; l < GetNumShaderStages(); ++l)
+ if (m_pStaticResourceCaches != nullptr)
{
- m_pStaticResourceLayouts[l].~ShaderResourceLayoutD3D11();
+ for (Uint32 s = 0; s < GetNumShaderStages(); ++s)
+ {
+ m_pStaticResourceCaches[s].Destroy(GetRawAllocator());
+ m_pStaticResourceCaches[s].~ShaderResourceCacheD3D11();
+ }
}
- // m_pStaticResourceLayouts and m_pStaticResourceCaches are allocated in contiguous chunks of memory.
- if (auto* pRawMem = m_pStaticResourceLayouts)
+
+ // All subobjects are allocated in contiguous chunks of memory.
+ if (auto* pRawMem = m_pStaticResourceCaches)
GetRawAllocator().Free(pRawMem);
}
@@ -213,42 +247,36 @@ void PipelineStateD3D11Impl::InitResourceLayouts(const PipelineStateCreateInfo&
}
#endif
- decltype(m_ImmutableSamplers) ImmutableSamplers(STD_ALLOCATOR_RAW_MEM(ImmutableSamplerInfo, GetRawAllocator(), "Allocator for vector<ImmutableSamplerInfo>"));
+ decltype(m_ImmutableSamplers) ImmutableSamplers{STD_ALLOCATOR_RAW_MEM(ImmutableSamplerInfo, GetRawAllocator(), "Allocator for vector<ImmutableSamplerInfo>")};
+
std::array<size_t, MAX_SHADERS_IN_PIPELINE> ShaderResLayoutDataSizes = {};
std::array<size_t, MAX_SHADERS_IN_PIPELINE> ShaderResCacheDataSizes = {};
for (Uint32 s = 0; s < ShaderStages.size(); ++s)
{
- const auto* pShader = ShaderStages[s].second;
- const auto& ShaderDesc = pShader->GetDesc();
- const auto& ShaderResources = *pShader->GetD3D11Resources();
- VERIFY_EXPR(ShaderDesc.ShaderType == ShaderResources.GetShaderType());
+ const auto* pShader = ShaderStages[s].second;
+ const auto& ShaderDesc = pShader->GetDesc();
+ const auto& Resources = *pShader->GetD3D11Resources();
+ VERIFY_EXPR(ShaderDesc.ShaderType == Resources.GetShaderType());
- new (m_pStaticResourceCaches + s) ShaderResourceCacheD3D11;
- // Do not initialize the cache as this will be performed by the resource layout
+ // The cache will be initialized by the resource layout
// Shader resource layout will only contain dynamic and mutable variables
const SHADER_RESOURCE_VARIABLE_TYPE StaticVarTypes[] = {SHADER_RESOURCE_VARIABLE_TYPE_STATIC};
- // clang-format off
- new (m_pStaticResourceLayouts + s)
- ShaderResourceLayoutD3D11
- {
- *this,
- pShader->GetD3D11Resources(),
- m_Desc.ResourceLayout,
- StaticVarTypes,
- _countof(StaticVarTypes),
- m_pStaticResourceCaches[s],
- GetRawAllocator(),
- GetRawAllocator()
- };
- // clang-format on
+ m_pStaticResourceLayouts[s].Initialize(
+ pShader->GetD3D11Resources(),
+ m_Desc.ResourceLayout,
+ StaticVarTypes,
+ _countof(StaticVarTypes),
+ GetRawAllocator(),
+ GetRawAllocator() //
+ );
// Initialize immutable samplers
- for (Uint32 sam = 0; sam < ShaderResources.GetNumSamplers(); ++sam)
+ for (Uint32 sam = 0; sam < Resources.GetNumSamplers(); ++sam)
{
- const auto& SamplerAttribs = ShaderResources.GetSampler(sam);
+ const auto& SamplerAttribs = Resources.GetSampler(sam);
constexpr bool LogImtblSamplerArrayError = true;
- auto SrcImtblSamplerInd = ShaderResources.FindImmutableSampler(SamplerAttribs, ResourceLayout, LogImtblSamplerArrayError);
+ auto SrcImtblSamplerInd = Resources.FindImmutableSampler(SamplerAttribs, ResourceLayout, LogImtblSamplerArrayError);
if (SrcImtblSamplerInd >= 0)
{
const auto& SrcImtblSamplerInfo = ResourceLayout.ImmutableSamplers[SrcImtblSamplerInd];
@@ -267,8 +295,8 @@ void PipelineStateD3D11Impl::InitResourceLayouts(const PipelineStateCreateInfo&
SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE,
SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC //
};
- ShaderResLayoutDataSizes[s] = ShaderResourceLayoutD3D11::GetRequiredMemorySize(ShaderResources, ResourceLayout, SRBVarTypes, _countof(SRBVarTypes));
- ShaderResCacheDataSizes[s] = ShaderResourceCacheD3D11::GetRequriedMemorySize(ShaderResources);
+ ShaderResLayoutDataSizes[s] = ShaderResourceLayoutD3D11::GetRequiredMemorySize(Resources, ResourceLayout, SRBVarTypes, _countof(SRBVarTypes));
+ ShaderResCacheDataSizes[s] = ShaderResourceCacheD3D11::GetRequriedMemorySize(Resources);
}
auto ShaderInd = GetShaderTypePipelineIndex(ShaderDesc.ShaderType, m_Desc.PipelineType);
diff --git a/Graphics/GraphicsEngineD3D11/src/ShaderResourceBindingD3D11Impl.cpp b/Graphics/GraphicsEngineD3D11/src/ShaderResourceBindingD3D11Impl.cpp
index 5e95db97..f7ce059b 100644
--- a/Graphics/GraphicsEngineD3D11/src/ShaderResourceBindingD3D11Impl.cpp
+++ b/Graphics/GraphicsEngineD3D11/src/ShaderResourceBindingD3D11Impl.cpp
@@ -77,20 +77,15 @@ ShaderResourceBindingD3D11Impl::ShaderResourceBindingD3D11Impl(IReferenceCounter
// Shader resource layout will only contain dynamic and mutable variables
// http://diligentgraphics.com/diligent-engine/architecture/d3d11/shader-resource-cache#Shader-Resource-Cache-Initialization
SHADER_RESOURCE_VARIABLE_TYPE VarTypes[] = {SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE, SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC};
- // clang-format off
- new (m_pResourceLayouts + s)
- ShaderResourceLayoutD3D11
- {
- *this,
- pShaderD3D11->GetD3D11Resources(),
- PSODesc.ResourceLayout,
- VarTypes,
- _countof(VarTypes),
- m_pBoundResourceCaches[s],
- ResCacheDataAllocator,
- ResLayoutDataAllocator
- };
- // clang-format on
+ new (m_pResourceLayouts + s) ShaderResourceLayoutD3D11{*this, m_pBoundResourceCaches[s]};
+ m_pResourceLayouts[s].Initialize(
+ pShaderD3D11->GetD3D11Resources(),
+ PSODesc.ResourceLayout,
+ VarTypes,
+ _countof(VarTypes),
+ ResCacheDataAllocator,
+ ResLayoutDataAllocator //
+ );
const auto ShaderType = pShaderD3D11->GetDesc().ShaderType;
const auto ShaderInd = GetShaderTypePipelineIndex(ShaderType, PSODesc.PipelineType);
diff --git a/Graphics/GraphicsEngineD3D11/src/ShaderResourceCacheD3D11.cpp b/Graphics/GraphicsEngineD3D11/src/ShaderResourceCacheD3D11.cpp
index 28086285..3aaf82b7 100755
--- a/Graphics/GraphicsEngineD3D11/src/ShaderResourceCacheD3D11.cpp
+++ b/Graphics/GraphicsEngineD3D11/src/ShaderResourceCacheD3D11.cpp
@@ -148,61 +148,60 @@ void ShaderResourceCacheD3D11::Initialize(Uint32 CBCount, Uint32 SRVCount, Uint3
void ShaderResourceCacheD3D11::Destroy(IMemoryAllocator& MemAllocator)
{
- VERIFY(IsInitialized(), "Resource cache is not initialized");
+ if (!IsInitialized())
+ return;
+
VERIFY(m_pdbgMemoryAllocator == &MemAllocator, "The allocator does not match the one used to create resources");
- if (IsInitialized())
+ // Explicitly destory all objects
+ auto CBCount = GetCBCount();
+ if (CBCount != 0)
{
- // Explicitly destory all objects
- auto CBCount = GetCBCount();
- if (CBCount != 0)
- {
- CachedCB* CBs = nullptr;
- ID3D11Buffer** d3d11CBs = nullptr;
- GetCBArrays(CBs, d3d11CBs);
- for (size_t cb = 0; cb < CBCount; ++cb)
- CBs[cb].~CachedCB();
- }
+ CachedCB* CBs = nullptr;
+ ID3D11Buffer** d3d11CBs = nullptr;
+ GetCBArrays(CBs, d3d11CBs);
+ for (size_t cb = 0; cb < CBCount; ++cb)
+ CBs[cb].~CachedCB();
+ }
- auto SRVCount = GetSRVCount();
- if (SRVCount != 0)
- {
- CachedResource* SRVResources = nullptr;
- ID3D11ShaderResourceView** d3d11SRVs = nullptr;
- GetSRVArrays(SRVResources, d3d11SRVs);
- for (size_t srv = 0; srv < SRVCount; ++srv)
- SRVResources[srv].~CachedResource();
- }
+ auto SRVCount = GetSRVCount();
+ if (SRVCount != 0)
+ {
+ CachedResource* SRVResources = nullptr;
+ ID3D11ShaderResourceView** d3d11SRVs = nullptr;
+ GetSRVArrays(SRVResources, d3d11SRVs);
+ for (size_t srv = 0; srv < SRVCount; ++srv)
+ SRVResources[srv].~CachedResource();
+ }
- auto SamplerCount = GetSamplerCount();
- if (SamplerCount != 0)
- {
- CachedSampler* Samplers = nullptr;
- ID3D11SamplerState** d3d11Samplers = nullptr;
- GetSamplerArrays(Samplers, d3d11Samplers);
- for (size_t sam = 0; sam < SamplerCount; ++sam)
- Samplers[sam].~CachedSampler();
- }
+ auto SamplerCount = GetSamplerCount();
+ if (SamplerCount != 0)
+ {
+ CachedSampler* Samplers = nullptr;
+ ID3D11SamplerState** d3d11Samplers = nullptr;
+ GetSamplerArrays(Samplers, d3d11Samplers);
+ for (size_t sam = 0; sam < SamplerCount; ++sam)
+ Samplers[sam].~CachedSampler();
+ }
- auto UAVCount = GetUAVCount();
- if (UAVCount != 0)
- {
- CachedResource* UAVResources = nullptr;
- ID3D11UnorderedAccessView** d3d11UAVs = nullptr;
- GetUAVArrays(UAVResources, d3d11UAVs);
- for (size_t uav = 0; uav < UAVCount; ++uav)
- UAVResources[uav].~CachedResource();
- }
+ auto UAVCount = GetUAVCount();
+ if (UAVCount != 0)
+ {
+ CachedResource* UAVResources = nullptr;
+ ID3D11UnorderedAccessView** d3d11UAVs = nullptr;
+ GetUAVArrays(UAVResources, d3d11UAVs);
+ for (size_t uav = 0; uav < UAVCount; ++uav)
+ UAVResources[uav].~CachedResource();
+ }
- m_SRVOffset = InvalidResourceOffset;
- m_SamplerOffset = InvalidResourceOffset;
- m_UAVOffset = InvalidResourceOffset;
- m_MemoryEndOffset = InvalidResourceOffset;
+ m_SRVOffset = InvalidResourceOffset;
+ m_SamplerOffset = InvalidResourceOffset;
+ m_UAVOffset = InvalidResourceOffset;
+ m_MemoryEndOffset = InvalidResourceOffset;
- if (m_pResourceData != nullptr)
- MemAllocator.Free(m_pResourceData);
- m_pResourceData = nullptr;
- }
+ if (m_pResourceData != nullptr)
+ MemAllocator.Free(m_pResourceData);
+ m_pResourceData = nullptr;
}
ShaderResourceCacheD3D11::~ShaderResourceCacheD3D11()
diff --git a/Graphics/GraphicsEngineD3D11/src/ShaderResourceLayoutD3D11.cpp b/Graphics/GraphicsEngineD3D11/src/ShaderResourceLayoutD3D11.cpp
index c1e6e65a..f7c1958d 100755
--- a/Graphics/GraphicsEngineD3D11/src/ShaderResourceLayoutD3D11.cpp
+++ b/Graphics/GraphicsEngineD3D11/src/ShaderResourceLayoutD3D11.cpp
@@ -84,7 +84,7 @@ ShaderResourceLayoutD3D11::~ShaderResourceLayoutD3D11()
size_t ShaderResourceLayoutD3D11::GetRequiredMemorySize(const ShaderResourcesD3D11& SrcResources,
const PipelineResourceLayoutDesc& ResourceLayout,
const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes,
- Uint32 NumAllowedTypes)
+ Uint32 NumAllowedTypes) noexcept
{
// Skip immutable samplers as they are initialized directly in the resource cache by the PSO
constexpr bool CountImtblSamplers = false;
@@ -101,20 +101,15 @@ size_t ShaderResourceLayoutD3D11::GetRequiredMemorySize(const ShaderResourcesD3D
}
-ShaderResourceLayoutD3D11::ShaderResourceLayoutD3D11(IObject& Owner,
- std::shared_ptr<const ShaderResourcesD3D11> pSrcResources,
- const PipelineResourceLayoutDesc& ResourceLayout,
- const SHADER_RESOURCE_VARIABLE_TYPE* VarTypes,
- Uint32 NumVarTypes,
- ShaderResourceCacheD3D11& ResourceCache,
- IMemoryAllocator& ResCacheDataAllocator,
- IMemoryAllocator& ResLayoutDataAllocator) :
- // clang-format off
- m_Owner {Owner},
- m_pResources {std::move(pSrcResources)},
- m_ResourceCache {ResourceCache}
-// clang-format on
+void ShaderResourceLayoutD3D11::Initialize(std::shared_ptr<const ShaderResourcesD3D11> pSrcResources,
+ const PipelineResourceLayoutDesc& ResourceLayout,
+ const SHADER_RESOURCE_VARIABLE_TYPE* VarTypes,
+ Uint32 NumVarTypes,
+ IMemoryAllocator& ResCacheDataAllocator,
+ IMemoryAllocator& ResLayoutDataAllocator)
{
+ m_pResources = std::move(pSrcResources);
+
// http://diligentgraphics.com/diligent-engine/architecture/d3d11/shader-resource-layout#Shader-Resource-Layout-Initialization
const auto AllowedTypeBits = GetAllowedTypeBits(VarTypes, NumVarTypes);
diff --git a/Graphics/GraphicsEngineD3D12/include/PipelineStateD3D12Impl.hpp b/Graphics/GraphicsEngineD3D12/include/PipelineStateD3D12Impl.hpp
index 31d95179..fa761fc7 100644
--- a/Graphics/GraphicsEngineD3D12/include/PipelineStateD3D12Impl.hpp
+++ b/Graphics/GraphicsEngineD3D12/include/PipelineStateD3D12Impl.hpp
@@ -133,11 +133,13 @@ private:
};
template <typename PSOCreateInfoType>
- LinearAllocator InitInternalObjects(const PSOCreateInfoType& CreateInfo, std::vector<D3D12PipelineShaderStageInfo>& ShaderStages);
+ void InitInternalObjects(const PSOCreateInfoType& CreateInfo, std::vector<D3D12PipelineShaderStageInfo>& ShaderStages);
void InitResourceLayouts(const PipelineStateCreateInfo& CreateInfo,
std::vector<D3D12PipelineShaderStageInfo>& ShaderStages);
+ void Destruct();
+
CComPtr<ID3D12PipelineState> m_pd3d12PSO;
RootSignature m_RootSig;
diff --git a/Graphics/GraphicsEngineD3D12/include/ShaderResourceCacheD3D12.hpp b/Graphics/GraphicsEngineD3D12/include/ShaderResourceCacheD3D12.hpp
index 1a0362ab..8a8f7b25 100644
--- a/Graphics/GraphicsEngineD3D12/include/ShaderResourceCacheD3D12.hpp
+++ b/Graphics/GraphicsEngineD3D12/include/ShaderResourceCacheD3D12.hpp
@@ -110,7 +110,7 @@ public:
SRBResources
};
- ShaderResourceCacheD3D12(DbgCacheContentType dbgContentType)
+ ShaderResourceCacheD3D12(DbgCacheContentType dbgContentType) noexcept
// clang-format off
#ifdef DILIGENT_DEBUG
: m_DbgContentType
diff --git a/Graphics/GraphicsEngineD3D12/include/ShaderResourceLayoutD3D12.hpp b/Graphics/GraphicsEngineD3D12/include/ShaderResourceLayoutD3D12.hpp
index 5426d98b..719345fc 100644
--- a/Graphics/GraphicsEngineD3D12/include/ShaderResourceLayoutD3D12.hpp
+++ b/Graphics/GraphicsEngineD3D12/include/ShaderResourceLayoutD3D12.hpp
@@ -112,21 +112,24 @@ namespace Diligent
class ShaderResourceLayoutD3D12 final
{
public:
- // There are two modes a layout can be constructed:
+ explicit ShaderResourceLayoutD3D12(IObject& Owner) noexcept :
+ m_Owner{Owner}
+ {}
+
+ // There are two modes a layout can be initialized:
// - initialize static resource layout and initialize shader resource cache to hold static resources
// - initialize reference layouts that address all types of resources (static, mutable, dynamic).
// Root indices and descriptor table offsets are assigned during the initialization;
// no shader resource cache is provided
- ShaderResourceLayoutD3D12(IObject& Owner,
- ID3D12Device* pd3d12Device,
- PIPELINE_TYPE PipelineType,
- const PipelineResourceLayoutDesc& ResourceLayout,
- std::shared_ptr<const ShaderResourcesD3D12> pSrcResources,
- IMemoryAllocator& LayoutDataAllocator,
- const SHADER_RESOURCE_VARIABLE_TYPE* const VarTypes,
- Uint32 NumAllowedTypes,
- ShaderResourceCacheD3D12* pResourceCache,
- class RootSignature* pRootSig);
+ void Initialize(ID3D12Device* pd3d12Device,
+ PIPELINE_TYPE PipelineType,
+ const PipelineResourceLayoutDesc& ResourceLayout,
+ std::shared_ptr<const ShaderResourcesD3D12> pSrcResources,
+ IMemoryAllocator& LayoutDataAllocator,
+ const SHADER_RESOURCE_VARIABLE_TYPE* const VarTypes,
+ Uint32 NumAllowedTypes,
+ ShaderResourceCacheD3D12* pResourceCache,
+ class RootSignature* pRootSig);
// clang-format off
ShaderResourceLayoutD3D12 (const ShaderResourceLayoutD3D12&) = delete;
diff --git a/Graphics/GraphicsEngineD3D12/include/ShaderVariableD3D12.hpp b/Graphics/GraphicsEngineD3D12/include/ShaderVariableD3D12.hpp
index 213748d9..c30d8296 100644
--- a/Graphics/GraphicsEngineD3D12/include/ShaderVariableD3D12.hpp
+++ b/Graphics/GraphicsEngineD3D12/include/ShaderVariableD3D12.hpp
@@ -76,12 +76,16 @@ class ShaderVariableD3D12Impl;
class ShaderVariableManagerD3D12
{
public:
- ShaderVariableManagerD3D12(IObject& Owner,
- const ShaderResourceLayoutD3D12& Layout,
- IMemoryAllocator& Allocator,
- const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes,
- Uint32 NumAllowedTypes,
- ShaderResourceCacheD3D12& ResourceCache);
+ ShaderVariableManagerD3D12(IObject& Owner,
+ ShaderResourceCacheD3D12& ResourceCache) noexcept :
+ m_Owner{Owner},
+ m_ResourceCache{ResourceCache}
+ {}
+
+ void Initialize(const ShaderResourceLayoutD3D12& Layout,
+ IMemoryAllocator& Allocator,
+ const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes,
+ Uint32 NumAllowedTypes);
~ShaderVariableManagerD3D12();
void Destroy(IMemoryAllocator& Allocator);
@@ -120,7 +124,7 @@ private:
Uint32 m_NumVariables = 0;
#ifdef DILIGENT_DEBUG
- IMemoryAllocator& m_DbgAllocator;
+ IMemoryAllocator* m_pDbgAllocator = nullptr;
#endif
// clang-format on
};
diff --git a/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp
index b65ad4fc..2d31e70d 100644
--- a/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp
+++ b/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp
@@ -99,34 +99,47 @@ private:
};
template <typename PSOCreateInfoType>
-LinearAllocator PipelineStateD3D12Impl::InitInternalObjects(const PSOCreateInfoType& CreateInfo,
- std::vector<D3D12PipelineShaderStageInfo>& ShaderStages)
+void PipelineStateD3D12Impl::InitInternalObjects(const PSOCreateInfoType& CreateInfo,
+ std::vector<D3D12PipelineShaderStageInfo>& ShaderStages)
{
m_ResourceLayoutIndex.fill(-1);
ExtractShaders<ShaderD3D12Impl>(CreateInfo, ShaderStages);
- // Memory must be released if an exception is thrown.
LinearAllocator MemPool{GetRawAllocator()};
- MemPool.AddSpace<ShaderResourceLayoutD3D12>(GetNumShaderStages() * 2);
- MemPool.AddSpace<ShaderResourceCacheD3D12>(GetNumShaderStages());
- MemPool.AddSpace<ShaderVariableManagerD3D12>(GetNumShaderStages());
+ const auto NumShaderStages = GetNumShaderStages();
+ VERIFY_EXPR(NumShaderStages > 0 && NumShaderStages == ShaderStages.size());
+
+ MemPool.AddSpace<ShaderResourceCacheD3D12>(NumShaderStages);
+ MemPool.AddSpace<ShaderResourceLayoutD3D12>(NumShaderStages * 2);
+ MemPool.AddSpace<ShaderVariableManagerD3D12>(NumShaderStages);
ReserveSpaceForPipelineDesc(CreateInfo, MemPool);
MemPool.Reserve();
- m_RootSig.AllocateImmutableSamplers(CreateInfo.PSODesc.ResourceLayout);
+ m_pStaticResourceCaches = MemPool.ConstructArray<ShaderResourceCacheD3D12>(NumShaderStages, ShaderResourceCacheD3D12::DbgCacheContentType::StaticShaderResources);
+
+ // The memory is now owned by PipelineStateD3D12Impl and will be freed by Destruct().
+ auto* Ptr = MemPool.ReleaseOwnership();
+ VERIFY_EXPR(Ptr == m_pStaticResourceCaches);
+ (void)Ptr;
- m_pShaderResourceLayouts = MemPool.Allocate<ShaderResourceLayoutD3D12>(GetNumShaderStages() * 2);
- m_pStaticResourceCaches = MemPool.Allocate<ShaderResourceCacheD3D12>(GetNumShaderStages());
- m_pStaticVarManagers = MemPool.Allocate<ShaderVariableManagerD3D12>(GetNumShaderStages());
+ m_pShaderResourceLayouts = MemPool.ConstructArray<ShaderResourceLayoutD3D12>(NumShaderStages * 2, std::ref(*this));
+
+ m_pStaticVarManagers = MemPool.Allocate<ShaderVariableManagerD3D12>(NumShaderStages);
+ for (Uint32 s = 0; s < NumShaderStages; ++s)
+ new (m_pStaticVarManagers + s) ShaderVariableManagerD3D12{*this, GetStaticShaderResCache(s)};
InitializePipelineDesc(CreateInfo, MemPool);
- InitResourceLayouts(CreateInfo, ShaderStages);
- return MemPool;
+ m_RootSig.AllocateImmutableSamplers(CreateInfo.PSODesc.ResourceLayout);
+
+ // It is important to construct all objects before initializing them because if an exception is thrown,
+ // destructors will be called for all objects
+
+ InitResourceLayouts(CreateInfo, ShaderStages);
}
@@ -136,197 +149,202 @@ PipelineStateD3D12Impl::PipelineStateD3D12Impl(IReferenceCounters*
TPipelineStateBase{pRefCounters, pDeviceD3D12, CreateInfo.PSODesc},
m_SRBMemAllocator{GetRawAllocator()}
{
- std::vector<D3D12PipelineShaderStageInfo> ShaderStages;
-
- auto MemPool = InitInternalObjects(CreateInfo, ShaderStages);
-
- auto pd3d12Device = pDeviceD3D12->GetD3D12Device();
- if (m_Desc.PipelineType == PIPELINE_TYPE_GRAPHICS)
+ try
{
- const auto& GraphicsPipeline = GetGraphicsPipelineDesc();
+ std::vector<D3D12PipelineShaderStageInfo> ShaderStages;
- D3D12_GRAPHICS_PIPELINE_STATE_DESC d3d12PSODesc = {};
+ InitInternalObjects(CreateInfo, ShaderStages);
- for (const auto& Stage : ShaderStages)
+ auto pd3d12Device = pDeviceD3D12->GetD3D12Device();
+ if (m_Desc.PipelineType == PIPELINE_TYPE_GRAPHICS)
{
- auto* pShaderD3D12 = Stage.pShader;
- auto ShaderType = pShaderD3D12->GetDesc().ShaderType;
- VERIFY_EXPR(ShaderType == Stage.Type);
+ const auto& GraphicsPipeline = GetGraphicsPipelineDesc();
+
+ D3D12_GRAPHICS_PIPELINE_STATE_DESC d3d12PSODesc = {};
- D3D12_SHADER_BYTECODE* pd3d12ShaderBytecode = nullptr;
- switch (ShaderType)
+ for (const auto& Stage : ShaderStages)
{
- // clang-format off
+ auto* pShaderD3D12 = Stage.pShader;
+ auto ShaderType = pShaderD3D12->GetDesc().ShaderType;
+ VERIFY_EXPR(ShaderType == Stage.Type);
+
+ D3D12_SHADER_BYTECODE* pd3d12ShaderBytecode = nullptr;
+ switch (ShaderType)
+ {
+ // clang-format off
case SHADER_TYPE_VERTEX: pd3d12ShaderBytecode = &d3d12PSODesc.VS; break;
case SHADER_TYPE_PIXEL: pd3d12ShaderBytecode = &d3d12PSODesc.PS; break;
case SHADER_TYPE_GEOMETRY: pd3d12ShaderBytecode = &d3d12PSODesc.GS; break;
case SHADER_TYPE_HULL: pd3d12ShaderBytecode = &d3d12PSODesc.HS; break;
case SHADER_TYPE_DOMAIN: pd3d12ShaderBytecode = &d3d12PSODesc.DS; break;
- // clang-format on
- default: UNEXPECTED("Unexpected shader type");
- }
- auto* pByteCode = pShaderD3D12->GetShaderByteCode();
+ // clang-format on
+ default: UNEXPECTED("Unexpected shader type");
+ }
+ auto* pByteCode = pShaderD3D12->GetShaderByteCode();
- pd3d12ShaderBytecode->pShaderBytecode = pByteCode->GetBufferPointer();
- pd3d12ShaderBytecode->BytecodeLength = pByteCode->GetBufferSize();
- }
+ pd3d12ShaderBytecode->pShaderBytecode = pByteCode->GetBufferPointer();
+ pd3d12ShaderBytecode->BytecodeLength = pByteCode->GetBufferSize();
+ }
- d3d12PSODesc.pRootSignature = m_RootSig.GetD3D12RootSignature();
+ d3d12PSODesc.pRootSignature = m_RootSig.GetD3D12RootSignature();
- memset(&d3d12PSODesc.StreamOutput, 0, sizeof(d3d12PSODesc.StreamOutput));
+ memset(&d3d12PSODesc.StreamOutput, 0, sizeof(d3d12PSODesc.StreamOutput));
- BlendStateDesc_To_D3D12_BLEND_DESC(GraphicsPipeline.BlendDesc, d3d12PSODesc.BlendState);
- // The sample mask for the blend state.
- d3d12PSODesc.SampleMask = GraphicsPipeline.SampleMask;
+ BlendStateDesc_To_D3D12_BLEND_DESC(GraphicsPipeline.BlendDesc, d3d12PSODesc.BlendState);
+ // The sample mask for the blend state.
+ d3d12PSODesc.SampleMask = GraphicsPipeline.SampleMask;
- RasterizerStateDesc_To_D3D12_RASTERIZER_DESC(GraphicsPipeline.RasterizerDesc, d3d12PSODesc.RasterizerState);
- DepthStencilStateDesc_To_D3D12_DEPTH_STENCIL_DESC(GraphicsPipeline.DepthStencilDesc, d3d12PSODesc.DepthStencilState);
+ RasterizerStateDesc_To_D3D12_RASTERIZER_DESC(GraphicsPipeline.RasterizerDesc, d3d12PSODesc.RasterizerState);
+ DepthStencilStateDesc_To_D3D12_DEPTH_STENCIL_DESC(GraphicsPipeline.DepthStencilDesc, d3d12PSODesc.DepthStencilState);
- std::vector<D3D12_INPUT_ELEMENT_DESC, STDAllocatorRawMem<D3D12_INPUT_ELEMENT_DESC>> d312InputElements(STD_ALLOCATOR_RAW_MEM(D3D12_INPUT_ELEMENT_DESC, GetRawAllocator(), "Allocator for vector<D3D12_INPUT_ELEMENT_DESC>"));
+ std::vector<D3D12_INPUT_ELEMENT_DESC, STDAllocatorRawMem<D3D12_INPUT_ELEMENT_DESC>> d312InputElements(STD_ALLOCATOR_RAW_MEM(D3D12_INPUT_ELEMENT_DESC, GetRawAllocator(), "Allocator for vector<D3D12_INPUT_ELEMENT_DESC>"));
- const auto& InputLayout = GetGraphicsPipelineDesc().InputLayout;
- if (InputLayout.NumElements > 0)
- {
- LayoutElements_To_D3D12_INPUT_ELEMENT_DESCs(InputLayout, d312InputElements);
- d3d12PSODesc.InputLayout.NumElements = static_cast<UINT>(d312InputElements.size());
- d3d12PSODesc.InputLayout.pInputElementDescs = d312InputElements.data();
- }
- else
- {
- d3d12PSODesc.InputLayout.NumElements = 0;
- d3d12PSODesc.InputLayout.pInputElementDescs = nullptr;
- }
+ const auto& InputLayout = GetGraphicsPipelineDesc().InputLayout;
+ if (InputLayout.NumElements > 0)
+ {
+ LayoutElements_To_D3D12_INPUT_ELEMENT_DESCs(InputLayout, d312InputElements);
+ d3d12PSODesc.InputLayout.NumElements = static_cast<UINT>(d312InputElements.size());
+ d3d12PSODesc.InputLayout.pInputElementDescs = d312InputElements.data();
+ }
+ else
+ {
+ d3d12PSODesc.InputLayout.NumElements = 0;
+ d3d12PSODesc.InputLayout.pInputElementDescs = nullptr;
+ }
- d3d12PSODesc.IBStripCutValue = D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_DISABLED;
- static const PrimitiveTopology_To_D3D12_PRIMITIVE_TOPOLOGY_TYPE PrimTopologyToD3D12TopologyType;
- d3d12PSODesc.PrimitiveTopologyType = PrimTopologyToD3D12TopologyType[GraphicsPipeline.PrimitiveTopology];
+ d3d12PSODesc.IBStripCutValue = D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_DISABLED;
+ static const PrimitiveTopology_To_D3D12_PRIMITIVE_TOPOLOGY_TYPE PrimTopologyToD3D12TopologyType;
+ d3d12PSODesc.PrimitiveTopologyType = PrimTopologyToD3D12TopologyType[GraphicsPipeline.PrimitiveTopology];
- d3d12PSODesc.NumRenderTargets = GraphicsPipeline.NumRenderTargets;
- for (Uint32 rt = 0; rt < GraphicsPipeline.NumRenderTargets; ++rt)
- d3d12PSODesc.RTVFormats[rt] = TexFormatToDXGI_Format(GraphicsPipeline.RTVFormats[rt]);
- for (Uint32 rt = GraphicsPipeline.NumRenderTargets; rt < _countof(d3d12PSODesc.RTVFormats); ++rt)
- d3d12PSODesc.RTVFormats[rt] = DXGI_FORMAT_UNKNOWN;
- d3d12PSODesc.DSVFormat = TexFormatToDXGI_Format(GraphicsPipeline.DSVFormat);
+ d3d12PSODesc.NumRenderTargets = GraphicsPipeline.NumRenderTargets;
+ for (Uint32 rt = 0; rt < GraphicsPipeline.NumRenderTargets; ++rt)
+ d3d12PSODesc.RTVFormats[rt] = TexFormatToDXGI_Format(GraphicsPipeline.RTVFormats[rt]);
+ for (Uint32 rt = GraphicsPipeline.NumRenderTargets; rt < _countof(d3d12PSODesc.RTVFormats); ++rt)
+ d3d12PSODesc.RTVFormats[rt] = DXGI_FORMAT_UNKNOWN;
+ d3d12PSODesc.DSVFormat = TexFormatToDXGI_Format(GraphicsPipeline.DSVFormat);
- d3d12PSODesc.SampleDesc.Count = GraphicsPipeline.SmplDesc.Count;
- d3d12PSODesc.SampleDesc.Quality = GraphicsPipeline.SmplDesc.Quality;
+ d3d12PSODesc.SampleDesc.Count = GraphicsPipeline.SmplDesc.Count;
+ d3d12PSODesc.SampleDesc.Quality = GraphicsPipeline.SmplDesc.Quality;
- // For single GPU operation, set this to zero. If there are multiple GPU nodes,
- // set bits to identify the nodes (the device's physical adapters) for which the
- // graphics pipeline state is to apply. Each bit in the mask corresponds to a single node.
- d3d12PSODesc.NodeMask = 0;
+ // For single GPU operation, set this to zero. If there are multiple GPU nodes,
+ // set bits to identify the nodes (the device's physical adapters) for which the
+ // graphics pipeline state is to apply. Each bit in the mask corresponds to a single node.
+ d3d12PSODesc.NodeMask = 0;
- d3d12PSODesc.CachedPSO.pCachedBlob = nullptr;
- d3d12PSODesc.CachedPSO.CachedBlobSizeInBytes = 0;
+ d3d12PSODesc.CachedPSO.pCachedBlob = nullptr;
+ d3d12PSODesc.CachedPSO.CachedBlobSizeInBytes = 0;
- // The only valid bit is D3D12_PIPELINE_STATE_FLAG_TOOL_DEBUG, which can only be set on WARP devices.
- d3d12PSODesc.Flags = D3D12_PIPELINE_STATE_FLAG_NONE;
+ // The only valid bit is D3D12_PIPELINE_STATE_FLAG_TOOL_DEBUG, which can only be set on WARP devices.
+ d3d12PSODesc.Flags = D3D12_PIPELINE_STATE_FLAG_NONE;
- HRESULT hr = pd3d12Device->CreateGraphicsPipelineState(&d3d12PSODesc, __uuidof(ID3D12PipelineState), reinterpret_cast<void**>(static_cast<ID3D12PipelineState**>(&m_pd3d12PSO)));
- if (FAILED(hr))
- LOG_ERROR_AND_THROW("Failed to create pipeline state");
- }
+ HRESULT hr = pd3d12Device->CreateGraphicsPipelineState(&d3d12PSODesc, __uuidof(ID3D12PipelineState), reinterpret_cast<void**>(static_cast<ID3D12PipelineState**>(&m_pd3d12PSO)));
+ if (FAILED(hr))
+ LOG_ERROR_AND_THROW("Failed to create pipeline state");
+ }
#ifdef D3D12_H_HAS_MESH_SHADER
- else if (m_Desc.PipelineType == PIPELINE_TYPE_MESH)
- {
- const auto& GraphicsPipeline = GetGraphicsPipelineDesc();
-
- struct MESH_SHADER_PIPELINE_STATE_DESC
+ else if (m_Desc.PipelineType == PIPELINE_TYPE_MESH)
{
- PSS_SubObject<D3D12_PIPELINE_STATE_FLAGS, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_FLAGS> Flags;
- PSS_SubObject<UINT, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_NODE_MASK> NodeMask;
- PSS_SubObject<ID3D12RootSignature*, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_ROOT_SIGNATURE> pRootSignature;
- PSS_SubObject<D3D12_SHADER_BYTECODE, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_PS> PS;
- PSS_SubObject<D3D12_SHADER_BYTECODE, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_AS> AS;
- PSS_SubObject<D3D12_SHADER_BYTECODE, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_MS> MS;
- PSS_SubObject<D3D12_BLEND_DESC, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_BLEND> BlendState;
- PSS_SubObject<D3D12_DEPTH_STENCIL_DESC, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_DEPTH_STENCIL> DepthStencilState;
- PSS_SubObject<D3D12_RASTERIZER_DESC, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_RASTERIZER> RasterizerState;
- PSS_SubObject<DXGI_SAMPLE_DESC, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_SAMPLE_DESC> SampleDesc;
- PSS_SubObject<UINT, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_SAMPLE_MASK> SampleMask;
- PSS_SubObject<DXGI_FORMAT, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_DEPTH_STENCIL_FORMAT> DSVFormat;
- PSS_SubObject<D3D12_RT_FORMAT_ARRAY, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_RENDER_TARGET_FORMATS> RTVFormatArray;
- PSS_SubObject<D3D12_CACHED_PIPELINE_STATE, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_CACHED_PSO> CachedPSO;
- };
- MESH_SHADER_PIPELINE_STATE_DESC d3d12PSODesc = {};
-
- for (const auto& Stage : ShaderStages)
- {
- auto* pShaderD3D12 = Stage.pShader;
- auto ShaderType = pShaderD3D12->GetDesc().ShaderType;
- VERIFY_EXPR(ShaderType == Stage.Type);
+ const auto& GraphicsPipeline = GetGraphicsPipelineDesc();
- D3D12_SHADER_BYTECODE* pd3d12ShaderBytecode = nullptr;
- switch (ShaderType)
+ struct MESH_SHADER_PIPELINE_STATE_DESC
{
- // clang-format off
+ PSS_SubObject<D3D12_PIPELINE_STATE_FLAGS, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_FLAGS> Flags;
+ PSS_SubObject<UINT, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_NODE_MASK> NodeMask;
+ PSS_SubObject<ID3D12RootSignature*, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_ROOT_SIGNATURE> pRootSignature;
+ PSS_SubObject<D3D12_SHADER_BYTECODE, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_PS> PS;
+ PSS_SubObject<D3D12_SHADER_BYTECODE, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_AS> AS;
+ PSS_SubObject<D3D12_SHADER_BYTECODE, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_MS> MS;
+ PSS_SubObject<D3D12_BLEND_DESC, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_BLEND> BlendState;
+ PSS_SubObject<D3D12_DEPTH_STENCIL_DESC, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_DEPTH_STENCIL> DepthStencilState;
+ PSS_SubObject<D3D12_RASTERIZER_DESC, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_RASTERIZER> RasterizerState;
+ PSS_SubObject<DXGI_SAMPLE_DESC, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_SAMPLE_DESC> SampleDesc;
+ PSS_SubObject<UINT, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_SAMPLE_MASK> SampleMask;
+ PSS_SubObject<DXGI_FORMAT, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_DEPTH_STENCIL_FORMAT> DSVFormat;
+ PSS_SubObject<D3D12_RT_FORMAT_ARRAY, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_RENDER_TARGET_FORMATS> RTVFormatArray;
+ PSS_SubObject<D3D12_CACHED_PIPELINE_STATE, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_CACHED_PSO> CachedPSO;
+ };
+ MESH_SHADER_PIPELINE_STATE_DESC d3d12PSODesc = {};
+
+ for (const auto& Stage : ShaderStages)
+ {
+ auto* pShaderD3D12 = Stage.pShader;
+ auto ShaderType = pShaderD3D12->GetDesc().ShaderType;
+ VERIFY_EXPR(ShaderType == Stage.Type);
+
+ D3D12_SHADER_BYTECODE* pd3d12ShaderBytecode = nullptr;
+ switch (ShaderType)
+ {
+ // clang-format off
case SHADER_TYPE_AMPLIFICATION: pd3d12ShaderBytecode = &d3d12PSODesc.AS; break;
case SHADER_TYPE_MESH: pd3d12ShaderBytecode = &d3d12PSODesc.MS; break;
case SHADER_TYPE_PIXEL: pd3d12ShaderBytecode = &d3d12PSODesc.PS; break;
- // clang-format on
- default: UNEXPECTED("Unexpected shader type");
- }
- auto* pByteCode = pShaderD3D12->GetShaderByteCode();
+ // clang-format on
+ default: UNEXPECTED("Unexpected shader type");
+ }
+ auto* pByteCode = pShaderD3D12->GetShaderByteCode();
- pd3d12ShaderBytecode->pShaderBytecode = pByteCode->GetBufferPointer();
- pd3d12ShaderBytecode->BytecodeLength = pByteCode->GetBufferSize();
- }
+ pd3d12ShaderBytecode->pShaderBytecode = pByteCode->GetBufferPointer();
+ pd3d12ShaderBytecode->BytecodeLength = pByteCode->GetBufferSize();
+ }
- d3d12PSODesc.pRootSignature = m_RootSig.GetD3D12RootSignature();
+ d3d12PSODesc.pRootSignature = m_RootSig.GetD3D12RootSignature();
- BlendStateDesc_To_D3D12_BLEND_DESC(GraphicsPipeline.BlendDesc, *d3d12PSODesc.BlendState);
- d3d12PSODesc.SampleMask = GraphicsPipeline.SampleMask;
+ BlendStateDesc_To_D3D12_BLEND_DESC(GraphicsPipeline.BlendDesc, *d3d12PSODesc.BlendState);
+ d3d12PSODesc.SampleMask = GraphicsPipeline.SampleMask;
- RasterizerStateDesc_To_D3D12_RASTERIZER_DESC(GraphicsPipeline.RasterizerDesc, *d3d12PSODesc.RasterizerState);
- DepthStencilStateDesc_To_D3D12_DEPTH_STENCIL_DESC(GraphicsPipeline.DepthStencilDesc, *d3d12PSODesc.DepthStencilState);
+ RasterizerStateDesc_To_D3D12_RASTERIZER_DESC(GraphicsPipeline.RasterizerDesc, *d3d12PSODesc.RasterizerState);
+ DepthStencilStateDesc_To_D3D12_DEPTH_STENCIL_DESC(GraphicsPipeline.DepthStencilDesc, *d3d12PSODesc.DepthStencilState);
- d3d12PSODesc.RTVFormatArray->NumRenderTargets = GraphicsPipeline.NumRenderTargets;
- for (Uint32 rt = 0; rt < GraphicsPipeline.NumRenderTargets; ++rt)
- d3d12PSODesc.RTVFormatArray->RTFormats[rt] = TexFormatToDXGI_Format(GraphicsPipeline.RTVFormats[rt]);
- for (Uint32 rt = GraphicsPipeline.NumRenderTargets; rt < _countof(d3d12PSODesc.RTVFormatArray->RTFormats); ++rt)
- d3d12PSODesc.RTVFormatArray->RTFormats[rt] = DXGI_FORMAT_UNKNOWN;
- d3d12PSODesc.DSVFormat = TexFormatToDXGI_Format(GraphicsPipeline.DSVFormat);
+ d3d12PSODesc.RTVFormatArray->NumRenderTargets = GraphicsPipeline.NumRenderTargets;
+ for (Uint32 rt = 0; rt < GraphicsPipeline.NumRenderTargets; ++rt)
+ d3d12PSODesc.RTVFormatArray->RTFormats[rt] = TexFormatToDXGI_Format(GraphicsPipeline.RTVFormats[rt]);
+ for (Uint32 rt = GraphicsPipeline.NumRenderTargets; rt < _countof(d3d12PSODesc.RTVFormatArray->RTFormats); ++rt)
+ d3d12PSODesc.RTVFormatArray->RTFormats[rt] = DXGI_FORMAT_UNKNOWN;
+ d3d12PSODesc.DSVFormat = TexFormatToDXGI_Format(GraphicsPipeline.DSVFormat);
- d3d12PSODesc.SampleDesc->Count = GraphicsPipeline.SmplDesc.Count;
- d3d12PSODesc.SampleDesc->Quality = GraphicsPipeline.SmplDesc.Quality;
+ d3d12PSODesc.SampleDesc->Count = GraphicsPipeline.SmplDesc.Count;
+ d3d12PSODesc.SampleDesc->Quality = GraphicsPipeline.SmplDesc.Quality;
- // For single GPU operation, set this to zero. If there are multiple GPU nodes,
- // set bits to identify the nodes (the device's physical adapters) for which the
- // graphics pipeline state is to apply. Each bit in the mask corresponds to a single node.
- d3d12PSODesc.NodeMask = 0;
+ // For single GPU operation, set this to zero. If there are multiple GPU nodes,
+ // set bits to identify the nodes (the device's physical adapters) for which the
+ // graphics pipeline state is to apply. Each bit in the mask corresponds to a single node.
+ d3d12PSODesc.NodeMask = 0;
- d3d12PSODesc.CachedPSO->pCachedBlob = nullptr;
- d3d12PSODesc.CachedPSO->CachedBlobSizeInBytes = 0;
+ d3d12PSODesc.CachedPSO->pCachedBlob = nullptr;
+ d3d12PSODesc.CachedPSO->CachedBlobSizeInBytes = 0;
- // The only valid bit is D3D12_PIPELINE_STATE_FLAG_TOOL_DEBUG, which can only be set on WARP devices.
- d3d12PSODesc.Flags = D3D12_PIPELINE_STATE_FLAG_NONE;
+ // The only valid bit is D3D12_PIPELINE_STATE_FLAG_TOOL_DEBUG, which can only be set on WARP devices.
+ d3d12PSODesc.Flags = D3D12_PIPELINE_STATE_FLAG_NONE;
- D3D12_PIPELINE_STATE_STREAM_DESC streamDesc;
- streamDesc.SizeInBytes = sizeof(d3d12PSODesc);
- streamDesc.pPipelineStateSubobjectStream = &d3d12PSODesc;
+ D3D12_PIPELINE_STATE_STREAM_DESC streamDesc;
+ streamDesc.SizeInBytes = sizeof(d3d12PSODesc);
+ streamDesc.pPipelineStateSubobjectStream = &d3d12PSODesc;
- auto* device2 = pDeviceD3D12->GetD3D12Device2();
+ auto* device2 = pDeviceD3D12->GetD3D12Device2();
- CHECK_D3D_RESULT_THROW(device2->CreatePipelineState(&streamDesc, IID_PPV_ARGS(&m_pd3d12PSO)), "Failed to create pipeline state");
- }
+ CHECK_D3D_RESULT_THROW(device2->CreatePipelineState(&streamDesc, IID_PPV_ARGS(&m_pd3d12PSO)), "Failed to create pipeline state");
+ }
#endif // D3D12_H_HAS_MESH_SHADER
- else
- {
- LOG_ERROR_AND_THROW("Unsupported pipeline type");
- }
+ else
+ {
+ LOG_ERROR_AND_THROW("Unsupported pipeline type");
+ }
- if (*m_Desc.Name != 0)
+ if (*m_Desc.Name != 0)
+ {
+ m_pd3d12PSO->SetName(WidenString(m_Desc.Name).c_str());
+ String RootSignatureDesc("Root signature for PSO '");
+ RootSignatureDesc.append(m_Desc.Name);
+ RootSignatureDesc.push_back('\'');
+ m_RootSig.GetD3D12RootSignature()->SetName(WidenString(RootSignatureDesc).c_str());
+ }
+ }
+ catch (...)
{
- m_pd3d12PSO->SetName(WidenString(m_Desc.Name).c_str());
- String RootSignatureDesc("Root signature for PSO '");
- RootSignatureDesc.append(m_Desc.Name);
- RootSignatureDesc.push_back('\'');
- m_RootSig.GetD3D12RootSignature()->SetName(WidenString(RootSignatureDesc).c_str());
+ Destruct();
+ throw;
}
-
- void* Ptr = MemPool.Release();
- VERIFY_EXPR(Ptr == m_pShaderResourceLayouts);
}
PipelineStateD3D12Impl::PipelineStateD3D12Impl(IReferenceCounters* pRefCounters,
@@ -335,67 +353,92 @@ PipelineStateD3D12Impl::PipelineStateD3D12Impl(IReferenceCounters*
TPipelineStateBase{pRefCounters, pDeviceD3D12, CreateInfo.PSODesc},
m_SRBMemAllocator{GetRawAllocator()}
{
- std::vector<D3D12PipelineShaderStageInfo> ShaderStages;
+ try
+ {
+ std::vector<D3D12PipelineShaderStageInfo> ShaderStages;
- auto MemPool = InitInternalObjects(CreateInfo, ShaderStages);
+ InitInternalObjects(CreateInfo, ShaderStages);
- auto pd3d12Device = pDeviceD3D12->GetD3D12Device();
+ auto pd3d12Device = pDeviceD3D12->GetD3D12Device();
- D3D12_COMPUTE_PIPELINE_STATE_DESC d3d12PSODesc = {};
+ D3D12_COMPUTE_PIPELINE_STATE_DESC d3d12PSODesc = {};
- VERIFY_EXPR(ShaderStages[0].Type == SHADER_TYPE_COMPUTE);
- auto* pByteCode = ShaderStages[0].pShader->GetShaderByteCode();
- d3d12PSODesc.CS.pShaderBytecode = pByteCode->GetBufferPointer();
- d3d12PSODesc.CS.BytecodeLength = pByteCode->GetBufferSize();
+ VERIFY_EXPR(ShaderStages[0].Type == SHADER_TYPE_COMPUTE);
+ auto* pByteCode = ShaderStages[0].pShader->GetShaderByteCode();
+ d3d12PSODesc.CS.pShaderBytecode = pByteCode->GetBufferPointer();
+ d3d12PSODesc.CS.BytecodeLength = pByteCode->GetBufferSize();
- // For single GPU operation, set this to zero. If there are multiple GPU nodes,
- // set bits to identify the nodes (the device's physical adapters) for which the
- // graphics pipeline state is to apply. Each bit in the mask corresponds to a single node.
- d3d12PSODesc.NodeMask = 0;
+ // For single GPU operation, set this to zero. If there are multiple GPU nodes,
+ // set bits to identify the nodes (the device's physical adapters) for which the
+ // graphics pipeline state is to apply. Each bit in the mask corresponds to a single node.
+ d3d12PSODesc.NodeMask = 0;
- d3d12PSODesc.CachedPSO.pCachedBlob = nullptr;
- d3d12PSODesc.CachedPSO.CachedBlobSizeInBytes = 0;
+ d3d12PSODesc.CachedPSO.pCachedBlob = nullptr;
+ d3d12PSODesc.CachedPSO.CachedBlobSizeInBytes = 0;
- // The only valid bit is D3D12_PIPELINE_STATE_FLAG_TOOL_DEBUG, which can only be set on WARP devices.
- d3d12PSODesc.Flags = D3D12_PIPELINE_STATE_FLAG_NONE;
+ // The only valid bit is D3D12_PIPELINE_STATE_FLAG_TOOL_DEBUG, which can only be set on WARP devices.
+ d3d12PSODesc.Flags = D3D12_PIPELINE_STATE_FLAG_NONE;
- d3d12PSODesc.pRootSignature = m_RootSig.GetD3D12RootSignature();
+ d3d12PSODesc.pRootSignature = m_RootSig.GetD3D12RootSignature();
- HRESULT hr = pd3d12Device->CreateComputePipelineState(&d3d12PSODesc, __uuidof(ID3D12PipelineState), reinterpret_cast<void**>(static_cast<ID3D12PipelineState**>(&m_pd3d12PSO)));
- if (FAILED(hr))
- LOG_ERROR_AND_THROW("Failed to create pipeline state");
+ HRESULT hr = pd3d12Device->CreateComputePipelineState(&d3d12PSODesc, __uuidof(ID3D12PipelineState), reinterpret_cast<void**>(static_cast<ID3D12PipelineState**>(&m_pd3d12PSO)));
+ if (FAILED(hr))
+ LOG_ERROR_AND_THROW("Failed to create pipeline state");
- if (*m_Desc.Name != 0)
+ if (*m_Desc.Name != 0)
+ {
+ m_pd3d12PSO->SetName(WidenString(m_Desc.Name).c_str());
+ String RootSignatureDesc("Root signature for PSO '");
+ RootSignatureDesc.append(m_Desc.Name);
+ RootSignatureDesc.push_back('\'');
+ m_RootSig.GetD3D12RootSignature()->SetName(WidenString(RootSignatureDesc).c_str());
+ }
+ }
+ catch (...)
{
- m_pd3d12PSO->SetName(WidenString(m_Desc.Name).c_str());
- String RootSignatureDesc("Root signature for PSO '");
- RootSignatureDesc.append(m_Desc.Name);
- RootSignatureDesc.push_back('\'');
- m_RootSig.GetD3D12RootSignature()->SetName(WidenString(RootSignatureDesc).c_str());
+ Destruct();
+ throw;
}
-
- void* Ptr = MemPool.Release();
- VERIFY_EXPR(Ptr == m_pShaderResourceLayouts);
}
PipelineStateD3D12Impl::~PipelineStateD3D12Impl()
{
+ Destruct();
+}
+
+void PipelineStateD3D12Impl::Destruct()
+{
auto& ShaderResLayoutAllocator = GetRawAllocator();
for (Uint32 s = 0; s < GetNumShaderStages(); ++s)
{
- m_pStaticVarManagers[s].Destroy(GetRawAllocator());
- m_pStaticVarManagers[s].~ShaderVariableManagerD3D12();
- m_pStaticResourceCaches[s].~ShaderResourceCacheD3D12();
- m_pShaderResourceLayouts[s].~ShaderResourceLayoutD3D12();
- m_pShaderResourceLayouts[GetNumShaderStages() + s].~ShaderResourceLayoutD3D12();
+ if (m_pStaticVarManagers != nullptr)
+ {
+ m_pStaticVarManagers[s].Destroy(GetRawAllocator());
+ m_pStaticVarManagers[s].~ShaderVariableManagerD3D12();
+ }
+
+ if (m_pShaderResourceLayouts != nullptr)
+ {
+ m_pShaderResourceLayouts[s].~ShaderResourceLayoutD3D12();
+ m_pShaderResourceLayouts[GetNumShaderStages() + s].~ShaderResourceLayoutD3D12();
+ }
+
+ if (m_pStaticResourceCaches != nullptr)
+ {
+ m_pStaticResourceCaches[s].~ShaderResourceCacheD3D12();
+ }
+ }
+ // All internal objects are allocated in contiguous chunks of memory.
+ if (auto* pRawMem = m_pStaticResourceCaches)
+ {
+ ShaderResLayoutAllocator.Free(pRawMem);
}
- // m_pShaderResourceLayouts, m_pStaticResourceCaches, and m_pShaderResourceLayouts are allocated in
- // contiguous chunks of memory.
- auto* pRawMem = m_pShaderResourceLayouts;
- ShaderResLayoutAllocator.Free(pRawMem);
- // D3D12 object can only be destroyed when it is no longer used by the GPU
- m_pDevice->SafeReleaseDeviceObject(std::move(m_pd3d12PSO), m_Desc.CommandQueueMask);
+ if (m_pd3d12PSO)
+ {
+ // D3D12 object can only be destroyed when it is no longer used by the GPU
+ m_pDevice->SafeReleaseDeviceObject(std::move(m_pd3d12PSO), m_Desc.CommandQueueMask);
+ }
}
IMPLEMENT_QUERY_INTERFACE(PipelineStateD3D12Impl, IID_PipelineStateD3D12, TPipelineStateBase)
@@ -429,49 +472,37 @@ void PipelineStateD3D12Impl::InitResourceLayouts(const PipelineStateCreateInfo&
m_ResourceLayoutIndex[ShaderInd] = static_cast<Int8>(s);
- new (m_pShaderResourceLayouts + s)
- ShaderResourceLayoutD3D12 //
- {
- *this,
- pd3d12Device,
- m_Desc.PipelineType,
- ResourceLayout,
- pShaderD3D12->GetShaderResources(),
- GetRawAllocator(),
- nullptr,
- 0,
- nullptr,
- &m_RootSig //
- };
-
- new (m_pStaticResourceCaches + s) ShaderResourceCacheD3D12{ShaderResourceCacheD3D12::DbgCacheContentType::StaticShaderResources};
+ m_pShaderResourceLayouts[s].Initialize(
+ pd3d12Device,
+ m_Desc.PipelineType,
+ ResourceLayout,
+ pShaderD3D12->GetShaderResources(),
+ GetRawAllocator(),
+ nullptr,
+ 0,
+ nullptr,
+ &m_RootSig //
+ );
const SHADER_RESOURCE_VARIABLE_TYPE StaticVarType[] = {SHADER_RESOURCE_VARIABLE_TYPE_STATIC};
- new (m_pShaderResourceLayouts + GetNumShaderStages() + s)
- ShaderResourceLayoutD3D12 //
- {
- *this,
- pd3d12Device,
- m_Desc.PipelineType,
- ResourceLayout,
- pShaderD3D12->GetShaderResources(),
- GetRawAllocator(),
- StaticVarType,
- _countof(StaticVarType),
- m_pStaticResourceCaches + s,
- nullptr //
- };
-
- new (m_pStaticVarManagers + s)
- ShaderVariableManagerD3D12 //
- {
- *this,
- GetStaticShaderResLayout(static_cast<Uint32>(s)),
- GetRawAllocator(),
- nullptr,
- 0,
- GetStaticShaderResCache(static_cast<Uint32>(s)) //
- };
+ m_pShaderResourceLayouts[GetNumShaderStages() + s].Initialize(
+ pd3d12Device,
+ m_Desc.PipelineType,
+ ResourceLayout,
+ pShaderD3D12->GetShaderResources(),
+ GetRawAllocator(),
+ StaticVarType,
+ _countof(StaticVarType),
+ m_pStaticResourceCaches + s,
+ nullptr //
+ );
+
+ m_pStaticVarManagers[s].Initialize(
+ GetStaticShaderResLayout(static_cast<Uint32>(s)),
+ GetRawAllocator(),
+ nullptr,
+ 0 //
+ );
}
m_RootSig.Finalize(pd3d12Device);
diff --git a/Graphics/GraphicsEngineD3D12/src/ShaderResourceBindingD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/ShaderResourceBindingD3D12Impl.cpp
index 3293283a..1c5ae5f5 100644
--- a/Graphics/GraphicsEngineD3D12/src/ShaderResourceBindingD3D12Impl.cpp
+++ b/Graphics/GraphicsEngineD3D12/src/ShaderResourceBindingD3D12Impl.cpp
@@ -67,16 +67,13 @@ ShaderResourceBindingD3D12Impl::ShaderResourceBindingD3D12Impl(IReferenceCounter
const SHADER_RESOURCE_VARIABLE_TYPE AllowedVarTypes[] = {SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE, SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC};
const auto& SrcLayout = pPSO->GetShaderResLayout(s);
// Create shader variable manager in place
- new (m_pShaderVarMgrs + s)
- ShaderVariableManagerD3D12 //
- {
- *this,
- SrcLayout,
- VarDataAllocator,
- AllowedVarTypes,
- _countof(AllowedVarTypes),
- m_ShaderResourceCache //
- };
+ new (m_pShaderVarMgrs + s) ShaderVariableManagerD3D12{*this, m_ShaderResourceCache};
+ m_pShaderVarMgrs[s].Initialize(
+ SrcLayout,
+ VarDataAllocator,
+ AllowedVarTypes,
+ _countof(AllowedVarTypes) //
+ );
m_ResourceLayoutIndex[ShaderInd] = static_cast<Int8>(s);
}
diff --git a/Graphics/GraphicsEngineD3D12/src/ShaderResourceLayoutD3D12.cpp b/Graphics/GraphicsEngineD3D12/src/ShaderResourceLayoutD3D12.cpp
index 06e902fb..c0428e7e 100644
--- a/Graphics/GraphicsEngineD3D12/src/ShaderResourceLayoutD3D12.cpp
+++ b/Graphics/GraphicsEngineD3D12/src/ShaderResourceLayoutD3D12.cpp
@@ -113,22 +113,19 @@ void ShaderResourceLayoutD3D12::AllocateMemory(IMemoryAllocator&
// http://diligentgraphics.com/diligent-engine/architecture/d3d12/shader-resource-layout#Initializing-Shader-Resource-Layouts-and-Root-Signature-in-a-Pipeline-State-Object
// http://diligentgraphics.com/diligent-engine/architecture/d3d12/shader-resource-cache#Initializing-Shader-Resource-Layouts-in-a-Pipeline-State
-ShaderResourceLayoutD3D12::ShaderResourceLayoutD3D12(IObject& Owner,
- ID3D12Device* pd3d12Device,
- PIPELINE_TYPE PipelineType,
- const PipelineResourceLayoutDesc& ResourceLayout,
- std::shared_ptr<const ShaderResourcesD3D12> pSrcResources,
- IMemoryAllocator& LayoutDataAllocator,
- const SHADER_RESOURCE_VARIABLE_TYPE* const AllowedVarTypes,
- Uint32 NumAllowedTypes,
- ShaderResourceCacheD3D12* pResourceCache,
- RootSignature* pRootSig) :
- // clang-format off
- m_Owner {Owner},
- m_pd3d12Device {pd3d12Device},
- m_pResources {std::move(pSrcResources)}
-// clang-format on
+void ShaderResourceLayoutD3D12::Initialize(ID3D12Device* pd3d12Device,
+ PIPELINE_TYPE PipelineType,
+ const PipelineResourceLayoutDesc& ResourceLayout,
+ std::shared_ptr<const ShaderResourcesD3D12> pSrcResources,
+ IMemoryAllocator& LayoutDataAllocator,
+ const SHADER_RESOURCE_VARIABLE_TYPE* const AllowedVarTypes,
+ Uint32 NumAllowedTypes,
+ ShaderResourceCacheD3D12* pResourceCache,
+ RootSignature* pRootSig)
{
+ m_pd3d12Device = pd3d12Device;
+ m_pResources = std::move(pSrcResources);
+
VERIFY_EXPR((pResourceCache != nullptr) ^ (pRootSig != nullptr));
const Uint32 AllowedTypeBits = GetAllowedTypeBits(AllowedVarTypes, NumAllowedTypes);
diff --git a/Graphics/GraphicsEngineD3D12/src/ShaderVariableD3D12.cpp b/Graphics/GraphicsEngineD3D12/src/ShaderVariableD3D12.cpp
index f7c23096..fd58eacf 100644
--- a/Graphics/GraphicsEngineD3D12/src/ShaderVariableD3D12.cpp
+++ b/Graphics/GraphicsEngineD3D12/src/ShaderVariableD3D12.cpp
@@ -54,20 +54,15 @@ size_t ShaderVariableManagerD3D12::GetRequiredMemorySize(const ShaderResourceLay
}
// Creates shader variable for every resource from SrcLayout whose type is one AllowedVarTypes
-ShaderVariableManagerD3D12::ShaderVariableManagerD3D12(IObject& Owner,
- const ShaderResourceLayoutD3D12& SrcLayout,
- IMemoryAllocator& Allocator,
- const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes,
- Uint32 NumAllowedTypes,
- ShaderResourceCacheD3D12& ResourceCache) :
- // clang-format off
- m_Owner {Owner},
- m_ResourceCache {ResourceCache}
+void ShaderVariableManagerD3D12::Initialize(const ShaderResourceLayoutD3D12& SrcLayout,
+ IMemoryAllocator& Allocator,
+ const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes,
+ Uint32 NumAllowedTypes)
+{
#ifdef DILIGENT_DEBUG
- , m_DbgAllocator {Allocator}
+ m_pDbgAllocator = &Allocator;
#endif
-// clang-format on
-{
+
const Uint32 AllowedTypeBits = GetAllowedTypeBits(AllowedVarTypes, NumAllowedTypes);
VERIFY_EXPR(m_NumVariables == 0);
auto MemSize = GetRequiredMemorySize(SrcLayout, AllowedVarTypes, NumAllowedTypes, m_NumVariables);
@@ -113,10 +108,10 @@ ShaderVariableManagerD3D12::~ShaderVariableManagerD3D12()
void ShaderVariableManagerD3D12::Destroy(IMemoryAllocator& Allocator)
{
- VERIFY(&m_DbgAllocator == &Allocator, "Incosistent alloctor");
-
if (m_pVariables != nullptr)
{
+ VERIFY(m_pDbgAllocator == &Allocator, "Incosistent alloctor");
+
for (Uint32 v = 0; v < m_NumVariables; ++v)
m_pVariables[v].~ShaderVariableD3D12Impl();
Allocator.Free(m_pVariables);
diff --git a/Graphics/GraphicsEngineD3DBase/include/ShaderResources.hpp b/Graphics/GraphicsEngineD3DBase/include/ShaderResources.hpp
index f15d2e74..efbff703 100644
--- a/Graphics/GraphicsEngineD3DBase/include/ShaderResources.hpp
+++ b/Graphics/GraphicsEngineD3DBase/include/ShaderResources.hpp
@@ -385,7 +385,7 @@ public:
const ShaderResources* const pShaderResources[],
Uint32 NumShaders,
bool VerifyVariables,
- bool VerifyImmutableSamplers);
+ bool VerifyImmutableSamplers) noexcept;
#endif
void GetShaderModel(Uint32& Major, Uint32& Minor) const
diff --git a/Graphics/GraphicsEngineD3DBase/src/ShaderResources.cpp b/Graphics/GraphicsEngineD3DBase/src/ShaderResources.cpp
index 86a7fc35..b975b506 100644
--- a/Graphics/GraphicsEngineD3DBase/src/ShaderResources.cpp
+++ b/Graphics/GraphicsEngineD3DBase/src/ShaderResources.cpp
@@ -219,7 +219,7 @@ void ShaderResources::DvpVerifyResourceLayout(const PipelineResourceLayoutDesc&
const ShaderResources* const pShaderResources[],
Uint32 NumShaders,
bool VerifyVariables,
- bool VerifyImmutableSamplers)
+ bool VerifyImmutableSamplers) noexcept
{
auto GetAllowedShadersString = [&](SHADER_TYPE ShaderStages) //
{
diff --git a/Graphics/GraphicsEngineOpenGL/include/GLProgramResourceCache.hpp b/Graphics/GraphicsEngineOpenGL/include/GLProgramResourceCache.hpp
index eab96f6a..07c8f39e 100644
--- a/Graphics/GraphicsEngineOpenGL/include/GLProgramResourceCache.hpp
+++ b/Graphics/GraphicsEngineOpenGL/include/GLProgramResourceCache.hpp
@@ -45,7 +45,7 @@ namespace Diligent
class GLProgramResourceCache
{
public:
- GLProgramResourceCache()
+ GLProgramResourceCache() noexcept
{}
~GLProgramResourceCache();
diff --git a/Graphics/GraphicsEngineOpenGL/include/PipelineStateGLImpl.hpp b/Graphics/GraphicsEngineOpenGL/include/PipelineStateGLImpl.hpp
index 0c5692d0..93180774 100644
--- a/Graphics/GraphicsEngineOpenGL/include/PipelineStateGLImpl.hpp
+++ b/Graphics/GraphicsEngineOpenGL/include/PipelineStateGLImpl.hpp
@@ -114,6 +114,8 @@ private:
void InitResourceLayouts(const std::vector<GLPipelineShaderStageInfo>& ShaderStages,
LinearAllocator& MemPool);
+ void Destruct();
+
// Linked GL programs for every shader stage. Every pipeline needs to have its own programs
// because resource bindings assigned by GLProgramResources::LoadUniforms depend on other
// shader stages.
diff --git a/Graphics/GraphicsEngineOpenGL/src/GLProgramResourceCache.cpp b/Graphics/GraphicsEngineOpenGL/src/GLProgramResourceCache.cpp
index 95557557..84cdc46e 100644
--- a/Graphics/GraphicsEngineOpenGL/src/GLProgramResourceCache.cpp
+++ b/Graphics/GraphicsEngineOpenGL/src/GLProgramResourceCache.cpp
@@ -92,7 +92,9 @@ GLProgramResourceCache::~GLProgramResourceCache()
void GLProgramResourceCache::Destroy(IMemoryAllocator& MemAllocator)
{
- VERIFY(IsInitialized(), "Resource cache is not initialized");
+ if (!IsInitialized())
+ return;
+
VERIFY(m_pdbgMemoryAllocator == &MemAllocator, "The allocator does not match the one used to create resources");
for (Uint32 cb = 0; cb < GetUBCount(); ++cb)
diff --git a/Graphics/GraphicsEngineOpenGL/src/PipelineStateGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/PipelineStateGLImpl.cpp
index 8bc3802e..8b429094 100644
--- a/Graphics/GraphicsEngineOpenGL/src/PipelineStateGLImpl.cpp
+++ b/Graphics/GraphicsEngineOpenGL/src/PipelineStateGLImpl.cpp
@@ -40,22 +40,37 @@ namespace Diligent
template <typename PSOCreateInfoType>
void PipelineStateGLImpl::Initialize(const PSOCreateInfoType& CreateInfo, const std::vector<GLPipelineShaderStageInfo>& ShaderStages)
{
- // Memory must be released if an exception is thrown.
LinearAllocator MemPool{GetRawAllocator()};
+ VERIFY_EXPR(m_NumShaderStages > 0 && m_NumShaderStages == ShaderStages.size());
+ if (!GetDevice()->GetDeviceCaps().Features.SeparablePrograms)
+ m_NumShaderStages = 1;
- MemPool.AddSpace<GLProgramObj>(GetNumShaderStages());
- MemPool.AddSpace<GLProgramResources>(GetNumShaderStages());
+ const auto NumPrograms = GetNumShaderStages();
+
+ MemPool.AddSpace<GLProgramObj>(NumPrograms);
+ MemPool.AddSpace<GLProgramResources>(NumPrograms);
MemPool.AddSpace<SamplerPtr>(m_Desc.ResourceLayout.NumImmutableSamplers);
ReserveSpaceForPipelineDesc(CreateInfo, MemPool);
MemPool.Reserve();
- InitResourceLayouts(ShaderStages, MemPool);
- InitializePipelineDesc(CreateInfo, MemPool);
+ m_GLPrograms = MemPool.ConstructArray<GLProgramObj>(NumPrograms, false);
- void* Ptr = MemPool.Release();
+ // The memory is now owned by PipelineStateVkImpl and will be freed by Destruct().
+ auto* Ptr = MemPool.ReleaseOwnership();
VERIFY_EXPR(Ptr == m_GLPrograms);
+ (void)Ptr;
+
+ m_ProgramResources = MemPool.ConstructArray<GLProgramResources>(NumPrograms);
+
+ m_ImmutableSamplers = MemPool.ConstructArray<SamplerPtr>(m_Desc.ResourceLayout.NumImmutableSamplers);
+
+ // It is important to construct all objects before initializing them because if an exception is thrown,
+ // destructors will be called for all objects
+
+ InitResourceLayouts(ShaderStages, MemPool);
+ InitializePipelineDesc(CreateInfo, MemPool);
}
PipelineStateGLImpl::PipelineStateGLImpl(IReferenceCounters* pRefCounters,
@@ -74,26 +89,33 @@ PipelineStateGLImpl::PipelineStateGLImpl(IReferenceCounters*
m_StaticResourceLayout{*this}
// clang-format on
{
- std::vector<GLPipelineShaderStageInfo> ShaderStages;
- ExtractShaders<ShaderGLImpl>(CreateInfo, ShaderStages);
+ try
+ {
+ std::vector<GLPipelineShaderStageInfo> ShaderStages;
+ ExtractShaders<ShaderGLImpl>(CreateInfo, ShaderStages);
+
+ RefCntAutoPtr<ShaderGLImpl> pTempPS;
+ if (CreateInfo.pPS == nullptr)
+ {
+ // Some OpenGL implementations fail if fragment shader is not present, so
+ // create a dummy one.
+ ShaderCreateInfo ShaderCI;
+ ShaderCI.SourceLanguage = SHADER_SOURCE_LANGUAGE_GLSL;
+ ShaderCI.Source = "void main(){}";
+ ShaderCI.Desc.ShaderType = SHADER_TYPE_PIXEL;
+ ShaderCI.Desc.Name = "Dummy fragment shader";
+ pDeviceGL->CreateShader(ShaderCI, reinterpret_cast<IShader**>(static_cast<ShaderGLImpl**>(&pTempPS)));
+
+ ShaderStages.emplace_back(SHADER_TYPE_PIXEL, pTempPS);
+ m_ShaderStageTypes[m_NumShaderStages++] = SHADER_TYPE_PIXEL;
+ }
- RefCntAutoPtr<ShaderGLImpl> pTempPS;
- if (CreateInfo.pPS == nullptr)
+ Initialize(CreateInfo, ShaderStages);
+ }
+ catch (...)
{
- // Some OpenGL implementations fail if fragment shader is not present, so
- // create a dummy one.
- ShaderCreateInfo ShaderCI;
- ShaderCI.SourceLanguage = SHADER_SOURCE_LANGUAGE_GLSL;
- ShaderCI.Source = "void main(){}";
- ShaderCI.Desc.ShaderType = SHADER_TYPE_PIXEL;
- ShaderCI.Desc.Name = "Dummy fragment shader";
- pDeviceGL->CreateShader(ShaderCI, reinterpret_cast<IShader**>(static_cast<ShaderGLImpl**>(&pTempPS)));
-
- ShaderStages.emplace_back(SHADER_TYPE_PIXEL, pTempPS);
- m_ShaderStageTypes[m_NumShaderStages++] = SHADER_TYPE_PIXEL;
+ Destruct();
}
-
- Initialize(CreateInfo, ShaderStages);
}
PipelineStateGLImpl::PipelineStateGLImpl(IReferenceCounters* pRefCounters,
@@ -112,30 +134,54 @@ PipelineStateGLImpl::PipelineStateGLImpl(IReferenceCounters* p
m_StaticResourceLayout{*this}
// clang-format on
{
- std::vector<GLPipelineShaderStageInfo> ShaderStages;
- ExtractShaders<ShaderGLImpl>(CreateInfo, ShaderStages);
+ try
+ {
+ std::vector<GLPipelineShaderStageInfo> ShaderStages;
+ ExtractShaders<ShaderGLImpl>(CreateInfo, ShaderStages);
- Initialize(CreateInfo, ShaderStages);
+ Initialize(CreateInfo, ShaderStages);
+ }
+ catch (...)
+ {
+ Destruct();
+ }
}
PipelineStateGLImpl::~PipelineStateGLImpl()
{
+ Destruct();
+}
+
+void PipelineStateGLImpl::Destruct()
+{
auto& RawAllocator = GetRawAllocator();
m_StaticResourceCache.Destroy(RawAllocator);
GetDevice()->OnDestroyPSO(this);
- for (Uint32 i = 0; i < GetNumShaderStages(); ++i)
+ if (m_ImmutableSamplers != nullptr)
{
- m_GLPrograms[i].~GLProgramObj();
- m_ProgramResources[i].~GLProgramResources();
+ for (Uint32 i = 0; i < m_Desc.ResourceLayout.NumImmutableSamplers; ++i)
+ {
+ m_ImmutableSamplers[i].~SamplerPtr();
+ }
}
- for (Uint32 i = 0; i < m_Desc.ResourceLayout.NumImmutableSamplers; ++i)
+
+ for (Uint32 i = 0; i < GetNumShaderStages(); ++i)
{
- m_ImmutableSamplers[i].~SamplerPtr();
+ if (m_GLPrograms != nullptr)
+ {
+ m_GLPrograms[i].~GLProgramObj();
+ }
+ if (m_ProgramResources != nullptr)
+ {
+ m_ProgramResources[i].~GLProgramResources();
+ }
}
- void* pRawMem = m_GLPrograms;
- RawAllocator.Free(pRawMem);
+ if (void* pRawMem = m_GLPrograms)
+ {
+ RawAllocator.Free(pRawMem);
+ }
}
IMPLEMENT_QUERY_INTERFACE(PipelineStateGLImpl, IID_PipelineStateGL, TPipelineStateBase)
@@ -145,8 +191,8 @@ void PipelineStateGLImpl::InitResourceLayouts(const std::vector<GLPipelineShader
LinearAllocator& MemPool)
{
auto* const pDeviceGL = GetDevice();
- const auto& DeviceCaps = pDeviceGL->GetDeviceCaps();
- VERIFY(DeviceCaps.DevType != RENDER_DEVICE_TYPE_UNDEFINED, "Device caps are not initialized");
+ const auto& deviceCaps = pDeviceGL->GetDeviceCaps();
+ VERIFY(deviceCaps.DevType != RENDER_DEVICE_TYPE_UNDEFINED, "Device caps are not initialized");
auto pImmediateCtx = m_pDevice->GetImmediateContext();
VERIFY_EXPR(pImmediateCtx);
@@ -157,18 +203,16 @@ void PipelineStateGLImpl::InitResourceLayouts(const std::vector<GLPipelineShader
m_TotalSamplerBindings = 0;
m_TotalImageBindings = 0;
m_TotalStorageBufferBindings = 0;
- if (DeviceCaps.Features.SeparablePrograms)
+ if (deviceCaps.Features.SeparablePrograms)
{
// Program pipelines are not shared between GL contexts, so we cannot create
// it now
m_ShaderResourceLayoutHash = 0;
- m_GLPrograms = MemPool.Allocate<GLProgramObj>(ShaderStages.size());
- m_ProgramResources = MemPool.ConstructArray<GLProgramResources>(ShaderStages.size());
for (size_t i = 0; i < ShaderStages.size(); ++i)
{
auto* pShaderGL = ShaderStages[i].pShader;
const auto& ShaderDesc = pShaderGL->GetDesc();
- new (m_GLPrograms + i) GLProgramObj{ShaderGLImpl::LinkProgram(&pShaderGL, 1, true)};
+ m_GLPrograms[i] = GLProgramObj{ShaderGLImpl::LinkProgram(&pShaderGL, 1, true)};
// Load uniforms and assign bindings
m_ProgramResources[i].LoadUniforms(ShaderDesc.ShaderType, m_GLPrograms[i], GLState,
m_TotalUniformBufferBindings,
@@ -191,8 +235,7 @@ void PipelineStateGLImpl::InitResourceLayouts(const std::vector<GLPipelineShader
ActiveStages |= Stage.Type;
}
- m_GLPrograms = MemPool.Construct<GLProgramObj>(ShaderGLImpl::LinkProgram(Shaders.data(), static_cast<Uint32>(ShaderStages.size()), false));
- m_ProgramResources = MemPool.Construct<GLProgramResources>();
+ m_GLPrograms[0] = ShaderGLImpl::LinkProgram(Shaders.data(), static_cast<Uint32>(Shaders.size()), false);
m_ProgramResources[0].LoadUniforms(ActiveStages, m_GLPrograms[0], GLState,
m_TotalUniformBufferBindings,
@@ -204,10 +247,9 @@ void PipelineStateGLImpl::InitResourceLayouts(const std::vector<GLPipelineShader
}
// Initialize master resource layout that keeps all variable types and does not reference a resource cache
- m_ResourceLayout.Initialize(m_ProgramResources, static_cast<Uint32>(ShaderStages.size()), m_Desc.PipelineType, m_Desc.ResourceLayout, nullptr, 0, nullptr);
+ m_ResourceLayout.Initialize(m_ProgramResources, GetNumShaderStages(), m_Desc.PipelineType, m_Desc.ResourceLayout, nullptr, 0, nullptr);
}
- m_ImmutableSamplers = MemPool.ConstructArray<SamplerPtr>(m_Desc.ResourceLayout.NumImmutableSamplers);
for (Uint32 s = 0; s < m_Desc.ResourceLayout.NumImmutableSamplers; ++s)
{
pDeviceGL->CreateSampler(m_Desc.ResourceLayout.ImmutableSamplers[s].Desc, &m_ImmutableSamplers[s]);
@@ -216,7 +258,7 @@ void PipelineStateGLImpl::InitResourceLayouts(const std::vector<GLPipelineShader
{
// Clone only static variables into static resource layout, assign and initialize static resource cache
const SHADER_RESOURCE_VARIABLE_TYPE StaticVars[] = {SHADER_RESOURCE_VARIABLE_TYPE_STATIC};
- m_StaticResourceLayout.Initialize(m_ProgramResources, static_cast<Uint32>(ShaderStages.size()), m_Desc.PipelineType, m_Desc.ResourceLayout, StaticVars, _countof(StaticVars), &m_StaticResourceCache);
+ m_StaticResourceLayout.Initialize(m_ProgramResources, GetNumShaderStages(), m_Desc.PipelineType, m_Desc.ResourceLayout, StaticVars, _countof(StaticVars), &m_StaticResourceCache);
InitImmutableSamplersInResourceCache(m_StaticResourceLayout, m_StaticResourceCache);
}
}
diff --git a/Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.hpp b/Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.hpp
index 96b34008..d4f2fc36 100644
--- a/Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.hpp
+++ b/Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.hpp
@@ -129,13 +129,15 @@ private:
using TShaderStages = ShaderResourceLayoutVk::TShaderStages;
template <typename PSOCreateInfoType>
- LinearAllocator InitInternalObjects(const PSOCreateInfoType& CreateInfo,
- std::vector<VkPipelineShaderStageCreateInfo>& vkShaderStages,
- std::vector<VulkanUtilities::ShaderModuleWrapper>& ShaderModules);
+ void InitInternalObjects(const PSOCreateInfoType& CreateInfo,
+ std::vector<VkPipelineShaderStageCreateInfo>& vkShaderStages,
+ std::vector<VulkanUtilities::ShaderModuleWrapper>& ShaderModules);
void InitResourceLayouts(const PipelineStateCreateInfo& CreateInfo,
TShaderStages& ShaderStages);
+ void Destruct();
+
const ShaderResourceLayoutVk& GetStaticShaderResLayout(Uint32 ShaderInd) const
{
VERIFY_EXPR(ShaderInd < GetNumShaderStages());
@@ -148,7 +150,7 @@ private:
return m_StaticResCaches[ShaderInd];
}
- ShaderVariableManagerVk& GetStaticVarMgr(Uint32 ShaderInd) const
+ const ShaderVariableManagerVk& GetStaticVarMgr(Uint32 ShaderInd) const
{
VERIFY_EXPR(ShaderInd < GetNumShaderStages());
return m_StaticVarsMgrs[ShaderInd];
diff --git a/Graphics/GraphicsEngineVulkan/include/ShaderResourceCacheVk.hpp b/Graphics/GraphicsEngineVulkan/include/ShaderResourceCacheVk.hpp
index a5278cb7..7d77ff48 100644
--- a/Graphics/GraphicsEngineVulkan/include/ShaderResourceCacheVk.hpp
+++ b/Graphics/GraphicsEngineVulkan/include/ShaderResourceCacheVk.hpp
@@ -75,7 +75,7 @@ public:
};
// clang-format off
- ShaderResourceCacheVk(DbgCacheContentType dbgContentType)
+ ShaderResourceCacheVk(DbgCacheContentType dbgContentType) noexcept
#ifdef DILIGENT_DEBUG
: m_DbgContentType{dbgContentType}
#endif
diff --git a/Graphics/GraphicsEngineVulkan/include/ShaderResourceLayoutVk.hpp b/Graphics/GraphicsEngineVulkan/include/ShaderResourceLayoutVk.hpp
index 0013fe23..9452a390 100644
--- a/Graphics/GraphicsEngineVulkan/include/ShaderResourceLayoutVk.hpp
+++ b/Graphics/GraphicsEngineVulkan/include/ShaderResourceLayoutVk.hpp
@@ -128,7 +128,7 @@ public:
};
using TShaderStages = std::vector<ShaderStageInfo>;
- ShaderResourceLayoutVk(const VulkanUtilities::VulkanLogicalDevice& LogicalDevice) :
+ ShaderResourceLayoutVk(const VulkanUtilities::VulkanLogicalDevice& LogicalDevice) noexcept :
m_LogicalDevice{LogicalDevice}
{
}
diff --git a/Graphics/GraphicsEngineVulkan/include/ShaderVariableVk.hpp b/Graphics/GraphicsEngineVulkan/include/ShaderVariableVk.hpp
index 9039e04e..27689c1e 100644
--- a/Graphics/GraphicsEngineVulkan/include/ShaderVariableVk.hpp
+++ b/Graphics/GraphicsEngineVulkan/include/ShaderVariableVk.hpp
@@ -73,21 +73,25 @@ class ShaderVariableVkImpl;
class ShaderVariableManagerVk
{
public:
- ShaderVariableManagerVk(IObject& Owner,
- const ShaderResourceLayoutVk& SrcLayout,
- IMemoryAllocator& Allocator,
- const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes,
- Uint32 NumAllowedTypes,
- ShaderResourceCacheVk& ResourceCache);
+ ShaderVariableManagerVk(IObject& Owner,
+ ShaderResourceCacheVk& ResourceCache) noexcept :
+ m_Owner{Owner},
+ m_ResourceCache{ResourceCache}
+ {}
+
+ void Initialize(const ShaderResourceLayoutVk& SrcLayout,
+ IMemoryAllocator& Allocator,
+ const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes,
+ Uint32 NumAllowedTypes);
~ShaderVariableManagerVk();
void DestroyVariables(IMemoryAllocator& Allocator);
- ShaderVariableVkImpl* GetVariable(const Char* Name);
- ShaderVariableVkImpl* GetVariable(Uint32 Index);
+ ShaderVariableVkImpl* GetVariable(const Char* Name) const;
+ ShaderVariableVkImpl* GetVariable(Uint32 Index) const;
- void BindResources(IResourceMapping* pResourceMapping, Uint32 Flags);
+ void BindResources(IResourceMapping* pResourceMapping, Uint32 Flags) const;
static size_t GetRequiredMemorySize(const ShaderResourceLayoutVk& Layout,
const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes,
@@ -115,7 +119,7 @@ private:
Uint32 m_NumVariables = 0;
#ifdef DILIGENT_DEBUG
- IMemoryAllocator& m_DbgAllocator;
+ IMemoryAllocator* m_pDbgAllocator = nullptr;
#endif
};
diff --git a/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp
index 6cbe5da9..83512870 100644
--- a/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp
@@ -413,15 +413,12 @@ void PipelineStateVkImpl::InitResourceLayouts(const PipelineStateCreateInfo& Cre
const auto ShaderType = StageInfo.Type;
const auto ShaderTypeInd = GetShaderTypePipelineIndex(ShaderType, m_Desc.PipelineType);
- new (m_ShaderResourceLayouts + s) ShaderResourceLayoutVk{LogicalDevice};
-
m_ResourceLayoutIndex[ShaderTypeInd] = static_cast<Int8>(s);
- auto* pStaticResLayout = new (m_ShaderResourceLayouts + ShaderStages.size() + s) ShaderResourceLayoutVk{LogicalDevice};
- auto* pStaticResCache = new (m_StaticResCaches + s) ShaderResourceCacheVk{ShaderResourceCacheVk::DbgCacheContentType::StaticShaderResources};
- pStaticResLayout->InitializeStaticResourceLayout(StageInfo.pShader, GetRawAllocator(), m_Desc.ResourceLayout, m_StaticResCaches[s]);
+ auto& StaticResLayout = m_ShaderResourceLayouts[GetNumShaderStages() + s];
+ StaticResLayout.InitializeStaticResourceLayout(StageInfo.pShader, GetRawAllocator(), m_Desc.ResourceLayout, m_StaticResCaches[s]);
- new (m_StaticVarsMgrs + s) ShaderVariableManagerVk{*this, *pStaticResLayout, GetRawAllocator(), nullptr, 0, *pStaticResCache};
+ m_StaticVarsMgrs[s].Initialize(StaticResLayout, GetRawAllocator(), nullptr, 0);
}
ShaderResourceLayoutVk::Initialize(pDeviceVk, ShaderStages, m_ShaderResourceLayouts, GetRawAllocator(),
m_Desc.ResourceLayout, m_PipelineLayout,
@@ -464,37 +461,52 @@ void PipelineStateVkImpl::InitResourceLayouts(const PipelineStateCreateInfo& Cre
}
template <typename PSOCreateInfoType>
-LinearAllocator PipelineStateVkImpl::InitInternalObjects(const PSOCreateInfoType& CreateInfo,
- std::vector<VkPipelineShaderStageCreateInfo>& vkShaderStages,
- std::vector<VulkanUtilities::ShaderModuleWrapper>& ShaderModules)
+void PipelineStateVkImpl::InitInternalObjects(const PSOCreateInfoType& CreateInfo,
+ std::vector<VkPipelineShaderStageCreateInfo>& vkShaderStages,
+ std::vector<VulkanUtilities::ShaderModuleWrapper>& ShaderModules)
{
m_ResourceLayoutIndex.fill(-1);
TShaderStages ShaderStages;
ExtractShaders<ShaderVkImpl>(CreateInfo, ShaderStages);
- // Memory must be released if an exception is thrown.
LinearAllocator MemPool{GetRawAllocator()};
- MemPool.AddSpace<ShaderResourceLayoutVk>(GetNumShaderStages() * 2);
- MemPool.AddSpace<ShaderResourceCacheVk>(GetNumShaderStages());
- MemPool.AddSpace<ShaderVariableManagerVk>(GetNumShaderStages());
+ const auto NumShaderStages = GetNumShaderStages();
+ VERIFY_EXPR(NumShaderStages > 0 && NumShaderStages == ShaderStages.size());
+
+ MemPool.AddSpace<ShaderResourceCacheVk>(NumShaderStages);
+ MemPool.AddSpace<ShaderResourceLayoutVk>(NumShaderStages * 2);
+ MemPool.AddSpace<ShaderVariableManagerVk>(NumShaderStages);
ReserveSpaceForPipelineDesc(CreateInfo, MemPool);
MemPool.Reserve();
- m_ShaderResourceLayouts = MemPool.Allocate<ShaderResourceLayoutVk>(GetNumShaderStages() * 2);
- m_StaticResCaches = MemPool.Allocate<ShaderResourceCacheVk>(GetNumShaderStages());
- m_StaticVarsMgrs = MemPool.Allocate<ShaderVariableManagerVk>(GetNumShaderStages());
+ const auto& LogicalDevice = GetDevice()->GetLogicalDevice();
+
+ m_StaticResCaches = MemPool.ConstructArray<ShaderResourceCacheVk>(NumShaderStages, ShaderResourceCacheVk::DbgCacheContentType::StaticShaderResources);
+
+ // The memory is now owned by PipelineStateVkImpl and will be freed by Destruct().
+ auto* Ptr = MemPool.ReleaseOwnership();
+ VERIFY_EXPR(Ptr == m_StaticResCaches);
+ (void)Ptr;
+
+ m_ShaderResourceLayouts = MemPool.ConstructArray<ShaderResourceLayoutVk>(NumShaderStages * 2, LogicalDevice);
+
+ m_StaticVarsMgrs = MemPool.Allocate<ShaderVariableManagerVk>(NumShaderStages);
+ for (Uint32 s = 0; s < NumShaderStages; ++s)
+ new (m_StaticVarsMgrs + s) ShaderVariableManagerVk{*this, m_StaticResCaches[s]};
InitializePipelineDesc(CreateInfo, MemPool);
+
+ // It is important to construct all objects before initializing them because if an exception is thrown,
+ // destructors will be called for all objects
+
InitResourceLayouts(CreateInfo, ShaderStages);
// Create shader modules and initialize shader stages
InitPipelineShaderStages(GetDevice()->GetLogicalDevice(), ShaderStages, ShaderModules, vkShaderStages);
-
- return MemPool;
}
PipelineStateVkImpl::PipelineStateVkImpl(IReferenceCounters* pRefCounters,
@@ -503,15 +515,20 @@ PipelineStateVkImpl::PipelineStateVkImpl(IReferenceCounters*
TPipelineStateBase{pRefCounters, pDeviceVk, CreateInfo.PSODesc},
m_SRBMemAllocator{GetRawAllocator()}
{
- std::vector<VkPipelineShaderStageCreateInfo> vkShaderStages;
- std::vector<VulkanUtilities::ShaderModuleWrapper> ShaderModules;
-
- auto MemPool = InitInternalObjects(CreateInfo, vkShaderStages, ShaderModules);
+ try
+ {
+ std::vector<VkPipelineShaderStageCreateInfo> vkShaderStages;
+ std::vector<VulkanUtilities::ShaderModuleWrapper> ShaderModules;
- CreateGraphicsPipeline(pDeviceVk, vkShaderStages, m_PipelineLayout, m_Desc, GetGraphicsPipelineDesc(), m_Pipeline, m_pRenderPass);
+ InitInternalObjects(CreateInfo, vkShaderStages, ShaderModules);
- void* Ptr = MemPool.Release();
- VERIFY_EXPR(Ptr == m_ShaderResourceLayouts);
+ CreateGraphicsPipeline(pDeviceVk, vkShaderStages, m_PipelineLayout, m_Desc, GetGraphicsPipelineDesc(), m_Pipeline, m_pRenderPass);
+ }
+ catch (...)
+ {
+ Destruct();
+ throw;
+ }
}
@@ -521,39 +538,59 @@ PipelineStateVkImpl::PipelineStateVkImpl(IReferenceCounters* p
TPipelineStateBase{pRefCounters, pDeviceVk, CreateInfo.PSODesc},
m_SRBMemAllocator{GetRawAllocator()}
{
- std::vector<VkPipelineShaderStageCreateInfo> vkShaderStages;
- std::vector<VulkanUtilities::ShaderModuleWrapper> ShaderModules;
-
- auto MemPool = InitInternalObjects(CreateInfo, vkShaderStages, ShaderModules);
+ try
+ {
+ std::vector<VkPipelineShaderStageCreateInfo> vkShaderStages;
+ std::vector<VulkanUtilities::ShaderModuleWrapper> ShaderModules;
- CreateComputePipeline(pDeviceVk, vkShaderStages, m_PipelineLayout, m_Desc, m_Pipeline);
+ InitInternalObjects(CreateInfo, vkShaderStages, ShaderModules);
- void* Ptr = MemPool.Release();
- VERIFY_EXPR(Ptr == m_ShaderResourceLayouts);
+ CreateComputePipeline(pDeviceVk, vkShaderStages, m_PipelineLayout, m_Desc, m_Pipeline);
+ }
+ catch (...)
+ {
+ Destruct();
+ throw;
+ }
}
PipelineStateVkImpl::~PipelineStateVkImpl()
{
+ Destruct();
+}
+
+void PipelineStateVkImpl::Destruct()
+{
m_pDevice->SafeReleaseDeviceObject(std::move(m_Pipeline), m_Desc.CommandQueueMask);
m_PipelineLayout.Release(m_pDevice, m_Desc.CommandQueueMask);
auto& RawAllocator = GetRawAllocator();
- for (Uint32 s = 0; s < GetNumShaderStages() * 2; ++s)
+ for (Uint32 s = 0; s < GetNumShaderStages(); ++s)
{
- m_ShaderResourceLayouts[s].~ShaderResourceLayoutVk();
+ if (m_StaticVarsMgrs != nullptr)
+ {
+ m_StaticVarsMgrs[s].DestroyVariables(GetRawAllocator());
+ m_StaticVarsMgrs[s].~ShaderVariableManagerVk();
+ }
+
+ if (m_ShaderResourceLayouts != nullptr)
+ {
+ m_ShaderResourceLayouts[s].~ShaderResourceLayoutVk();
+ m_ShaderResourceLayouts[GetNumShaderStages() + s].~ShaderResourceLayoutVk();
+ }
+
+ if (m_StaticResCaches != nullptr)
+ {
+ m_StaticResCaches[s].~ShaderResourceCacheVk();
+ }
}
- for (Uint32 s = 0; s < GetNumShaderStages(); ++s)
+ // All internal objects are allocted in contiguous chunks of memory.
+ if (void* pRawMem = m_StaticResCaches)
{
- m_StaticResCaches[s].~ShaderResourceCacheVk();
- m_StaticVarsMgrs[s].DestroyVariables(GetRawAllocator());
- m_StaticVarsMgrs[s].~ShaderVariableManagerVk();
+ RawAllocator.Free(pRawMem);
}
- // m_ShaderResourceLayouts, m_StaticResCaches and m_StaticVarsMgrs are allocted in
- // contiguous chunks of memory.
- void* pRawMem = m_ShaderResourceLayouts;
- RawAllocator.Free(pRawMem);
}
IMPLEMENT_QUERY_INTERFACE(PipelineStateVkImpl, IID_PipelineStateVk, TPipelineStateBase)
@@ -746,7 +783,7 @@ IShaderResourceVariable* PipelineStateVkImpl::GetStaticVariableByIndex(SHADER_TY
if (LayoutInd < 0)
return nullptr;
- auto& StaticVarMgr = GetStaticVarMgr(LayoutInd);
+ const auto& StaticVarMgr = GetStaticVarMgr(LayoutInd);
return StaticVarMgr.GetVariable(Index);
}
diff --git a/Graphics/GraphicsEngineVulkan/src/ShaderResourceBindingVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/ShaderResourceBindingVkImpl.cpp
index 91008811..21b216db 100644
--- a/Graphics/GraphicsEngineVulkan/src/ShaderResourceBindingVkImpl.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/ShaderResourceBindingVkImpl.cpp
@@ -75,7 +75,8 @@ ShaderResourceBindingVkImpl::ShaderResourceBindingVkImpl(IReferenceCounters* pR
// Initialize vars manager to reference mutable and dynamic variables
// Note that the cache has space for all variable types
const SHADER_RESOURCE_VARIABLE_TYPE VarTypes[] = {SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE, SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC};
- new (m_pShaderVarMgrs + s) ShaderVariableManagerVk{*this, SrcLayout, VarDataAllocator, VarTypes, _countof(VarTypes), m_ShaderResourceCache};
+ new (m_pShaderVarMgrs + s) ShaderVariableManagerVk{*this, m_ShaderResourceCache};
+ m_pShaderVarMgrs[s].Initialize(SrcLayout, VarDataAllocator, VarTypes, _countof(VarTypes));
}
#ifdef DILIGENT_DEBUG
m_ShaderResourceCache.DbgVerifyResourceInitialization();
diff --git a/Graphics/GraphicsEngineVulkan/src/ShaderVariableVk.cpp b/Graphics/GraphicsEngineVulkan/src/ShaderVariableVk.cpp
index 82d26b44..7e06bd69 100644
--- a/Graphics/GraphicsEngineVulkan/src/ShaderVariableVk.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/ShaderVariableVk.cpp
@@ -65,20 +65,15 @@ size_t ShaderVariableManagerVk::GetRequiredMemorySize(const ShaderResourceLayout
}
// Creates shader variable for every resource from SrcLayout whose type is one AllowedVarTypes
-ShaderVariableManagerVk::ShaderVariableManagerVk(IObject& Owner,
- const ShaderResourceLayoutVk& SrcLayout,
- IMemoryAllocator& Allocator,
- const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes,
- Uint32 NumAllowedTypes,
- ShaderResourceCacheVk& ResourceCache) :
- // clang-format off
- m_Owner {Owner },
- m_ResourceCache{ResourceCache}
+void ShaderVariableManagerVk::Initialize(const ShaderResourceLayoutVk& SrcLayout,
+ IMemoryAllocator& Allocator,
+ const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes,
+ Uint32 NumAllowedTypes)
+{
#ifdef DILIGENT_DEBUG
- , m_DbgAllocator {Allocator}
+ m_pDbgAllocator = &Allocator;
#endif
-// clang-format on
-{
+
const Uint32 AllowedTypeBits = GetAllowedTypeBits(AllowedVarTypes, NumAllowedTypes);
VERIFY_EXPR(m_NumVariables == 0);
auto MemSize = GetRequiredMemorySize(SrcLayout, AllowedVarTypes, NumAllowedTypes, m_NumVariables);
@@ -119,10 +114,10 @@ ShaderVariableManagerVk::~ShaderVariableManagerVk()
void ShaderVariableManagerVk::DestroyVariables(IMemoryAllocator& Allocator)
{
- VERIFY(&m_DbgAllocator == &Allocator, "Incosistent alloctor");
-
if (m_pVariables != nullptr)
{
+ VERIFY(m_pDbgAllocator == &Allocator, "Incosistent alloctor");
+
for (Uint32 v = 0; v < m_NumVariables; ++v)
m_pVariables[v].~ShaderVariableVkImpl();
Allocator.Free(m_pVariables);
@@ -130,7 +125,7 @@ void ShaderVariableManagerVk::DestroyVariables(IMemoryAllocator& Allocator)
}
}
-ShaderVariableVkImpl* ShaderVariableManagerVk::GetVariable(const Char* Name)
+ShaderVariableVkImpl* ShaderVariableManagerVk::GetVariable(const Char* Name) const
{
ShaderVariableVkImpl* pVar = nullptr;
for (Uint32 v = 0; v < m_NumVariables; ++v)
@@ -147,7 +142,7 @@ ShaderVariableVkImpl* ShaderVariableManagerVk::GetVariable(const Char* Name)
}
-ShaderVariableVkImpl* ShaderVariableManagerVk::GetVariable(Uint32 Index)
+ShaderVariableVkImpl* ShaderVariableManagerVk::GetVariable(Uint32 Index) const
{
if (Index >= m_NumVariables)
{
@@ -178,7 +173,7 @@ Uint32 ShaderVariableManagerVk::GetVariableIndex(const ShaderVariableVkImpl& Var
}
}
-void ShaderVariableManagerVk::BindResources(IResourceMapping* pResourceMapping, Uint32 Flags)
+void ShaderVariableManagerVk::BindResources(IResourceMapping* pResourceMapping, Uint32 Flags) const
{
if (!pResourceMapping)
{