From 2250c36e3570a949104a3a49b02546a3dd8f1917 Mon Sep 17 00:00:00 2001 From: assiduous Date: Wed, 7 Oct 2020 14:57:33 -0700 Subject: Updated PipelineState[D3D11,D3D12,Vk]Impl to allocate single chunk of memory for resource layout, resource cache and var managers objects --- .../src/PipelineStateD3D12Impl.cpp | 33 +++++++++++----------- 1 file changed, 16 insertions(+), 17 deletions(-) (limited to 'Graphics/GraphicsEngineD3D12') diff --git a/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp index 138b6b3d..e9c313a5 100644 --- a/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp @@ -110,20 +110,18 @@ PipelineStateD3D12Impl::PipelineStateD3D12Impl(IReferenceCounters* pR const auto& ResourceLayout = m_Desc.ResourceLayout; m_RootSig.AllocateStaticSamplers(ResourceLayout); - { - auto& ShaderResLayoutAllocator = GetRawAllocator(); - m_pShaderResourceLayouts = ALLOCATE(ShaderResLayoutAllocator, "Raw memory for ShaderResourceLayoutD3D12", ShaderResourceLayoutD3D12, m_NumShaders * 2); - } - - { - auto& ShaderResCacheAllocator = GetRawAllocator(); - m_pStaticResourceCaches = ALLOCATE(ShaderResCacheAllocator, "Raw memory for ShaderResourceCacheD3D12", ShaderResourceCacheD3D12, m_NumShaders); - } - - { - auto& ShaderVarMgrAllocator = GetRawAllocator(); - m_pStaticVarManagers = ALLOCATE(ShaderVarMgrAllocator, "Raw memory for ShaderVariableManagerD3D12", ShaderVariableManagerD3D12, m_NumShaders); - } + // clang-format off + static_assert((sizeof(ShaderResourceLayoutD3D12) % sizeof(void*)) == 0, "sizeof(ShaderResourceLayoutD3D12) is expected to be a multiple of sizeof(void*)"); + static_assert((sizeof(ShaderResourceCacheD3D12) % sizeof(void*)) == 0, "sizeof(ShaderResourceCacheD3D12) is expected to be a multiple of sizeof(void*)"); + static_assert((sizeof(ShaderVariableManagerD3D12) % sizeof(void*)) == 0, "sizeof(ShaderVariableManagerD3D12) is expected to be a multiple of sizeof(void*)"); + // clang-format on + const auto MemSize = (sizeof(ShaderResourceLayoutD3D12) * 2 + sizeof(ShaderResourceCacheD3D12) + sizeof(ShaderVariableManagerD3D12)) * m_NumShaders; + auto* const pRawMem = + ALLOCATE_RAW(GetRawAllocator(), "Raw memory for ShaderResourceLayoutD3D12, ShaderResourceCacheD3D12, and ShaderVariableManagerD3D12 arrays", MemSize); + + m_pShaderResourceLayouts = reinterpret_cast(pRawMem); + m_pStaticResourceCaches = reinterpret_cast(m_pShaderResourceLayouts + m_NumShaders * 2); + m_pStaticVarManagers = reinterpret_cast(m_pStaticResourceCaches + m_NumShaders); #ifdef DILIGENT_DEVELOPMENT { @@ -444,9 +442,10 @@ PipelineStateD3D12Impl::~PipelineStateD3D12Impl() m_pShaderResourceLayouts[s].~ShaderResourceLayoutD3D12(); m_pShaderResourceLayouts[m_NumShaders + s].~ShaderResourceLayoutD3D12(); } - ShaderResLayoutAllocator.Free(m_pStaticVarManagers); - ShaderResLayoutAllocator.Free(m_pStaticResourceCaches); - ShaderResLayoutAllocator.Free(m_pShaderResourceLayouts); + // 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); -- cgit v1.2.3 From 2b396d236ab33dfe9c0defbe401d354ed3fb34f9 Mon Sep 17 00:00:00 2001 From: azhirnov Date: Thu, 8 Oct 2020 21:45:01 +0300 Subject: removed strong references to shaders in PSO --- .../include/PipelineStateD3D12Impl.hpp | 8 +-- .../src/PipelineStateD3D12Impl.cpp | 69 +++++++++++----------- .../src/ShaderResourceBindingD3D12Impl.cpp | 16 +++-- 3 files changed, 44 insertions(+), 49 deletions(-) (limited to 'Graphics/GraphicsEngineD3D12') diff --git a/Graphics/GraphicsEngineD3D12/include/PipelineStateD3D12Impl.hpp b/Graphics/GraphicsEngineD3D12/include/PipelineStateD3D12Impl.hpp index a53a625d..1ce53c24 100644 --- a/Graphics/GraphicsEngineD3D12/include/PipelineStateD3D12Impl.hpp +++ b/Graphics/GraphicsEngineD3D12/include/PipelineStateD3D12Impl.hpp @@ -95,19 +95,19 @@ public: const ShaderResourceLayoutD3D12& GetShaderResLayout(Uint32 ShaderInd) const { - VERIFY_EXPR(ShaderInd < m_NumShaders); + VERIFY_EXPR(ShaderInd < GetNumShaderTypes()); return m_pShaderResourceLayouts[ShaderInd]; } const ShaderResourceLayoutD3D12& GetStaticShaderResLayout(Uint32 ShaderInd) const { - VERIFY_EXPR(ShaderInd < m_NumShaders); - return m_pShaderResourceLayouts[m_NumShaders + ShaderInd]; + VERIFY_EXPR(ShaderInd < GetNumShaderTypes()); + return m_pShaderResourceLayouts[GetNumShaderTypes() + ShaderInd]; } ShaderResourceCacheD3D12& GetStaticShaderResCache(Uint32 ShaderInd) const { - VERIFY_EXPR(ShaderInd < m_NumShaders); + VERIFY_EXPR(ShaderInd < GetNumShaderTypes()); return m_pStaticResourceCaches[ShaderInd]; } diff --git a/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp index e9c313a5..d5958ea8 100644 --- a/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp @@ -106,6 +106,9 @@ PipelineStateD3D12Impl::PipelineStateD3D12Impl(IReferenceCounters* pR { m_ResourceLayoutIndex.fill(-1); + ShaderStages_t ShaderStages; + ExtractShaders(ShaderStages); + auto pd3d12Device = pDeviceD3D12->GetD3D12Device(); const auto& ResourceLayout = m_Desc.ResourceLayout; m_RootSig.AllocateStaticSamplers(ResourceLayout); @@ -115,31 +118,31 @@ PipelineStateD3D12Impl::PipelineStateD3D12Impl(IReferenceCounters* pR static_assert((sizeof(ShaderResourceCacheD3D12) % sizeof(void*)) == 0, "sizeof(ShaderResourceCacheD3D12) is expected to be a multiple of sizeof(void*)"); static_assert((sizeof(ShaderVariableManagerD3D12) % sizeof(void*)) == 0, "sizeof(ShaderVariableManagerD3D12) is expected to be a multiple of sizeof(void*)"); // clang-format on - const auto MemSize = (sizeof(ShaderResourceLayoutD3D12) * 2 + sizeof(ShaderResourceCacheD3D12) + sizeof(ShaderVariableManagerD3D12)) * m_NumShaders; + const auto MemSize = (sizeof(ShaderResourceLayoutD3D12) * 2 + sizeof(ShaderResourceCacheD3D12) + sizeof(ShaderVariableManagerD3D12)) * GetNumShaderTypes(); auto* const pRawMem = ALLOCATE_RAW(GetRawAllocator(), "Raw memory for ShaderResourceLayoutD3D12, ShaderResourceCacheD3D12, and ShaderVariableManagerD3D12 arrays", MemSize); m_pShaderResourceLayouts = reinterpret_cast(pRawMem); - m_pStaticResourceCaches = reinterpret_cast(m_pShaderResourceLayouts + m_NumShaders * 2); - m_pStaticVarManagers = reinterpret_cast(m_pStaticResourceCaches + m_NumShaders); + m_pStaticResourceCaches = reinterpret_cast(m_pShaderResourceLayouts + GetNumShaderTypes() * 2); + m_pStaticVarManagers = reinterpret_cast(m_pStaticResourceCaches + GetNumShaderTypes()); #ifdef DILIGENT_DEVELOPMENT { const ShaderResources* pResources[MAX_SHADERS_IN_PIPELINE] = {}; - for (Uint32 s = 0; s < m_NumShaders; ++s) + for (size_t s = 0; s < ShaderStages.size(); ++s) { - const auto* pShader = GetShader(s); + const auto* pShader = ValidatedCast(ShaderStages[s].second); pResources[s] = &(*pShader->GetShaderResources()); } - ShaderResources::DvpVerifyResourceLayout(ResourceLayout, pResources, m_NumShaders, + ShaderResources::DvpVerifyResourceLayout(ResourceLayout, pResources, GetNumShaderTypes(), (CreateInfo.Flags & PSO_CREATE_FLAG_IGNORE_MISSING_VARIABLES) == 0, (CreateInfo.Flags & PSO_CREATE_FLAG_IGNORE_MISSING_STATIC_SAMPLERS) == 0); } #endif - for (Uint32 s = 0; s < m_NumShaders; ++s) + for (size_t s = 0; s < ShaderStages.size(); ++s) { - auto* pShaderD3D12 = GetShader(s); + auto* pShaderD3D12 = ValidatedCast(ShaderStages[s].second); auto ShaderType = pShaderD3D12->GetDesc().ShaderType; auto ShaderInd = GetShaderTypePipelineIndex(ShaderType, m_Desc.PipelineType); @@ -163,7 +166,7 @@ PipelineStateD3D12Impl::PipelineStateD3D12Impl(IReferenceCounters* pR new (m_pStaticResourceCaches + s) ShaderResourceCacheD3D12{ShaderResourceCacheD3D12::DbgCacheContentType::StaticShaderResources}; const SHADER_RESOURCE_VARIABLE_TYPE StaticVarType[] = {SHADER_RESOURCE_VARIABLE_TYPE_STATIC}; - new (m_pShaderResourceLayouts + m_NumShaders + s) + new (m_pShaderResourceLayouts + GetNumShaderTypes() + s) ShaderResourceLayoutD3D12 // { *this, @@ -182,11 +185,11 @@ PipelineStateD3D12Impl::PipelineStateD3D12Impl(IReferenceCounters* pR ShaderVariableManagerD3D12 // { *this, - GetStaticShaderResLayout(s), + GetStaticShaderResLayout(static_cast(s)), GetRawAllocator(), nullptr, 0, - GetStaticShaderResCache(s) // + GetStaticShaderResCache(static_cast(s)) // }; } m_RootSig.Finalize(pd3d12Device); @@ -195,14 +198,9 @@ PipelineStateD3D12Impl::PipelineStateD3D12Impl(IReferenceCounters* pR { case PIPELINE_TYPE_COMPUTE: { - auto& ComputePipeline = m_Desc.ComputePipeline; - - if (ComputePipeline.pCS == nullptr) - LOG_ERROR_AND_THROW("Compute shader is not set in the pipeline desc"); - D3D12_COMPUTE_PIPELINE_STATE_DESC d3d12PSODesc = {}; - auto* pByteCode = ValidatedCast(ComputePipeline.pCS)->GetShaderByteCode(); + auto* pByteCode = ValidatedCast(ShaderStages[0].second)->GetShaderByteCode(); d3d12PSODesc.CS.pShaderBytecode = pByteCode->GetBufferPointer(); d3d12PSODesc.CS.BytecodeLength = pByteCode->GetBufferSize(); @@ -231,9 +229,9 @@ PipelineStateD3D12Impl::PipelineStateD3D12Impl(IReferenceCounters* pR D3D12_GRAPHICS_PIPELINE_STATE_DESC d3d12PSODesc = {}; - for (Uint32 s = 0; s < m_NumShaders; ++s) + for (size_t s = 0; s < ShaderStages.size(); ++s) { - auto* pShaderD3D12 = GetShader(s); + auto* pShaderD3D12 = ValidatedCast(ShaderStages[s].second); auto ShaderType = pShaderD3D12->GetDesc().ShaderType; D3D12_SHADER_BYTECODE* pd3d12ShaderBytecode = nullptr; @@ -335,9 +333,9 @@ PipelineStateD3D12Impl::PipelineStateD3D12Impl(IReferenceCounters* pR }; MESH_SHADER_PIPELINE_STATE_DESC d3d12PSODesc = {}; - for (Uint32 s = 0; s < m_NumShaders; ++s) + for (size_t s = 0; s < ShaderStages.size(); ++s) { - auto* pShaderD3D12 = GetShader(s); + auto* pShaderD3D12 = ValidatedCast(ShaderStages[s].second); auto ShaderType = pShaderD3D12->GetDesc().ShaderType; D3D12_SHADER_BYTECODE* pd3d12ShaderBytecode = nullptr; @@ -412,7 +410,7 @@ PipelineStateD3D12Impl::PipelineStateD3D12Impl(IReferenceCounters* pR if (m_Desc.SRBAllocationGranularity > 1) { std::array ShaderVarMgrDataSizes = {}; - for (Uint32 s = 0; s < m_NumShaders; ++s) + for (Uint32 s = 0; s < GetNumShaderTypes(); ++s) { std::array AllowedVarTypes = { @@ -425,7 +423,7 @@ PipelineStateD3D12Impl::PipelineStateD3D12Impl(IReferenceCounters* pR } auto CacheMemorySize = m_RootSig.GetResourceCacheRequiredMemSize(); - m_SRBMemAllocator.Initialize(m_Desc.SRBAllocationGranularity, m_NumShaders, ShaderVarMgrDataSizes.data(), 1, &CacheMemorySize); + m_SRBMemAllocator.Initialize(m_Desc.SRBAllocationGranularity, GetNumShaderTypes(), ShaderVarMgrDataSizes.data(), 1, &CacheMemorySize); } m_ShaderResourceLayoutHash = m_RootSig.GetHash(); @@ -434,13 +432,13 @@ PipelineStateD3D12Impl::PipelineStateD3D12Impl(IReferenceCounters* pR PipelineStateD3D12Impl::~PipelineStateD3D12Impl() { auto& ShaderResLayoutAllocator = GetRawAllocator(); - for (Uint32 s = 0; s < m_NumShaders; ++s) + for (Uint32 s = 0; s < GetNumShaderTypes(); ++s) { m_pStaticVarManagers[s].Destroy(GetRawAllocator()); m_pStaticVarManagers[s].~ShaderVariableManagerD3D12(); m_pStaticResourceCaches[s].~ShaderResourceCacheD3D12(); m_pShaderResourceLayouts[s].~ShaderResourceLayoutD3D12(); - m_pShaderResourceLayouts[m_NumShaders + s].~ShaderResourceLayoutD3D12(); + m_pShaderResourceLayouts[GetNumShaderTypes() + s].~ShaderResourceLayoutD3D12(); } // m_pShaderResourceLayouts, m_pStaticResourceCaches, and m_pShaderResourceLayouts are allocated in // contiguous chunks of memory. @@ -479,27 +477,26 @@ bool PipelineStateD3D12Impl::IsCompatibleWith(const IPipelineState* pPSO) const #ifdef DILIGENT_DEBUG { bool IsCompatibleShaders = true; - if (m_NumShaders != pPSOD3D12->m_NumShaders) + if (GetNumShaderTypes() != pPSOD3D12->GetNumShaderTypes()) IsCompatibleShaders = false; if (IsCompatibleShaders) { - for (Uint32 s = 0; s < m_NumShaders; ++s) + for (Uint32 s = 0; s < GetNumShaderTypes(); ++s) { - auto* pShader0 = GetShader(s); - auto* pShader1 = pPSOD3D12->GetShader(s); - if (pShader0->GetDesc().ShaderType != pShader1->GetDesc().ShaderType) + if (GetShaderTypes()[s] != pPSOD3D12->GetShaderTypes()[s]) { IsCompatibleShaders = false; break; } - const ShaderResourcesD3D12* pRes0 = pShader0->GetShaderResources().get(); + // AZ TODO + /*const ShaderResourcesD3D12* pRes0 = pShader0->GetShaderResources().get(); const ShaderResourcesD3D12* pRes1 = pShader1->GetShaderResources().get(); if (!pRes0->IsCompatibleWith(*pRes1)) { IsCompatibleShaders = false; break; - } + }*/ } } @@ -606,7 +603,7 @@ bool PipelineStateD3D12Impl::ContainsShaderResources() const void PipelineStateD3D12Impl::BindStaticResources(Uint32 ShaderFlags, IResourceMapping* pResourceMapping, Uint32 Flags) { - for (Uint32 s = 0; s < m_NumShaders; ++s) + for (Uint32 s = 0; s < GetNumShaderTypes(); ++s) { auto ShaderType = GetStaticShaderResLayout(s).GetShaderType(); if ((ShaderFlags & ShaderType) != 0) @@ -620,7 +617,7 @@ Uint32 PipelineStateD3D12Impl::GetStaticVariableCount(SHADER_TYPE ShaderType) co if (LayoutInd < 0) return 0; - VERIFY_EXPR(static_cast(LayoutInd) < m_NumShaders); + VERIFY_EXPR(static_cast(LayoutInd) < GetNumShaderTypes()); return m_pStaticVarManagers[LayoutInd].GetVariableCount(); } @@ -630,7 +627,7 @@ IShaderResourceVariable* PipelineStateD3D12Impl::GetStaticVariableByName(SHADER_ if (LayoutInd < 0) return nullptr; - VERIFY_EXPR(static_cast(LayoutInd) < m_NumShaders); + VERIFY_EXPR(static_cast(LayoutInd) < GetNumShaderTypes()); return m_pStaticVarManagers[LayoutInd].GetVariable(Name); } @@ -640,7 +637,7 @@ IShaderResourceVariable* PipelineStateD3D12Impl::GetStaticVariableByIndex(SHADER if (LayoutInd < 0) return nullptr; - VERIFY_EXPR(static_cast(LayoutInd) < m_NumShaders); + VERIFY_EXPR(static_cast(LayoutInd) < GetNumShaderTypes()); return m_pStaticVarManagers[LayoutInd].GetVariable(Index); } diff --git a/Graphics/GraphicsEngineD3D12/src/ShaderResourceBindingD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/ShaderResourceBindingD3D12Impl.cpp index 257a4688..17387138 100644 --- a/Graphics/GraphicsEngineD3D12/src/ShaderResourceBindingD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/ShaderResourceBindingD3D12Impl.cpp @@ -45,11 +45,10 @@ ShaderResourceBindingD3D12Impl::ShaderResourceBindingD3D12Impl(IReferenceCounter IsPSOInternal }, m_ShaderResourceCache{ShaderResourceCacheD3D12::DbgCacheContentType::SRBResources}, - m_NumShaders {static_cast(pPSO->GetNumShaders())} + m_NumShaders {static_cast(pPSO->GetNumShaderTypes())} // clang-format on { m_ResourceLayoutIndex.fill(-1); - auto* ppShaders = pPSO->GetShaders(); auto* pRenderDeviceD3D12Impl = ValidatedCast(pPSO->GetDevice()); auto& ResCacheDataAllocator = pPSO->GetSRBMemoryAllocator().GetResourceCacheDataAllocator(0); @@ -59,9 +58,8 @@ ShaderResourceBindingD3D12Impl::ShaderResourceBindingD3D12Impl(IReferenceCounter for (Uint32 s = 0; s < m_NumShaders; ++s) { - auto* pShader = ppShaders[s]; - auto ShaderType = pShader->GetDesc().ShaderType; - auto ShaderInd = GetShaderTypePipelineIndex(ShaderType, pPSO->GetDesc().PipelineType); + auto ShaderType = pPSO->GetShaderTypes()[s]; + auto ShaderInd = GetShaderTypePipelineIndex(ShaderType, pPSO->GetDesc().PipelineType); auto& VarDataAllocator = pPSO->GetSRBMemoryAllocator().GetShaderVariableDataAllocator(s); @@ -189,20 +187,20 @@ void ShaderResourceBindingD3D12Impl::InitializeStaticResources(const IPipelineSt } auto* pPSO12 = ValidatedCast(pPSO); - auto NumShaders = pPSO12->GetNumShaders(); + auto NumShaders = pPSO12->GetNumShaderTypes(); // Copy static resources for (Uint32 s = 0; s < NumShaders; ++s) { const auto& ShaderResLayout = pPSO12->GetShaderResLayout(s); auto& StaticResLayout = pPSO12->GetStaticShaderResLayout(s); auto& StaticResCache = pPSO12->GetStaticShaderResCache(s); + #ifdef DILIGENT_DEVELOPMENT if (!StaticResLayout.dvpVerifyBindings(StaticResCache)) { - auto* pShader = pPSO12->GetShader(s); LOG_ERROR_MESSAGE("Static resources in SRB of PSO '", pPSO12->GetDesc().Name, - "' will not be successfully initialized because not all static resource bindings in shader '", - pShader->GetDesc().Name, + "' will not be successfully initialized because not all static resource bindings in shader type '", + GetShaderTypeLiteralName(pPSO12->GetShaderTypes()[s]), "' are valid. Please make sure you bind all static resources to PSO before calling InitializeStaticResources() " "directly or indirectly by passing InitStaticResources=true to CreateShaderResourceBinding() method."); } -- cgit v1.2.3 From 998165f350cfd8ae6bd9cbf6fc812874c1c3c3da Mon Sep 17 00:00:00 2001 From: azhirnov Date: Thu, 8 Oct 2020 22:14:06 +0300 Subject: Revert some changes in ShaderResourceLayoutVk, fixed PSO comparison --- .../GraphicsEngineD3D12/include/ShaderResourceLayoutD3D12.hpp | 2 ++ Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp | 10 +++++----- 2 files changed, 7 insertions(+), 5 deletions(-) (limited to 'Graphics/GraphicsEngineD3D12') diff --git a/Graphics/GraphicsEngineD3D12/include/ShaderResourceLayoutD3D12.hpp b/Graphics/GraphicsEngineD3D12/include/ShaderResourceLayoutD3D12.hpp index e043cf4a..5426d98b 100644 --- a/Graphics/GraphicsEngineD3D12/include/ShaderResourceLayoutD3D12.hpp +++ b/Graphics/GraphicsEngineD3D12/include/ShaderResourceLayoutD3D12.hpp @@ -273,6 +273,8 @@ public: SHADER_TYPE GetShaderType() const { return m_pResources->GetShaderType(); } + const ShaderResourcesD3D12& GetResources() const { return *m_pResources; } + private: const D3D12Resource& GetAssignedSampler(const D3D12Resource& TexSrv) const; D3D12Resource& GetAssignedSampler(const D3D12Resource& TexSrv); diff --git a/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp index d5958ea8..3e8673d5 100644 --- a/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp @@ -489,14 +489,14 @@ bool PipelineStateD3D12Impl::IsCompatibleWith(const IPipelineState* pPSO) const IsCompatibleShaders = false; break; } - // AZ TODO - /*const ShaderResourcesD3D12* pRes0 = pShader0->GetShaderResources().get(); - const ShaderResourcesD3D12* pRes1 = pShader1->GetShaderResources().get(); - if (!pRes0->IsCompatibleWith(*pRes1)) + + const auto& Res0 = GetShaderResLayout(s).GetResources(); + const auto& Res1 = pPSOD3D12->GetShaderResLayout(s).GetResources(); + if (!Res0.IsCompatibleWith(Res1)) { IsCompatibleShaders = false; break; - }*/ + } } } -- cgit v1.2.3 From 91aac63f651da1079be93d2fe722cd10e4e15570 Mon Sep 17 00:00:00 2001 From: assiduous Date: Sat, 10 Oct 2020 19:28:54 -0700 Subject: A number of corrections for PSO refactoring --- .../include/PipelineStateD3D12Impl.hpp | 8 +-- .../src/PipelineStateD3D12Impl.cpp | 64 +++++++++++++--------- .../src/ShaderResourceBindingD3D12Impl.cpp | 8 +-- 3 files changed, 47 insertions(+), 33 deletions(-) (limited to 'Graphics/GraphicsEngineD3D12') diff --git a/Graphics/GraphicsEngineD3D12/include/PipelineStateD3D12Impl.hpp b/Graphics/GraphicsEngineD3D12/include/PipelineStateD3D12Impl.hpp index 1ce53c24..00b2affd 100644 --- a/Graphics/GraphicsEngineD3D12/include/PipelineStateD3D12Impl.hpp +++ b/Graphics/GraphicsEngineD3D12/include/PipelineStateD3D12Impl.hpp @@ -95,19 +95,19 @@ public: const ShaderResourceLayoutD3D12& GetShaderResLayout(Uint32 ShaderInd) const { - VERIFY_EXPR(ShaderInd < GetNumShaderTypes()); + VERIFY_EXPR(ShaderInd < GetNumShaderStages()); return m_pShaderResourceLayouts[ShaderInd]; } const ShaderResourceLayoutD3D12& GetStaticShaderResLayout(Uint32 ShaderInd) const { - VERIFY_EXPR(ShaderInd < GetNumShaderTypes()); - return m_pShaderResourceLayouts[GetNumShaderTypes() + ShaderInd]; + VERIFY_EXPR(ShaderInd < GetNumShaderStages()); + return m_pShaderResourceLayouts[GetNumShaderStages() + ShaderInd]; } ShaderResourceCacheD3D12& GetStaticShaderResCache(Uint32 ShaderInd) const { - VERIFY_EXPR(ShaderInd < GetNumShaderTypes()); + VERIFY_EXPR(ShaderInd < GetNumShaderStages()); return m_pStaticResourceCaches[ShaderInd]; } diff --git a/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp index 3e8673d5..f5d60b60 100644 --- a/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp @@ -106,8 +106,19 @@ PipelineStateD3D12Impl::PipelineStateD3D12Impl(IReferenceCounters* pR { m_ResourceLayoutIndex.fill(-1); - ShaderStages_t ShaderStages; - ExtractShaders(ShaderStages); + struct D3D12PipelineShaderStageInfo + { + const SHADER_TYPE Type; + ShaderD3D12Impl* const pShader; + D3D12PipelineShaderStageInfo(SHADER_TYPE _Type, + ShaderD3D12Impl* _pShader) : + Type{_Type}, + pShader{_pShader} + {} + }; + std::vector ShaderStages; + ExtractShaders(ShaderStages); + VERIFY_EXPR(GetNumShaderStages() == ShaderStages.size()); auto pd3d12Device = pDeviceD3D12->GetD3D12Device(); const auto& ResourceLayout = m_Desc.ResourceLayout; @@ -118,23 +129,23 @@ PipelineStateD3D12Impl::PipelineStateD3D12Impl(IReferenceCounters* pR static_assert((sizeof(ShaderResourceCacheD3D12) % sizeof(void*)) == 0, "sizeof(ShaderResourceCacheD3D12) is expected to be a multiple of sizeof(void*)"); static_assert((sizeof(ShaderVariableManagerD3D12) % sizeof(void*)) == 0, "sizeof(ShaderVariableManagerD3D12) is expected to be a multiple of sizeof(void*)"); // clang-format on - const auto MemSize = (sizeof(ShaderResourceLayoutD3D12) * 2 + sizeof(ShaderResourceCacheD3D12) + sizeof(ShaderVariableManagerD3D12)) * GetNumShaderTypes(); + const auto MemSize = (sizeof(ShaderResourceLayoutD3D12) * 2 + sizeof(ShaderResourceCacheD3D12) + sizeof(ShaderVariableManagerD3D12)) * GetNumShaderStages(); auto* const pRawMem = ALLOCATE_RAW(GetRawAllocator(), "Raw memory for ShaderResourceLayoutD3D12, ShaderResourceCacheD3D12, and ShaderVariableManagerD3D12 arrays", MemSize); m_pShaderResourceLayouts = reinterpret_cast(pRawMem); - m_pStaticResourceCaches = reinterpret_cast(m_pShaderResourceLayouts + GetNumShaderTypes() * 2); - m_pStaticVarManagers = reinterpret_cast(m_pStaticResourceCaches + GetNumShaderTypes()); + m_pStaticResourceCaches = reinterpret_cast(m_pShaderResourceLayouts + GetNumShaderStages() * 2); + m_pStaticVarManagers = reinterpret_cast(m_pStaticResourceCaches + GetNumShaderStages()); #ifdef DILIGENT_DEVELOPMENT { const ShaderResources* pResources[MAX_SHADERS_IN_PIPELINE] = {}; for (size_t s = 0; s < ShaderStages.size(); ++s) { - const auto* pShader = ValidatedCast(ShaderStages[s].second); + const auto* pShader = ShaderStages[s].pShader; pResources[s] = &(*pShader->GetShaderResources()); } - ShaderResources::DvpVerifyResourceLayout(ResourceLayout, pResources, GetNumShaderTypes(), + ShaderResources::DvpVerifyResourceLayout(ResourceLayout, pResources, GetNumShaderStages(), (CreateInfo.Flags & PSO_CREATE_FLAG_IGNORE_MISSING_VARIABLES) == 0, (CreateInfo.Flags & PSO_CREATE_FLAG_IGNORE_MISSING_STATIC_SAMPLERS) == 0); } @@ -142,7 +153,7 @@ PipelineStateD3D12Impl::PipelineStateD3D12Impl(IReferenceCounters* pR for (size_t s = 0; s < ShaderStages.size(); ++s) { - auto* pShaderD3D12 = ValidatedCast(ShaderStages[s].second); + auto* pShaderD3D12 = ShaderStages[s].pShader; auto ShaderType = pShaderD3D12->GetDesc().ShaderType; auto ShaderInd = GetShaderTypePipelineIndex(ShaderType, m_Desc.PipelineType); @@ -166,7 +177,7 @@ PipelineStateD3D12Impl::PipelineStateD3D12Impl(IReferenceCounters* pR new (m_pStaticResourceCaches + s) ShaderResourceCacheD3D12{ShaderResourceCacheD3D12::DbgCacheContentType::StaticShaderResources}; const SHADER_RESOURCE_VARIABLE_TYPE StaticVarType[] = {SHADER_RESOURCE_VARIABLE_TYPE_STATIC}; - new (m_pShaderResourceLayouts + GetNumShaderTypes() + s) + new (m_pShaderResourceLayouts + GetNumShaderStages() + s) ShaderResourceLayoutD3D12 // { *this, @@ -200,7 +211,8 @@ PipelineStateD3D12Impl::PipelineStateD3D12Impl(IReferenceCounters* pR { D3D12_COMPUTE_PIPELINE_STATE_DESC d3d12PSODesc = {}; - auto* pByteCode = ValidatedCast(ShaderStages[0].second)->GetShaderByteCode(); + VERIFY_EXPR(ShaderStages[0].Type == SHADER_TYPE_COMPUTE); + auto* pByteCode = ShaderStages[0].pShader->GetShaderByteCode(); d3d12PSODesc.CS.pShaderBytecode = pByteCode->GetBufferPointer(); d3d12PSODesc.CS.BytecodeLength = pByteCode->GetBufferSize(); @@ -229,10 +241,11 @@ PipelineStateD3D12Impl::PipelineStateD3D12Impl(IReferenceCounters* pR D3D12_GRAPHICS_PIPELINE_STATE_DESC d3d12PSODesc = {}; - for (size_t s = 0; s < ShaderStages.size(); ++s) + for (const auto& Stage : ShaderStages) { - auto* pShaderD3D12 = ValidatedCast(ShaderStages[s].second); + auto* pShaderD3D12 = Stage.pShader; auto ShaderType = pShaderD3D12->GetDesc().ShaderType; + VERIFY_EXPR(ShaderType == Stage.Type); D3D12_SHADER_BYTECODE* pd3d12ShaderBytecode = nullptr; switch (ShaderType) @@ -333,10 +346,11 @@ PipelineStateD3D12Impl::PipelineStateD3D12Impl(IReferenceCounters* pR }; MESH_SHADER_PIPELINE_STATE_DESC d3d12PSODesc = {}; - for (size_t s = 0; s < ShaderStages.size(); ++s) + for (const auto& Stage : ShaderStages) { - auto* pShaderD3D12 = ValidatedCast(ShaderStages[s].second); + auto* pShaderD3D12 = Stage.pShader; auto ShaderType = pShaderD3D12->GetDesc().ShaderType; + VERIFY_EXPR(ShaderType == Stage.Type); D3D12_SHADER_BYTECODE* pd3d12ShaderBytecode = nullptr; switch (ShaderType) @@ -410,7 +424,7 @@ PipelineStateD3D12Impl::PipelineStateD3D12Impl(IReferenceCounters* pR if (m_Desc.SRBAllocationGranularity > 1) { std::array ShaderVarMgrDataSizes = {}; - for (Uint32 s = 0; s < GetNumShaderTypes(); ++s) + for (Uint32 s = 0; s < GetNumShaderStages(); ++s) { std::array AllowedVarTypes = { @@ -423,7 +437,7 @@ PipelineStateD3D12Impl::PipelineStateD3D12Impl(IReferenceCounters* pR } auto CacheMemorySize = m_RootSig.GetResourceCacheRequiredMemSize(); - m_SRBMemAllocator.Initialize(m_Desc.SRBAllocationGranularity, GetNumShaderTypes(), ShaderVarMgrDataSizes.data(), 1, &CacheMemorySize); + m_SRBMemAllocator.Initialize(m_Desc.SRBAllocationGranularity, GetNumShaderStages(), ShaderVarMgrDataSizes.data(), 1, &CacheMemorySize); } m_ShaderResourceLayoutHash = m_RootSig.GetHash(); @@ -432,13 +446,13 @@ PipelineStateD3D12Impl::PipelineStateD3D12Impl(IReferenceCounters* pR PipelineStateD3D12Impl::~PipelineStateD3D12Impl() { auto& ShaderResLayoutAllocator = GetRawAllocator(); - for (Uint32 s = 0; s < GetNumShaderTypes(); ++s) + 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[GetNumShaderTypes() + s].~ShaderResourceLayoutD3D12(); + m_pShaderResourceLayouts[GetNumShaderStages() + s].~ShaderResourceLayoutD3D12(); } // m_pShaderResourceLayouts, m_pStaticResourceCaches, and m_pShaderResourceLayouts are allocated in // contiguous chunks of memory. @@ -477,14 +491,14 @@ bool PipelineStateD3D12Impl::IsCompatibleWith(const IPipelineState* pPSO) const #ifdef DILIGENT_DEBUG { bool IsCompatibleShaders = true; - if (GetNumShaderTypes() != pPSOD3D12->GetNumShaderTypes()) + if (GetNumShaderStages() != pPSOD3D12->GetNumShaderStages()) IsCompatibleShaders = false; if (IsCompatibleShaders) { - for (Uint32 s = 0; s < GetNumShaderTypes(); ++s) + for (Uint32 s = 0; s < GetNumShaderStages(); ++s) { - if (GetShaderTypes()[s] != pPSOD3D12->GetShaderTypes()[s]) + if (GetShaderStageType(s) != pPSOD3D12->GetShaderStageType(s)) { IsCompatibleShaders = false; break; @@ -603,7 +617,7 @@ bool PipelineStateD3D12Impl::ContainsShaderResources() const void PipelineStateD3D12Impl::BindStaticResources(Uint32 ShaderFlags, IResourceMapping* pResourceMapping, Uint32 Flags) { - for (Uint32 s = 0; s < GetNumShaderTypes(); ++s) + for (Uint32 s = 0; s < GetNumShaderStages(); ++s) { auto ShaderType = GetStaticShaderResLayout(s).GetShaderType(); if ((ShaderFlags & ShaderType) != 0) @@ -617,7 +631,7 @@ Uint32 PipelineStateD3D12Impl::GetStaticVariableCount(SHADER_TYPE ShaderType) co if (LayoutInd < 0) return 0; - VERIFY_EXPR(static_cast(LayoutInd) < GetNumShaderTypes()); + VERIFY_EXPR(static_cast(LayoutInd) < GetNumShaderStages()); return m_pStaticVarManagers[LayoutInd].GetVariableCount(); } @@ -627,7 +641,7 @@ IShaderResourceVariable* PipelineStateD3D12Impl::GetStaticVariableByName(SHADER_ if (LayoutInd < 0) return nullptr; - VERIFY_EXPR(static_cast(LayoutInd) < GetNumShaderTypes()); + VERIFY_EXPR(static_cast(LayoutInd) < GetNumShaderStages()); return m_pStaticVarManagers[LayoutInd].GetVariable(Name); } @@ -637,7 +651,7 @@ IShaderResourceVariable* PipelineStateD3D12Impl::GetStaticVariableByIndex(SHADER if (LayoutInd < 0) return nullptr; - VERIFY_EXPR(static_cast(LayoutInd) < GetNumShaderTypes()); + VERIFY_EXPR(static_cast(LayoutInd) < GetNumShaderStages()); return m_pStaticVarManagers[LayoutInd].GetVariable(Index); } diff --git a/Graphics/GraphicsEngineD3D12/src/ShaderResourceBindingD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/ShaderResourceBindingD3D12Impl.cpp index 17387138..3293283a 100644 --- a/Graphics/GraphicsEngineD3D12/src/ShaderResourceBindingD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/ShaderResourceBindingD3D12Impl.cpp @@ -45,7 +45,7 @@ ShaderResourceBindingD3D12Impl::ShaderResourceBindingD3D12Impl(IReferenceCounter IsPSOInternal }, m_ShaderResourceCache{ShaderResourceCacheD3D12::DbgCacheContentType::SRBResources}, - m_NumShaders {static_cast(pPSO->GetNumShaderTypes())} + m_NumShaders {static_cast(pPSO->GetNumShaderStages())} // clang-format on { m_ResourceLayoutIndex.fill(-1); @@ -58,7 +58,7 @@ ShaderResourceBindingD3D12Impl::ShaderResourceBindingD3D12Impl(IReferenceCounter for (Uint32 s = 0; s < m_NumShaders; ++s) { - auto ShaderType = pPSO->GetShaderTypes()[s]; + auto ShaderType = pPSO->GetShaderStageType(s); auto ShaderInd = GetShaderTypePipelineIndex(ShaderType, pPSO->GetDesc().PipelineType); auto& VarDataAllocator = pPSO->GetSRBMemoryAllocator().GetShaderVariableDataAllocator(s); @@ -187,7 +187,7 @@ void ShaderResourceBindingD3D12Impl::InitializeStaticResources(const IPipelineSt } auto* pPSO12 = ValidatedCast(pPSO); - auto NumShaders = pPSO12->GetNumShaderTypes(); + auto NumShaders = pPSO12->GetNumShaderStages(); // Copy static resources for (Uint32 s = 0; s < NumShaders; ++s) { @@ -200,7 +200,7 @@ void ShaderResourceBindingD3D12Impl::InitializeStaticResources(const IPipelineSt { LOG_ERROR_MESSAGE("Static resources in SRB of PSO '", pPSO12->GetDesc().Name, "' will not be successfully initialized because not all static resource bindings in shader type '", - GetShaderTypeLiteralName(pPSO12->GetShaderTypes()[s]), + GetShaderTypeLiteralName(pPSO12->GetShaderStageType(s)), "' are valid. Please make sure you bind all static resources to PSO before calling InitializeStaticResources() " "directly or indirectly by passing InitStaticResources=true to CreateShaderResourceBinding() method."); } -- cgit v1.2.3 From b3fec8bd40e80115086281bce74774617aa95e23 Mon Sep 17 00:00:00 2001 From: assiduous Date: Wed, 14 Oct 2020 01:04:05 -0700 Subject: Added buffer mode validation when binding buffer views --- .../GraphicsEngineD3D12/src/ShaderResourceLayoutD3D12.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'Graphics/GraphicsEngineD3D12') diff --git a/Graphics/GraphicsEngineD3D12/src/ShaderResourceLayoutD3D12.cpp b/Graphics/GraphicsEngineD3D12/src/ShaderResourceLayoutD3D12.cpp index 6c313882..f00d62e7 100644 --- a/Graphics/GraphicsEngineD3D12/src/ShaderResourceLayoutD3D12.cpp +++ b/Graphics/GraphicsEngineD3D12/src/ShaderResourceLayoutD3D12.cpp @@ -38,6 +38,7 @@ #include "RootSignature.hpp" #include "PipelineStateD3D12Impl.hpp" #include "ShaderResourceVariableBase.hpp" +#include "ShaderVariableD3DBase.hpp" namespace Diligent { @@ -429,6 +430,11 @@ template <> struct ResourceViewTraits { static const INTERFACE_ID& IID; + + static bool VerifyView(ITextureViewD3D12* pViewD3D12, const D3DShaderResourceAttribs& Attribs, const char* ShaderName) + { + return true; + } }; const INTERFACE_ID& ResourceViewTraits::IID = IID_TextureViewD3D12; @@ -436,6 +442,11 @@ template <> struct ResourceViewTraits { static const INTERFACE_ID& IID; + + static bool VerifyView(IBufferViewD3D12* pViewD3D12, const D3DShaderResourceAttribs& Attribs, const char* ShaderName) + { + return VerifyBufferViewModeD3D(pViewD3D12, Attribs, ShaderName); + } }; const INTERFACE_ID& ResourceViewTraits::IID = IID_BufferViewD3D12; @@ -454,6 +465,7 @@ void ShaderResourceLayoutD3D12::D3D12Resource::CacheResourceView(IDeviceObject* RefCntAutoPtr pViewD3D12(pView, ResourceViewTraits::IID); #ifdef DILIGENT_DEVELOPMENT VerifyResourceViewBinding(Attribs, GetVariableType(), ArrayIndex, pView, pViewD3D12.RawPtr(), {dbgExpectedViewType}, DstRes.pObject.RawPtr(), ParentResLayout.GetShaderName()); + ResourceViewTraits::VerifyView(pViewD3D12, Attribs, ParentResLayout.GetShaderName()); #endif if (pViewD3D12) { -- cgit v1.2.3 From 259a9d5897937dcaaca1b4b294bb8d5250371e76 Mon Sep 17 00:00:00 2001 From: azhirnov Date: Thu, 15 Oct 2020 20:55:38 +0300 Subject: Added GraphicsPipelineCreateInfo and ComputePipelineCreateInfo instead of single PipelineCreateInfo. Some optimizations for dynamic memory allocations in PipelineState. --- .../include/PipelineStateD3D12Impl.hpp | 24 +- .../include/RenderDeviceD3D12Impl.hpp | 7 +- .../src/DeviceContextD3D12Impl.cpp | 65 ++- .../src/PipelineStateD3D12Impl.cpp | 575 +++++++++++---------- .../src/RenderDeviceD3D12Impl.cpp | 13 +- 5 files changed, 382 insertions(+), 302 deletions(-) (limited to 'Graphics/GraphicsEngineD3D12') diff --git a/Graphics/GraphicsEngineD3D12/include/PipelineStateD3D12Impl.hpp b/Graphics/GraphicsEngineD3D12/include/PipelineStateD3D12Impl.hpp index 00b2affd..821ff951 100644 --- a/Graphics/GraphicsEngineD3D12/include/PipelineStateD3D12Impl.hpp +++ b/Graphics/GraphicsEngineD3D12/include/PipelineStateD3D12Impl.hpp @@ -38,6 +38,7 @@ #include "SRBMemoryAllocator.hpp" #include "RenderDeviceD3D12Impl.hpp" #include "ShaderVariableD3D12.hpp" +#include "ShaderD3D12Impl.hpp" namespace Diligent { @@ -50,7 +51,8 @@ class PipelineStateD3D12Impl final : public PipelineStateBase; - PipelineStateD3D12Impl(IReferenceCounters* pRefCounters, RenderDeviceD3D12Impl* pDeviceD3D12, const PipelineStateCreateInfo& CreateInfo); + PipelineStateD3D12Impl(IReferenceCounters* pRefCounters, RenderDeviceD3D12Impl* pDeviceD3D12, const GraphicsPipelineStateCreateInfo& CreateInfo); + PipelineStateD3D12Impl(IReferenceCounters* pRefCounters, RenderDeviceD3D12Impl* pDeviceD3D12, const ComputePipelineStateCreateInfo& CreateInfo); ~PipelineStateD3D12Impl(); virtual void DILIGENT_CALL_TYPE QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface) override final; @@ -119,15 +121,29 @@ public: } private: + struct D3D12PipelineShaderStageInfo + { + const SHADER_TYPE Type; + ShaderD3D12Impl* const pShader; + D3D12PipelineShaderStageInfo(SHADER_TYPE _Type, + ShaderD3D12Impl* _pShader) : + Type{_Type}, + pShader{_pShader} + {} + }; + void InitResourceLayouts(RenderDeviceD3D12Impl* pDeviceD3D12, + const PipelineStateCreateInfo& CreateInfo, + std::vector& ShaderStages); + CComPtr m_pd3d12PSO; RootSignature m_RootSig; // Must be defined before default SRB SRBMemoryAllocator m_SRBMemAllocator; - ShaderResourceLayoutD3D12* m_pShaderResourceLayouts = nullptr; - ShaderResourceCacheD3D12* m_pStaticResourceCaches = nullptr; - ShaderVariableManagerD3D12* m_pStaticVarManagers = nullptr; + ShaderResourceLayoutD3D12* m_pShaderResourceLayouts = nullptr; // [m_NumShaderStages * 2] + ShaderResourceCacheD3D12* m_pStaticResourceCaches = nullptr; // [m_NumShaderStages] + ShaderVariableManagerD3D12* m_pStaticVarManagers = nullptr; // [m_NumShaderStages] // Resource layout index in m_pShaderResourceLayouts array for every shader stage, // indexed by the shader type pipeline index (returned by GetShaderTypePipelineIndex) diff --git a/Graphics/GraphicsEngineD3D12/include/RenderDeviceD3D12Impl.hpp b/Graphics/GraphicsEngineD3D12/include/RenderDeviceD3D12Impl.hpp index 0dc4201e..7083e30d 100644 --- a/Graphics/GraphicsEngineD3D12/include/RenderDeviceD3D12Impl.hpp +++ b/Graphics/GraphicsEngineD3D12/include/RenderDeviceD3D12Impl.hpp @@ -62,8 +62,11 @@ public: virtual void DILIGENT_CALL_TYPE QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface) override final; - /// Implementation of IRenderDevice::CreatePipelineState() in Direct3D12 backend. - virtual void DILIGENT_CALL_TYPE CreatePipelineState(const PipelineStateCreateInfo& PSOCreateInfo, IPipelineState** ppPipelineState) override final; + /// Implementation of IRenderDevice::CreateGraphicsPipelineState() in Direct3D12 backend. + virtual void DILIGENT_CALL_TYPE CreateGraphicsPipelineState(const GraphicsPipelineStateCreateInfo& PSOCreateInfo, IPipelineState** ppPipelineState) override final; + + /// Implementation of IRenderDevice::CreateComputePipelineState() in Direct3D12 backend. + virtual void DILIGENT_CALL_TYPE CreateComputePipelineState(const ComputePipelineStateCreateInfo& PSOCreateInfo, IPipelineState** ppPipelineState) override final; /// Implementation of IRenderDevice::CreateBuffer() in Direct3D12 backend. virtual void DILIGENT_CALL_TYPE CreateBuffer(const BufferDesc& BuffDesc, diff --git a/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp index 546c9de8..f1bc35eb 100644 --- a/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp @@ -211,49 +211,58 @@ void DeviceContextD3D12Impl::SetPipelineState(IPipelineState* pPipelineState) // This is necessary because if the command list had been flushed // and the first PSO set on the command list was a compute pipeline, // the states would otherwise never be committed (since m_pPipelineState != nullptr) - CommitStates = OldPSODesc.IsComputePipeline(); + CommitStates = !OldPSODesc.IsAnyGraphicsPipeline(); // We also need to update scissor rect if ScissorEnable state has changed - CommitScissor = OldPSODesc.GraphicsPipeline.RasterizerDesc.ScissorEnable != PSODesc.GraphicsPipeline.RasterizerDesc.ScissorEnable; + if (OldPSODesc.IsAnyGraphicsPipeline() && PSODesc.IsAnyGraphicsPipeline()) + CommitScissor = m_pPipelineState->GetGraphicsPipelineDesc().RasterizerDesc.ScissorEnable != pPipelineStateD3D12->GetGraphicsPipelineDesc().RasterizerDesc.ScissorEnable; } TDeviceContextBase::SetPipelineState(pPipelineStateD3D12, 0 /*Dummy*/); - auto& CmdCtx = GetCmdContext(); - + auto& CmdCtx = GetCmdContext(); auto* pd3d12PSO = pPipelineStateD3D12->GetD3D12PipelineState(); - if (PSODesc.IsComputePipeline()) - { - CmdCtx.AsComputeContext().SetPipelineState(pd3d12PSO); - } - else + + switch (PSODesc.PipelineType) { - VERIFY_EXPR(PSODesc.IsAnyGraphicsPipeline()); + case PIPELINE_TYPE_GRAPHICS: + case PIPELINE_TYPE_MESH: + { + auto& GraphicsPipeline = pPipelineStateD3D12->GetGraphicsPipelineDesc(); + auto& GraphicsCtx = CmdCtx.AsGraphicsContext(); + GraphicsCtx.SetPipelineState(pd3d12PSO); - auto& GraphicsCtx = CmdCtx.AsGraphicsContext(); - GraphicsCtx.SetPipelineState(pd3d12PSO); + if (PSODesc.PipelineType == PIPELINE_TYPE_GRAPHICS) + { + auto D3D12Topology = TopologyToD3D12Topology(GraphicsPipeline.PrimitiveTopology); + GraphicsCtx.SetPrimitiveTopology(D3D12Topology); + } - if (PSODesc.PipelineType == PIPELINE_TYPE_GRAPHICS) - { - auto D3D12Topology = TopologyToD3D12Topology(PSODesc.GraphicsPipeline.PrimitiveTopology); - GraphicsCtx.SetPrimitiveTopology(D3D12Topology); - } + if (CommitStates) + { + GraphicsCtx.SetStencilRef(m_StencilRef); + GraphicsCtx.SetBlendFactor(m_BlendFactors); + if (GraphicsPipeline.pRenderPass == nullptr) + { + CommitRenderTargets(RESOURCE_STATE_TRANSITION_MODE_VERIFY); + } + CommitViewports(); + } - if (CommitStates) - { - GraphicsCtx.SetStencilRef(m_StencilRef); - GraphicsCtx.SetBlendFactor(m_BlendFactors); - if (PSODesc.GraphicsPipeline.pRenderPass == nullptr) + if (CommitStates || CommitScissor) { - CommitRenderTargets(RESOURCE_STATE_TRANSITION_MODE_VERIFY); + CommitScissorRects(GraphicsCtx, GraphicsPipeline.RasterizerDesc.ScissorEnable); } - CommitViewports(); + break; } - - if (CommitStates || CommitScissor) + case PIPELINE_TYPE_COMPUTE: { - CommitScissorRects(GraphicsCtx, PSODesc.GraphicsPipeline.RasterizerDesc.ScissorEnable); + CmdCtx.AsComputeContext().SetPipelineState(pd3d12PSO); + break; } + default: + UNEXPECTED("unknown pipeline type"); } + m_State.pCommittedResourceCache = nullptr; m_State.bRootViewsCommitted = false; } @@ -964,7 +973,7 @@ void DeviceContextD3D12Impl::SetScissorRects(Uint32 NumRects, const Rect* pRects if (m_pPipelineState) { const auto& PSODesc = m_pPipelineState->GetDesc(); - if (PSODesc.IsAnyGraphicsPipeline() && PSODesc.GraphicsPipeline.RasterizerDesc.ScissorEnable) + if (PSODesc.IsAnyGraphicsPipeline() && m_pPipelineState->GetGraphicsPipelineDesc().RasterizerDesc.ScissorEnable) { VERIFY(NumRects == m_NumScissorRects, "Unexpected number of scissor rects"); auto& Ctx = GetCmdContext().AsGraphicsContext(); diff --git a/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp index f5d60b60..0d26db2a 100644 --- a/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp @@ -98,44 +98,324 @@ private: std::array m_Map; }; -PipelineStateD3D12Impl::PipelineStateD3D12Impl(IReferenceCounters* pRefCounters, - RenderDeviceD3D12Impl* pDeviceD3D12, - const PipelineStateCreateInfo& CreateInfo) : +PipelineStateD3D12Impl::PipelineStateD3D12Impl(IReferenceCounters* pRefCounters, + RenderDeviceD3D12Impl* pDeviceD3D12, + const GraphicsPipelineStateCreateInfo& CreateInfo) : TPipelineStateBase{pRefCounters, pDeviceD3D12, CreateInfo.PSODesc}, m_SRBMemAllocator{GetRawAllocator()} { m_ResourceLayoutIndex.fill(-1); - struct D3D12PipelineShaderStageInfo + std::vector ShaderStages; + ExtractShaders(CreateInfo, ShaderStages); + + // Memory must be released if an exception is thrown. + LinearAllocator MemPool{GetRawAllocator()}; + + MemPool.AddRequiredSize(GetNumShaderStages() * 2); + MemPool.AddRequiredSize(GetNumShaderStages()); + MemPool.AddRequiredSize(GetNumShaderStages()); + + ValidateAndReserveSpace(CreateInfo, MemPool); + + MemPool.Reserve(); + + auto pd3d12Device = pDeviceD3D12->GetD3D12Device(); + m_RootSig.AllocateStaticSamplers(m_Desc.ResourceLayout); + + m_pShaderResourceLayouts = MemPool.Allocate(GetNumShaderStages() * 2); + m_pStaticResourceCaches = MemPool.Allocate(GetNumShaderStages()); + m_pStaticVarManagers = MemPool.Allocate(GetNumShaderStages()); + + InitGraphicsPipeline(CreateInfo, MemPool); + InitResourceLayouts(pDeviceD3D12, CreateInfo, ShaderStages); + + if (m_Desc.PipelineType == PIPELINE_TYPE_GRAPHICS) + { + const auto& GraphicsPipeline = GetGraphicsPipelineDesc(); + + D3D12_GRAPHICS_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_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(); + + pd3d12ShaderBytecode->pShaderBytecode = pByteCode->GetBufferPointer(); + pd3d12ShaderBytecode->BytecodeLength = pByteCode->GetBufferSize(); + } + + d3d12PSODesc.pRootSignature = m_RootSig.GetD3D12RootSignature(); + + 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; + + RasterizerStateDesc_To_D3D12_RASTERIZER_DESC(GraphicsPipeline.RasterizerDesc, d3d12PSODesc.RasterizerState); + DepthStencilStateDesc_To_D3D12_DEPTH_STENCIL_DESC(GraphicsPipeline.DepthStencilDesc, d3d12PSODesc.DepthStencilState); + + std::vector> d312InputElements(STD_ALLOCATOR_RAW_MEM(D3D12_INPUT_ELEMENT_DESC, GetRawAllocator(), "Allocator for vector")); + + const auto& InputLayout = GetGraphicsPipelineDesc().InputLayout; + if (InputLayout.NumElements > 0) + { + LayoutElements_To_D3D12_INPUT_ELEMENT_DESCs(InputLayout, d312InputElements); + d3d12PSODesc.InputLayout.NumElements = static_cast(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.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; + + // 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; + + // 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(static_cast(&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 SHADER_TYPE Type; - ShaderD3D12Impl* const pShader; - D3D12PipelineShaderStageInfo(SHADER_TYPE _Type, - ShaderD3D12Impl* _pShader) : - Type{_Type}, - pShader{_pShader} - {} - }; + const auto& GraphicsPipeline = GetGraphicsPipelineDesc(); + + struct MESH_SHADER_PIPELINE_STATE_DESC + { + PSS_SubObject Flags; + PSS_SubObject NodeMask; + PSS_SubObject pRootSignature; + PSS_SubObject PS; + PSS_SubObject AS; + PSS_SubObject MS; + PSS_SubObject BlendState; + PSS_SubObject DepthStencilState; + PSS_SubObject RasterizerState; + PSS_SubObject SampleDesc; + PSS_SubObject SampleMask; + PSS_SubObject DSVFormat; + PSS_SubObject RTVFormatArray; + PSS_SubObject 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(); + + pd3d12ShaderBytecode->pShaderBytecode = pByteCode->GetBufferPointer(); + pd3d12ShaderBytecode->BytecodeLength = pByteCode->GetBufferSize(); + } + + d3d12PSODesc.pRootSignature = m_RootSig.GetD3D12RootSignature(); + + 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); + + 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; + + // 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; + + // 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; + + auto* device2 = pDeviceD3D12->GetD3D12Device2(); + + 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"); + } + + 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()); + } + + void* Ptr = MemPool.Release(); + VERIFY_EXPR(Ptr == m_pShaderResourceLayouts); +} + +PipelineStateD3D12Impl::PipelineStateD3D12Impl(IReferenceCounters* pRefCounters, + RenderDeviceD3D12Impl* pDeviceD3D12, + const ComputePipelineStateCreateInfo& CreateInfo) : + TPipelineStateBase{pRefCounters, pDeviceD3D12, CreateInfo.PSODesc}, + m_SRBMemAllocator{GetRawAllocator()} +{ + m_ResourceLayoutIndex.fill(-1); + std::vector ShaderStages; - ExtractShaders(ShaderStages); - VERIFY_EXPR(GetNumShaderStages() == ShaderStages.size()); + ExtractShaders(CreateInfo, ShaderStages); - auto pd3d12Device = pDeviceD3D12->GetD3D12Device(); - const auto& ResourceLayout = m_Desc.ResourceLayout; - m_RootSig.AllocateStaticSamplers(ResourceLayout); + // Memory must be released if an exception is thrown. + LinearAllocator MemPool{GetRawAllocator()}; + + MemPool.AddRequiredSize(GetNumShaderStages() * 2); + MemPool.AddRequiredSize(GetNumShaderStages()); + MemPool.AddRequiredSize(GetNumShaderStages()); + + ValidateAndReserveSpace(CreateInfo, MemPool); + + MemPool.Reserve(); + + auto pd3d12Device = pDeviceD3D12->GetD3D12Device(); + m_RootSig.AllocateStaticSamplers(m_Desc.ResourceLayout); + + m_pShaderResourceLayouts = MemPool.Allocate(GetNumShaderStages() * 2); + m_pStaticResourceCaches = MemPool.Allocate(GetNumShaderStages()); + m_pStaticVarManagers = MemPool.Allocate(GetNumShaderStages()); + + InitComputePipeline(CreateInfo, MemPool); + InitResourceLayouts(pDeviceD3D12, CreateInfo, ShaderStages); + + 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(); + + // 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; + + // 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(); + + HRESULT hr = pd3d12Device->CreateComputePipelineState(&d3d12PSODesc, __uuidof(ID3D12PipelineState), reinterpret_cast(static_cast(&m_pd3d12PSO))); + if (FAILED(hr)) + LOG_ERROR_AND_THROW("Failed to create pipeline state"); + + 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()); + } + + void* Ptr = MemPool.Release(); + VERIFY_EXPR(Ptr == m_pShaderResourceLayouts); +} + +PipelineStateD3D12Impl::~PipelineStateD3D12Impl() +{ + 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(); + } + // m_pShaderResourceLayouts, m_pStaticResourceCaches, and m_pShaderResourceLayouts are allocated in + // contiguous chunks of memory. + auto* pRawMem = m_pShaderResourceLayouts; + ShaderResLayoutAllocator.Free(pRawMem); - // clang-format off - static_assert((sizeof(ShaderResourceLayoutD3D12) % sizeof(void*)) == 0, "sizeof(ShaderResourceLayoutD3D12) is expected to be a multiple of sizeof(void*)"); - static_assert((sizeof(ShaderResourceCacheD3D12) % sizeof(void*)) == 0, "sizeof(ShaderResourceCacheD3D12) is expected to be a multiple of sizeof(void*)"); - static_assert((sizeof(ShaderVariableManagerD3D12) % sizeof(void*)) == 0, "sizeof(ShaderVariableManagerD3D12) is expected to be a multiple of sizeof(void*)"); - // clang-format on - const auto MemSize = (sizeof(ShaderResourceLayoutD3D12) * 2 + sizeof(ShaderResourceCacheD3D12) + sizeof(ShaderVariableManagerD3D12)) * GetNumShaderStages(); - auto* const pRawMem = - ALLOCATE_RAW(GetRawAllocator(), "Raw memory for ShaderResourceLayoutD3D12, ShaderResourceCacheD3D12, and ShaderVariableManagerD3D12 arrays", MemSize); + // 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) - m_pShaderResourceLayouts = reinterpret_cast(pRawMem); - m_pStaticResourceCaches = reinterpret_cast(m_pShaderResourceLayouts + GetNumShaderStages() * 2); - m_pStaticVarManagers = reinterpret_cast(m_pStaticResourceCaches + GetNumShaderStages()); + +void PipelineStateD3D12Impl::InitResourceLayouts(RenderDeviceD3D12Impl* pDeviceD3D12, + const PipelineStateCreateInfo& CreateInfo, + std::vector& ShaderStages) +{ + auto pd3d12Device = pDeviceD3D12->GetD3D12Device(); + const auto& ResourceLayout = m_Desc.ResourceLayout; #ifdef DILIGENT_DEVELOPMENT { @@ -205,222 +485,6 @@ PipelineStateD3D12Impl::PipelineStateD3D12Impl(IReferenceCounters* pR } m_RootSig.Finalize(pd3d12Device); - switch (m_Desc.PipelineType) - { - case PIPELINE_TYPE_COMPUTE: - { - 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(); - - // 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; - - // 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(); - - HRESULT hr = pd3d12Device->CreateComputePipelineState(&d3d12PSODesc, __uuidof(ID3D12PipelineState), reinterpret_cast(static_cast(&m_pd3d12PSO))); - if (FAILED(hr)) - LOG_ERROR_AND_THROW("Failed to create pipeline state"); - break; - } - - case PIPELINE_TYPE_GRAPHICS: - { - const auto& GraphicsPipeline = m_Desc.GraphicsPipeline; - - D3D12_GRAPHICS_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_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(); - - pd3d12ShaderBytecode->pShaderBytecode = pByteCode->GetBufferPointer(); - pd3d12ShaderBytecode->BytecodeLength = pByteCode->GetBufferSize(); - } - - d3d12PSODesc.pRootSignature = m_RootSig.GetD3D12RootSignature(); - - 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; - - RasterizerStateDesc_To_D3D12_RASTERIZER_DESC(GraphicsPipeline.RasterizerDesc, d3d12PSODesc.RasterizerState); - DepthStencilStateDesc_To_D3D12_DEPTH_STENCIL_DESC(GraphicsPipeline.DepthStencilDesc, d3d12PSODesc.DepthStencilState); - - std::vector> d312InputElements(STD_ALLOCATOR_RAW_MEM(D3D12_INPUT_ELEMENT_DESC, GetRawAllocator(), "Allocator for vector")); - - const auto& InputLayout = m_Desc.GraphicsPipeline.InputLayout; - if (InputLayout.NumElements > 0) - { - LayoutElements_To_D3D12_INPUT_ELEMENT_DESCs(InputLayout, d312InputElements); - d3d12PSODesc.InputLayout.NumElements = static_cast(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.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; - - // 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; - - // 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(static_cast(&m_pd3d12PSO))); - if (FAILED(hr)) - LOG_ERROR_AND_THROW("Failed to create pipeline state"); - break; - } - -#ifdef D3D12_H_HAS_MESH_SHADER - case PIPELINE_TYPE_MESH: - { - const auto& GraphicsPipeline = m_Desc.GraphicsPipeline; - - struct MESH_SHADER_PIPELINE_STATE_DESC - { - PSS_SubObject Flags; - PSS_SubObject NodeMask; - PSS_SubObject pRootSignature; - PSS_SubObject PS; - PSS_SubObject AS; - PSS_SubObject MS; - PSS_SubObject BlendState; - PSS_SubObject DepthStencilState; - PSS_SubObject RasterizerState; - PSS_SubObject SampleDesc; - PSS_SubObject SampleMask; - PSS_SubObject DSVFormat; - PSS_SubObject RTVFormatArray; - PSS_SubObject 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(); - - pd3d12ShaderBytecode->pShaderBytecode = pByteCode->GetBufferPointer(); - pd3d12ShaderBytecode->BytecodeLength = pByteCode->GetBufferSize(); - } - - d3d12PSODesc.pRootSignature = m_RootSig.GetD3D12RootSignature(); - - 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); - - 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; - - // 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; - - // 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; - - auto* device2 = pDeviceD3D12->GetD3D12Device2(); - - CHECK_D3D_RESULT_THROW(device2->CreatePipelineState(&streamDesc, IID_PPV_ARGS(&m_pd3d12PSO)), "Failed to create pipeline state"); - break; - } -#endif // D3D12_H_HAS_MESH_SHADER - - default: - LOG_ERROR_AND_THROW("Unsupported pipeline type"); - } - - 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()); - } - if (m_Desc.SRBAllocationGranularity > 1) { std::array ShaderVarMgrDataSizes = {}; @@ -443,29 +507,6 @@ PipelineStateD3D12Impl::PipelineStateD3D12Impl(IReferenceCounters* pR m_ShaderResourceLayoutHash = m_RootSig.GetHash(); } -PipelineStateD3D12Impl::~PipelineStateD3D12Impl() -{ - 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(); - } - // 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); -} - -IMPLEMENT_QUERY_INTERFACE(PipelineStateD3D12Impl, IID_PipelineStateD3D12, TPipelineStateBase) - - void PipelineStateD3D12Impl::CreateShaderResourceBinding(IShaderResourceBinding** ppShaderResourceBinding, bool InitStaticResources) { auto& SRBAllocator = m_pDevice->GetSRBAllocator(); diff --git a/Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp index db86d662..97069bd2 100644 --- a/Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp @@ -534,7 +534,18 @@ void RenderDeviceD3D12Impl::TestTextureFormat(TEXTURE_FORMAT TexFormat) IMPLEMENT_QUERY_INTERFACE(RenderDeviceD3D12Impl, IID_RenderDeviceD3D12, TRenderDeviceBase) -void RenderDeviceD3D12Impl::CreatePipelineState(const PipelineStateCreateInfo& PSOCreateInfo, IPipelineState** ppPipelineState) +void RenderDeviceD3D12Impl::CreateGraphicsPipelineState(const GraphicsPipelineStateCreateInfo& PSOCreateInfo, IPipelineState** ppPipelineState) +{ + CreateDeviceObject("Pipeline State", PSOCreateInfo.PSODesc, ppPipelineState, + [&]() // + { + PipelineStateD3D12Impl* pPipelineStateD3D12(NEW_RC_OBJ(m_PSOAllocator, "PipelineStateD3D12Impl instance", PipelineStateD3D12Impl)(this, PSOCreateInfo)); + pPipelineStateD3D12->QueryInterface(IID_PipelineState, reinterpret_cast(ppPipelineState)); + OnCreateDeviceObject(pPipelineStateD3D12); + }); +} + +void RenderDeviceD3D12Impl::CreateComputePipelineState(const ComputePipelineStateCreateInfo& PSOCreateInfo, IPipelineState** ppPipelineState) { CreateDeviceObject("Pipeline State", PSOCreateInfo.PSODesc, ppPipelineState, [&]() // -- cgit v1.2.3 From e7b18160a758b30dd6b701b4aa6f43c9c2061ccf Mon Sep 17 00:00:00 2001 From: assiduous Date: Sat, 17 Oct 2020 09:56:34 -0700 Subject: All backends: added resource dimension validation when setting shader variables --- Graphics/GraphicsEngineD3D12/src/ShaderResourceLayoutD3D12.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Graphics/GraphicsEngineD3D12') diff --git a/Graphics/GraphicsEngineD3D12/src/ShaderResourceLayoutD3D12.cpp b/Graphics/GraphicsEngineD3D12/src/ShaderResourceLayoutD3D12.cpp index f00d62e7..c0029da5 100644 --- a/Graphics/GraphicsEngineD3D12/src/ShaderResourceLayoutD3D12.cpp +++ b/Graphics/GraphicsEngineD3D12/src/ShaderResourceLayoutD3D12.cpp @@ -462,7 +462,7 @@ void ShaderResourceLayoutD3D12::D3D12Resource::CacheResourceView(IDeviceObject* { // We cannot use ValidatedCast<> here as the resource retrieved from the // resource mapping can be of wrong type - RefCntAutoPtr pViewD3D12(pView, ResourceViewTraits::IID); + RefCntAutoPtr pViewD3D12{pView, ResourceViewTraits::IID}; #ifdef DILIGENT_DEVELOPMENT VerifyResourceViewBinding(Attribs, GetVariableType(), ArrayIndex, pView, pViewD3D12.RawPtr(), {dbgExpectedViewType}, DstRes.pObject.RawPtr(), ParentResLayout.GetShaderName()); ResourceViewTraits::VerifyView(pViewD3D12, Attribs, ParentResLayout.GetShaderName()); -- cgit v1.2.3 From 645ef7e425d6ff4ee64b782d27767e0a5732be50 Mon Sep 17 00:00:00 2001 From: assiduous Date: Sun, 18 Oct 2020 13:06:48 -0700 Subject: A number of fixes for PSO creation refactoring (API240075) --- .../include/PipelineStateD3D12Impl.hpp | 7 ++- .../include/RenderDeviceD3D12Impl.hpp | 3 + .../src/DeviceContextD3D12Impl.cpp | 2 + .../src/PipelineStateD3D12Impl.cpp | 70 ++++++++++------------ .../src/RenderDeviceD3D12Impl.cpp | 41 ++++++------- 5 files changed, 61 insertions(+), 62 deletions(-) (limited to 'Graphics/GraphicsEngineD3D12') diff --git a/Graphics/GraphicsEngineD3D12/include/PipelineStateD3D12Impl.hpp b/Graphics/GraphicsEngineD3D12/include/PipelineStateD3D12Impl.hpp index 821ff951..31d95179 100644 --- a/Graphics/GraphicsEngineD3D12/include/PipelineStateD3D12Impl.hpp +++ b/Graphics/GraphicsEngineD3D12/include/PipelineStateD3D12Impl.hpp @@ -131,8 +131,11 @@ private: pShader{_pShader} {} }; - void InitResourceLayouts(RenderDeviceD3D12Impl* pDeviceD3D12, - const PipelineStateCreateInfo& CreateInfo, + + template + LinearAllocator InitInternalObjects(const PSOCreateInfoType& CreateInfo, std::vector& ShaderStages); + + void InitResourceLayouts(const PipelineStateCreateInfo& CreateInfo, std::vector& ShaderStages); CComPtr m_pd3d12PSO; diff --git a/Graphics/GraphicsEngineD3D12/include/RenderDeviceD3D12Impl.hpp b/Graphics/GraphicsEngineD3D12/include/RenderDeviceD3D12Impl.hpp index 7083e30d..34a77213 100644 --- a/Graphics/GraphicsEngineD3D12/include/RenderDeviceD3D12Impl.hpp +++ b/Graphics/GraphicsEngineD3D12/include/RenderDeviceD3D12Impl.hpp @@ -165,6 +165,9 @@ public: D3D_FEATURE_LEVEL GetD3DFeatureLevel() const; private: + template + void CreatePipelineState(const PSOCreateInfoType& PSOCreateInfo, IPipelineState** ppPipelineState); + virtual void TestTextureFormat(TEXTURE_FORMAT TexFormat) override final; void FreeCommandContext(PooledCommandContext&& Ctx); diff --git a/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp index f1bc35eb..938c9468 100644 --- a/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp @@ -254,11 +254,13 @@ void DeviceContextD3D12Impl::SetPipelineState(IPipelineState* pPipelineState) } break; } + case PIPELINE_TYPE_COMPUTE: { CmdCtx.AsComputeContext().SetPipelineState(pd3d12PSO); break; } + default: UNEXPECTED("unknown pipeline type"); } diff --git a/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp index 0d26db2a..f04a309e 100644 --- a/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp @@ -98,38 +98,49 @@ private: std::array m_Map; }; -PipelineStateD3D12Impl::PipelineStateD3D12Impl(IReferenceCounters* pRefCounters, - RenderDeviceD3D12Impl* pDeviceD3D12, - const GraphicsPipelineStateCreateInfo& CreateInfo) : - TPipelineStateBase{pRefCounters, pDeviceD3D12, CreateInfo.PSODesc}, - m_SRBMemAllocator{GetRawAllocator()} +template +LinearAllocator PipelineStateD3D12Impl::InitInternalObjects(const PSOCreateInfoType& CreateInfo, + std::vector& ShaderStages) { m_ResourceLayoutIndex.fill(-1); - std::vector ShaderStages; ExtractShaders(CreateInfo, ShaderStages); // Memory must be released if an exception is thrown. LinearAllocator MemPool{GetRawAllocator()}; - MemPool.AddRequiredSize(GetNumShaderStages() * 2); - MemPool.AddRequiredSize(GetNumShaderStages()); - MemPool.AddRequiredSize(GetNumShaderStages()); + MemPool.AddSpace(GetNumShaderStages() * 2); + MemPool.AddSpace(GetNumShaderStages()); + MemPool.AddSpace(GetNumShaderStages()); - ValidateAndReserveSpace(CreateInfo, MemPool); + ReserveSpaceForPipelineDesc(CreateInfo, MemPool); MemPool.Reserve(); - auto pd3d12Device = pDeviceD3D12->GetD3D12Device(); - m_RootSig.AllocateStaticSamplers(m_Desc.ResourceLayout); + m_RootSig.AllocateStaticSamplers(CreateInfo.PSODesc.ResourceLayout); m_pShaderResourceLayouts = MemPool.Allocate(GetNumShaderStages() * 2); m_pStaticResourceCaches = MemPool.Allocate(GetNumShaderStages()); m_pStaticVarManagers = MemPool.Allocate(GetNumShaderStages()); - InitGraphicsPipeline(CreateInfo, MemPool); - InitResourceLayouts(pDeviceD3D12, CreateInfo, ShaderStages); + InitializePipelineDesc(CreateInfo, MemPool); + InitResourceLayouts(CreateInfo, ShaderStages); + + return MemPool; +} + + +PipelineStateD3D12Impl::PipelineStateD3D12Impl(IReferenceCounters* pRefCounters, + RenderDeviceD3D12Impl* pDeviceD3D12, + const GraphicsPipelineStateCreateInfo& CreateInfo) : + TPipelineStateBase{pRefCounters, pDeviceD3D12, CreateInfo.PSODesc}, + m_SRBMemAllocator{GetRawAllocator()} +{ + std::vector ShaderStages; + + auto MemPool = InitInternalObjects(CreateInfo, ShaderStages); + auto pd3d12Device = pDeviceD3D12->GetD3D12Device(); if (m_Desc.PipelineType == PIPELINE_TYPE_GRAPHICS) { const auto& GraphicsPipeline = GetGraphicsPipelineDesc(); @@ -324,31 +335,11 @@ PipelineStateD3D12Impl::PipelineStateD3D12Impl(IReferenceCounters* TPipelineStateBase{pRefCounters, pDeviceD3D12, CreateInfo.PSODesc}, m_SRBMemAllocator{GetRawAllocator()} { - m_ResourceLayoutIndex.fill(-1); - std::vector ShaderStages; - ExtractShaders(CreateInfo, ShaderStages); - - // Memory must be released if an exception is thrown. - LinearAllocator MemPool{GetRawAllocator()}; - MemPool.AddRequiredSize(GetNumShaderStages() * 2); - MemPool.AddRequiredSize(GetNumShaderStages()); - MemPool.AddRequiredSize(GetNumShaderStages()); - - ValidateAndReserveSpace(CreateInfo, MemPool); - - MemPool.Reserve(); + auto MemPool = InitInternalObjects(CreateInfo, ShaderStages); auto pd3d12Device = pDeviceD3D12->GetD3D12Device(); - m_RootSig.AllocateStaticSamplers(m_Desc.ResourceLayout); - - m_pShaderResourceLayouts = MemPool.Allocate(GetNumShaderStages() * 2); - m_pStaticResourceCaches = MemPool.Allocate(GetNumShaderStages()); - m_pStaticVarManagers = MemPool.Allocate(GetNumShaderStages()); - - InitComputePipeline(CreateInfo, MemPool); - InitResourceLayouts(pDeviceD3D12, CreateInfo, ShaderStages); D3D12_COMPUTE_PIPELINE_STATE_DESC d3d12PSODesc = {}; @@ -410,11 +401,10 @@ PipelineStateD3D12Impl::~PipelineStateD3D12Impl() IMPLEMENT_QUERY_INTERFACE(PipelineStateD3D12Impl, IID_PipelineStateD3D12, TPipelineStateBase) -void PipelineStateD3D12Impl::InitResourceLayouts(RenderDeviceD3D12Impl* pDeviceD3D12, - const PipelineStateCreateInfo& CreateInfo, +void PipelineStateD3D12Impl::InitResourceLayouts(const PipelineStateCreateInfo& CreateInfo, std::vector& ShaderStages) { - auto pd3d12Device = pDeviceD3D12->GetD3D12Device(); + auto pd3d12Device = GetDevice()->GetD3D12Device(); const auto& ResourceLayout = m_Desc.ResourceLayout; #ifdef DILIGENT_DEVELOPMENT @@ -443,7 +433,7 @@ void PipelineStateD3D12Impl::InitResourceLayouts(RenderDeviceD3D12Impl* ShaderResourceLayoutD3D12 // { *this, - pDeviceD3D12->GetD3D12Device(), + pd3d12Device, m_Desc.PipelineType, ResourceLayout, pShaderD3D12->GetShaderResources(), @@ -461,7 +451,7 @@ void PipelineStateD3D12Impl::InitResourceLayouts(RenderDeviceD3D12Impl* ShaderResourceLayoutD3D12 // { *this, - pDeviceD3D12->GetD3D12Device(), + pd3d12Device, m_Desc.PipelineType, ResourceLayout, pShaderD3D12->GetShaderResources(), diff --git a/Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp index 97069bd2..ba91f7bc 100644 --- a/Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp @@ -534,26 +534,27 @@ void RenderDeviceD3D12Impl::TestTextureFormat(TEXTURE_FORMAT TexFormat) IMPLEMENT_QUERY_INTERFACE(RenderDeviceD3D12Impl, IID_RenderDeviceD3D12, TRenderDeviceBase) -void RenderDeviceD3D12Impl::CreateGraphicsPipelineState(const GraphicsPipelineStateCreateInfo& PSOCreateInfo, IPipelineState** ppPipelineState) +template +void RenderDeviceD3D12Impl::CreatePipelineState(const PSOCreateInfoType& PSOCreateInfo, IPipelineState** ppPipelineState) { CreateDeviceObject("Pipeline State", PSOCreateInfo.PSODesc, ppPipelineState, [&]() // { - PipelineStateD3D12Impl* pPipelineStateD3D12(NEW_RC_OBJ(m_PSOAllocator, "PipelineStateD3D12Impl instance", PipelineStateD3D12Impl)(this, PSOCreateInfo)); + PipelineStateD3D12Impl* pPipelineStateD3D12{NEW_RC_OBJ(m_PSOAllocator, "PipelineStateD3D12Impl instance", PipelineStateD3D12Impl)(this, PSOCreateInfo)}; pPipelineStateD3D12->QueryInterface(IID_PipelineState, reinterpret_cast(ppPipelineState)); OnCreateDeviceObject(pPipelineStateD3D12); }); } + +void RenderDeviceD3D12Impl::CreateGraphicsPipelineState(const GraphicsPipelineStateCreateInfo& PSOCreateInfo, IPipelineState** ppPipelineState) +{ + CreatePipelineState(PSOCreateInfo, ppPipelineState); +} + void RenderDeviceD3D12Impl::CreateComputePipelineState(const ComputePipelineStateCreateInfo& PSOCreateInfo, IPipelineState** ppPipelineState) { - CreateDeviceObject("Pipeline State", PSOCreateInfo.PSODesc, ppPipelineState, - [&]() // - { - PipelineStateD3D12Impl* pPipelineStateD3D12(NEW_RC_OBJ(m_PSOAllocator, "PipelineStateD3D12Impl instance", PipelineStateD3D12Impl)(this, PSOCreateInfo)); - pPipelineStateD3D12->QueryInterface(IID_PipelineState, reinterpret_cast(ppPipelineState)); - OnCreateDeviceObject(pPipelineStateD3D12); - }); + CreatePipelineState(PSOCreateInfo, ppPipelineState); } void RenderDeviceD3D12Impl::CreateBufferFromD3DResource(ID3D12Resource* pd3d12Buffer, const BufferDesc& BuffDesc, RESOURCE_STATE InitialState, IBuffer** ppBuffer) @@ -561,7 +562,7 @@ void RenderDeviceD3D12Impl::CreateBufferFromD3DResource(ID3D12Resource* pd3d12Bu CreateDeviceObject("buffer", BuffDesc, ppBuffer, [&]() // { - BufferD3D12Impl* pBufferD3D12(NEW_RC_OBJ(m_BufObjAllocator, "BufferD3D12Impl instance", BufferD3D12Impl)(m_BuffViewObjAllocator, this, BuffDesc, InitialState, pd3d12Buffer)); + BufferD3D12Impl* pBufferD3D12{NEW_RC_OBJ(m_BufObjAllocator, "BufferD3D12Impl instance", BufferD3D12Impl)(m_BuffViewObjAllocator, this, BuffDesc, InitialState, pd3d12Buffer)}; pBufferD3D12->QueryInterface(IID_Buffer, reinterpret_cast(ppBuffer)); pBufferD3D12->CreateDefaultViews(); OnCreateDeviceObject(pBufferD3D12); @@ -573,7 +574,7 @@ void RenderDeviceD3D12Impl::CreateBuffer(const BufferDesc& BuffDesc, const Buffe CreateDeviceObject("buffer", BuffDesc, ppBuffer, [&]() // { - BufferD3D12Impl* pBufferD3D12(NEW_RC_OBJ(m_BufObjAllocator, "BufferD3D12Impl instance", BufferD3D12Impl)(m_BuffViewObjAllocator, this, BuffDesc, pBuffData)); + BufferD3D12Impl* pBufferD3D12{NEW_RC_OBJ(m_BufObjAllocator, "BufferD3D12Impl instance", BufferD3D12Impl)(m_BuffViewObjAllocator, this, BuffDesc, pBuffData)}; pBufferD3D12->QueryInterface(IID_Buffer, reinterpret_cast(ppBuffer)); pBufferD3D12->CreateDefaultViews(); OnCreateDeviceObject(pBufferD3D12); @@ -586,7 +587,7 @@ void RenderDeviceD3D12Impl::CreateShader(const ShaderCreateInfo& ShaderCI, IShad CreateDeviceObject("shader", ShaderCI.Desc, ppShader, [&]() // { - ShaderD3D12Impl* pShaderD3D12(NEW_RC_OBJ(m_ShaderObjAllocator, "ShaderD3D12Impl instance", ShaderD3D12Impl)(this, ShaderCI)); + ShaderD3D12Impl* pShaderD3D12{NEW_RC_OBJ(m_ShaderObjAllocator, "ShaderD3D12Impl instance", ShaderD3D12Impl)(this, ShaderCI)}; pShaderD3D12->QueryInterface(IID_Shader, reinterpret_cast(ppShader)); OnCreateDeviceObject(pShaderD3D12); @@ -600,7 +601,7 @@ void RenderDeviceD3D12Impl::CreateTextureFromD3DResource(ID3D12Resource* pd3d12T CreateDeviceObject("texture", TexDesc, ppTexture, [&]() // { - TextureD3D12Impl* pTextureD3D12 = NEW_RC_OBJ(m_TexObjAllocator, "TextureD3D12Impl instance", TextureD3D12Impl)(m_TexViewObjAllocator, this, TexDesc, InitialState, pd3d12Texture); + TextureD3D12Impl* pTextureD3D12{NEW_RC_OBJ(m_TexObjAllocator, "TextureD3D12Impl instance", TextureD3D12Impl)(m_TexViewObjAllocator, this, TexDesc, InitialState, pd3d12Texture)}; pTextureD3D12->QueryInterface(IID_Texture, reinterpret_cast(ppTexture)); pTextureD3D12->CreateDefaultViews(); @@ -613,7 +614,7 @@ void RenderDeviceD3D12Impl::CreateTexture(const TextureDesc& TexDesc, ID3D12Reso CreateDeviceObject("texture", TexDesc, ppTexture, [&]() // { - TextureD3D12Impl* pTextureD3D12 = NEW_RC_OBJ(m_TexObjAllocator, "TextureD3D12Impl instance", TextureD3D12Impl)(m_TexViewObjAllocator, this, TexDesc, InitialState, pd3d12Texture); + TextureD3D12Impl* pTextureD3D12{NEW_RC_OBJ(m_TexObjAllocator, "TextureD3D12Impl instance", TextureD3D12Impl)(m_TexViewObjAllocator, this, TexDesc, InitialState, pd3d12Texture)}; pTextureD3D12->QueryInterface(IID_TextureD3D12, reinterpret_cast(ppTexture)); }); } @@ -623,7 +624,7 @@ void RenderDeviceD3D12Impl::CreateTexture(const TextureDesc& TexDesc, const Text CreateDeviceObject("texture", TexDesc, ppTexture, [&]() // { - TextureD3D12Impl* pTextureD3D12 = NEW_RC_OBJ(m_TexObjAllocator, "TextureD3D12Impl instance", TextureD3D12Impl)(m_TexViewObjAllocator, this, TexDesc, pData); + TextureD3D12Impl* pTextureD3D12{NEW_RC_OBJ(m_TexObjAllocator, "TextureD3D12Impl instance", TextureD3D12Impl)(m_TexViewObjAllocator, this, TexDesc, pData)}; pTextureD3D12->QueryInterface(IID_Texture, reinterpret_cast(ppTexture)); pTextureD3D12->CreateDefaultViews(); @@ -639,7 +640,7 @@ void RenderDeviceD3D12Impl::CreateSampler(const SamplerDesc& SamplerDesc, ISampl m_SamplersRegistry.Find(SamplerDesc, reinterpret_cast(ppSampler)); if (*ppSampler == nullptr) { - SamplerD3D12Impl* pSamplerD3D12(NEW_RC_OBJ(m_SamplerObjAllocator, "SamplerD3D12Impl instance", SamplerD3D12Impl)(this, SamplerDesc)); + SamplerD3D12Impl* pSamplerD3D12{NEW_RC_OBJ(m_SamplerObjAllocator, "SamplerD3D12Impl instance", SamplerD3D12Impl)(this, SamplerDesc)}; pSamplerD3D12->QueryInterface(IID_Sampler, reinterpret_cast(ppSampler)); OnCreateDeviceObject(pSamplerD3D12); m_SamplersRegistry.Add(SamplerDesc, *ppSampler); @@ -652,7 +653,7 @@ void RenderDeviceD3D12Impl::CreateFence(const FenceDesc& Desc, IFence** ppFence) CreateDeviceObject("Fence", Desc, ppFence, [&]() // { - FenceD3D12Impl* pFenceD3D12(NEW_RC_OBJ(m_FenceAllocator, "FenceD3D12Impl instance", FenceD3D12Impl)(this, Desc)); + FenceD3D12Impl* pFenceD3D12{NEW_RC_OBJ(m_FenceAllocator, "FenceD3D12Impl instance", FenceD3D12Impl)(this, Desc)}; pFenceD3D12->QueryInterface(IID_Fence, reinterpret_cast(ppFence)); OnCreateDeviceObject(pFenceD3D12); }); @@ -663,7 +664,7 @@ void RenderDeviceD3D12Impl::CreateQuery(const QueryDesc& Desc, IQuery** ppQuery) CreateDeviceObject("Query", Desc, ppQuery, [&]() // { - QueryD3D12Impl* pQueryD3D12(NEW_RC_OBJ(m_QueryAllocator, "QueryD3D12Impl instance", QueryD3D12Impl)(this, Desc)); + QueryD3D12Impl* pQueryD3D12{NEW_RC_OBJ(m_QueryAllocator, "QueryD3D12Impl instance", QueryD3D12Impl)(this, Desc)}; pQueryD3D12->QueryInterface(IID_Query, reinterpret_cast(ppQuery)); OnCreateDeviceObject(pQueryD3D12); }); @@ -674,7 +675,7 @@ void RenderDeviceD3D12Impl::CreateRenderPass(const RenderPassDesc& Desc, IRender CreateDeviceObject("RenderPass", Desc, ppRenderPass, [&]() // { - RenderPassD3D12Impl* pRenderPassD3D12(NEW_RC_OBJ(m_RenderPassAllocator, "RenderPassD3D12Impl instance", RenderPassD3D12Impl)(this, Desc)); + RenderPassD3D12Impl* pRenderPassD3D12{NEW_RC_OBJ(m_RenderPassAllocator, "RenderPassD3D12Impl instance", RenderPassD3D12Impl)(this, Desc)}; pRenderPassD3D12->QueryInterface(IID_RenderPass, reinterpret_cast(ppRenderPass)); OnCreateDeviceObject(pRenderPassD3D12); }); @@ -685,7 +686,7 @@ void RenderDeviceD3D12Impl::CreateFramebuffer(const FramebufferDesc& Desc, IFram CreateDeviceObject("Framebuffer", Desc, ppFramebuffer, [&]() // { - FramebufferD3D12Impl* pFramebufferD3D12(NEW_RC_OBJ(m_FramebufferAllocator, "FramebufferD3D12Impl instance", FramebufferD3D12Impl)(this, Desc)); + FramebufferD3D12Impl* pFramebufferD3D12{NEW_RC_OBJ(m_FramebufferAllocator, "FramebufferD3D12Impl instance", FramebufferD3D12Impl)(this, Desc)}; pFramebufferD3D12->QueryInterface(IID_Framebuffer, reinterpret_cast(ppFramebuffer)); OnCreateDeviceObject(pFramebufferD3D12); }); -- cgit v1.2.3 From a520bf4f9748d20e432bcf7994be3148d0b75d54 Mon Sep 17 00:00:00 2001 From: assiduous Date: Mon, 19 Oct 2020 10:21:30 -0700 Subject: Renamed static sampler to immutable sampler (API240076) --- .../GraphicsEngineD3D12/include/RootSignature.hpp | 22 +++---- .../src/D3D12TypeConversions.cpp | 2 +- .../src/PipelineStateD3D12Impl.cpp | 4 +- Graphics/GraphicsEngineD3D12/src/RootSignature.cpp | 73 +++++++++++----------- .../src/ShaderResourceLayoutD3D12.cpp | 37 ++++++----- 5 files changed, 71 insertions(+), 67 deletions(-) (limited to 'Graphics/GraphicsEngineD3D12') diff --git a/Graphics/GraphicsEngineD3D12/include/RootSignature.hpp b/Graphics/GraphicsEngineD3D12/include/RootSignature.hpp index 2bf6d0b3..232bce65 100644 --- a/Graphics/GraphicsEngineD3D12/include/RootSignature.hpp +++ b/Graphics/GraphicsEngineD3D12/include/RootSignature.hpp @@ -302,7 +302,7 @@ class RootSignature public: RootSignature(); - void AllocateStaticSamplers(const PipelineResourceLayoutDesc& ResourceLayout); + void AllocateImmutableSamplers(const PipelineResourceLayoutDesc& ResourceLayout); void Finalize(ID3D12Device* pd3d12Device); @@ -312,10 +312,10 @@ public: void InitResourceCache(class RenderDeviceD3D12Impl* pDeviceD3D12Impl, class ShaderResourceCacheD3D12& ResourceCache, IMemoryAllocator& CacheMemAllocator) const; - void InitStaticSampler(SHADER_TYPE ShaderType, - const char* SamplerName, - const char* SamplerSuffix, - const D3DShaderResourceAttribs& ShaderResAttribs); + void InitImmutableSampler(SHADER_TYPE ShaderType, + const char* SamplerName, + const char* SamplerSuffix, + const D3DShaderResourceAttribs& ShaderResAttribs); void AllocateResourceSlot(SHADER_TYPE ShaderType, PIPELINE_TYPE PipelineType, @@ -481,22 +481,22 @@ private: RootParamsManager m_RootParams; - struct StaticSamplerAttribs + struct ImmutableSamplerAttribs { - StaticSamplerDesc SamplerDesc; + ImmutableSamplerDesc SamplerDesc; UINT ShaderRegister = static_cast(-1); UINT ArraySize = 0; UINT RegisterSpace = 0; D3D12_SHADER_VISIBILITY ShaderVisibility = static_cast(-1); - StaticSamplerAttribs() noexcept {} - StaticSamplerAttribs(const StaticSamplerDesc& SamDesc, D3D12_SHADER_VISIBILITY Visibility) noexcept : + ImmutableSamplerAttribs() noexcept {} + ImmutableSamplerAttribs(const ImmutableSamplerDesc& SamDesc, D3D12_SHADER_VISIBILITY Visibility) noexcept : SamplerDesc(SamDesc), ShaderVisibility(Visibility) {} }; - // Note: sizeof(m_StaticSamplers) == 56 (MS compiler, release x64) - std::vector> m_StaticSamplers; + // Note: sizeof(m_ImmutableSamplers) == 56 (MS compiler, release x64) + std::vector> m_ImmutableSamplers; IMemoryAllocator& m_MemAllocator; diff --git a/Graphics/GraphicsEngineD3D12/src/D3D12TypeConversions.cpp b/Graphics/GraphicsEngineD3D12/src/D3D12TypeConversions.cpp index 23652519..34a98a45 100644 --- a/Graphics/GraphicsEngineD3D12/src/D3D12TypeConversions.cpp +++ b/Graphics/GraphicsEngineD3D12/src/D3D12TypeConversions.cpp @@ -321,7 +321,7 @@ D3D12_STATIC_BORDER_COLOR BorderColorToD3D12StaticBorderColor(const Float32 Bord StaticBorderColor = D3D12_STATIC_BORDER_COLOR_OPAQUE_WHITE; else { - LOG_ERROR_MESSAGE("Static samplers only allow transparent black (0,0,0,0), opaque black (0,0,0,1) or opaque white (1,1,1,1) as border colors."); + LOG_ERROR_MESSAGE("D3D12 static samplers only allow transparent black (0,0,0,0), opaque black (0,0,0,1) or opaque white (1,1,1,1) as border colors."); } return StaticBorderColor; } diff --git a/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp index f04a309e..b65ad4fc 100644 --- a/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp @@ -117,7 +117,7 @@ LinearAllocator PipelineStateD3D12Impl::InitInternalObjects(const PSOCreateInfoT MemPool.Reserve(); - m_RootSig.AllocateStaticSamplers(CreateInfo.PSODesc.ResourceLayout); + m_RootSig.AllocateImmutableSamplers(CreateInfo.PSODesc.ResourceLayout); m_pShaderResourceLayouts = MemPool.Allocate(GetNumShaderStages() * 2); m_pStaticResourceCaches = MemPool.Allocate(GetNumShaderStages()); @@ -417,7 +417,7 @@ void PipelineStateD3D12Impl::InitResourceLayouts(const PipelineStateCreateInfo& } ShaderResources::DvpVerifyResourceLayout(ResourceLayout, pResources, GetNumShaderStages(), (CreateInfo.Flags & PSO_CREATE_FLAG_IGNORE_MISSING_VARIABLES) == 0, - (CreateInfo.Flags & PSO_CREATE_FLAG_IGNORE_MISSING_STATIC_SAMPLERS) == 0); + (CreateInfo.Flags & PSO_CREATE_FLAG_IGNORE_MISSING_IMMUTABLE_SAMPLERS) == 0); } #endif diff --git a/Graphics/GraphicsEngineD3D12/src/RootSignature.cpp b/Graphics/GraphicsEngineD3D12/src/RootSignature.cpp index bba639f8..2afb9eb1 100644 --- a/Graphics/GraphicsEngineD3D12/src/RootSignature.cpp +++ b/Graphics/GraphicsEngineD3D12/src/RootSignature.cpp @@ -166,7 +166,7 @@ size_t RootSignature::RootParamsManager::GetHash() const RootSignature::RootSignature() : m_RootParams{GetRawAllocator()}, m_MemAllocator{GetRawAllocator()}, - m_StaticSamplers(STD_ALLOCATOR_RAW_MEM(StaticSamplerAttribs, GetRawAllocator(), "Allocator for vector")) + m_ImmutableSamplers(STD_ALLOCATOR_RAW_MEM(ImmutableSamplerAttribs, GetRawAllocator(), "Allocator for vector")) { m_SrvCbvUavRootTablesMap.fill(InvalidRootTableIndex); m_SamplerRootTablesMap.fill(InvalidRootTableIndex); @@ -282,29 +282,30 @@ D3D12_DESCRIPTOR_HEAP_TYPE HeapTypeFromRangeType(D3D12_DESCRIPTOR_RANGE_TYPE Ran } -void RootSignature::InitStaticSampler(SHADER_TYPE ShaderType, - const char* SamplerName, - const char* SamplerSuffix, - const D3DShaderResourceAttribs& SamplerAttribs) +void RootSignature::InitImmutableSampler(SHADER_TYPE ShaderType, + const char* SamplerName, + const char* SamplerSuffix, + const D3DShaderResourceAttribs& SamplerAttribs) { auto ShaderVisibility = GetShaderVisibility(ShaderType); auto SamplerFound = false; - for (auto& StSmplr : m_StaticSamplers) + for (auto& ImtblSmplr : m_ImmutableSamplers) { - if (StSmplr.ShaderVisibility == ShaderVisibility && - StreqSuff(SamplerName, StSmplr.SamplerDesc.SamplerOrTextureName, SamplerSuffix)) + if (ImtblSmplr.ShaderVisibility == ShaderVisibility && + StreqSuff(SamplerName, ImtblSmplr.SamplerDesc.SamplerOrTextureName, SamplerSuffix)) { - StSmplr.ShaderRegister = SamplerAttribs.BindPoint; - StSmplr.ArraySize = SamplerAttribs.BindCount; - StSmplr.RegisterSpace = 0; - SamplerFound = true; + ImtblSmplr.ShaderRegister = SamplerAttribs.BindPoint; + ImtblSmplr.ArraySize = SamplerAttribs.BindCount; + ImtblSmplr.RegisterSpace = 0; + + SamplerFound = true; break; } } if (!SamplerFound) { - LOG_ERROR("Unable to find static sampler \'", SamplerName, '\''); + LOG_ERROR("Unable to find immutable sampler \'", SamplerName, '\''); } } @@ -446,19 +447,19 @@ void RootSignature::dbgVerifyRootParameters() const } #endif -void RootSignature::AllocateStaticSamplers(const PipelineResourceLayoutDesc& ResourceLayout) +void RootSignature::AllocateImmutableSamplers(const PipelineResourceLayoutDesc& ResourceLayout) { - if (ResourceLayout.NumStaticSamplers > 0) + if (ResourceLayout.NumImmutableSamplers > 0) { - m_StaticSamplers.reserve(ResourceLayout.NumStaticSamplers); - for (Uint32 sam = 0; sam < ResourceLayout.NumStaticSamplers; ++sam) + m_ImmutableSamplers.reserve(ResourceLayout.NumImmutableSamplers); + for (Uint32 sam = 0; sam < ResourceLayout.NumImmutableSamplers; ++sam) { - const auto& StSamDesc = ResourceLayout.StaticSamplers[sam]; - Uint32 ShaderStages = StSamDesc.ShaderStages; + const auto& ImtblSamDesc = ResourceLayout.ImmutableSamplers[sam]; + Uint32 ShaderStages = ImtblSamDesc.ShaderStages; while (ShaderStages != 0) { auto Stage = ShaderStages & ~(ShaderStages - 1); - m_StaticSamplers.emplace_back(StSamDesc, GetShaderVisibility(static_cast(Stage))); + m_ImmutableSamplers.emplace_back(ImtblSamDesc, GetShaderVisibility(static_cast(Stage))); ShaderStages &= ~Stage; } } @@ -516,19 +517,19 @@ void RootSignature::Finalize(ID3D12Device* pd3d12Device) rootSignatureDesc.pParameters = D3D12Parameters.size() ? D3D12Parameters.data() : nullptr; UINT TotalD3D12StaticSamplers = 0; - for (const auto& StSam : m_StaticSamplers) - TotalD3D12StaticSamplers += StSam.ArraySize; + for (const auto& ImtblSam : m_ImmutableSamplers) + TotalD3D12StaticSamplers += ImtblSam.ArraySize; rootSignatureDesc.NumStaticSamplers = TotalD3D12StaticSamplers; rootSignatureDesc.pStaticSamplers = nullptr; std::vector> D3D12StaticSamplers(STD_ALLOCATOR_RAW_MEM(D3D12_STATIC_SAMPLER_DESC, GetRawAllocator(), "Allocator for vector")); D3D12StaticSamplers.reserve(TotalD3D12StaticSamplers); - if (!m_StaticSamplers.empty()) + if (!m_ImmutableSamplers.empty()) { - for (size_t s = 0; s < m_StaticSamplers.size(); ++s) + for (size_t s = 0; s < m_ImmutableSamplers.size(); ++s) { - const auto& StSmplrDesc = m_StaticSamplers[s]; - const auto& SamDesc = StSmplrDesc.SamplerDesc.Desc; - for (UINT ArrInd = 0; ArrInd < StSmplrDesc.ArraySize; ++ArrInd) + const auto& ImtblSmplrDesc = m_ImmutableSamplers[s]; + const auto& SamDesc = ImtblSmplrDesc.SamplerDesc.Desc; + for (UINT ArrInd = 0; ArrInd < ImtblSmplrDesc.ArraySize; ++ArrInd) { D3D12StaticSamplers.emplace_back( D3D12_STATIC_SAMPLER_DESC // @@ -543,18 +544,18 @@ void RootSignature::Finalize(ID3D12Device* pd3d12Device) BorderColorToD3D12StaticBorderColor(SamDesc.BorderColor), SamDesc.MinLOD, SamDesc.MaxLOD, - StSmplrDesc.ShaderRegister + ArrInd, - StSmplrDesc.RegisterSpace, - StSmplrDesc.ShaderVisibility // - } // + ImtblSmplrDesc.ShaderRegister + ArrInd, + ImtblSmplrDesc.RegisterSpace, + ImtblSmplrDesc.ShaderVisibility // + } // ); } } rootSignatureDesc.pStaticSamplers = D3D12StaticSamplers.data(); - // Release static samplers array, we no longer need it - std::vector> EmptySamplers(STD_ALLOCATOR_RAW_MEM(StaticSamplerAttribs, GetRawAllocator(), "Allocator for vector")); - m_StaticSamplers.swap(EmptySamplers); + // Release immutable samplers array, we no longer need it + std::vector> EmptySamplers(STD_ALLOCATOR_RAW_MEM(ImmutableSamplerAttribs, GetRawAllocator(), "Allocator for vector")); + m_ImmutableSamplers.swap(EmptySamplers); VERIFY_EXPR(D3D12StaticSamplers.size() == TotalD3D12StaticSamplers); } @@ -640,7 +641,7 @@ void RootSignature::InitResourceCache(RenderDeviceD3D12Impl* pDeviceD3D12Impl DEV_CHECK_ERR(!SamplerHeapSpace.IsNull(), "Failed to allocate ", TotalSamplerDescriptors, " GPU-visible Sampler descriptor", (TotalSamplerDescriptors > 1 ? "s" : ""), - ". Consider using static samplers in the Pipeline State Object or " + ". Consider using immutable samplers in the Pipeline State Object or " "increasing GPUDescriptorHeapSize[1] in EngineD3D12CreateInfo."); } VERIFY_EXPR(TotalSamplerDescriptors == 0 && SamplerHeapSpace.IsNull() || SamplerHeapSpace.GetNumHandles() == TotalSamplerDescriptors); @@ -965,7 +966,7 @@ void RootSignature::CommitDescriptorHandlesInternal_SMD(RenderDeviceD3D12Impl* DEV_CHECK_ERR(DynamicSamplerDescriptors.GetDescriptorHeap() != nullptr, "Failed to allocate ", NumDynamicSamplerDescriptors, " dynamic GPU-visible Sampler descriptor", (NumDynamicSamplerDescriptors > 1 ? "s" : ""), - ". Consider using static samplers in the Pipeline State Object, increasing GPUDescriptorHeapDynamicSize[1] in " + ". Consider using immutable samplers in the Pipeline State Object, increasing GPUDescriptorHeapDynamicSize[1] in " "EngineD3D12CreateInfo, or optimizing dynamic resource utilization by using static or mutable shader resource variables instead."); } diff --git a/Graphics/GraphicsEngineD3D12/src/ShaderResourceLayoutD3D12.cpp b/Graphics/GraphicsEngineD3D12/src/ShaderResourceLayoutD3D12.cpp index c0029da5..06e902fb 100644 --- a/Graphics/GraphicsEngineD3D12/src/ShaderResourceLayoutD3D12.cpp +++ b/Graphics/GraphicsEngineD3D12/src/ShaderResourceLayoutD3D12.cpp @@ -149,10 +149,11 @@ ShaderResourceLayoutD3D12::ShaderResourceLayoutD3D12(IObject& auto VarType = m_pResources->FindVariableType(Sam, ResourceLayout); if (IsAllowedType(VarType, AllowedTypeBits)) { - constexpr bool LogStaticSamplerArrayError = true; - auto StaticSamplerInd = m_pResources->FindStaticSampler(Sam, ResourceLayout, LogStaticSamplerArrayError); - // Skip static samplers - if (StaticSamplerInd < 0) + constexpr bool LogImtblSamplerArrayError = true; + + auto ImtblSamplerInd = m_pResources->FindImmutableSampler(Sam, ResourceLayout, LogImtblSamplerArrayError); + // Skip immutable samplers + if (ImtblSamplerInd < 0) ++SamplerCount[VarType]; } }, @@ -237,7 +238,7 @@ ShaderResourceLayoutD3D12::ShaderResourceLayoutD3D12(IObject& VERIFY(RootIndex != D3D12Resource::InvalidRootIndex, "Root index must be valid"); VERIFY(Offset != D3D12Resource::InvalidOffset, "Offset must be valid"); - // Static samplers are never copied, and SamplerId == InvalidSamplerId + // Immutable samplers are never copied, and SamplerId == InvalidSamplerId auto& NewResource = (ResType == CachedResourceType::Sampler) ? GetSampler(VarType, CurrSampler[VarType]++) : GetSrvCbvUav(VarType, CurrCbvSrvUav[VarType]++); @@ -258,12 +259,13 @@ ShaderResourceLayoutD3D12::ShaderResourceLayoutD3D12(IObject& if (IsAllowedType(VarType, AllowedTypeBits)) { // The error (if any) have already been logged when counting the resources - constexpr bool LogStaticSamplerArrayError = false; - auto StaticSamplerInd = m_pResources->FindStaticSampler(Sam, ResourceLayout, LogStaticSamplerArrayError); - if (StaticSamplerInd >= 0) + constexpr bool LogImtblSamplerArrayError = false; + + auto ImtblSamplerInd = m_pResources->FindImmutableSampler(Sam, ResourceLayout, LogImtblSamplerArrayError); + if (ImtblSamplerInd >= 0) { if (pRootSig != nullptr) - pRootSig->InitStaticSampler(m_pResources->GetShaderType(), Sam.Name, m_pResources->GetCombinedSamplerSuffix(), Sam); + pRootSig->InitImmutableSampler(m_pResources->GetShaderType(), Sam.Name, m_pResources->GetCombinedSamplerSuffix(), Sam); } else { @@ -290,18 +292,19 @@ ShaderResourceLayoutD3D12::ShaderResourceLayoutD3D12(IObject& ") of the sampler '", SamplerAttribs.Name, "' that is assigned to it"); // The error (if any) have already been logged when counting the resources - constexpr bool LogStaticSamplerArrayError = false; - auto StaticSamplerInd = m_pResources->FindStaticSampler(SamplerAttribs, ResourceLayout, LogStaticSamplerArrayError); - if (StaticSamplerInd >= 0) + constexpr bool LogImtblSamplerArrayError = false; + + auto ImtblSamplerInd = m_pResources->FindImmutableSampler(SamplerAttribs, ResourceLayout, LogImtblSamplerArrayError); + if (ImtblSamplerInd >= 0) { - // Static samplers are never copied, and SamplerId == InvalidSamplerId + // Immutable samplers are never copied, and SamplerId == InvalidSamplerId #ifdef DILIGENT_DEBUG auto SamplerCount = GetTotalSamplerCount(); for (Uint32 s = 0; s < SamplerCount; ++s) { const auto& Sampler = GetSampler(s); if (strcmp(Sampler.Attribs.Name, SamplerAttribs.Name) == 0) - LOG_ERROR("Static sampler '", Sampler.Attribs.Name, "' was found among resources. This seems to be a bug"); + LOG_ERROR("Immutable sampler '", Sampler.Attribs.Name, "' was found among resources. This seems to be a bug"); } #endif } @@ -619,7 +622,7 @@ void ShaderResourceLayoutD3D12::D3D12Resource::BindResource(IDeviceObject* if (ValidSamplerAssigned()) { auto& Sam = ParentResLayout.GetAssignedSampler(*this); - //VERIFY( !Sam.Attribs.IsStaticSampler(), "Static samplers should never be assigned space in the cache" ); + //VERIFY( !Sam.Attribs.IsImmutableSampler(), "Immutable samplers should never be assigned space in the cache" ); VERIFY_EXPR(Attribs.BindCount == Sam.Attribs.BindCount || Sam.Attribs.BindCount == 1); auto SamplerArrInd = Sam.Attribs.BindCount > 1 ? ArrayIndex : 0; @@ -793,7 +796,7 @@ void ShaderResourceLayoutD3D12::CopyStaticResourceDesriptorHandles(const ShaderR { const auto& SamInfo = DstLayout.GetAssignedSampler(res); - //VERIFY(!SamInfo.Attribs.IsStaticSampler(), "Static samplers should never be assigned space in the cache"); + //VERIFY(!SamInfo.Attribs.IsImmutableSampler(), "Immutable samplers should never be assigned space in the cache"); VERIFY(SamInfo.Attribs.IsValidBindPoint(), "Sampler bind point must be valid"); VERIFY_EXPR(SamInfo.Attribs.BindCount == res.Attribs.BindCount || SamInfo.Attribs.BindCount == 1); @@ -920,7 +923,7 @@ bool ShaderResourceLayoutD3D12::dvpVerifyBindings(const ShaderResourceCacheD3D12 { VERIFY(res.GetResType() == CachedResourceType::TexSRV, "Sampler can only be assigned to a texture SRV"); const auto& SamInfo = GetAssignedSampler(res); - //VERIFY(!SamInfo.Attribs.IsStaticSampler(), "Static samplers should never be assigned space in the cache" ); + //VERIFY(!SamInfo.Attribs.IsImmutableSampler(), "Immutable samplers should never be assigned space in the cache" ); VERIFY(SamInfo.Attribs.IsValidBindPoint(), "Sampler bind point must be valid"); for (Uint32 ArrInd = 0; ArrInd < SamInfo.Attribs.BindCount; ++ArrInd) -- cgit v1.2.3 From e5f36378de4a7258fcc9d6ca7a349df1136b7444 Mon Sep 17 00:00:00 2001 From: assiduous Date: Mon, 19 Oct 2020 12:08:40 -0700 Subject: Renamed USAGE_STATIC to USAGE_IMMUTABLE (API240077) --- Graphics/GraphicsEngineD3D12/src/BufferD3D12Impl.cpp | 4 ++-- Graphics/GraphicsEngineD3D12/src/TextureD3D12Impl.cpp | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'Graphics/GraphicsEngineD3D12') diff --git a/Graphics/GraphicsEngineD3D12/src/BufferD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/BufferD3D12Impl.cpp index c89a7423..d7cd54b6 100644 --- a/Graphics/GraphicsEngineD3D12/src/BufferD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/BufferD3D12Impl.cpp @@ -68,8 +68,8 @@ BufferD3D12Impl::BufferD3D12Impl(IReferenceCounters* pRefCounters, LOG_ERROR_AND_THROW("Unified resources are not supported in Direct3D12"); } - if (m_Desc.Usage == USAGE_STATIC) - VERIFY(pBuffData != nullptr && pBuffData->pData != nullptr, "Initial data must not be null for static buffers"); + if (m_Desc.Usage == USAGE_IMMUTABLE) + VERIFY(pBuffData != nullptr && pBuffData->pData != nullptr, "Initial data must not be null for immutable buffers"); if (m_Desc.Usage == USAGE_DYNAMIC) VERIFY(pBuffData == nullptr || pBuffData->pData == nullptr, "Initial data must be null for dynamic buffers"); diff --git a/Graphics/GraphicsEngineD3D12/src/TextureD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/TextureD3D12Impl.cpp index a4033f51..22829770 100644 --- a/Graphics/GraphicsEngineD3D12/src/TextureD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/TextureD3D12Impl.cpp @@ -135,8 +135,8 @@ TextureD3D12Impl::TextureD3D12Impl(IReferenceCounters* pRefCounters, const TextureData* pInitData /*= nullptr*/) : TTextureBase{pRefCounters, TexViewObjAllocator, pRenderDeviceD3D12, TexDesc} { - if (m_Desc.Usage == USAGE_STATIC && (pInitData == nullptr || pInitData->pSubResources == nullptr)) - LOG_ERROR_AND_THROW("Static textures must be initialized with data at creation time: pInitData can't be null"); + if (m_Desc.Usage == USAGE_IMMUTABLE && (pInitData == nullptr || pInitData->pSubResources == nullptr)) + LOG_ERROR_AND_THROW("Immutable textures must be initialized with data at creation time: pInitData can't be null"); if ((m_Desc.MiscFlags & MISC_TEXTURE_FLAG_GENERATE_MIPS) != 0) { @@ -149,7 +149,7 @@ TextureD3D12Impl::TextureD3D12Impl(IReferenceCounters* pRefCounters, D3D12_RESOURCE_DESC Desc = GetD3D12TextureDesc(); auto* pd3d12Device = pRenderDeviceD3D12->GetD3D12Device(); - if (m_Desc.Usage == USAGE_STATIC || m_Desc.Usage == USAGE_DEFAULT || m_Desc.Usage == USAGE_DYNAMIC) + if (m_Desc.Usage == USAGE_IMMUTABLE || m_Desc.Usage == USAGE_DEFAULT || m_Desc.Usage == USAGE_DYNAMIC) { D3D12_CLEAR_VALUE ClearValue = {}; D3D12_CLEAR_VALUE* pClearValue = nullptr; -- cgit v1.2.3 From 13b0b54987db2684e46e337d2e5be5b81366083b Mon Sep 17 00:00:00 2001 From: assiduous Date: Tue, 20 Oct 2020 13:26:21 -0700 Subject: Improved exception safety of pipeline state object construction --- .../include/PipelineStateD3D12Impl.hpp | 4 +- .../include/ShaderResourceCacheD3D12.hpp | 2 +- .../include/ShaderResourceLayoutD3D12.hpp | 25 +- .../include/ShaderVariableD3D12.hpp | 18 +- .../src/PipelineStateD3D12Impl.cpp | 501 +++++++++++---------- .../src/ShaderResourceBindingD3D12Impl.cpp | 17 +- .../src/ShaderResourceLayoutD3D12.cpp | 27 +- .../src/ShaderVariableD3D12.cpp | 23 +- 8 files changed, 323 insertions(+), 294 deletions(-) (limited to 'Graphics/GraphicsEngineD3D12') 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 - LinearAllocator InitInternalObjects(const PSOCreateInfoType& CreateInfo, std::vector& ShaderStages); + void InitInternalObjects(const PSOCreateInfoType& CreateInfo, std::vector& ShaderStages); void InitResourceLayouts(const PipelineStateCreateInfo& CreateInfo, std::vector& ShaderStages); + void Destruct(); + CComPtr 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 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 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 -LinearAllocator PipelineStateD3D12Impl::InitInternalObjects(const PSOCreateInfoType& CreateInfo, - std::vector& ShaderStages) +void PipelineStateD3D12Impl::InitInternalObjects(const PSOCreateInfoType& CreateInfo, + std::vector& ShaderStages) { m_ResourceLayoutIndex.fill(-1); ExtractShaders(CreateInfo, ShaderStages); - // Memory must be released if an exception is thrown. LinearAllocator MemPool{GetRawAllocator()}; - MemPool.AddSpace(GetNumShaderStages() * 2); - MemPool.AddSpace(GetNumShaderStages()); - MemPool.AddSpace(GetNumShaderStages()); + const auto NumShaderStages = GetNumShaderStages(); + VERIFY_EXPR(NumShaderStages > 0 && NumShaderStages == ShaderStages.size()); + + MemPool.AddSpace(NumShaderStages); + MemPool.AddSpace(NumShaderStages * 2); + MemPool.AddSpace(NumShaderStages); ReserveSpaceForPipelineDesc(CreateInfo, MemPool); MemPool.Reserve(); - m_RootSig.AllocateImmutableSamplers(CreateInfo.PSODesc.ResourceLayout); + m_pStaticResourceCaches = MemPool.ConstructArray(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(GetNumShaderStages() * 2); - m_pStaticResourceCaches = MemPool.Allocate(GetNumShaderStages()); - m_pStaticVarManagers = MemPool.Allocate(GetNumShaderStages()); + m_pShaderResourceLayouts = MemPool.ConstructArray(NumShaderStages * 2, std::ref(*this)); + + m_pStaticVarManagers = MemPool.Allocate(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 ShaderStages; - - auto MemPool = InitInternalObjects(CreateInfo, ShaderStages); - - auto pd3d12Device = pDeviceD3D12->GetD3D12Device(); - if (m_Desc.PipelineType == PIPELINE_TYPE_GRAPHICS) + try { - const auto& GraphicsPipeline = GetGraphicsPipelineDesc(); + std::vector 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> d312InputElements(STD_ALLOCATOR_RAW_MEM(D3D12_INPUT_ELEMENT_DESC, GetRawAllocator(), "Allocator for vector")); + std::vector> d312InputElements(STD_ALLOCATOR_RAW_MEM(D3D12_INPUT_ELEMENT_DESC, GetRawAllocator(), "Allocator for vector")); - const auto& InputLayout = GetGraphicsPipelineDesc().InputLayout; - if (InputLayout.NumElements > 0) - { - LayoutElements_To_D3D12_INPUT_ELEMENT_DESCs(InputLayout, d312InputElements); - d3d12PSODesc.InputLayout.NumElements = static_cast(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(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(static_cast(&m_pd3d12PSO))); - if (FAILED(hr)) - LOG_ERROR_AND_THROW("Failed to create pipeline state"); - } + HRESULT hr = pd3d12Device->CreateGraphicsPipelineState(&d3d12PSODesc, __uuidof(ID3D12PipelineState), reinterpret_cast(static_cast(&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 Flags; - PSS_SubObject NodeMask; - PSS_SubObject pRootSignature; - PSS_SubObject PS; - PSS_SubObject AS; - PSS_SubObject MS; - PSS_SubObject BlendState; - PSS_SubObject DepthStencilState; - PSS_SubObject RasterizerState; - PSS_SubObject SampleDesc; - PSS_SubObject SampleMask; - PSS_SubObject DSVFormat; - PSS_SubObject RTVFormatArray; - PSS_SubObject 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 Flags; + PSS_SubObject NodeMask; + PSS_SubObject pRootSignature; + PSS_SubObject PS; + PSS_SubObject AS; + PSS_SubObject MS; + PSS_SubObject BlendState; + PSS_SubObject DepthStencilState; + PSS_SubObject RasterizerState; + PSS_SubObject SampleDesc; + PSS_SubObject SampleMask; + PSS_SubObject DSVFormat; + PSS_SubObject RTVFormatArray; + PSS_SubObject 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 ShaderStages; + try + { + std::vector 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(static_cast(&m_pd3d12PSO))); - if (FAILED(hr)) - LOG_ERROR_AND_THROW("Failed to create pipeline state"); + HRESULT hr = pd3d12Device->CreateComputePipelineState(&d3d12PSODesc, __uuidof(ID3D12PipelineState), reinterpret_cast(static_cast(&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(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(s)), - GetRawAllocator(), - nullptr, - 0, - GetStaticShaderResCache(static_cast(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(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(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 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 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); -- cgit v1.2.3 From 0c7e8e2efc95362cbc0998558bb41789a3943037 Mon Sep 17 00:00:00 2001 From: assiduous Date: Tue, 20 Oct 2020 14:06:33 -0700 Subject: Improved exception safety of SRB object creation --- .../include/ShaderResourceBindingD3D12Impl.hpp | 2 + .../src/ShaderResourceBindingD3D12Impl.cpp | 88 ++++++++++++++-------- 2 files changed, 59 insertions(+), 31 deletions(-) (limited to 'Graphics/GraphicsEngineD3D12') diff --git a/Graphics/GraphicsEngineD3D12/include/ShaderResourceBindingD3D12Impl.hpp b/Graphics/GraphicsEngineD3D12/include/ShaderResourceBindingD3D12Impl.hpp index 846cb329..7be3372d 100644 --- a/Graphics/GraphicsEngineD3D12/include/ShaderResourceBindingD3D12Impl.hpp +++ b/Graphics/GraphicsEngineD3D12/include/ShaderResourceBindingD3D12Impl.hpp @@ -78,6 +78,8 @@ public: } private: + void Destruct(); + ShaderResourceCacheD3D12 m_ShaderResourceCache; ShaderVariableManagerD3D12* m_pShaderVarMgrs = nullptr; diff --git a/Graphics/GraphicsEngineD3D12/src/ShaderResourceBindingD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/ShaderResourceBindingD3D12Impl.cpp index 1c5ae5f5..1511bd01 100644 --- a/Graphics/GraphicsEngineD3D12/src/ShaderResourceBindingD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/ShaderResourceBindingD3D12Impl.cpp @@ -30,6 +30,7 @@ #include "PipelineStateD3D12Impl.hpp" #include "ShaderD3D12Impl.hpp" #include "RenderDeviceD3D12Impl.hpp" +#include "LinearAllocator.hpp" namespace Diligent { @@ -48,48 +49,73 @@ ShaderResourceBindingD3D12Impl::ShaderResourceBindingD3D12Impl(IReferenceCounter m_NumShaders {static_cast(pPSO->GetNumShaderStages())} // clang-format on { - m_ResourceLayoutIndex.fill(-1); + try + { + m_ResourceLayoutIndex.fill(-1); + + LinearAllocator MemPool{GetRawAllocator()}; + MemPool.AddSpace(m_NumShaders); + MemPool.Reserve(); + m_pShaderVarMgrs = MemPool.ConstructArray(m_NumShaders, std::ref(*this), std::ref(m_ShaderResourceCache)); - auto* pRenderDeviceD3D12Impl = ValidatedCast(pPSO->GetDevice()); - auto& ResCacheDataAllocator = pPSO->GetSRBMemoryAllocator().GetResourceCacheDataAllocator(0); - pPSO->GetRootSignature().InitResourceCache(pRenderDeviceD3D12Impl, m_ShaderResourceCache, ResCacheDataAllocator); + // The memory is now owned by ShaderResourceBindingD3D12Impl and will be freed by Destruct(). + auto* Ptr = MemPool.ReleaseOwnership(); + VERIFY_EXPR(Ptr == m_pShaderVarMgrs); + (void)Ptr; - m_pShaderVarMgrs = ALLOCATE(GetRawAllocator(), "Raw memory for ShaderVariableManagerD3D12", ShaderVariableManagerD3D12, m_NumShaders); + // It is important to construct all objects before initializing them because if an exception is thrown, + // destructors will be called for all objects - for (Uint32 s = 0; s < m_NumShaders; ++s) + auto* pRenderDeviceD3D12Impl = ValidatedCast(pPSO->GetDevice()); + auto& ResCacheDataAllocator = pPSO->GetSRBMemoryAllocator().GetResourceCacheDataAllocator(0); + pPSO->GetRootSignature().InitResourceCache(pRenderDeviceD3D12Impl, m_ShaderResourceCache, ResCacheDataAllocator); + + for (Uint32 s = 0; s < m_NumShaders; ++s) + { + const auto ShaderType = pPSO->GetShaderStageType(s); + const auto& SrcLayout = pPSO->GetShaderResLayout(s); + const auto ShaderInd = GetShaderTypePipelineIndex(ShaderType, pPSO->GetDesc().PipelineType); + + auto& VarDataAllocator = pPSO->GetSRBMemoryAllocator().GetShaderVariableDataAllocator(s); + + // http://diligentgraphics.com/diligent-engine/architecture/d3d12/shader-resource-layout#Initializing-Resource-Layouts-in-a-Shader-Resource-Binding-Object + const SHADER_RESOURCE_VARIABLE_TYPE AllowedVarTypes[] = {SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE, SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC}; + m_pShaderVarMgrs[s].Initialize( + SrcLayout, + VarDataAllocator, + AllowedVarTypes, + _countof(AllowedVarTypes) // + ); + + m_ResourceLayoutIndex[ShaderInd] = static_cast(s); + } + } + catch (...) { - auto ShaderType = pPSO->GetShaderStageType(s); - auto ShaderInd = GetShaderTypePipelineIndex(ShaderType, pPSO->GetDesc().PipelineType); - - auto& VarDataAllocator = pPSO->GetSRBMemoryAllocator().GetShaderVariableDataAllocator(s); - - // http://diligentgraphics.com/diligent-engine/architecture/d3d12/shader-resource-layout#Initializing-Resource-Layouts-in-a-Shader-Resource-Binding-Object - 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, m_ShaderResourceCache}; - m_pShaderVarMgrs[s].Initialize( - SrcLayout, - VarDataAllocator, - AllowedVarTypes, - _countof(AllowedVarTypes) // - ); - - m_ResourceLayoutIndex[ShaderInd] = static_cast(s); + Destruct(); + throw; } } + ShaderResourceBindingD3D12Impl::~ShaderResourceBindingD3D12Impl() { - auto* pPSO = ValidatedCast(m_pPSO); - for (Uint32 s = 0; s < m_NumShaders; ++s) + Destruct(); +} + +void ShaderResourceBindingD3D12Impl::Destruct() +{ + if (m_pShaderVarMgrs != nullptr) { - auto& VarDataAllocator = pPSO->GetSRBMemoryAllocator().GetShaderVariableDataAllocator(s); - m_pShaderVarMgrs[s].Destroy(VarDataAllocator); - m_pShaderVarMgrs[s].~ShaderVariableManagerD3D12(); + auto& SRBMemAllocator = m_pPSO->GetSRBMemoryAllocator(); + for (Uint32 s = 0; s < m_NumShaders; ++s) + { + auto& VarDataAllocator = SRBMemAllocator.GetShaderVariableDataAllocator(s); + m_pShaderVarMgrs[s].Destroy(VarDataAllocator); + m_pShaderVarMgrs[s].~ShaderVariableManagerD3D12(); + } + GetRawAllocator().Free(m_pShaderVarMgrs); } - - GetRawAllocator().Free(m_pShaderVarMgrs); } IMPLEMENT_QUERY_INTERFACE(ShaderResourceBindingD3D12Impl, IID_ShaderResourceBindingD3D12, TBase) -- cgit v1.2.3 From b9d1a84943f61d1b48ffb1847cd0b3f7b8c60fb2 Mon Sep 17 00:00:00 2001 From: assiduous Date: Tue, 20 Oct 2020 18:05:02 -0700 Subject: Added ShaderResourceQueries device feature and EngineGLCreateInfo::ForceNonSeparablePrograms parameter (API 240078) --- Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Graphics/GraphicsEngineD3D12') diff --git a/Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp index ba91f7bc..377eb5a7 100644 --- a/Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp @@ -297,7 +297,7 @@ RenderDeviceD3D12Impl::RenderDeviceD3D12Impl(IReferenceCounters* pRefCo #undef CHECK_REQUIRED_FEATURE #if defined(_MSC_VER) && defined(_WIN64) - static_assert(sizeof(DeviceFeatures) == 30, "Did you add a new feature to DeviceFeatures? Please handle its satus here."); + static_assert(sizeof(DeviceFeatures) == 31, "Did you add a new feature to DeviceFeatures? Please handle its satus here."); #endif auto& TexCaps = m_DeviceCaps.TexCaps; -- cgit v1.2.3