summaryrefslogtreecommitdiffstats
path: root/Graphics/GraphicsEngineD3D12
diff options
context:
space:
mode:
authorassiduous <assiduous@diligentgraphics.com>2021-02-25 18:27:16 +0000
committerassiduous <assiduous@diligentgraphics.com>2021-03-19 00:38:11 +0000
commitac31c5733af9596eb2cdb9c5bc30e8feb7c9fd7a (patch)
treee50f8aebe82d485f7fe63bdfa32aad23194534b7 /Graphics/GraphicsEngineD3D12
parentFew updates to RenderDeviceD3D12Impl (diff)
downloadDiligentCore-ac31c5733af9596eb2cdb9c5bc30e8feb7c9fd7a.tar.gz
DiligentCore-ac31c5733af9596eb2cdb9c5bc30e8feb7c9fd7a.zip
D3D12 backend: added extra validation of pipeline resource signature resources and samplers
Diffstat (limited to 'Graphics/GraphicsEngineD3D12')
-rw-r--r--Graphics/GraphicsEngineD3D12/include/PipelineStateD3D12Impl.hpp8
-rw-r--r--Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp6
-rw-r--r--Graphics/GraphicsEngineD3D12/src/PipelineResourceSignatureD3D12Impl.cpp67
-rw-r--r--Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp3
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);