diff options
| author | assiduous <assiduous@diligentgraphics.com> | 2020-10-20 20:26:21 +0000 |
|---|---|---|
| committer | assiduous <assiduous@diligentgraphics.com> | 2020-10-20 20:26:21 +0000 |
| commit | 13b0b54987db2684e46e337d2e5be5b81366083b (patch) | |
| tree | 40f2f3c7b180c7728bc8676cd32614e16fac17a0 /Graphics/GraphicsEngineD3D12 | |
| parent | Renamed USAGE_STATIC to USAGE_IMMUTABLE (API240077) (diff) | |
| download | DiligentCore-13b0b54987db2684e46e337d2e5be5b81366083b.tar.gz DiligentCore-13b0b54987db2684e46e337d2e5be5b81366083b.zip | |
Improved exception safety of pipeline state object construction
Diffstat (limited to 'Graphics/GraphicsEngineD3D12')
8 files changed, 323 insertions, 294 deletions
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); |
