Diligent Engine API Reference: D:/GitHub/DiligentEngine/DiligentCore/Graphics/GraphicsEngineD3D12/include/RootSignature.h Source File

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
161 class RootSignature
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 {
288 StaticSamplerDesc SamplerDesc;
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 }
Diligent::IShader
Shader interface.
Definition: Shader.h:288
Diligent::SHADER_TYPE
SHADER_TYPE
Describes the shader type.
Definition: Shader.h:46
Diligent::RootSignature
Implementation of the Diligent::RootSignature class.
Definition: RootSignature.h:161
Diligent
Namespace for the OpenGL implementation of the graphics engine.
Definition: BufferD3D11Impl.h:34
Diligent::StaticSamplerDesc
Static sampler description.
Definition: Shader.h:136
Diligent::SamplerDesc
Sampler description.
Definition: Sampler.h:52
Diligent::SHADER_VARIABLE_TYPE
SHADER_VARIABLE_TYPE
Describes shader variable type that is used by ShaderVariableDesc.
Definition: Shader.h:100
Diligent::SHADER_VARIABLE_TYPE_NUM_TYPES
Total number of shader variable types.
Definition: Shader.h:117
Diligent::RenderDeviceD3D12Impl
Implementation of the Diligent::IRenderDeviceD3D12 interface.
Definition: RenderDeviceD3D12Impl.h:43