summaryrefslogtreecommitdiffstats
path: root/Graphics/GraphicsEngineD3D12
diff options
context:
space:
mode:
authorEgor Yusov <egor.yusov@gmail.com>2018-03-11 21:20:21 +0000
committerEgor Yusov <egor.yusov@gmail.com>2018-03-11 21:20:21 +0000
commit8a176f30d6c0ee19af6240ad48c2128222ad653c (patch)
tree4f12cfff2a0952dbe7722374dcd4767172d68e77 /Graphics/GraphicsEngineD3D12
parentImplemented PSO compatibility in D3D11 (diff)
downloadDiligentCore-8a176f30d6c0ee19af6240ad48c2128222ad653c.tar.gz
DiligentCore-8a176f30d6c0ee19af6240ad48c2128222ad653c.zip
Implemented PSO compatibility in D3D12
Diffstat (limited to 'Graphics/GraphicsEngineD3D12')
-rw-r--r--Graphics/GraphicsEngineD3D12/include/RootSignature.h113
-rw-r--r--Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp52
-rw-r--r--Graphics/GraphicsEngineD3D12/src/RootSignature.cpp37
-rw-r--r--Graphics/GraphicsEngineD3D12/src/ShaderResourceBindingD3D12Impl.cpp4
4 files changed, 200 insertions, 6 deletions
diff --git a/Graphics/GraphicsEngineD3D12/include/RootSignature.h b/Graphics/GraphicsEngineD3D12/include/RootSignature.h
index 1244f0bf..46e4fc1c 100644
--- a/Graphics/GraphicsEngineD3D12/include/RootSignature.h
+++ b/Graphics/GraphicsEngineD3D12/include/RootSignature.h
@@ -146,6 +146,107 @@ public:
Uint32 GetRootIndex()const{return m_RootIndex;}
operator const D3D12_ROOT_PARAMETER&()const{return m_RootParam;}
+
+ bool operator == (const RootParameter&rhs)const
+ {
+ if (m_ShaderVarType != rhs.m_ShaderVarType ||
+ m_DescriptorTableSize != rhs.m_DescriptorTableSize ||
+ m_RootIndex != rhs.m_RootIndex)
+ return false;
+
+ if (m_RootParam.ParameterType != rhs.m_RootParam.ParameterType ||
+ m_RootParam.ShaderVisibility != rhs.m_RootParam.ShaderVisibility)
+ return false;
+
+ switch(m_RootParam.ParameterType)
+ {
+ case D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE:
+ {
+ const auto &tbl0 = m_RootParam.DescriptorTable;
+ const auto &tbl1 = rhs.m_RootParam.DescriptorTable;
+ if(tbl0.NumDescriptorRanges != tbl1.NumDescriptorRanges)
+ return false;
+ for(UINT r=0; r < tbl0.NumDescriptorRanges; ++r)
+ {
+ const auto &rng0 = tbl0.pDescriptorRanges[r];
+ const auto &rng1 = tbl1.pDescriptorRanges[r];
+ if( memcmp(&rng0, &rng1, sizeof(rng0)) != 0)
+ return false;
+ }
+ }
+ break;
+
+ case D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS:
+ {
+ const auto &cnst0 = m_RootParam.Constants;
+ const auto &cnst1 = rhs.m_RootParam.Constants;
+ if (memcmp(&cnst0, &cnst1, sizeof(cnst0)) != 0)
+ return false;
+ }
+ break;
+
+ case D3D12_ROOT_PARAMETER_TYPE_CBV:
+ case D3D12_ROOT_PARAMETER_TYPE_SRV:
+ case D3D12_ROOT_PARAMETER_TYPE_UAV:
+ {
+ const auto &dscr0 = m_RootParam.Descriptor;
+ const auto &dscr1 = rhs.m_RootParam.Descriptor;
+ if (memcmp(&dscr0, &dscr1, sizeof(dscr0)) != 0)
+ return false;
+ }
+ break;
+
+ default: UNEXPECTED("Unexpected root parameter type");
+ }
+
+ return true;
+ }
+
+ bool operator != (const RootParameter&rhs)const
+ {
+ return !(*this == rhs);
+ }
+
+ size_t GetHash()const
+ {
+ size_t hash = ComputeHash(m_ShaderVarType, m_DescriptorTableSize, m_RootIndex);
+ HashCombine(hash, m_RootParam.ParameterType, m_RootParam.ShaderVisibility);
+
+ switch (m_RootParam.ParameterType)
+ {
+ case D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE:
+ {
+ const auto &tbl = m_RootParam.DescriptorTable;
+ HashCombine(hash, tbl.NumDescriptorRanges);
+ for (UINT r = 0; r < tbl.NumDescriptorRanges; ++r)
+ {
+ const auto &rng = tbl.pDescriptorRanges[r];
+ HashCombine(hash, rng.BaseShaderRegister, rng.NumDescriptors, rng.OffsetInDescriptorsFromTableStart, rng.RangeType, rng.RegisterSpace);
+ }
+ }
+ break;
+
+ case D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS:
+ {
+ const auto &cnst = m_RootParam.Constants;
+ HashCombine(hash, cnst.Num32BitValues, cnst.RegisterSpace, cnst.ShaderRegister);
+ }
+ break;
+
+ case D3D12_ROOT_PARAMETER_TYPE_CBV:
+ case D3D12_ROOT_PARAMETER_TYPE_SRV:
+ case D3D12_ROOT_PARAMETER_TYPE_UAV:
+ {
+ const auto &dscr = m_RootParam.Descriptor;
+ HashCombine(hash, dscr.RegisterSpace, dscr.ShaderRegister);
+ }
+ break;
+
+ default: UNEXPECTED("Unexpected root parameter type");
+ }
+
+ return hash;
+ }
private:
@@ -204,6 +305,15 @@ public:
return m_TotalSamplerSlots[VarType];
}
+ bool IsSameAs(const RootSignature& RS)const
+ {
+ return m_RootParams == RS.m_RootParams;
+ }
+ size_t GetHash()const
+ {
+ return m_RootParams.GetHash();
+ }
+
private:
#ifdef _DEBUG
void dbgVerifyRootParameters()const;
@@ -258,6 +368,9 @@ private:
template<class TOperation>
void ProcessRootTables(TOperation)const;
+ bool operator == (const RootParamsManager& RootParams)const;
+ size_t GetHash()const;
+
private:
size_t GetRequiredMemorySize(Uint32 NumExtraRootTables, Uint32 NumExtraRootViews, Uint32 NumExtraDescriptorRanges)const;
D3D12_DESCRIPTOR_RANGE* Extend(Uint32 NumExtraRootTables, Uint32 NumExtraRootViews, Uint32 NumExtraDescriptorRanges, Uint32 RootTableToAddRanges = static_cast<Uint32>(-1));
diff --git a/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp
index 7fe35e92..de4648c4 100644
--- a/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp
+++ b/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp
@@ -220,6 +220,8 @@ PipelineStateD3D12Impl :: PipelineStateD3D12Impl(IReferenceCounters *pRefCounter
auto &SRBAllocator = pDeviceD3D12->GetSRBAllocator();
// Default shader resource binding must be initialized after resource layouts are parsed!
m_pDefaultShaderResBinding.reset( NEW_RC_OBJ(SRBAllocator, "ShaderResourceBindingD3D12Impl instance", ShaderResourceBindingD3D12Impl, this)(this, true) );
+
+ m_ShaderResourceLayoutHash = m_RootSig.GetHash();
}
PipelineStateD3D12Impl::~PipelineStateD3D12Impl()
@@ -267,8 +269,50 @@ void PipelineStateD3D12Impl::CreateShaderResourceBinding(IShaderResourceBinding
bool PipelineStateD3D12Impl::IsCompatibleWith(const IPipelineState *pPSO)const
{
- UNSUPPORTED("Not yet implemented");
- return false;
+ VERIFY_EXPR(pPSO != nullptr);
+
+ if (pPSO == this)
+ return true;
+
+ const PipelineStateD3D12Impl *pPSOD3D12 = ValidatedCast<const PipelineStateD3D12Impl>(pPSO);
+ if (m_ShaderResourceLayoutHash != pPSOD3D12->m_ShaderResourceLayoutHash)
+ return false;
+
+ auto IsSameRootSignature = m_RootSig.IsSameAs(pPSOD3D12->m_RootSig);
+
+#ifdef _DEBUG
+ {
+ bool IsCompatibleShaders = true;
+ if (m_NumShaders != pPSOD3D12->m_NumShaders)
+ IsCompatibleShaders = false;
+
+ if(IsCompatibleShaders)
+ {
+ for (Uint32 s = 0; s < m_NumShaders; ++s)
+ {
+ auto *pShader0 = ValidatedCast<ShaderD3D12Impl>(m_ppShaders[s]);
+ auto *pShader1 = ValidatedCast<ShaderD3D12Impl>(pPSOD3D12->m_ppShaders[s]);
+ if (pShader0->GetDesc().ShaderType != pShader1->GetDesc().ShaderType)
+ {
+ IsCompatibleShaders = false;
+ break;
+ }
+ const ShaderResourcesD3D12 *pRes0 = pShader0->GetShaderResources().get();
+ const ShaderResourcesD3D12 *pRes1 = pShader1->GetShaderResources().get();
+ if (!pRes0->IsCompatibleWith(*pRes1))
+ {
+ IsCompatibleShaders = false;
+ break;
+ }
+ }
+ }
+
+ if(IsCompatibleShaders)
+ VERIFY(IsSameRootSignature, "Compatible shaders must have same root signatures");
+ }
+#endif
+
+ return IsSameRootSignature;
}
const ShaderResourceLayoutD3D12& PipelineStateD3D12Impl::GetShaderResLayout(SHADER_TYPE ShaderType)const
@@ -299,9 +343,9 @@ ShaderResourceCacheD3D12* PipelineStateD3D12Impl::CommitAndTransitionShaderResou
#ifdef VERIFY_SHADER_BINDINGS
{
auto *pRefPSO = pResBindingD3D12Impl->GetPipelineState();
- if (pRefPSO != this)
+ if ( IsIncompatibleWith(pRefPSO) )
{
- LOG_ERROR_MESSAGE("Shader resource binding does not match the pipeline state \"", m_Desc.Name, "\". Operation will be ignored.");
+ LOG_ERROR_MESSAGE("Shader resource binding is incompatible with the pipeline state \"", m_Desc.Name, "\". Operation will be ignored.");
return nullptr;
}
}
diff --git a/Graphics/GraphicsEngineD3D12/src/RootSignature.cpp b/Graphics/GraphicsEngineD3D12/src/RootSignature.cpp
index 1adcede1..2011bebe 100644
--- a/Graphics/GraphicsEngineD3D12/src/RootSignature.cpp
+++ b/Graphics/GraphicsEngineD3D12/src/RootSignature.cpp
@@ -32,6 +32,7 @@
#include "TextureD3D12Impl.h"
#include "BufferD3D12Impl.h"
#include "D3D12TypeConversions.h"
+#include "HashUtils.h"
namespace Diligent
{
@@ -111,6 +112,42 @@ void RootSignature::RootParamsManager::AddDescriptorRanges(Uint32 RootTableInd,
VERIFY_EXPR( (char*)pRangePtr == (char*)m_pMemory.get() + GetRequiredMemorySize(0, 0, 0));
}
+bool RootSignature::RootParamsManager::operator == (const RootParamsManager& RootParams)const
+{
+ if (m_NumRootTables != RootParams.m_NumRootTables ||
+ m_NumRootViews != RootParams.m_NumRootViews)
+ return false;
+
+ for (Uint32 rv = 0; rv < m_NumRootViews; ++rv)
+ {
+ const auto &RV0 = GetRootView(rv);
+ const auto &RV1 = RootParams.GetRootView(rv);
+ if (RV0 != RV1)
+ return false;
+ }
+
+ for (Uint32 rv = 0; rv < m_NumRootTables; ++rv)
+ {
+ const auto &RT0 = GetRootTable(rv);
+ const auto &RT1 = RootParams.GetRootTable(rv);
+ if (RT0 != RT1)
+ return false;
+ }
+
+ return true;
+}
+
+size_t RootSignature::RootParamsManager::GetHash()const
+{
+ size_t hash = ComputeHash(m_NumRootTables, m_NumRootViews);
+ for (Uint32 rv = 0; rv < m_NumRootViews; ++rv)
+ HashCombine(hash, GetRootView(rv).GetHash());
+
+ for (Uint32 rv = 0; rv < m_NumRootTables; ++rv)
+ HashCombine(hash, GetRootTable(rv).GetHash());
+
+ return hash;
+}
RootSignature::RootSignature() :
m_RootParams(GetRawAllocator()),
diff --git a/Graphics/GraphicsEngineD3D12/src/ShaderResourceBindingD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/ShaderResourceBindingD3D12Impl.cpp
index 8af3d7a2..63552f93 100644
--- a/Graphics/GraphicsEngineD3D12/src/ShaderResourceBindingD3D12Impl.cpp
+++ b/Graphics/GraphicsEngineD3D12/src/ShaderResourceBindingD3D12Impl.cpp
@@ -105,9 +105,9 @@ IShaderVariable *ShaderResourceBindingD3D12Impl::GetVariable(SHADER_TYPE ShaderT
void ShaderResourceBindingD3D12Impl::dbgVerifyResourceBindings(const PipelineStateD3D12Impl *pPSO)
{
auto *pRefPSO = GetPipelineState();
- if (pRefPSO != pPSO)
+ if (pPSO->IsIncompatibleWith(pRefPSO))
{
- LOG_ERROR("Shader resource binding does not match the pipeline state \"", pPSO->GetDesc().Name, '\"');
+ LOG_ERROR("Shader resource binding is incompatible with the pipeline state \"", pPSO->GetDesc().Name, '\"');
return;
}
for(Uint32 l = 0; l < m_NumShaders; ++l)