Skip to content

Commit aea9cac

Browse files
D3D12/RootParamsManager: add support for root constants (#672)
1 parent 61f2358 commit aea9cac

File tree

4 files changed

+138
-29
lines changed

4 files changed

+138
-29
lines changed

Graphics/GraphicsEngineD3D12/include/PipelineResourceSignatureD3D12Impl.hpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ class PipelineResourceSignatureD3D12Impl final : public PipelineResourceSignatur
125125

126126
Uint32 GetTotalRootParamsCount() const
127127
{
128-
return m_RootParams.GetNumRootTables() + m_RootParams.GetNumRootViews();
128+
return m_RootParams.GetNumRootTables() + m_RootParams.GetNumRootViews() + m_RootParams.GetNumRootConstants();
129129
}
130130

131131
Uint32 GetNumRootTables() const
@@ -138,6 +138,11 @@ class PipelineResourceSignatureD3D12Impl final : public PipelineResourceSignatur
138138
return m_RootParams.GetNumRootViews();
139139
}
140140

141+
Uint32 GetNumRootConstants() const
142+
{
143+
return m_RootParams.GetNumRootConstants();
144+
}
145+
141146
void InitSRBResourceCache(ShaderResourceCacheD3D12& ResourceCache);
142147

143148
void CopyStaticResources(ShaderResourceCacheD3D12& ResourceCache) const;

Graphics/GraphicsEngineD3D12/include/RootParamsManager.hpp

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ class RootParamsManager
139139

140140
Uint32 GetNumRootTables() const { return m_NumRootTables; }
141141
Uint32 GetNumRootViews() const { return m_NumRootViews; }
142+
Uint32 GetNumRootConstants() const { return m_NumRootConstants; }
142143

143144
const RootParameter& GetRootTable(Uint32 TableInd) const
144145
{
@@ -152,6 +153,12 @@ class RootParamsManager
152153
return m_pRootViews[ViewInd];
153154
}
154155

156+
const RootParameter& GetRootConstants(Uint32 ConstInd) const
157+
{
158+
VERIFY_EXPR(ConstInd < m_NumRootConstants);
159+
return m_pRootConstants[ConstInd];
160+
}
161+
155162
// Returns the total number of resources in a given parameter group and descriptor heap type
156163
Uint32 GetParameterGroupSize(D3D12_DESCRIPTOR_HEAP_TYPE d3d12HeapType, ROOT_PARAMETER_GROUP Group) const
157164
{
@@ -169,11 +176,18 @@ class RootParamsManager
169176

170177
std::unique_ptr<void, STDDeleter<void, IMemoryAllocator>> m_pMemory;
171178

179+
// The number of root tables
172180
Uint32 m_NumRootTables = 0;
173-
Uint32 m_NumRootViews = 0;
174181

175-
const RootParameter* m_pRootTables = nullptr;
176-
const RootParameter* m_pRootViews = nullptr;
182+
// The number of root views
183+
Uint32 m_NumRootViews = 0;
184+
185+
// The number of root constant parameters (not the number of 32-bit constants)
186+
Uint32 m_NumRootConstants = 0;
187+
188+
const RootParameter* m_pRootTables = nullptr;
189+
const RootParameter* m_pRootViews = nullptr;
190+
const RootParameter* m_pRootConstants = nullptr;
177191

178192
// The total number of resources placed in descriptor tables for each heap type and parameter group type
179193
std::array<std::array<Uint32, ROOT_PARAMETER_GROUP_COUNT>, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER + 1> m_ParameterGroupSizes{};
@@ -206,6 +220,14 @@ class RootParamsBuilder
206220
D3D12_SHADER_VISIBILITY Visibility,
207221
ROOT_PARAMETER_GROUP RootType);
208222

