summaryrefslogtreecommitdiffstats
path: root/Graphics/GraphicsEngineD3D12
diff options
context:
space:
mode:
authorassiduous <assiduous@diligentgraphics.com>2021-02-15 03:08:26 +0000
committerassiduous <assiduous@diligentgraphics.com>2021-03-19 00:31:37 +0000
commit2d68a6e0686f2931a5047430e4085b2710bb1098 (patch)
treecb5506d5ac6fe891190ab7db19833dbc87cc051b /Graphics/GraphicsEngineD3D12
parentFew minor updates to PipelineResourceSignature{Vk and D3D12}Impl (diff)
downloadDiligentCore-2d68a6e0686f2931a5047430e4085b2710bb1098.tar.gz
DiligentCore-2d68a6e0686f2931a5047430e4085b2710bb1098.zip
Reworked D3D12 resource signatures to not rely on fixed MAX_SPACES_PER_SIGNATURE; reworked handling of immutable samplers
Diffstat (limited to 'Graphics/GraphicsEngineD3D12')
-rw-r--r--Graphics/GraphicsEngineD3D12/include/PipelineResourceSignatureD3D12Impl.hpp67
-rw-r--r--Graphics/GraphicsEngineD3D12/include/RootSignature.hpp22
-rw-r--r--Graphics/GraphicsEngineD3D12/src/D3D12TypeConversions.cpp39
-rw-r--r--Graphics/GraphicsEngineD3D12/src/PipelineResourceSignatureD3D12Impl.cpp191
-rw-r--r--Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp24
-rw-r--r--Graphics/GraphicsEngineD3D12/src/RootSignature.cpp178
6 files changed, 296 insertions, 225 deletions
diff --git a/Graphics/GraphicsEngineD3D12/include/PipelineResourceSignatureD3D12Impl.hpp b/Graphics/GraphicsEngineD3D12/include/PipelineResourceSignatureD3D12Impl.hpp
index 9f0fda98..8fd7ee7d 100644
--- a/Graphics/GraphicsEngineD3D12/include/PipelineResourceSignatureD3D12Impl.hpp
+++ b/Graphics/GraphicsEngineD3D12/include/PipelineResourceSignatureD3D12Impl.hpp
@@ -53,8 +53,6 @@ class PipelineResourceSignatureD3D12Impl final : public PipelineResourceSignatur
public:
using TPipelineResourceSignatureBase = PipelineResourceSignatureBase<IPipelineResourceSignature, RenderDeviceD3D12Impl>;
- static constexpr Uint32 MAX_SPACES_PER_SIGNATURE = 128;
-
PipelineResourceSignatureD3D12Impl(IReferenceCounters* pRefCounters,
RenderDeviceD3D12Impl* pDevice,
const PipelineResourceSignatureDesc& Desc,
@@ -77,10 +75,11 @@ public:
static constexpr Uint32 _SpaceBits = 8;
static constexpr Uint32 _SigRootIndexBits = 3;
static constexpr Uint32 _SamplerAssignedBits = 1;
- static constexpr Uint32 _RootViewFlagBits = 1;
+ static constexpr Uint32 _RootParamTypeBits = 3;
static_assert((1u << _RegisterBits) >= MAX_RESOURCES_IN_SIGNATURE, "Not enough bits to store sahder register");
static_assert((1u << _SamplerIndBits) >= MAX_RESOURCES_IN_SIGNATURE, "Not enough bits to store sampler resource index");
+ static_assert((1u << _RootParamTypeBits) > D3D12_ROOT_PARAMETER_TYPE_UAV + 1, "Not enough bits to store D3D12_ROOT_PARAMETER_TYPE");
public:
static constexpr Uint32 InvalidSamplerInd = (1u << _SamplerIndBits) - 1;
@@ -93,41 +92,42 @@ public:
/* 0 */const Uint32 Register : _RegisterBits; // Shader register
/* 2 */const Uint32 SRBRootIndex : _SRBRootIndexBits; // Root view/table index in the SRB
/* 4 */const Uint32 SamplerInd : _SamplerIndBits; // Index in m_Desc.Resources and m_pResourceAttribs
-/* 6 */const Uint32 Space : _SpaceBits; // Shader register space (local space in range 0..MAX_SPACES_PER_SIGNATURE)
+/* 6 */const Uint32 Space : _SpaceBits; // Shader register space
/* 7.0*/const Uint32 SigRootIndex : _SigRootIndexBits; // Root table index for signature (static only)
/* 7.3*/const Uint32 ImtblSamplerAssigned : _SamplerAssignedBits; // Immutable sampler flag
-/* 7.4*/const Uint32 IsRootView : _RootViewFlagBits; // Is root view (for debugging)
+/* 7.4*/const Uint32 RootParamType : _RootParamTypeBits; // Root parameter type (for debugging)
/* 8 */const Uint32 SigOffsetFromTableStart; // Offset in the root table for signature (static only)
/* 12 */const Uint32 SRBOffsetFromTableStart; // Offset in the root table for SRB
/* 16 */
// clang-format on
- ResourceAttribs(Uint32 _Register,
- Uint32 _Space,
- Uint32 _SamplerInd,
- Uint32 _SRBRootIndex,
- Uint32 _SRBOffsetFromTableStart,
- Uint32 _SigRootIndex,
- Uint32 _SigOffsetFromTableStart,
- bool _ImtblSamplerAssigned,
- bool _IsRootView) noexcept :
+ ResourceAttribs(Uint32 _Register,
+ Uint32 _Space,
+ Uint32 _SamplerInd,
+ Uint32 _SRBRootIndex,
+ Uint32 _SRBOffsetFromTableStart,
+ Uint32 _SigRootIndex,
+ Uint32 _SigOffsetFromTableStart,
+ bool _ImtblSamplerAssigned,
+ D3D12_ROOT_PARAMETER_TYPE _RootParamType) noexcept :
// clang-format off
- Register {_Register },
- SRBRootIndex {_SRBRootIndex },
- SamplerInd {_SamplerInd },
- SigRootIndex {_SigRootIndex },
- Space {_Space },
- ImtblSamplerAssigned {_ImtblSamplerAssigned ? 1u : 0u},
- IsRootView {_IsRootView ? 1u : 0u },
- SigOffsetFromTableStart{_SigOffsetFromTableStart },
- SRBOffsetFromTableStart{_SRBOffsetFromTableStart }
+ Register {_Register },
+ SRBRootIndex {_SRBRootIndex },
+ SamplerInd {_SamplerInd },
+ SigRootIndex {_SigRootIndex },
+ Space {_Space },
+ ImtblSamplerAssigned {_ImtblSamplerAssigned ? 1u : 0u },
+ RootParamType {static_cast<Uint32>(_RootParamType)},
+ SigOffsetFromTableStart{_SigOffsetFromTableStart },
+ SRBOffsetFromTableStart{_SRBOffsetFromTableStart }
// clang-format on
{
VERIFY(Register == _Register, "Shader register (", _Register, ") exceeds maximum representable value");
VERIFY(SRBRootIndex == _SRBRootIndex, "SRB Root index (", _SRBRootIndex, ") exceeds maximum representable value");
- VERIFY(SigRootIndex == _SigRootIndex, "Signature Root index (", SigRootIndex, ") exceeds maximum representable value");
+ VERIFY(SigRootIndex == _SigRootIndex, "Signature Root index (", _SigRootIndex, ") exceeds maximum representable value");
VERIFY(SamplerInd == _SamplerInd, "Sampler index (", _SamplerInd, ") exceeds maximum representable value");
- VERIFY(Space == _Space, "Space (", Space, ") exceeds maximum representable value");
+ VERIFY(Space == _Space, "Space (", _Space, ") exceeds maximum representable value");
+ VERIFY(GetD3D12RootParamType() == _RootParamType, "Not enough bits to represent root parameter type");
}
bool IsImmutableSamplerAssigned() const { return ImtblSamplerAssigned != 0; }
@@ -135,6 +135,8 @@ public:
Uint32 RootIndex(CacheContentType Type) const { return Type == CacheContentType::SRB ? SRBRootIndex : SigRootIndex; }
Uint32 OffsetFromTableStart(CacheContentType Type) const { return Type == CacheContentType::SRB ? SRBOffsetFromTableStart : SigOffsetFromTableStart; }
+
+ D3D12_ROOT_PARAMETER_TYPE GetD3D12RootParamType() const { return static_cast<D3D12_ROOT_PARAMETER_TYPE>(RootParamType); }
};
const ResourceAttribs& GetResourceAttribs(Uint32 ResIndex) const
@@ -160,7 +162,7 @@ public:
public:
Uint32 ArraySize = 1;
Uint32 ShaderRegister : _ShaderRegisterBits;
- Uint32 RegisterSpace : _RegisterSpaceBits; // (local space in range 0..MAX_SPACES_PER_SIGNATURE)
+ Uint32 RegisterSpace : _RegisterSpaceBits;
ImmutableSamplerAttribs() :
ShaderRegister{_InvalidShaderRegister},
@@ -180,7 +182,11 @@ public:
VERIFY(RegisterSpace == _RegisterSpace, "Shader register space (", _RegisterSpace, ") exceeds maximum representable value");
}
- bool IsAssigned() const { return ShaderRegister != _InvalidShaderRegister; }
+ bool IsValid() const
+ {
+ return ShaderRegister != _InvalidShaderRegister &&
+ RegisterSpace != _InvalidRegisterSpace;
+ }
};
const ImmutableSamplerAttribs& GetImmutableSamplerAttribs(Uint32 SampIndex) const
@@ -210,11 +216,6 @@ public:
return m_RootParams.GetNumRootViews();
}
- Uint32 GetBaseRegisterSpace() const
- {
- return m_Desc.BindingIndex * MAX_SPACES_PER_SIGNATURE;
- }
-
virtual void DILIGENT_CALL_TYPE CreateShaderResourceBinding(IShaderResourceBinding** ppShaderResourceBinding,
bool InitStaticResources) override final;
@@ -296,8 +297,6 @@ private:
std::array<Int8, MAX_SHADERS_IN_PIPELINE> m_StaticVarIndex = {-1, -1, -1, -1, -1, -1};
static_assert(MAX_SHADERS_IN_PIPELINE == 6, "Please update the initializer list above");
- Uint32 m_NumSpaces = 0;
-
ShaderResourceCacheD3D12* m_pStaticResCache = nullptr;
ShaderVariableManagerD3D12* m_StaticVarsMgrs = nullptr; // [m_NumShaderStages]
diff --git a/Graphics/GraphicsEngineD3D12/include/RootSignature.hpp b/Graphics/GraphicsEngineD3D12/include/RootSignature.hpp
index 7e1817ea..a2ef646c 100644
--- a/Graphics/GraphicsEngineD3D12/include/RootSignature.hpp
+++ b/Graphics/GraphicsEngineD3D12/include/RootSignature.hpp
@@ -79,11 +79,24 @@ public:
return m_FirstRootIndex[BindingIndex];
}
+ Uint32 GetFirstRegisterSpace(Uint32 BindingIndex) const
+ {
+ VERIFY_EXPR(BindingIndex <= m_SignatureCount);
+ return m_FirstRegisterSpace[BindingIndex];
+ }
+
+ Uint32 GetTotalSpaces() const
+ {
+ return m_TotalSpacesUsed;
+ }
+
using SignatureArrayType = std::array<RefCntAutoPtr<PipelineResourceSignatureD3D12Impl>, MAX_RESOURCE_SIGNATURES>;
private:
- using FirstRootIndexArrayType = std::array<Uint32, MAX_RESOURCE_SIGNATURES>; // AZ TODO: use 8 or 16 bit int
- FirstRootIndexArrayType m_FirstRootIndex = {};
+ std::array<Uint16, MAX_RESOURCE_SIGNATURES> m_FirstRootIndex = {};
+ std::array<Uint16, MAX_RESOURCE_SIGNATURES> m_FirstRegisterSpace = {};
+
+ Uint32 m_TotalSpacesUsed = 0;
size_t m_Hash = 0;
CComPtr<ID3D12RootSignature> m_pd3d12RootSignature;
@@ -105,16 +118,17 @@ public:
bool IsShaderRecord(const D3DShaderResourceAttribs& CB);
- ID3D12RootSignature* Create(ID3D12Device* pDevice);
+ ID3D12RootSignature* Create(ID3D12Device* pDevice, Uint32 RegisterSpace);
bool IsDefined() const { return m_ShaderRecordSize > 0 && m_pName != nullptr; }
const char* GetName() const { return m_pName; }
- Uint32 GetRegisterSpace() const { return PipelineResourceSignatureD3D12Impl::MAX_SPACES_PER_SIGNATURE * MAX_RESOURCE_SIGNATURES; }
Uint32 GetShaderRegister() const { return 0; }
+ Uint32 GetRegisterSpace() const { return m_RegisterSpace; }
private:
const char* m_pName = nullptr;
const Uint32 m_ShaderRecordSize = 0;
+ Uint32 m_RegisterSpace = 0;
CComPtr<ID3D12RootSignature> m_pd3d12RootSignature;
};
diff --git a/Graphics/GraphicsEngineD3D12/src/D3D12TypeConversions.cpp b/Graphics/GraphicsEngineD3D12/src/D3D12TypeConversions.cpp
index 5ea9ed01..66edc30d 100644
--- a/Graphics/GraphicsEngineD3D12/src/D3D12TypeConversions.cpp
+++ b/Graphics/GraphicsEngineD3D12/src/D3D12TypeConversions.cpp
@@ -543,6 +543,8 @@ D3D12_RENDER_PASS_ENDING_ACCESS_TYPE AttachmentStoreOpToD3D12EndingAccessType(AT
D3D12_SHADER_VISIBILITY ShaderTypeToD3D12ShaderVisibility(SHADER_TYPE ShaderType)
{
+ VERIFY(IsPowerOfTwo(ShaderType), "Only single shader stage should be provided");
+
static_assert(SHADER_TYPE_LAST == 0x2000, "Please update the switch below to handle the new shader type");
switch (ShaderType)
{
@@ -793,40 +795,9 @@ D3D12_DESCRIPTOR_HEAP_TYPE D3D12DescriptorRangeTypeToD3D12HeapType(D3D12_DESCRIP
D3D12_SHADER_VISIBILITY ShaderStagesToD3D12ShaderVisibility(SHADER_TYPE Stages)
{
- if (!IsPowerOfTwo(Stages))
- {
- return D3D12_SHADER_VISIBILITY_ALL;
- }
-
- static_assert(SHADER_TYPE_LAST == 0x2000, "Please update the switch below to handle the new shader type");
- switch (Stages)
- {
- // clang-format off
- case SHADER_TYPE_PIXEL: return D3D12_SHADER_VISIBILITY_PIXEL;
- case SHADER_TYPE_VERTEX: return D3D12_SHADER_VISIBILITY_VERTEX;
- case SHADER_TYPE_GEOMETRY: return D3D12_SHADER_VISIBILITY_GEOMETRY;
- case SHADER_TYPE_HULL: return D3D12_SHADER_VISIBILITY_HULL;
- case SHADER_TYPE_DOMAIN: return D3D12_SHADER_VISIBILITY_DOMAIN;
-
-#ifdef D3D12_H_HAS_MESH_SHADER
- case SHADER_TYPE_AMPLIFICATION: return D3D12_SHADER_VISIBILITY_AMPLIFICATION;
- case SHADER_TYPE_MESH: return D3D12_SHADER_VISIBILITY_MESH;
-#endif
- // clang-format on
-
- case SHADER_TYPE_COMPUTE:
- case SHADER_TYPE_RAY_GEN:
- case SHADER_TYPE_RAY_MISS:
- case SHADER_TYPE_RAY_CLOSEST_HIT:
- case SHADER_TYPE_RAY_ANY_HIT:
- case SHADER_TYPE_RAY_INTERSECTION:
- case SHADER_TYPE_CALLABLE:
- return D3D12_SHADER_VISIBILITY_ALL;
-
- default:
- UNEXPECTED("Unknown shader type");
- return D3D12_SHADER_VISIBILITY_ALL;
- }
+ return IsPowerOfTwo(Stages) ?
+ ShaderTypeToD3D12ShaderVisibility(Stages) :
+ D3D12_SHADER_VISIBILITY_ALL;
}
} // namespace Diligent
diff --git a/Graphics/GraphicsEngineD3D12/src/PipelineResourceSignatureD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/PipelineResourceSignatureD3D12Impl.cpp
index dd257c2e..fe9f17f5 100644
--- a/Graphics/GraphicsEngineD3D12/src/PipelineResourceSignatureD3D12Impl.cpp
+++ b/Graphics/GraphicsEngineD3D12/src/PipelineResourceSignatureD3D12Impl.cpp
@@ -190,26 +190,99 @@ PipelineResourceSignatureD3D12Impl::PipelineResourceSignatureD3D12Impl(IReferenc
void PipelineResourceSignatureD3D12Impl::CreateLayout()
{
- const Uint32 FirstSpace = GetBaseRegisterSpace();
+ // Index of the assigned sampler, for every texture SRV in m_Desc.Resources, or InvalidSamplerInd.
+ std::vector<Uint32> TextureSrvToAssignedSamplerInd(m_Desc.NumResources, ResourceAttribs::InvalidSamplerInd);
+ // Index of the immutable sampler for every sampler in m_Desc.Resources, or -1.
+ std::vector<int> ResourceToImmutableSamplerInd(m_Desc.NumResources, -1);
+ for (Uint32 i = 0; i < m_Desc.NumResources; ++i)
+ {
+ const auto& ResDesc = m_Desc.Resources[i];
+
+ if (ResDesc.ResourceType == SHADER_RESOURCE_TYPE_SAMPLER)
+ {
+ // We only need to search for immutable samplers for SHADER_RESOURCE_TYPE_SAMPLER.
+ // For SHADER_RESOURCE_TYPE_TEXTURE_SRV, we will look for the assigned sampler and check if it is immutable.
+
+ // Note that FindImmutableSampler() below will work properly both when combined texture samplers are used and when not:
+ // - When combined texture samplers are used, sampler suffix will not be null,
+ // and we will be looking for the 'Texture_sampler' name.
+ // - When combined texture samplers are not used, sampler suffix will be null,
+ // and we will be looking for the sampler name itself.
+ const auto SrcImmutableSamplerInd = FindImmutableSampler(m_Desc.ImmutableSamplers, m_Desc.NumImmutableSamplers, ResDesc.ShaderStages,
+ ResDesc.Name, GetCombinedSamplerSuffix());
+ if (SrcImmutableSamplerInd >= 0)
+ {
+ ResourceToImmutableSamplerInd[i] = SrcImmutableSamplerInd;
+ // Set the immutable sampler array size to match the resource array size
+ auto& DstImtblSampAttribs = m_ImmutableSamplers[SrcImmutableSamplerInd];
+ // One immutable sampler may be used by different arrays in different shader stages - use the maximum array size
+ DstImtblSampAttribs.ArraySize = std::max(DstImtblSampAttribs.ArraySize, ResDesc.ArraySize);
+ }
+ }
- std::array<Uint32, D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER + 1> NumResources = {};
+ if (ResDesc.ResourceType == SHADER_RESOURCE_TYPE_TEXTURE_SRV)
+ {
+ TextureSrvToAssignedSamplerInd[i] = FindAssignedSampler(ResDesc);
+ }
+ }
+
+ // The total number of resources (counting array size), for every descriptor range type
+ std::array<Uint32, D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER + 1> NumResources = {};
+ // Static resource cache table sizes
std::array<Uint32, D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER + 1> StaticResCacheTblSizes = {};
+ // Allocate registers for immutable samplers first
+ for (Uint32 i = 0; i < m_Desc.NumImmutableSamplers; ++i)
+ {
+ auto& ImmutableSampler = m_ImmutableSamplers[i];
+
+ constexpr auto DescriptorRangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER;
+
+ ImmutableSampler.RegisterSpace = 0;
+ ImmutableSampler.ShaderRegister = NumResources[DescriptorRangeType];
+ NumResources[DescriptorRangeType] += ImmutableSampler.ArraySize;
+ }
+
+
RootParamsBuilder ParamsBuilder;
+
+ Uint32 NextRTSizedArraySpace = 1;
for (Uint32 i = 0; i < m_Desc.NumResources; ++i)
{
const auto& ResDesc = m_Desc.Resources[i];
-
VERIFY(i == 0 || ResDesc.VarType >= m_Desc.Resources[i - 1].VarType, "Resources must be sorted by variable type");
- const bool IsRuntimeSizedArray = (ResDesc.Flags & PIPELINE_RESOURCE_FLAG_RUNTIME_ARRAY) != 0;
- const auto DescriptorRangeType = ResourceTypeToD3D12DescriptorRangeType(ResDesc.ResourceType);
- Uint32 Register = IsRuntimeSizedArray ? 0 : NumResources[DescriptorRangeType];
- Uint32 Space = (IsRuntimeSizedArray ? m_NumSpaces++ : 0);
- Uint32 SRBRootIndex = ResourceAttribs::InvalidSRBRootIndex;
- Uint32 SRBOffsetFromTableStart = ResourceAttribs::InvalidOffset;
- Uint32 SigRootIndex = ResourceAttribs::InvalidSigRootIndex;
- Uint32 SigOffsetFromTableStart = ResourceAttribs::InvalidOffset;
+ auto AssignedSamplerInd = TextureSrvToAssignedSamplerInd[i];
+ auto SrcImmutableSamplerInd = ResourceToImmutableSamplerInd[i];
+ if (AssignedSamplerInd != ResourceAttribs::InvalidSamplerInd)
+ {
+ VERIFY_EXPR(ResDesc.ResourceType == SHADER_RESOURCE_TYPE_TEXTURE_SRV);
+ SrcImmutableSamplerInd = ResourceToImmutableSamplerInd[AssignedSamplerInd];
+ if (SrcImmutableSamplerInd >= 0)
+ AssignedSamplerInd = ResourceAttribs::InvalidSamplerInd;
+ }
+
+ const auto DescriptorRangeType = ResourceTypeToD3D12DescriptorRangeType(ResDesc.ResourceType);
+ Uint32 Register = 0;
+ Uint32 Space = 0;
+ if ((ResDesc.Flags & PIPELINE_RESOURCE_FLAG_RUNTIME_ARRAY) != 0)
+ {
+ // All run-time sized arrays are allocated in separate spaces.
+ Space = NextRTSizedArraySpace++;
+ Register = 0;
+ }
+ else
+ {
+ // Normal resources go into space 0.
+ Space = 0;
+ Register = NumResources[DescriptorRangeType];
+ NumResources[DescriptorRangeType] += ResDesc.ArraySize;
+ }
+
+ Uint32 SRBRootIndex = ResourceAttribs::InvalidSRBRootIndex;
+ Uint32 SRBOffsetFromTableStart = ResourceAttribs::InvalidOffset;
+ Uint32 SigRootIndex = ResourceAttribs::InvalidSigRootIndex;
+ Uint32 SigOffsetFromTableStart = ResourceAttribs::InvalidOffset;
if (ResDesc.VarType == SHADER_RESOURCE_VARIABLE_TYPE_STATIC)
{
@@ -218,59 +291,49 @@ void PipelineResourceSignatureD3D12Impl::CreateLayout()
// UAVs at root index D3D12_DESCRIPTOR_RANGE_TYPE_UAV (1)
// CBVs at root index D3D12_DESCRIPTOR_RANGE_TYPE_CBV (2)
// Samplers at root index D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER (3)
- SigRootIndex = ResourceTypeToD3D12DescriptorRangeType(ResDesc.ResourceType);
+ SigRootIndex = DescriptorRangeType;
SigOffsetFromTableStart = StaticResCacheTblSizes[SigRootIndex];
StaticResCacheTblSizes[SigRootIndex] += ResDesc.ArraySize;
}
- const bool IsBuffer =
- ResDesc.ResourceType == SHADER_RESOURCE_TYPE_CONSTANT_BUFFER ||
- ResDesc.ResourceType == SHADER_RESOURCE_TYPE_BUFFER_SRV ||
- ResDesc.ResourceType == SHADER_RESOURCE_TYPE_BUFFER_UAV;
- const bool UseDynamicOffset = (ResDesc.Flags & PIPELINE_RESOURCE_FLAG_NO_DYNAMIC_BUFFERS) == 0;
- const bool IsFormattedBuffer = (ResDesc.Flags & PIPELINE_RESOURCE_FLAG_FORMATTED_BUFFER) != 0;
- const bool IsRootView = IsBuffer && UseDynamicOffset && !IsFormattedBuffer;
-
- // runtime sized array must be in separate space
- if (!IsRuntimeSizedArray)
- NumResources[DescriptorRangeType] += ResDesc.ArraySize;
-
- const Int32 SrcImmutableSamplerInd = ResDesc.ResourceType == SHADER_RESOURCE_TYPE_SAMPLER ?
- FindImmutableSampler(m_Desc.ImmutableSamplers, m_Desc.NumImmutableSamplers, ResDesc.ShaderStages, ResDesc.Name, GetCombinedSamplerSuffix()) :
- -1;
-
- const auto AssignedSamplerInd = (SrcImmutableSamplerInd == -1 && ResDesc.ResourceType == SHADER_RESOURCE_TYPE_TEXTURE_SRV) ?
- FindAssignedSampler(ResDesc) :
- ResourceAttribs::InvalidSamplerInd;
-
- if (SrcImmutableSamplerInd >= 0)
+ auto d3d12RootParamType = static_cast<D3D12_ROOT_PARAMETER_TYPE>(D3D12_ROOT_PARAMETER_TYPE_UAV + 1);
+ // Do not allocate resource slot for immutable samplers that are also defined as resource
+ if (!(ResDesc.ResourceType == SHADER_RESOURCE_TYPE_SAMPLER && SrcImmutableSamplerInd >= 0))
{
- auto& ImmutableSampler = m_ImmutableSamplers[SrcImmutableSamplerInd];
+ const auto UseDynamicOffset = (ResDesc.Flags & PIPELINE_RESOURCE_FLAG_NO_DYNAMIC_BUFFERS) == 0;
+ const auto IsFormattedBuffer = (ResDesc.Flags & PIPELINE_RESOURCE_FLAG_FORMATTED_BUFFER) != 0;
- if (!ImmutableSampler.IsAssigned())
- {
- ImmutableSampler.ShaderRegister = Register;
- ImmutableSampler.RegisterSpace = Space;
- ImmutableSampler.ArraySize = ResDesc.ArraySize;
- }
- else
+ d3d12RootParamType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
+ switch (ResDesc.ResourceType)
{
- Register = ImmutableSampler.ShaderRegister;
- Space = ImmutableSampler.RegisterSpace;
+ case SHADER_RESOURCE_TYPE_CONSTANT_BUFFER:
+ VERIFY(!IsFormattedBuffer, "Constant buffers can't be labeled as formatted. This error should've been cuaght by ValidatePipelineResourceSignatureDesc().");
+ d3d12RootParamType = UseDynamicOffset ? D3D12_ROOT_PARAMETER_TYPE_CBV : D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
+ break;
- VERIFY_EXPR(ResDesc.ArraySize == ImmutableSampler.ArraySize);
+ case SHADER_RESOURCE_TYPE_BUFFER_SRV:
+ d3d12RootParamType = UseDynamicOffset && !IsFormattedBuffer ? D3D12_ROOT_PARAMETER_TYPE_SRV : D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
+ break;
- // Use previous bind point and decrease resource counter
- if (!IsRuntimeSizedArray)
- NumResources[DescriptorRangeType] -= ResDesc.ArraySize;
+ case SHADER_RESOURCE_TYPE_BUFFER_UAV:
+ d3d12RootParamType = UseDynamicOffset && !IsFormattedBuffer ? D3D12_ROOT_PARAMETER_TYPE_UAV : D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
+ break;
+
+ default:
+ d3d12RootParamType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
}
+
+ ParamsBuilder.AllocateResourceSlot(ResDesc.ShaderStages, ResDesc.VarType, d3d12RootParamType,
+ DescriptorRangeType, ResDesc.ArraySize, Register, Space, SRBRootIndex,
+ SRBOffsetFromTableStart);
}
else
{
- ParamsBuilder.AllocateResourceSlot(ResDesc.ShaderStages, ResDesc.VarType,
- IsRootView ? D3D12_ROOT_PARAMETER_TYPE_CBV : D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE,
- DescriptorRangeType, ResDesc.ArraySize, Register, FirstSpace + Space, SRBRootIndex,
- SRBOffsetFromTableStart);
+ const auto& ImtblSamAttribs = GetImmutableSamplerAttribs(SrcImmutableSamplerInd);
+ VERIFY_EXPR(ImtblSamAttribs.IsValid());
+ // Initialize space and register, which are required for register remapping
+ Space = ImtblSamAttribs.RegisterSpace;
+ Register = ImtblSamAttribs.ShaderRegister;
}
new (m_pResourceAttribs + i) ResourceAttribs //
@@ -283,25 +346,11 @@ void PipelineResourceSignatureD3D12Impl::CreateLayout()
SigRootIndex,
SigOffsetFromTableStart,
SrcImmutableSamplerInd >= 0,
- IsRootView //
+ d3d12RootParamType //
};
}
ParamsBuilder.InitializeMgr(GetRawAllocator(), m_RootParams);
- // Add immutable samplers that do not exist in m_Desc.Resources
- for (Uint32 i = 0; i < m_Desc.NumImmutableSamplers; ++i)
- {
- auto& ImmutableSampler = m_ImmutableSamplers[i];
- if (ImmutableSampler.IsAssigned())
- continue;
-
- const auto DescriptorRangeType = ResourceTypeToD3D12DescriptorRangeType(SHADER_RESOURCE_TYPE_SAMPLER);
-
- ImmutableSampler.RegisterSpace = 0;
- ImmutableSampler.ShaderRegister = NumResources[DescriptorRangeType];
- NumResources[DescriptorRangeType] += 1;
- }
-
if (m_Desc.SRBAllocationGranularity > 1)
{
std::array<size_t, MAX_SHADERS_IN_PIPELINE> ShaderVariableDataSizes = {};
@@ -1199,8 +1248,8 @@ struct BindResourceHelper
ShaderResourceCacheD3D12& ResourceCache;
#ifdef DILIGENT_DEBUG
- bool dbgIsDynamic = false;
- bool dbgIsRootView = false;
+ bool dbgIsDynamic = false;
+ D3D12_ROOT_PARAMETER_TYPE dbgParamType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
#endif
void BindResource(IDeviceObject* pObj) const;
@@ -1256,7 +1305,7 @@ void BindResourceHelper::CacheCB(IDeviceObject* pBuffer) const
}
else
{
- VERIFY(dbgIsRootView || dbgIsDynamic, "Descriptor in root table can be used only in dynamic tables.");
+ VERIFY(dbgParamType == D3D12_ROOT_PARAMETER_TYPE_CBV || dbgIsDynamic, "Descriptor in root table can be used only in dynamic tables.");
}
auto& BoundDynamicCBsCounter = ResourceCache.GetBoundDynamicCBsCounter();
@@ -1587,8 +1636,8 @@ void PipelineResourceSignatureD3D12Impl::BindResource(IDeviceObject*
ResourceCache};
#ifdef DILIGENT_DEBUG
- Helper.dbgIsDynamic = RootTable.IsDynamic();
- Helper.dbgIsRootView = Attribs.IsRootView != 0;
+ Helper.dbgIsDynamic = RootTable.IsDynamic();
+ Helper.dbgParamType = Attribs.GetD3D12RootParamType();
#endif
Helper.BindResource(pObj);
diff --git a/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp
index ca0d0fb8..149b0678 100644
--- a/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp
+++ b/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp
@@ -527,6 +527,7 @@ void PipelineStateD3D12Impl::InitRootSignature(const PipelineStateCreateInfo& Cr
}
else
{
+ // TODO: move to base class
const auto PipelineType = CreateInfo.PSODesc.PipelineType;
for (Uint32 i = 0; i < SignatureCount; ++i)
{
@@ -581,7 +582,7 @@ void PipelineStateD3D12Impl::InitRootSignature(const PipelineStateCreateInfo& Cr
auto* pSignature = GetSignature(Sig);
if (pSignature != nullptr)
{
- const Uint32 FirstSpace = pSignature->GetBaseRegisterSpace();
+ const Uint32 FirstSpace = m_RootSig->GetFirstRegisterSpace(Sig);
for (Uint32 r = 0, ResCount = pSignature->GetTotalResourceCount(); r < ResCount; ++r)
{
@@ -605,14 +606,21 @@ void PipelineStateD3D12Impl::InitRootSignature(const PipelineStateCreateInfo& Cr
{
HasImtblSampArray = HasImtblSampArray || (SampAttr.ArraySize > 1);
- auto IsUnique = ResourceMap.emplace(HashMapStringKey{ImtblSam.SamplerOrTextureName}, BindInfo).second;
- if (!IsUnique && pSignature->IsUsingCombinedSamplers())
- {
- // add sampler with suffix
- String SampName{ImtblSam.SamplerOrTextureName};
+ String SampName{ImtblSam.SamplerOrTextureName};
+ if (pSignature->IsUsingCombinedSamplers())
SampName += pSignature->GetCombinedSamplerSuffix();
- ResourceMap.emplace(HashMapStringKey{SampName}, BindInfo);
+
+ auto it_inserted = ResourceMap.emplace(HashMapStringKey{SampName}, BindInfo);
+#ifdef DILIGENT_DEBUG
+ if (!it_inserted.second)
+ {
+ const auto& ExistingBindInfo = it_inserted.first->second;
+ VERIFY(ExistingBindInfo.BindPoint == BindInfo.BindPoint,
+ "Bind point defined by the immutable sampler attribs is inconsistent with the bind point defined by the sampler resource.");
+ VERIFY(ExistingBindInfo.Space == BindInfo.Space,
+ "Register space defined by the immutable sampler attribs is inconsistent with the bind point defined by the sampler resource.");
}
+#endif
}
}
}
@@ -980,7 +988,7 @@ PipelineStateD3D12Impl::PipelineStateD3D12Impl(IReferenceCounters*
D3D12_GLOBAL_ROOT_SIGNATURE GlobalRoot = {m_RootSig->GetD3D12RootSignature()};
Subobjects.push_back({D3D12_STATE_SUBOBJECT_TYPE_GLOBAL_ROOT_SIGNATURE, &GlobalRoot});
- D3D12_LOCAL_ROOT_SIGNATURE LocalRoot = {LocalRootSig.Create(pd3d12Device)};
+ D3D12_LOCAL_ROOT_SIGNATURE LocalRoot = {LocalRootSig.Create(pd3d12Device, m_RootSig->GetTotalSpaces())};
if (LocalRoot.pLocalRootSignature)
Subobjects.push_back({D3D12_STATE_SUBOBJECT_TYPE_LOCAL_ROOT_SIGNATURE, &LocalRoot});
diff --git a/Graphics/GraphicsEngineD3D12/src/RootSignature.cpp b/Graphics/GraphicsEngineD3D12/src/RootSignature.cpp
index 32a63841..a794f4fe 100644
--- a/Graphics/GraphicsEngineD3D12/src/RootSignature.cpp
+++ b/Graphics/GraphicsEngineD3D12/src/RootSignature.cpp
@@ -84,104 +84,132 @@ void RootSignatureD3D12::Finalize()
rootSignatureDesc.Flags = D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT;
Uint32 TotalParams = 0;
- Uint32 TotalD3D12StaticSamplers = 0;
-
+ Uint32 Totald3d12StaticSamplers = 0;
+ Uint32 TotalDescriptorRanges = 0;
for (Uint32 s = 0; s < m_SignatureCount; ++s)
{
auto& pSignature = m_Signatures[s];
- if (pSignature != nullptr)
- {
- auto& RootParams = pSignature->m_RootParams;
+ if (pSignature == nullptr)
+ continue;
- m_FirstRootIndex[s] = TotalParams;
- TotalParams += RootParams.GetNumRootTables() + RootParams.GetNumRootViews();
+ auto& RootParams = pSignature->m_RootParams;
- for (Uint32 samp = 0, SampCount = pSignature->GetImmutableSamplerCount(); samp < SampCount; ++samp)
- {
- const auto& ImtblSam = pSignature->GetImmutableSamplerAttribs(samp);
- VERIFY_EXPR(ImtblSam.IsAssigned());
+ m_FirstRootIndex[s] = static_cast<Uint16>(TotalParams);
+ TotalParams += RootParams.GetNumRootTables() + RootParams.GetNumRootViews();
- TotalD3D12StaticSamplers += ImtblSam.ArraySize;
- }
+ for (Uint32 rt = 0; rt < RootParams.GetNumRootTables(); ++rt)
+ {
+ const auto& RootTable = RootParams.GetRootTable(rt);
+ TotalDescriptorRanges += RootTable.d3d12RootParam.DescriptorTable.NumDescriptorRanges;
+ }
+
+ for (Uint32 samp = 0, SampCount = pSignature->GetImmutableSamplerCount(); samp < SampCount; ++samp)
+ {
+ const auto& ImtblSam = pSignature->GetImmutableSamplerAttribs(samp);
+ VERIFY_EXPR(ImtblSam.IsValid());
+
+ Totald3d12StaticSamplers += ImtblSam.ArraySize;
}
}
- std::vector<D3D12_ROOT_PARAMETER, STDAllocatorRawMem<D3D12_ROOT_PARAMETER>> D3D12Parameters(TotalParams, D3D12_ROOT_PARAMETER{}, STD_ALLOCATOR_RAW_MEM(D3D12_ROOT_PARAMETER, GetRawAllocator(), "Allocator for vector<D3D12_ROOT_PARAMETER>"));
- std::vector<D3D12_STATIC_SAMPLER_DESC, STDAllocatorRawMem<D3D12_STATIC_SAMPLER_DESC>> D3D12StaticSamplers(STD_ALLOCATOR_RAW_MEM(D3D12_STATIC_SAMPLER_DESC, GetRawAllocator(), "Allocator for vector<D3D12_STATIC_SAMPLER_DESC>"));
- D3D12StaticSamplers.reserve(TotalD3D12StaticSamplers);
+ std::vector<D3D12_ROOT_PARAMETER, STDAllocatorRawMem<D3D12_ROOT_PARAMETER>> d3d12Parameters(TotalParams, D3D12_ROOT_PARAMETER{}, STD_ALLOCATOR_RAW_MEM(D3D12_ROOT_PARAMETER, GetRawAllocator(), "Allocator for vector<D3D12_ROOT_PARAMETER>"));
+ std::vector<D3D12_DESCRIPTOR_RANGE, STDAllocatorRawMem<D3D12_DESCRIPTOR_RANGE>> d3d12DescrRanges(TotalDescriptorRanges, D3D12_DESCRIPTOR_RANGE{}, STD_ALLOCATOR_RAW_MEM(D3D12_DESCRIPTOR_RANGE, GetRawAllocator(), "Allocator for vector<D3D12_DESCRIPTOR_RANGE>"));
+ std::vector<D3D12_STATIC_SAMPLER_DESC, STDAllocatorRawMem<D3D12_STATIC_SAMPLER_DESC>> d3d12StaticSamplers(STD_ALLOCATOR_RAW_MEM(D3D12_STATIC_SAMPLER_DESC, GetRawAllocator(), "Allocator for vector<D3D12_STATIC_SAMPLER_DESC>"));
+ d3d12StaticSamplers.reserve(Totald3d12StaticSamplers);
+ auto descr_range_it = d3d12DescrRanges.begin();
+
+ Uint32 BaseRegisterSpace = 0;
for (Uint32 sig = 0; sig < m_SignatureCount; ++sig)
{
- auto& pSignature = m_Signatures[sig];
+ m_FirstRegisterSpace[sig] = static_cast<Uint16>(BaseRegisterSpace);
- if (pSignature != nullptr)
- {
- const auto FirstRootIndex = m_FirstRootIndex[sig];
- const Uint32 FirstSpace = pSignature->GetBaseRegisterSpace();
+ const auto& pSignature = m_Signatures[sig];
+ if (pSignature == nullptr)
+ continue;
- auto& RootParams = pSignature->m_RootParams;
- for (Uint32 rt = 0; rt < RootParams.GetNumRootTables(); ++rt)
- {
- const auto& RootTable = RootParams.GetRootTable(rt);
- const auto& SrcParam = RootTable.d3d12RootParam;
- const Uint32 RootIndex = FirstRootIndex + RootTable.RootIndex;
- VERIFY(SrcParam.ParameterType == D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE && SrcParam.DescriptorTable.NumDescriptorRanges > 0, "Non-empty descriptor table is expected");
- D3D12Parameters[RootIndex] = SrcParam;
- }
+ const auto& RootParams = pSignature->m_RootParams;
+ const auto FirstRootIndex = m_FirstRootIndex[sig];
- for (Uint32 rv = 0; rv < RootParams.GetNumRootViews(); ++rv)
+ Uint32 MaxSpaceUsed = 0;
+ for (Uint32 rt = 0; rt < RootParams.GetNumRootTables(); ++rt)
+ {
+ const auto& RootTable = RootParams.GetRootTable(rt);
+ const auto& d3d12SrcParam = RootTable.d3d12RootParam;
+ const auto& d3d12SrcTbl = d3d12SrcParam.DescriptorTable;
+ const Uint32 RootIndex = FirstRootIndex + RootTable.RootIndex;
+ VERIFY(d3d12SrcParam.ParameterType == D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE && d3d12SrcParam.DescriptorTable.NumDescriptorRanges > 0, "Non-empty descriptor table is expected");
+ auto& d3d12DstParam = d3d12Parameters[RootIndex];
+ auto& d3d12DstTbl = d3d12DstParam.DescriptorTable;
+
+ d3d12DstParam = d3d12SrcParam;
+ memcpy(&*descr_range_it, d3d12SrcTbl.pDescriptorRanges, d3d12SrcTbl.NumDescriptorRanges * sizeof(D3D12_DESCRIPTOR_RANGE));
+ d3d12DstTbl.pDescriptorRanges = &*descr_range_it;
+ for (Uint32 r = 0; r < d3d12SrcTbl.NumDescriptorRanges; ++r, ++descr_range_it)
{
- const auto& RootView = RootParams.GetRootView(rv);
- const auto& SrcParam = RootView.d3d12RootParam;
- const Uint32 RootIndex = FirstRootIndex + RootView.RootIndex;
- VERIFY(SrcParam.ParameterType == D3D12_ROOT_PARAMETER_TYPE_CBV, "Root CBV is expected");
- D3D12Parameters[RootIndex] = SrcParam;
+ MaxSpaceUsed = std::max(MaxSpaceUsed, descr_range_it->RegisterSpace);
+ descr_range_it->RegisterSpace += BaseRegisterSpace;
}
+ }
+
+ for (Uint32 rv = 0; rv < RootParams.GetNumRootViews(); ++rv)
+ {
+ const auto& RootView = RootParams.GetRootView(rv);
+ const auto& d3d12SrcParam = RootView.d3d12RootParam;
+ const Uint32 RootIndex = FirstRootIndex + RootView.RootIndex;
+ VERIFY(d3d12SrcParam.ParameterType == D3D12_ROOT_PARAMETER_TYPE_CBV, "Root CBV is expected");
+ MaxSpaceUsed = std::max(MaxSpaceUsed, d3d12SrcParam.Descriptor.RegisterSpace);
+
+ d3d12Parameters[RootIndex] = d3d12SrcParam;
+ d3d12Parameters[RootIndex].Descriptor.RegisterSpace += BaseRegisterSpace;
+ }
+
+ for (Uint32 samp = 0, SampCount = pSignature->GetImmutableSamplerCount(); samp < SampCount; ++samp)
+ {
+ const auto& SampAttr = pSignature->GetImmutableSamplerAttribs(samp);
+ const auto& ImtblSam = pSignature->GetImmutableSamplerDesc(samp);
+ const auto& SamDesc = ImtblSam.Desc;
- for (Uint32 samp = 0, SampCount = pSignature->GetImmutableSamplerCount(); samp < SampCount; ++samp)
+ for (UINT ArrInd = 0; ArrInd < SampAttr.ArraySize; ++ArrInd)
{
- const auto& SampAttr = pSignature->GetImmutableSamplerAttribs(samp);
- const auto& ImtblSam = pSignature->GetImmutableSamplerDesc(samp);
- const auto& SamDesc = ImtblSam.Desc;
-
- for (UINT ArrInd = 0; ArrInd < SampAttr.ArraySize; ++ArrInd)
- {
- D3D12_SHADER_VISIBILITY ShaderVisibility = (ImtblSam.ShaderStages & (ImtblSam.ShaderStages - 1)) == 0 ?
- ShaderTypeToD3D12ShaderVisibility(ImtblSam.ShaderStages) :
- D3D12_SHADER_VISIBILITY_ALL;
-
- D3D12StaticSamplers.emplace_back(
- D3D12_STATIC_SAMPLER_DESC //
- {
- FilterTypeToD3D12Filter(SamDesc.MinFilter, SamDesc.MagFilter, SamDesc.MipFilter),
- TexAddressModeToD3D12AddressMode(SamDesc.AddressU),
- TexAddressModeToD3D12AddressMode(SamDesc.AddressV),
- TexAddressModeToD3D12AddressMode(SamDesc.AddressW),
- SamDesc.MipLODBias,
- SamDesc.MaxAnisotropy,
- ComparisonFuncToD3D12ComparisonFunc(SamDesc.ComparisonFunc),
- BorderColorToD3D12StaticBorderColor(SamDesc.BorderColor),
- SamDesc.MinLOD,
- SamDesc.MaxLOD,
- SampAttr.ShaderRegister + ArrInd,
- SampAttr.RegisterSpace + FirstSpace,
- ShaderVisibility //
- } //
- );
- }
+ auto ShaderVisibility = ShaderStagesToD3D12ShaderVisibility(ImtblSam.ShaderStages);
+
+ d3d12StaticSamplers.emplace_back(
+ D3D12_STATIC_SAMPLER_DESC //
+ {
+ FilterTypeToD3D12Filter(SamDesc.MinFilter, SamDesc.MagFilter, SamDesc.MipFilter),
+ TexAddressModeToD3D12AddressMode(SamDesc.AddressU),
+ TexAddressModeToD3D12AddressMode(SamDesc.AddressV),
+ TexAddressModeToD3D12AddressMode(SamDesc.AddressW),
+ SamDesc.MipLODBias,
+ SamDesc.MaxAnisotropy,
+ ComparisonFuncToD3D12ComparisonFunc(SamDesc.ComparisonFunc),
+ BorderColorToD3D12StaticBorderColor(SamDesc.BorderColor),
+ SamDesc.MinLOD,
+ SamDesc.MaxLOD,
+ SampAttr.ShaderRegister + ArrInd,
+ SampAttr.RegisterSpace + BaseRegisterSpace,
+ ShaderVisibility //
+ } //
+ );
}
}
+
+ BaseRegisterSpace += MaxSpaceUsed + 1;
}
+ m_TotalSpacesUsed = BaseRegisterSpace;
+
+ VERIFY_EXPR(descr_range_it == d3d12DescrRanges.end());
- rootSignatureDesc.NumParameters = static_cast<UINT>(D3D12Parameters.size());
- rootSignatureDesc.pParameters = D3D12Parameters.size() ? D3D12Parameters.data() : nullptr;
+ rootSignatureDesc.NumParameters = static_cast<UINT>(d3d12Parameters.size());
+ rootSignatureDesc.pParameters = d3d12Parameters.size() ? d3d12Parameters.data() : nullptr;
- rootSignatureDesc.NumStaticSamplers = TotalD3D12StaticSamplers;
+ rootSignatureDesc.NumStaticSamplers = Totald3d12StaticSamplers;
rootSignatureDesc.pStaticSamplers = nullptr;
- if (!D3D12StaticSamplers.empty())
+ if (!d3d12StaticSamplers.empty())
{
- rootSignatureDesc.pStaticSamplers = D3D12StaticSamplers.data();
- VERIFY_EXPR(D3D12StaticSamplers.size() == TotalD3D12StaticSamplers);
+ rootSignatureDesc.pStaticSamplers = d3d12StaticSamplers.data();
+ VERIFY_EXPR(d3d12StaticSamplers.size() == Totald3d12StaticSamplers);
}
CComPtr<ID3DBlob> signature;
@@ -220,11 +248,13 @@ bool LocalRootSignatureD3D12::IsShaderRecord(const D3DShaderResourceAttribs& CB)
return false;
}
-ID3D12RootSignature* LocalRootSignatureD3D12::Create(ID3D12Device* pDevice)
+ID3D12RootSignature* LocalRootSignatureD3D12::Create(ID3D12Device* pDevice, Uint32 RegisterSpace)
{
if (m_ShaderRecordSize == 0)
return nullptr;
+ m_RegisterSpace = RegisterSpace;
+
VERIFY(m_pd3d12RootSignature == nullptr, "This root signature is already created");
D3D12_ROOT_SIGNATURE_DESC d3d12RootSignatureDesc = {};
@@ -233,7 +263,7 @@ ID3D12RootSignature* LocalRootSignatureD3D12::Create(ID3D12Device* pDevice)
d3d12Params.ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS;
d3d12Params.ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
d3d12Params.Constants.Num32BitValues = m_ShaderRecordSize / 4;
- d3d12Params.Constants.RegisterSpace = GetRegisterSpace();
+ d3d12Params.Constants.RegisterSpace = m_RegisterSpace;
d3d12Params.Constants.ShaderRegister = GetShaderRegister();
d3d12RootSignatureDesc.Flags = D3D12_ROOT_SIGNATURE_FLAG_LOCAL_ROOT_SIGNATURE;