diff options
| author | assiduous <assiduous@diligentgraphics.com> | 2021-02-25 18:27:16 +0000 |
|---|---|---|
| committer | assiduous <assiduous@diligentgraphics.com> | 2021-03-19 00:38:11 +0000 |
| commit | ac31c5733af9596eb2cdb9c5bc30e8feb7c9fd7a (patch) | |
| tree | e50f8aebe82d485f7fe63bdfa32aad23194534b7 /Graphics/GraphicsEngineD3D12 | |
| parent | Few updates to RenderDeviceD3D12Impl (diff) | |
| download | DiligentCore-ac31c5733af9596eb2cdb9c5bc30e8feb7c9fd7a.tar.gz DiligentCore-ac31c5733af9596eb2cdb9c5bc30e8feb7c9fd7a.zip | |
D3D12 backend: added extra validation of pipeline resource signature resources and samplers
Diffstat (limited to 'Graphics/GraphicsEngineD3D12')
4 files changed, 75 insertions, 9 deletions
diff --git a/Graphics/GraphicsEngineD3D12/include/PipelineStateD3D12Impl.hpp b/Graphics/GraphicsEngineD3D12/include/PipelineStateD3D12Impl.hpp index 50fab6c5..98ff6232 100644 --- a/Graphics/GraphicsEngineD3D12/include/PipelineStateD3D12Impl.hpp +++ b/Graphics/GraphicsEngineD3D12/include/PipelineStateD3D12Impl.hpp @@ -63,7 +63,7 @@ public: virtual bool DILIGENT_CALL_TYPE IsCompatibleWith(const IPipelineState* pPSO) const override final; /// Implementation of IPipelineState::GetResourceSignatureCount() in Direct3D12 backend. - virtual Uint32 DILIGENT_CALL_TYPE GetResourceSignatureCount() const override final { return GetSignatureCount(); } + virtual Uint32 DILIGENT_CALL_TYPE GetResourceSignatureCount() const override final { return m_RootSig->GetSignatureCount(); } /// Implementation of IPipelineState::GetResourceSignature() in Direct3D12 backend. virtual IPipelineResourceSignature* DILIGENT_CALL_TYPE GetResourceSignature(Uint32 Index) const override final { return GetSignature(Index); } @@ -77,13 +77,11 @@ public: /// Implementation of IPipelineStateD3D12::GetD3D12RootSignature(). virtual ID3D12RootSignature* DILIGENT_CALL_TYPE GetD3D12RootSignature() const override final { return m_RootSig->GetD3D12RootSignature(); } - const RootSignatureD3D12* GetRootSignature() const { return m_RootSig; } - - Uint32 GetSignatureCount() const { return m_RootSig->GetSignatureCount(); } + const RootSignatureD3D12& GetRootSignature() const { return *m_RootSig; } PipelineResourceSignatureD3D12Impl* GetSignature(Uint32 index) const { - VERIFY_EXPR(index < GetSignatureCount()); + VERIFY_EXPR(index < GetResourceSignatureCount()); return m_ResourceSignatures[index]; } diff --git a/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp index 8cafe9dc..68407d16 100644 --- a/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp @@ -227,7 +227,7 @@ void DeviceContextD3D12Impl::SetPipelineState(IPipelineState* pPipelineState) auto& CmdCtx = GetCmdContext(); auto& RootInfo = GetRootTableInfo(PSODesc.PipelineType); - auto* pd3d12RootSig = pPipelineStateD3D12->GetRootSignature()->GetD3D12RootSignature(); + auto* pd3d12RootSig = pPipelineStateD3D12->GetRootSignature().GetD3D12RootSignature(); if (RootInfo.pRootSig != pd3d12RootSig) { @@ -238,7 +238,7 @@ void DeviceContextD3D12Impl::SetPipelineState(IPipelineState* pPipelineState) RootInfo.ActiveSRBMask = 0; m_State.CommittedResourcesValidated = false; - for (Uint32 i = 0, SignCount = pPipelineStateD3D12->GetSignatureCount(); i < SignCount; ++i) + for (Uint32 i = 0, SignCount = pPipelineStateD3D12->GetResourceSignatureCount(); i < SignCount; ++i) { const auto* pSignature = pPipelineStateD3D12->GetSignature(i); if (pSignature != nullptr) @@ -304,7 +304,7 @@ void DeviceContextD3D12Impl::SetPipelineState(IPipelineState* pPipelineState) template <bool IsCompute> void DeviceContextD3D12Impl::CommitRootTablesAndViews(RootTableInfo& RootInfo) { - const auto& RootSig = *m_pPipelineState->GetRootSignature(); + const auto& RootSig = m_pPipelineState->GetRootSignature(); auto& CmdCtx = GetCmdContext(); for (Uint32 s = 0; s < RootSig.GetSignatureCount(); ++s) diff --git a/Graphics/GraphicsEngineD3D12/src/PipelineResourceSignatureD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/PipelineResourceSignatureD3D12Impl.cpp index f5404d1a..73208ff0 100644 --- a/Graphics/GraphicsEngineD3D12/src/PipelineResourceSignatureD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/PipelineResourceSignatureD3D12Impl.cpp @@ -26,6 +26,9 @@ */ #include "pch.h" + +#include <unordered_map> + #include "PipelineResourceSignatureD3D12Impl.hpp" #include "ShaderResourceCacheD3D12.hpp" #include "ShaderVariableD3D12.hpp" @@ -60,6 +63,68 @@ inline bool ResourcesCompatible(const PipelineResourceSignatureD3D12Impl::Resour // clang-format on } +void ValidateD3D12PipelineResourceSignatureDesc(const PipelineResourceSignatureDesc& Desc) noexcept(false) +{ + { + std::unordered_multimap<HashMapStringKey, SHADER_TYPE, HashMapStringKey::Hasher> ResNameToShaderStages; + for (Uint32 i = 0; i < Desc.NumResources; ++i) + { + const auto& Res = Desc.Resources[i]; + + ResNameToShaderStages.emplace(Res.Name, Res.ShaderStages); + auto range = ResNameToShaderStages.equal_range(Res.Name); + auto multi_stage_it = ResNameToShaderStages.end(); + for (auto it = range.first; it != range.second; ++it) + { + if (!IsPowerOfTwo(it->second)) + { + if (multi_stage_it == ResNameToShaderStages.end()) + multi_stage_it = it; + else + { + LOG_ERROR_AND_THROW("Pipeline resource signature '", (Desc.Name != nullptr ? Desc.Name : ""), + "' defines separate resources with the name '", Res.Name, "' in shader stages ", + GetShaderStagesString(multi_stage_it->second), " and ", + GetShaderStagesString(it->second), + ". In Direct3D12 backend, only one resource in the group of resources with the same name can be shared between more than " + "one shader stages. To solve this problem, use single shader stage for all but one resource with the same name."); + } + } + } + } + } + + { + std::unordered_multimap<HashMapStringKey, SHADER_TYPE, HashMapStringKey::Hasher> SamNameToShaderStages; + for (Uint32 i = 0; i < Desc.NumImmutableSamplers; ++i) + { + const auto& Sam = Desc.ImmutableSamplers[i]; + + const auto* Name = Sam.SamplerOrTextureName; + SamNameToShaderStages.emplace(Name, Sam.ShaderStages); + auto range = SamNameToShaderStages.equal_range(Name); + auto multi_stage_it = SamNameToShaderStages.end(); + for (auto it = range.first; it != range.second; ++it) + { + if (!IsPowerOfTwo(it->second)) + { + if (multi_stage_it == SamNameToShaderStages.end()) + multi_stage_it = it; + else + { + LOG_ERROR_AND_THROW("Pipeline resource signature '", (Desc.Name != nullptr ? Desc.Name : ""), + "' defines immutable sampler with the name '", Name, "' in shader stages ", + GetShaderStagesString(multi_stage_it->second), " and ", + GetShaderStagesString(it->second), + ". In Direct3D12 backend, only one immutable sampler in the group of samplers with the same name can be shared between more than " + "one shader stages. To solve this problem, use single shader stage for all but one immutable sampler with the same name."); + } + } + } + } + } +} + } // namespace @@ -70,6 +135,8 @@ PipelineResourceSignatureD3D12Impl::PipelineResourceSignatureD3D12Impl(IReferenc TPipelineResourceSignatureBase{pRefCounters, pDevice, Desc, bIsDeviceInternal}, m_SRBMemAllocator{GetRawAllocator()} { + ValidateD3D12PipelineResourceSignatureDesc(Desc); + try { FixedLinearAllocator MemPool{GetRawAllocator()}; diff --git a/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp index 2bbfb956..959c6793 100644 --- a/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp @@ -26,6 +26,7 @@ */ #include "pch.h" + #include <array> #include <sstream> #include <d3dcompiler.h> @@ -672,7 +673,7 @@ void PipelineStateD3D12Impl::InitRootSignature(const PipelineStateCreateInfo& Cr PipelineStateD3D12Impl::ResourceAttribution PipelineStateD3D12Impl::GetResourceAttribution(const char* Name, SHADER_TYPE Stage) const { - const auto SignCount = GetSignatureCount(); + const auto SignCount = GetResourceSignatureCount(); for (Uint32 sign = 0; sign < SignCount; ++sign) { const auto* const pSignature = GetSignature(sign); |