223+
// Adds a new root constants parameter and returns the reference to it.
224+
RootParameter& AddRootConstants(Uint32 RootIndex,
225+
UINT Register,
226+
UINT RegisterSpace,
227+
UINT Num32BitValues,
228+
D3D12_SHADER_VISIBILITY Visibility,
229+
ROOT_PARAMETER_GROUP RootType);
230+
209231
struct RootTableData;
210232
// Adds a new root table parameter and returns the reference to it.
211233
RootTableData& AddRootTable(Uint32 RootIndex,
@@ -214,6 +236,10 @@ class RootParamsBuilder
214236
Uint32 NumRangesInNewTable = 1);
215237

216238

239+
#ifdef DILIGENT_DEBUG
240+
void DbgCheckRootIndexUniqueness(Uint32 RootIndex) const;
241+
#endif
242+
217243
private:
218244
struct RootTableData
219245
{
@@ -231,6 +257,7 @@ class RootParamsBuilder
231257
};
232258
std::vector<RootTableData> m_RootTables;
233259
std::vector<RootParameter> m_RootViews;
260+
std::vector<RootParameter> m_RootConstants;
234261

235262
static constexpr int InvalidRootTableIndex = -1;
236263

Graphics/GraphicsEngineD3D12/src/RootParamsManager.cpp

Lines changed: 85 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -144,13 +144,14 @@ size_t RootParameter::GetHash() const
144144

145145
RootParamsManager::~RootParamsManager()
146146
{
147-
static_assert(std::is_trivially_destructible<RootParameter>::value, "Destructors for m_pRootTables and m_pRootViews are required");
147+
static_assert(std::is_trivially_destructible<RootParameter>::value, "m_pRootTables, m_pRootViews and m_pRootConstants must be manually destroyed");
148148
}
149149

150150
bool RootParamsManager::operator==(const RootParamsManager& RootParams) const noexcept
151151
{
152152
if (m_NumRootTables != RootParams.m_NumRootTables ||
153-
m_NumRootViews != RootParams.m_NumRootViews)
153+
m_NumRootViews != RootParams.m_NumRootViews ||
154+
m_NumRootConstants != RootParams.m_NumRootConstants)
154155
return false;
155156

156157
for (Uint32 rv = 0; rv < m_NumRootViews; ++rv)
@@ -169,6 +170,14 @@ bool RootParamsManager::operator==(const RootParamsManager& RootParams) const no
169170
return false;
170171
}
171172

173+
for (Uint32 rc = 0; rc < m_NumRootConstants; ++rc)
174+
{
175+
const RootParameter& RC0 = GetRootConstants(rc);
176+
const RootParameter& RC1 = RootParams.GetRootConstants(rc);
177+
if (RC0 != RC1)
178+
return false;
179+
}
180+
172181
return true;
173182
}
174183

@@ -230,6 +239,13 @@ void RootParamsManager::Validate() const
230239
VERIFY(RootView.TableOffsetInGroupAllocation == RootParameter::InvalidTableOffsetInGroupAllocation,
231240
"Root views must not be assigned to descriptor table allocations.");
232241
}
242+
243+
for (Uint32 i = 0; i < GetNumRootConstants(); ++i)
244+
{
245+
const RootParameter& RootConst = GetRootConstants(i);
246+
VERIFY(RootConst.TableOffsetInGroupAllocation == RootParameter::InvalidTableOffsetInGroupAllocation,
247+
"Root constants must not be assigned to descriptor table allocations.");
248+
}
233249
}
234250
#endif
235251

@@ -243,6 +259,18 @@ RootParamsBuilder::RootParamsBuilder()
243259
Map.fill(InvalidRootTableIndex);
244260
}
245261

