Diligent Engine API Reference
RootSignature.h
1 /* Copyright 2015-2018 Egor Yusov
2  *
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
10  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
11  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS.
12  *
13  * In no event and under no legal theory, whether in tort (including negligence),
14  * contract, or otherwise, unless required by applicable law (such as deliberate
15  * and grossly negligent acts) or agreed to in writing, shall any Contributor be
16  * liable for any damages, including any direct, indirect, special, incidental,
17  * or consequential damages of any character arising as a result of this License or
18  * out of the use or inability to use the software (including but not limited to damages
19  * for loss of goodwill, work stoppage, computer failure or malfunction, or any and
20  * all other commercial damages or losses), even if such Contributor has been advised
21  * of the possibility of such damages.
22  */
23 
24 #pragma once
25 
28 #include "ShaderD3DBase.h"
29 #include "ShaderResourceLayoutD3D12.h"
30 
31 namespace Diligent
32 {
33 
34 SHADER_TYPE ShaderTypeFromShaderVisibility(D3D12_SHADER_VISIBILITY ShaderVisibility);
35 D3D12_SHADER_VISIBILITY GetShaderVisibility(SHADER_TYPE ShaderType);
36 D3D12_DESCRIPTOR_HEAP_TYPE dbgHeapTypeFromRangeType(D3D12_DESCRIPTOR_RANGE_TYPE RangeType);
37 
38 class RootParameter
39 {
40 public:
41 
42  RootParameter(D3D12_ROOT_PARAMETER_TYPE ParameterType, Uint32 RootIndex, UINT Register, UINT RegisterSpace, D3D12_SHADER_VISIBILITY Visibility, SHADER_VARIABLE_TYPE VarType) :
43  m_RootIndex(RootIndex),
44  m_ShaderVarType(VarType)
45  {
46  VERIFY(ParameterType == D3D12_ROOT_PARAMETER_TYPE_CBV || ParameterType == D3D12_ROOT_PARAMETER_TYPE_SRV || ParameterType == D3D12_ROOT_PARAMETER_TYPE_UAV, "Unexpected parameter type - verify argument list");
47  m_RootParam.ParameterType = ParameterType;
48  m_RootParam.ShaderVisibility = Visibility;
49  m_RootParam.Descriptor.ShaderRegister = Register;
50  m_RootParam.Descriptor.RegisterSpace = RegisterSpace;
51  }
52 
53  RootParameter( D3D12_ROOT_PARAMETER_TYPE ParameterType, Uint32 RootIndex, UINT Register, UINT RegisterSpace, UINT NumDwords, D3D12_SHADER_VISIBILITY Visibility, SHADER_VARIABLE_TYPE VarType) :
54  m_RootIndex(RootIndex),
55  m_ShaderVarType(VarType)
56  {
57  VERIFY(ParameterType == D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS, "Unexpected parameter type - verify argument list");
58  m_RootParam.ParameterType = ParameterType;
59  m_RootParam.ShaderVisibility = Visibility;
60  m_RootParam.Constants.Num32BitValues = NumDwords;
61  m_RootParam.Constants.ShaderRegister = Register;
62  m_RootParam.Constants.RegisterSpace = RegisterSpace;
63  }
64 
65  RootParameter( D3D12_ROOT_PARAMETER_TYPE ParameterType, Uint32 RootIndex, UINT NumRanges, D3D12_DESCRIPTOR_RANGE *pRanges, D3D12_SHADER_VISIBILITY Visibility, SHADER_VARIABLE_TYPE VarType) :
66  m_RootIndex(RootIndex),
67  m_ShaderVarType(VarType)
68  {
69  VERIFY(ParameterType == D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE, "Unexpected parameter type - verify argument list");
70  VERIFY_EXPR(pRanges != nullptr);
71  m_RootParam.ParameterType = ParameterType;
72  m_RootParam.ShaderVisibility = Visibility;
73  m_RootParam.DescriptorTable.NumDescriptorRanges = NumRanges;
74  m_RootParam.DescriptorTable.pDescriptorRanges = pRanges;
75 #ifdef _DEBUG
76  for(Uint32 r=0; r < NumRanges; ++r)
77  pRanges[r].RangeType = static_cast<D3D12_DESCRIPTOR_RANGE_TYPE>(-1);
78 #endif
79  }
80 
81  RootParameter(const RootParameter &RP):
82  m_RootParam( RP.m_RootParam),
83  m_DescriptorTableSize(RP.m_DescriptorTableSize),
84  m_ShaderVarType(RP.m_ShaderVarType),
85  m_RootIndex(RP.m_RootIndex)
86  {
87  VERIFY(m_RootParam.ParameterType != D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE, "Use another constructor to copy descriptor table");
88  }
89 
90  RootParameter(const RootParameter &RP, UINT NumRanges, D3D12_DESCRIPTOR_RANGE *pRanges):
91  m_RootParam( RP.m_RootParam),
92  m_DescriptorTableSize(RP.m_DescriptorTableSize),
93  m_ShaderVarType(RP.m_ShaderVarType),
94  m_RootIndex(RP.m_RootIndex)
95  {
96  VERIFY(m_RootParam.ParameterType == D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE, "Root parameter is expected to be a descriptor table");
97  VERIFY(NumRanges >= m_RootParam.DescriptorTable.NumDescriptorRanges, "New table must be larger than source one");
98  auto &DstTbl = m_RootParam.DescriptorTable;
99  DstTbl.NumDescriptorRanges = NumRanges;
100  DstTbl.pDescriptorRanges = pRanges;
101  const auto &SrcTbl = RP.m_RootParam.DescriptorTable;
102  memcpy(pRanges, SrcTbl.pDescriptorRanges, SrcTbl.NumDescriptorRanges * sizeof(D3D12_DESCRIPTOR_RANGE));
103 #ifdef _DEBUG
104  {
105  Uint32 dbgTableSize = 0;
106  for (Uint32 r = 0; r < SrcTbl.NumDescriptorRanges; ++r)
107  {
108  const auto &Range = SrcTbl.pDescriptorRanges[r];
109  dbgTableSize = std::max(dbgTableSize, Range.OffsetInDescriptorsFromTableStart + Range.NumDescriptors);
110  }
111  VERIFY(dbgTableSize == m_DescriptorTableSize, "Incorrect descriptor table size");
112 
113  for (Uint32 r = SrcTbl.NumDescriptorRanges; r < DstTbl.NumDescriptorRanges; ++r)
114  pRanges[r].RangeType = static_cast<D3D12_DESCRIPTOR_RANGE_TYPE>(-1);
115  }
116 #endif
117  }
118 
119  RootParameter& operator = (const RootParameter &RP) = delete;
120  RootParameter& operator = (RootParameter &&RP) = delete;
121 
122  void SetDescriptorRange( UINT RangeIndex, D3D12_DESCRIPTOR_RANGE_TYPE Type, UINT Register, UINT Count, UINT Space = 0, UINT OffsetFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND)
123  {
124  VERIFY(m_RootParam.ParameterType == D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE, "Incorrect parameter table: descriptor table is expected");
125  auto &Tbl = m_RootParam.DescriptorTable;
126  VERIFY(RangeIndex < Tbl.NumDescriptorRanges, "Invalid descriptor range index");
127  D3D12_DESCRIPTOR_RANGE &range = const_cast<D3D12_DESCRIPTOR_RANGE &>(Tbl.pDescriptorRanges[RangeIndex]);
128  VERIFY(range.RangeType == static_cast<D3D12_DESCRIPTOR_RANGE_TYPE>(-1), "Descriptor range has already been initialized. m_DescriptorTableSize may be updated incorrectly");
129  range.RangeType = Type;
130  range.NumDescriptors = Count;
131  range.BaseShaderRegister = Register;
132  range.RegisterSpace = Space;
133  range.OffsetInDescriptorsFromTableStart = OffsetFromTableStart;
134  m_DescriptorTableSize = std::max(m_DescriptorTableSize, OffsetFromTableStart + Count);
135  }
136 
137  SHADER_VARIABLE_TYPE GetShaderVariableType()const{ return m_ShaderVarType; }
138  Uint32 GetDescriptorTableSize()const
139  {
140  VERIFY(m_RootParam.ParameterType == D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE, "Incorrect parameter table: descriptor table is expected");
141  return m_DescriptorTableSize;
142  }
143  D3D12_SHADER_VISIBILITY GetShaderVisibility()const{return m_RootParam.ShaderVisibility;}
144  D3D12_ROOT_PARAMETER_TYPE GetParameterType()const{return m_RootParam.ParameterType;}
145 
146  Uint32 GetRootIndex()const{return m_RootIndex;}
147 
148  operator const D3D12_ROOT_PARAMETER&()const{return m_RootParam;}
149 
150 private:
151 
152  SHADER_VARIABLE_TYPE m_ShaderVarType = static_cast<SHADER_VARIABLE_TYPE>(-1);
153  D3D12_ROOT_PARAMETER m_RootParam = {};
154  Uint32 m_DescriptorTableSize = 0;
155  Uint32 m_RootIndex = static_cast<Uint32>(-1);
156 };
157 
158 
159 
162 {
163 public:
164  RootSignature();
165 
166  void AllocateStaticSamplers(IShader* const *ppShaders, Uint32 NumShaders);
167 
168  void Finalize(ID3D12Device *pd3d12Device);
169 
170  ID3D12RootSignature* GetD3D12RootSignature()const{return m_pd3d12RootSignature;}
171  void InitResourceCache(class RenderDeviceD3D12Impl *pDeviceD3D12Impl, class ShaderResourceCacheD3D12& ResourceCache, IMemoryAllocator &CacheMemAllocator)const;
172 
173  void InitStaticSampler(SHADER_TYPE ShaderType, const String &TextureName, const D3DShaderResourceAttribs &ShaderResAttribs);
174 
175  void AllocateResourceSlot(SHADER_TYPE ShaderType, const D3DShaderResourceAttribs &ShaderResAttribs, D3D12_DESCRIPTOR_RANGE_TYPE RangeType, Uint32 &RootIndex, Uint32 &OffsetFromTableStart);
176 
177  // This method should be thread-safe as it does not modify any object state
178  void (RootSignature::*CommitDescriptorHandles)(class RenderDeviceD3D12Impl *pRenderDeviceD3D12,
179  ShaderResourceCacheD3D12& ResourceCache,
180  class CommandContext &Ctx,
181  bool IsCompute)const = nullptr;
182 
183  void (RootSignature::*TransitionAndCommitDescriptorHandles)(class RenderDeviceD3D12Impl *pRenderDeviceD3D12,
184  ShaderResourceCacheD3D12& ResourceCache,
185  class CommandContext &Ctx,
186  bool IsCompute)const = nullptr;
187 
188  void TransitionResources(ShaderResourceCacheD3D12& ResourceCache,
189  class CommandContext &Ctx)const;
190 
191  void CommitRootViews(ShaderResourceCacheD3D12& ResourceCache,
192  class CommandContext &Ctx,
193  bool IsCompute,
194  Uint32 ContextId)const;
195 
196  Uint32 GetTotalSrvCbvUavSlots(SHADER_VARIABLE_TYPE VarType)const
197  {
198  VERIFY_EXPR(VarType >= 0 && VarType < SHADER_VARIABLE_TYPE_NUM_TYPES);
199  return m_TotalSrvCbvUavSlots[VarType];
200  }
201  Uint32 GetTotalSamplerSlots(SHADER_VARIABLE_TYPE VarType)const
202  {
203  VERIFY_EXPR(VarType >= 0 && VarType < SHADER_VARIABLE_TYPE_NUM_TYPES);
204  return m_TotalSamplerSlots[VarType];
205  }
206 
207 private:
208 #ifdef _DEBUG
209  void dbgVerifyRootParameters()const;
210 #endif
211 
212  Uint32 m_TotalSrvCbvUavSlots[SHADER_VARIABLE_TYPE_NUM_TYPES];
213  Uint32 m_TotalSamplerSlots[SHADER_VARIABLE_TYPE_NUM_TYPES];
214 
215  CComPtr<ID3D12RootSignature> m_pd3d12RootSignature;
216 
217  class RootParamsManager
218  {
219  public:
220  RootParamsManager(IMemoryAllocator &MemAllocator);
221 
222  RootParamsManager(const RootParamsManager&) = delete;
223  RootParamsManager& operator= (const RootParamsManager&) = delete;
224  RootParamsManager(RootParamsManager&&) = delete;
225  RootParamsManager& operator= (RootParamsManager&&) = delete;
226 
227  Uint32 GetNumRootTables()const{return m_NumRootTables;}
228  Uint32 GetNumRootViews()const{return m_NumRootViews;}
229 
230  const RootParameter& GetRootTable(Uint32 TableInd)const
231  {
232  VERIFY_EXPR(TableInd < m_NumRootTables);
233  return m_pRootTables[TableInd];
234  }
235 
236  RootParameter& GetRootTable(Uint32 TableInd)
237  {
238  VERIFY_EXPR(TableInd < m_NumRootTables);
239  return m_pRootTables[TableInd];
240  }
241 
242  const RootParameter& GetRootView(Uint32 ViewInd)const
243  {
244  VERIFY_EXPR(ViewInd < m_NumRootViews);
245  return m_pRootViews[ViewInd];
246  }
247 
248  RootParameter& GetRootView(Uint32 ViewInd)
249  {
250  VERIFY_EXPR(ViewInd < m_NumRootViews);
251  return m_pRootViews[ViewInd];
252  }
253 
254  void AddRootView(D3D12_ROOT_PARAMETER_TYPE ParameterType, Uint32 RootIndex, UINT Register, D3D12_SHADER_VISIBILITY Visibility, SHADER_VARIABLE_TYPE VarType);
255  void AddRootTable(Uint32 RootIndex, D3D12_SHADER_VISIBILITY Visibility, SHADER_VARIABLE_TYPE VarType, Uint32 NumRangesInNewTable = 1);
256  void AddDescriptorRanges(Uint32 RootTableInd, Uint32 NumExtraRanges = 1);
257 
258  template<class TOperation>
259  void ProcessRootTables(TOperation)const;
260 
261  private:
262  size_t GetRequiredMemorySize(Uint32 NumExtraRootTables, Uint32 NumExtraRootViews, Uint32 NumExtraDescriptorRanges)const;
263  D3D12_DESCRIPTOR_RANGE* Extend(Uint32 NumExtraRootTables, Uint32 NumExtraRootViews, Uint32 NumExtraDescriptorRanges, Uint32 RootTableToAddRanges = static_cast<Uint32>(-1));
264 
265  IMemoryAllocator &m_MemAllocator;
266  std::unique_ptr<void, STDDeleter<void, IMemoryAllocator>> m_pMemory;
267  Uint32 m_NumRootTables = 0;
268  Uint32 m_NumRootViews = 0;
269  Uint32 m_TotalDescriptorRanges = 0;
270  RootParameter *m_pRootTables = nullptr;
271  RootParameter *m_pRootViews = nullptr;
272  };
273 
274  static constexpr Uint8 InvalidRootTableIndex = static_cast<Uint8>(-1);
275 
276  // The array below contains array index of a CBV/SRV/UAV root table
277  // in m_RootParams (NOT the Root Index!), for every variable type
278  // (static, mutable, dynamic) and every shader type,
279  // or -1, if the table is not yet assigned to the combination
280  Uint8 m_SrvCbvUavRootTablesMap[SHADER_VARIABLE_TYPE_NUM_TYPES * 6];
281  // This array contains the same data for Sampler root table
282  Uint8 m_SamplerRootTablesMap[SHADER_VARIABLE_TYPE_NUM_TYPES * 6];
283 
284  RootParamsManager m_RootParams;
285 
286  struct StaticSamplerAttribs
287  {
289  UINT ShaderRegister = static_cast<UINT>(-1);
290  UINT ArraySize = 0;
291  UINT RegisterSpace = 0;
292  D3D12_SHADER_VISIBILITY ShaderVisibility = static_cast<D3D12_SHADER_VISIBILITY>(-1);
293 
294  StaticSamplerAttribs(){}
295  StaticSamplerAttribs(const StaticSamplerDesc& SamDesc, D3D12_SHADER_VISIBILITY Visibility) :
296  SamplerDesc(SamDesc),
297  ShaderVisibility(Visibility)
298  {}
299  };
300  // Note: sizeof(m_StaticSamplers) == 56 (MS compiler, release x64)
301  std::vector<StaticSamplerAttribs, STDAllocatorRawMem<StaticSamplerAttribs> > m_StaticSamplers;
302 
303  IMemoryAllocator &m_MemAllocator;
304 
305  // Commits descriptor handles for static and mutable variables
306  template<bool PerformResourceTransitions>
307  void CommitDescriptorHandlesInternal_SM(class RenderDeviceD3D12Impl *pRenderDeviceD3D12,
308  ShaderResourceCacheD3D12& ResourceCache,
309  class CommandContext &Ctx,
310  bool IsCompute)const;
311  template<bool PerformResourceTransitions>
312  // Commits descriptor handles for static, mutable, and dynamic variables
313  void CommitDescriptorHandlesInternal_SMD(class RenderDeviceD3D12Impl *pRenderDeviceD3D12,
314  ShaderResourceCacheD3D12& ResourceCache,
315  class CommandContext &Ctx,
316  bool IsCompute)const;
317 };
318 
319 }
Shader interface.
Definition: Shader.h:288
SHADER_TYPE
Describes the shader type.
Definition: Shader.h:46
Implementation of the Diligent::RootSignature class.
Definition: RootSignature.h:161
Namespace for the OpenGL implementation of the graphics engine.
Definition: BufferD3D11Impl.h:34
Static sampler description.
Definition: Shader.h:136
Sampler description.
Definition: Sampler.h:52
SHADER_VARIABLE_TYPE
Describes shader variable type that is used by ShaderVariableDesc.
Definition: Shader.h:100
Total number of shader variable types.
Definition: Shader.h:117
Implementation of the Diligent::IRenderDeviceD3D12 interface.
Definition: RenderDeviceD3D12Impl.h:43