@@ -144,13 +144,14 @@ size_t RootParameter::GetHash() const
144144
145145RootParamsManager::~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
150150bool 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+
246274RootParameter& 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+
273317RootParamsBuilder::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 ();
0 commit comments