262+
#ifdef DILIGENT_DEBUG
263+
void RootParamsBuilder::DbgCheckRootIndexUniqueness(Uint32 RootIndex) const
264+
{
265+
for (const RootTableData& RootTbl : m_RootTables)
266+
VERIFY(RootTbl.RootIndex != RootIndex, "Index ", RootIndex, " is already used by another root table");
267+
for (const RootParameter& RootView : m_RootViews)
268+
VERIFY(RootView.RootIndex != RootIndex, "Index ", RootIndex, " is already used by another root view");
269+
for (const RootParameter& RootConst : m_RootConstants)
270+
VERIFY(RootConst.RootIndex != RootIndex, "Index ", RootIndex, " is already used by another root constant");
271+
}
272+
#endif
273+
246274
RootParameter& RootParamsBuilder::AddRootView(D3D12_ROOT_PARAMETER_TYPE ParameterType,
247275
Uint32 RootIndex,
248276
UINT Register,
@@ -255,11 +283,7 @@ RootParameter& RootParamsBuilder::AddRootView(D3D12_ROOT_PARAMETER_TYPE Paramete
255283
ParameterType == D3D12_ROOT_PARAMETER_TYPE_SRV ||
256284
ParameterType == D3D12_ROOT_PARAMETER_TYPE_UAV),
257285
"Unexpected parameter type SBV, SRV or UAV is expected");
258-
259-
for (const RootTableData& RootTbl : m_RootTables)
260-
VERIFY(RootTbl.RootIndex != RootIndex, "Index ", RootIndex, " is already used by another root table");
261-
for (const RootParameter& RootView : m_RootViews)
262-
VERIFY(RootView.RootIndex != RootIndex, "Index ", RootIndex, " is already used by another root view");
286+
DbgCheckRootIndexUniqueness(RootIndex);
263287
#endif
264288

265289
D3D12_ROOT_PARAMETER d3d12RootParam{ParameterType, {}, Visibility};
@@ -270,6 +294,26 @@ RootParameter& RootParamsBuilder::AddRootView(D3D12_ROOT_PARAMETER_TYPE Paramete
270294
return m_RootViews.back();
271295
}
272296

297+
RootParameter& RootParamsBuilder::AddRootConstants(Uint32 RootIndex,
298+
UINT Register,
299+
UINT RegisterSpace,
300+
UINT Num32BitValues,
301+
D3D12_SHADER_VISIBILITY Visibility,
302+
ROOT_PARAMETER_GROUP RootType)
303+
{
304+
#ifdef DILIGENT_DEBUG
305+
DbgCheckRootIndexUniqueness(RootIndex);
306+
#endif
307+
308+
D3D12_ROOT_PARAMETER d3d12RootParam{D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS, {}, Visibility};
309+
d3d12RootParam.Constants.ShaderRegister = Register;
310+
d3d12RootParam.Constants.RegisterSpace = RegisterSpace;
311+
d3d12RootParam.Constants.Num32BitValues = Num32BitValues;
312+
m_RootConstants.emplace_back(RootIndex, RootType, d3d12RootParam);
313+
314+
return m_RootConstants.back();
315+
}
316+
273317
RootParamsBuilder::RootTableData::RootTableData(Uint32 _RootIndex,
274318
D3D12_SHADER_VISIBILITY _Visibility,
275319
ROOT_PARAMETER_GROUP _Group,
@@ -305,10 +349,7 @@ RootParamsBuilder::RootTableData& RootParamsBuilder::AddRootTable(Uint32
305349
Uint32 NumRangesInNewTable)
306350
{
307351
#ifdef DILIGENT_DEBUG
308-
for (const RootTableData& RootTbl : m_RootTables)
309-
VERIFY(RootTbl.RootIndex != RootIndex, "Index ", RootIndex, " is already used by another root table");
310-
for (const RootParameter& RootView : m_RootViews)
311-
VERIFY(RootView.RootIndex != RootIndex, "Index ", RootIndex, " is already used by another root view");
352+
DbgCheckRootIndexUniqueness(RootIndex);
312353
#endif
313354

314355
m_RootTables.emplace_back(RootIndex, Visibility, Group, NumRangesInNewTable);
@@ -330,8 +371,8 @@ void RootParamsBuilder::AllocateResourceSlot(SHADER_TYPE Shade
330371
const D3D12_SHADER_VISIBILITY ShaderVisibility = ShaderStagesToD3D12ShaderVisibility(ShaderStages);
331372
const ROOT_PARAMETER_GROUP ParameterGroup = VariableTypeToRootParameterGroup(VariableType);
332373

333-
// Get the next available root index past all allocated tables and root views
334-
RootIndex = static_cast<Uint32>(m_RootTables.size() + m_RootViews.size());
374+
// Get the next available root index past all allocated tables, root views and root constants
375+
RootIndex = static_cast<Uint32>(m_RootTables.size() + m_RootViews.size() + m_RootConstants.size());
335376

336377
if (RootParameterType == D3D12_ROOT_PARAMETER_TYPE_CBV ||
337378
RootParameterType == D3D12_ROOT_PARAMETER_TYPE_SRV ||
@@ -345,6 +386,13 @@ void RootParamsBuilder::AllocateResourceSlot(SHADER_TYPE Shade
345386
// Add new root view to existing root parameters
346387
AddRootView(RootParameterType, RootIndex, Register, Space, ShaderVisibility, ParameterGroup);
347388
}
389+
else if (RootParameterType == D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS)
390+
{
391+
OffsetFromTableStart = 0;
392+
393+
// Add new 32-bit constants parameter to existing root parameters
394+
AddRootConstants(RootIndex, Register, Space, ArraySize, ShaderVisibility, ParameterGroup);
395+
}
348396
else if (RootParameterType == D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE)
349397
{
350398
const bool IsSampler = (RangeType == D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER);
@@ -406,15 +454,17 @@ void RootParamsBuilder::InitializeMgr(IMemoryAllocator& MemAllocator, RootParams
406454
{
407455
VERIFY(!ParamsMgr.m_pMemory, "Params manager has already been initialized!");
408456

409-
Uint32& NumRootTables = ParamsMgr.m_NumRootTables;
410-
Uint32& NumRootViews = ParamsMgr.m_NumRootViews;
457+
Uint32& NumRootTables = ParamsMgr.m_NumRootTables;
458+
Uint32& NumRootViews = ParamsMgr.m_NumRootViews;
459+
Uint32& NumRootConstants = ParamsMgr.m_NumRootConstants;
411460

412-
NumRootTables = static_cast<Uint32>(m_RootTables.size());
413-
NumRootViews = static_cast<Uint32>(m_RootViews.size());
414-
if (NumRootTables == 0 && NumRootViews == 0)
461+
NumRootTables = static_cast<Uint32>(m_RootTables.size());
462+
NumRootViews = static_cast<Uint32>(m_RootViews.size());
463+
NumRootConstants = static_cast<Uint32>(m_RootConstants.size());
464+
if (NumRootTables == 0 && NumRootViews == 0 && NumRootConstants == 0)
415465
return;
416466

417-
const size_t TotalRootParamsCount = m_RootTables.size() + m_RootViews.size();
467+
const size_t TotalRootParamsCount = m_RootTables.size() + m_RootViews.size() + m_RootConstants.size();
418468

419469
size_t TotalRangesCount = 0;
420470
for (RootTableData& Tbl : m_RootTables)
@@ -437,7 +487,8 @@ void RootParamsBuilder::InitializeMgr(IMemoryAllocator& MemAllocator, RootParams
437487
// Note: this order is more efficient than views->tables->ranges
438488
RootParameter* const pRootTables = reinterpret_cast<RootParameter*>(ParamsMgr.m_pMemory.get());
439489
RootParameter* const pRootViews = pRootTables + NumRootTables;
440-
D3D12_DESCRIPTOR_RANGE* const pDescriptorRanges = reinterpret_cast<D3D12_DESCRIPTOR_RANGE*>(pRootViews + NumRootViews);
490+
RootParameter* const pRootConstants = pRootViews + NumRootViews;
491+
D3D12_DESCRIPTOR_RANGE* const pDescriptorRanges = reinterpret_cast<D3D12_DESCRIPTOR_RANGE*>(pRootConstants + NumRootConstants);
441492

442493
// Copy descriptor tables
443494
D3D12_DESCRIPTOR_RANGE* pCurrDescrRangePtr = pDescriptorRanges;
@@ -484,8 +535,20 @@ void RootParamsBuilder::InitializeMgr(IMemoryAllocator& MemAllocator, RootParams
484535
"Unexpected parameter type: SBV, SRV or UAV is expected");
485536
new (pRootViews + rv) RootParameter{SrcView.RootIndex, SrcView.Group, d3d12RootParam};
486537
}
487-
ParamsMgr.m_pRootTables = NumRootTables != 0 ? pRootTables : nullptr;
488-
ParamsMgr.m_pRootViews = NumRootViews != 0 ? pRootViews : nullptr;
538+
539+
// Copy root constants
540+
for (Uint32 rc = 0; rc < NumRootConstants; ++rc)
541+
{
542+
const RootParameter& SrcConst = m_RootConstants[rc];
543+
const D3D12_ROOT_PARAMETER& d3d12RootParam = SrcConst.d3d12RootParam;
544+
VERIFY(d3d12RootParam.ParameterType == D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS,
545+
"Unexpected parameter type: 32-bit constants is expected");
546+
new (pRootConstants + rc) RootParameter{SrcConst.RootIndex, SrcConst.Group, d3d12RootParam};
547+
}
548+
549+
ParamsMgr.m_pRootTables = NumRootTables != 0 ? pRootTables : nullptr;
550+
ParamsMgr.m_pRootViews = NumRootViews != 0 ? pRootViews : nullptr;
551+
ParamsMgr.m_pRootConstants = NumRootConstants != 0 ? pRootConstants : nullptr;
489552

490553
#ifdef DILIGENT_DEBUG
491554
ParamsMgr.Validate();

Graphics/GraphicsEngineD3D12/src/RootSignature.cpp

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ RootSignatureD3D12::RootSignatureD3D12(IReferenceCounters*
7878
const RootParamsManager& RootParams = pSignature->GetRootParams();
7979

8080
SignInfo.BaseRootIndex = TotalParams;
81-
TotalParams += RootParams.GetNumRootTables() + RootParams.GetNumRootViews();
81+
TotalParams += RootParams.GetNumRootTables() + RootParams.GetNumRootViews() + RootParams.GetNumRootConstants();
8282

8383
for (Uint32 rt = 0; rt < RootParams.GetNumRootTables(); ++rt)
8484
{
@@ -166,6 +166,20 @@ RootSignatureD3D12::RootSignatureD3D12(IReferenceCounters*
166166
d3d12Parameters[RootIndex].Descriptor.RegisterSpace += BaseRegisterSpace;
167167
}
168168

169+
for (Uint32 rc = 0; rc < RootParams.GetNumRootConstants(); ++rc)
170+
{
171+
const RootParameter& RootConsts = RootParams.GetRootConstants(rc);
172+
const D3D12_ROOT_PARAMETER& d3d12SrcParam = RootConsts.d3d12RootParam;
173+
const Uint32 RootIndex = SignInfo.BaseRootIndex + RootConsts.RootIndex;
174+
VERIFY(d3d12SrcParam.ParameterType == D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS, "Root 32-bit constants is expected");
175+
176+
MaxSpaceUsed = std::max(MaxSpaceUsed, d3d12SrcParam.Constants.RegisterSpace);
177+
178+
d3d12Parameters[RootIndex] = d3d12SrcParam;
179+
// Offset register space value by the base register space of the current resource signature.
180+
d3d12Parameters[RootIndex].Constants.RegisterSpace += BaseRegisterSpace;
181+
}
182+
169183
for (Uint32 samp = 0, SampCount = pSignature->GetImmutableSamplerCount(); samp < SampCount; ++samp)
170184
{
171185
const ImmutableSamplerAttribsD3D12& SampAttr = pSignature->GetImmutableSamplerAttribs(samp);
@@ -191,8 +205,8 @@ RootSignatureD3D12::RootSignatureD3D12(IReferenceCounters*
191205
SamDesc.MaxLOD,
192206
SampAttr.ShaderRegister + ArrInd,
193207
SampAttr.RegisterSpace + BaseRegisterSpace,
194-
ShaderVisibility //
195-
} //
208+
ShaderVisibility,
209+
} //
196210
);
197211
}
198212
}

0 commit comments

Comments
 (0)