git.s-ol.nu ~forks/DiligentCore / 7f26e40
PSO refactoring for ray tracing azhirnov 10 months ago
81 changed file(s) with 3700 addition(s) and 1494 deletion(s). Raw diff Collapse all Expand all
1919 interface/HashUtils.hpp
2020 interface/LockHelper.hpp
2121 interface/LinearAllocator.hpp
22 interface/DynamicLinearAllocator.hpp
2223 interface/MemoryFileStream.hpp
2324 interface/ObjectBase.hpp
2425 interface/RefCntAutoPtr.hpp
3132 interface/Timer.hpp
3233 interface/UniqueIdentifier.hpp
3334 interface/ValidatedCast.hpp
35 interface/Definitions.hpp
3436 )
3537
3638 set(SOURCE
3232 #pragma once
3333
3434 #include "PlatformDefinitions.h"
35 #include "Definitions.hpp"
3536 #include "BasicTypes.h"
3637 #include "Errors.hpp"
3738 #include "FileWrapper.hpp"
4242 return val > 0 && (val & (val - 1)) == 0;
4343 }
4444
45 template <typename T>
46 inline T Align(T val, T alignment)
45 template <typename T1, typename T2>
46 inline typename std::conditional<sizeof(T1) >= sizeof(T2), T1, T2>::type Align(T1 val, T2 alignment)
4747 {
48 static_assert(std::is_unsigned<T1>::value == std::is_unsigned<T2>::value, "both types must be signed or unsigned");
49 static_assert(!std::is_pointer<T1>::value && !std::is_pointer<T2>::value, "types must not be pointers");
4850 VERIFY(IsPowerOfTwo(alignment), "Alignment (", alignment, ") must be power of 2");
49 return (val + (alignment - 1)) & ~(alignment - 1);
51
52 using T = typename std::conditional<sizeof(T1) >= sizeof(T2), T1, T2>::type;
53 return (static_cast<T>(val) + static_cast<T>(alignment - 1)) & ~static_cast<T>(alignment - 1);
5054 }
5155
52 template <typename T>
53 inline T* Align(T* val, size_t alignment)
56 template <typename PtrType, typename AlignType>
57 inline PtrType* Align(PtrType* val, AlignType alignment)
5458 {
55 return reinterpret_cast<T*>(Align(reinterpret_cast<uintptr_t>(val), static_cast<uintptr_t>(alignment)));
59 return reinterpret_cast<PtrType*>(Align(reinterpret_cast<uintptr_t>(val), static_cast<uintptr_t>(alignment)));
5660 }
5761
58 template <typename T>
59 inline T AlignDown(T val, T alignment)
62 template <typename T1, typename T2>
63 inline typename std::conditional<sizeof(T1) >= sizeof(T2), T1, T2>::type AlignDown(T1 val, T2 alignment)
6064 {
65 static_assert(std::is_unsigned<T1>::value == std::is_unsigned<T2>::value, "both types must be signed or unsigned");
66 static_assert(!std::is_pointer<T1>::value && !std::is_pointer<T2>::value, "types must not be pointers");
6167 VERIFY(IsPowerOfTwo(alignment), "Alignment (", alignment, ") must be power of 2");
62 return val & ~(alignment - 1);
68
69 using T = typename std::conditional<sizeof(T1) >= sizeof(T2), T1, T2>::type;
70 return static_cast<T>(val) & ~static_cast<T>(alignment - 1);
6371 }
6472
65 template <typename T>
66 inline T* AlignDown(T* val, size_t alignment)
73 template <typename PtrType, typename AlignType>
74 inline PtrType* AlignDown(PtrType* val, AlignType alignment)
6775 {
68 return reinterpret_cast<T*>(AlignDown(reinterpret_cast<uintptr_t>(val), static_cast<uintptr_t>(alignment)));
76 return reinterpret_cast<PtrType*>(AlignDown(reinterpret_cast<uintptr_t>(val), static_cast<uintptr_t>(alignment)));
6977 }
7078
7179 } // namespace Diligent
0 /*
1 * Copyright 2019-2020 Diligent Graphics LLC
2 * Copyright 2015-2019 Egor Yusov
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 * In no event and under no legal theory, whether in tort (including negligence),
17 * contract, or otherwise, unless required by applicable law (such as deliberate
18 * and grossly negligent acts) or agreed to in writing, shall any Contributor be
19 * liable for any damages, including any direct, indirect, special, incidental,
20 * or consequential damages of any character arising as a result of this License or
21 * out of the use or inability to use the software (including but not limited to damages
22 * for loss of goodwill, work stoppage, computer failure or malfunction, or any and
23 * all other commercial damages or losses), even if such Contributor has been advised
24 * of the possibility of such damages.
25 */
26
27 #pragma once
28
29 #ifdef _MSC_VER
30 # if _MSC_VER >= 1917
31 # define NDDISCARD [[nodiscard]]
32 # else
33 # define NDDISCARD
34 # endif
35 #endif // _MSC_VER
36
37 #ifdef __clang__
38 # if __has_feature(cxx_attributes)
39 # define NDDISCARD [[nodiscard]]
40 # else
41 # define NDDISCARD
42 # endif
43 #endif // __clang__
44
45 #ifdef __GNUC__
46 # if __has_cpp_attribute(nodiscard)
47 # define NDDISCARD [[nodiscard]]
48 # else
49 # define NDDISCARD
50 # endif
51 #endif // __GNUC__
0 /*
1 * Copyright 2019-2020 Diligent Graphics LLC
2 * Copyright 2015-2019 Egor Yusov
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 * In no event and under no legal theory, whether in tort (including negligence),
17 * contract, or otherwise, unless required by applicable law (such as deliberate
18 * and grossly negligent acts) or agreed to in writing, shall any Contributor be
19 * liable for any damages, including any direct, indirect, special, incidental,
20 * or consequential damages of any character arising as a result of this License or
21 * out of the use or inability to use the software (including but not limited to damages
22 * for loss of goodwill, work stoppage, computer failure or malfunction, or any and
23 * all other commercial damages or losses), even if such Contributor has been advised
24 * of the possibility of such damages.
25 */
26
27 #pragma once
28
29 /// \file
30 /// Defines Diligent::DynamicLinearAllocator class
31
32 #include <vector>
33
34 #include "../../Primitives/interface/BasicTypes.h"
35 #include "../../Primitives/interface/MemoryAllocator.h"
36 #include "../../Platforms/Basic/interface/DebugUtilities.hpp"
37 #include "Definitions.hpp"
38 #include "Align.hpp"
39
40 namespace Diligent
41 {
42
43 /// Implementation of a linear allocator on a fixed memory pages
44 class DynamicLinearAllocator
45 {
46 public:
47 // clang-format off
48 DynamicLinearAllocator (const DynamicLinearAllocator&) = delete;
49 DynamicLinearAllocator (DynamicLinearAllocator&&) = delete;
50 DynamicLinearAllocator& operator=(const DynamicLinearAllocator&) = delete;
51 DynamicLinearAllocator& operator=(DynamicLinearAllocator&&) = delete;
52 // clang-format on
53
54 explicit DynamicLinearAllocator(IMemoryAllocator& Allocator, Uint32 BlockSize = 4 << 10) :
55 m_pAllocator{&Allocator},
56 m_BlockSize{BlockSize}
57 {}
58
59 ~DynamicLinearAllocator()
60 {
61 Free();
62 }
63
64 void Free()
65 {
66 for (auto& block : m_Blocks)
67 {
68 m_pAllocator->Free(block.Page);
69 }
70 m_Blocks.clear();
71
72 m_pAllocator = nullptr;
73 }
74
75 void Discard()
76 {
77 for (auto& block : m_Blocks)
78 {
79 block.Size = 0;
80 }
81 }
82
83 NDDISCARD void* Allocate(size_t size, size_t align)
84 {
85 if (size == 0)
86 return nullptr;
87
88 for (auto& block : m_Blocks)
89 {
90 size_t offset = Align(reinterpret_cast<size_t>(block.Page) + block.Size, align) - reinterpret_cast<size_t>(block.Page);
91
92 if (size <= (block.Capacity - offset))
93 {
94 block.Size = offset + size;
95 return block.Page + offset;
96 }
97 }
98
99 // create new block
100 size_t BlockSize = m_BlockSize;
101 BlockSize = size * 2 < BlockSize ? BlockSize : size * 2;
102 m_Blocks.emplace_back(m_pAllocator->Allocate(BlockSize, "dynamic linear allocator page", __FILE__, __LINE__), 0, BlockSize);
103
104 auto& block = m_Blocks.back();
105 size_t offset = Align(reinterpret_cast<size_t>(block.Page), align) - reinterpret_cast<size_t>(block.Page);
106 block.Size = offset + size;
107 return block.Page + offset;
108 }
109
110 template <typename T>
111 NDDISCARD T* Allocate(size_t count = 1)
112 {
113 return reinterpret_cast<T*>(Allocate(sizeof(T) * count, alignof(T)));
114 }
115
116 template <typename T, typename... Args>
117 NDDISCARD T* Construct(Args&&... args)
118 {
119 T* Ptr = Allocate<T>(1);
120 new (Ptr) T{std::forward<Args>(args)...};
121 return Ptr;
122 }
123
124 template <typename T, typename... Args>
125 NDDISCARD T* ConstructArray(size_t count, const Args&... args)
126 {
127 T* Ptr = Allocate<T>(count);
128 for (size_t i = 0; i < count; ++i)
129 {
130 new (Ptr + i) T{args...};
131 }
132 return Ptr;
133 }
134
135 template <typename T>
136 NDDISCARD T* CopyArray(const T* Src, size_t count)
137 {
138 T* Dst = Allocate<T>(count);
139 for (size_t i = 0; i < count; ++i)
140 {
141 new (Dst + i) T{Src[i]};
142 }
143 return Dst;
144 }
145
146 NDDISCARD Char* CopyString(const Char* Str)
147 {
148 if (Str == nullptr)
149 return nullptr;
150
151 size_t len = strlen(Str) + 1;
152 Char* Dst = Allocate<Char>(len + 1);
153 std::memcpy(Dst, Str, sizeof(Char) * len);
154 Dst[len] = 0;
155 return Dst;
156 }
157
158 NDDISCARD wchar_t* CopyWString(const char* Str)
159 {
160 if (Str == nullptr)
161 return nullptr;
162
163 size_t len = strlen(Str) + 1;
164 auto* Dst = Allocate<wchar_t>(len + 1);
165 for (size_t i = 0; i < len; ++i)
166 {
167 Dst[i] = static_cast<wchar_t>(Str[i]);
168 }
169 Dst[len] = 0;
170 return Dst;
171 }
172
173 NDDISCARD Char* CopyString(const String& Str)
174 {
175 size_t len = Str.length() + 1;
176 Char* Dst = Allocate<Char>(len + 1);
177 std::memcpy(Dst, Str.c_str(), sizeof(Char) * len);
178 Dst[len] = 0;
179 return Dst;
180 }
181
182 private:
183 struct Block
184 {
185 uint8_t* Page = nullptr;
186 size_t Size = 0;
187 size_t Capacity = 0;
188
189 Block(void* _Page, size_t _Size, size_t _Capacity) :
190 Page{static_cast<uint8_t*>(_Page)}, Size{_Size}, Capacity{_Capacity} {}
191 };
192
193 std::vector<Block> m_Blocks;
194 Uint32 m_BlockSize = 4 << 10;
195 IMemoryAllocator* m_pAllocator = nullptr;
196 };
197
198 } // namespace Diligent
3434 #include "../../Primitives/interface/BasicTypes.h"
3535 #include "../../Primitives/interface/MemoryAllocator.h"
3636 #include "../../Platforms/Basic/interface/DebugUtilities.hpp"
37 #include "Definitions.hpp"
3738 #include "Align.hpp"
3839
3940 namespace Diligent
7980 Reset();
8081 }
8182
82 void* Release()
83 NDDISCARD void* Release()
8384 {
8485 void* Ptr = m_pDataStart;
8586 Reset();
8687 return Ptr;
8788 }
8889
89 void* ReleaseOwnership() noexcept
90 NDDISCARD void* ReleaseOwnership() noexcept
9091 {
9192 m_pAllocator = nullptr;
9293 return GetDataPtr();
9394 }
9495
95 void* GetDataPtr() const noexcept
96 NDDISCARD void* GetDataPtr() const noexcept
9697 {
9798 return m_pDataStart;
9899 }
167168 m_CurrAlignment = sizeof(void*);
168169 }
169170
170 void* Allocate(size_t size, size_t alignment)
171 NDDISCARD void* Allocate(size_t size, size_t alignment)
171172 {
172173 VERIFY(size == 0 || m_pDataStart != nullptr, "Memory has not been allocated");
173174 VERIFY(IsPowerOfTwo(alignment), "Alignment is not a power of two!");
200201 }
201202
202203 template <typename T>
203 T* Allocate(size_t count = 1)
204 NDDISCARD T* Allocate(size_t count = 1)
204205 {
205206 return reinterpret_cast<T*>(Allocate(sizeof(T) * count, alignof(T)));
206207 }
207208
208209 template <typename T, typename... Args>
209 T* Construct(Args&&... args)
210 NDDISCARD T* Construct(Args&&... args)
210211 {
211212 T* Ptr = Allocate<T>();
212213 new (Ptr) T{std::forward<Args>(args)...};
214215 }
215216
216217 template <typename T, typename... Args>
217 T* ConstructArray(size_t count, const Args&... args)
218 NDDISCARD T* ConstructArray(size_t count, const Args&... args)
218219 {
219220 T* Ptr = Allocate<T>(count);
220221 for (size_t i = 0; i < count; ++i)
225226 }
226227
227228 template <typename T>
228 T* Copy(const T& Src)
229 NDDISCARD T* Copy(const T& Src)
229230 {
230231 return Construct<T>(Src);
231232 }
232233
233234 template <typename T>
234 T* CopyArray(const T* Src, size_t count)
235 NDDISCARD T* CopyArray(const T* Src, size_t count)
235236 {
236237 T* Dst = Allocate<T>(count);
237238 for (size_t i = 0; i < count; ++i)
241242 return Dst;
242243 }
243244
244 Char* CopyString(const char* Str)
245 NDDISCARD Char* CopyString(const char* Str)
245246 {
246247 if (Str == nullptr)
247248 return nullptr;
263264 return Ptr;
264265 }
265266
266 Char* CopyString(const std::string& Str)
267 NDDISCARD Char* CopyString(const std::string& Str)
267268 {
268269 return CopyString(Str.c_str());
269270 }
270271
271 size_t GetCurrentSize() const
272 NDDISCARD size_t GetCurrentSize() const
272273 {
273274 return static_cast<size_t>(m_pCurrPtr - m_pDataStart);
274275 }
275276
276 size_t GetReservedSize() const
277 NDDISCARD size_t GetReservedSize() const
277278 {
278279 return m_ReservedSize;
279280 }
823823 static_assert(BIND_FLAGS_LAST == BIND_RAY_TRACING, "Please handle the new bind flag in the switch below");
824824 switch (BindFlag)
825825 {
826 // clang-format off
827 #define BIND_FLAG_STR_CASE(Flag) case Flag: return #Flag;
826 #define BIND_FLAG_STR_CASE(Flag) \
827 case Flag: return #Flag;
828828 BIND_FLAG_STR_CASE(BIND_VERTEX_BUFFER)
829 BIND_FLAG_STR_CASE(BIND_INDEX_BUFFER)
830 BIND_FLAG_STR_CASE(BIND_UNIFORM_BUFFER)
831 BIND_FLAG_STR_CASE(BIND_SHADER_RESOURCE)
832 BIND_FLAG_STR_CASE(BIND_STREAM_OUTPUT)
833 BIND_FLAG_STR_CASE(BIND_RENDER_TARGET)
834 BIND_FLAG_STR_CASE(BIND_DEPTH_STENCIL)
835 BIND_FLAG_STR_CASE(BIND_UNORDERED_ACCESS)
829 BIND_FLAG_STR_CASE(BIND_INDEX_BUFFER)
830 BIND_FLAG_STR_CASE(BIND_UNIFORM_BUFFER)
831 BIND_FLAG_STR_CASE(BIND_SHADER_RESOURCE)
832 BIND_FLAG_STR_CASE(BIND_STREAM_OUTPUT)
833 BIND_FLAG_STR_CASE(BIND_RENDER_TARGET)
834 BIND_FLAG_STR_CASE(BIND_DEPTH_STENCIL)
835 BIND_FLAG_STR_CASE(BIND_UNORDERED_ACCESS)
836836 BIND_FLAG_STR_CASE(BIND_INDIRECT_DRAW_ARGS)
837837 BIND_FLAG_STR_CASE(BIND_RAY_TRACING)
838 #undef BIND_FLAG_STR_CASE
839 // clang-format on
838 #undef BIND_FLAG_STR_CASE
840839 default: UNEXPECTED("Unexpected bind flag ", BindFlag); return "";
841840 }
842841 }
10861085
10871086 const char* GetQueryTypeString(QUERY_TYPE QueryType)
10881087 {
1088 static_assert(QUERY_TYPE_NUM_TYPES == 6, "Not all QUERY_TYPE enum values are handled");
10891089 // clang-format off
10901090 switch(QueryType)
10911091 {
10951095 case QUERY_TYPE_TIMESTAMP: return "QUERY_TYPE_TIMESTAMP";
10961096 case QUERY_TYPE_PIPELINE_STATISTICS: return "QUERY_TYPE_PIPELINE_STATISTICS";
10971097 case QUERY_TYPE_DURATION: return "QUERY_TYPE_DURATION";
1098
1099 static_assert(QUERY_TYPE_NUM_TYPES == 6, "Not all QUERY_TYPE enum values are handled");
11001098
11011099 default:
11021100 UNEXPECTED("Unepxected query type");
11331131
11341132 const char* GetPipelineTypeString(PIPELINE_TYPE PipelineType)
11351133 {
1134 static_assert(PIPELINE_TYPE_LAST == PIPELINE_TYPE_RAY_TRACING, "Please update this function to handle the new pipeline type");
11361135 // clang-format off
11371136 switch (PipelineType)
11381137 {
1139 case PIPELINE_TYPE_COMPUTE: return "compute";
1140 case PIPELINE_TYPE_GRAPHICS: return "graphics";
1141 case PIPELINE_TYPE_MESH: return "mesh";
1138 case PIPELINE_TYPE_COMPUTE: return "compute";
1139 case PIPELINE_TYPE_GRAPHICS: return "graphics";
1140 case PIPELINE_TYPE_MESH: return "mesh";
1141 case PIPELINE_TYPE_RAY_TRACING: return "ray tracing";
11421142
11431143 default:
11441144 UNEXPECTED("Unexpected pipeline type");
11491149
11501150 const char* GetShaderCompilerTypeString(SHADER_COMPILER Compiler)
11511151 {
1152 static_assert(SHADER_COMPILER_LAST == SHADER_COMPILER_FXC, "Please update this function to handle the new shader compiler");
1153 // clang-format off
11521154 switch (Compiler)
11531155 {
11541156 case SHADER_COMPILER_DEFAULT: return "Default";
11551157 case SHADER_COMPILER_GLSLANG: return "glslang";
1156 case SHADER_COMPILER_DXC: return "DXC";
1157 case SHADER_COMPILER_FXC: return "FXC";
1158 case SHADER_COMPILER_DXC: return "DXC";
1159 case SHADER_COMPILER_FXC: return "FXC";
11581160
11591161 default:
11601162 UNEXPECTED("Unexpected shader compiler");
11611163 return "UNKNOWN";
11621164 };
1165 // clang-format on
11631166 }
11641167
11651168 Uint32 ComputeMipLevelsCount(Uint32 Width)
13471350 case SHADER_TYPE_VERTEX: // Graphics
13481351 case SHADER_TYPE_AMPLIFICATION: // Mesh
13491352 case SHADER_TYPE_COMPUTE: // Compute
1353 case SHADER_TYPE_RAY_GEN: // RayTracing
13501354 return 0;
13511355
1352 case SHADER_TYPE_HULL: // Graphics
1353 case SHADER_TYPE_MESH: // Mesh
1356 case SHADER_TYPE_HULL: // Graphics
1357 case SHADER_TYPE_MESH: // Mesh
1358 case SHADER_TYPE_RAY_MISS: // RayTracing
13541359 return 1;
13551360
1356 case SHADER_TYPE_DOMAIN: // Graphics
1361 case SHADER_TYPE_DOMAIN: // Graphics
1362 case SHADER_TYPE_RAY_CLOSEST_HIT: // RayTracing
13571363 return 2;
13581364
1359 case SHADER_TYPE_GEOMETRY: // Graphics
1365 case SHADER_TYPE_GEOMETRY: // Graphics
1366 case SHADER_TYPE_RAY_ANY_HIT: // RayTracing
13601367 return 3;
13611368
1362 case SHADER_TYPE_PIXEL: // Graphics or Mesh
1369 case SHADER_TYPE_PIXEL: // Graphics or Mesh
1370 case SHADER_TYPE_RAY_INTERSECTION: // RayTracing
13631371 return 4;
13641372
1365 case SHADER_TYPE_RAY_GEN:
1366 case SHADER_TYPE_RAY_MISS:
1367 case SHADER_TYPE_RAY_CLOSEST_HIT:
1368 case SHADER_TYPE_RAY_ANY_HIT:
1369 case SHADER_TYPE_RAY_INTERSECTION:
1370 case SHADER_TYPE_CALLABLE:
1371 UNEXPECTED("This function is not currently indended to handle ray-tracing shader types");
1372 return -1;
1373 case SHADER_TYPE_CALLABLE: // RayTracing
1374 return 5;
13731375
13741376 default:
13751377 UNEXPECTED("Unexpected shader type (", ShaderType, ")");
14191421 }
14201422
14211423 case PIPELINE_TYPE_RAY_TRACING:
1422 UNEXPECTED("Ray tracing pipeline is not supported by this function");
1423 return SHADER_TYPE_UNKNOWN;
1424 switch (Index)
1425 {
1426 case 0: return SHADER_TYPE_RAY_GEN;
1427 case 1: return SHADER_TYPE_RAY_MISS;
1428 case 2: return SHADER_TYPE_RAY_CLOSEST_HIT;
1429 case 3: return SHADER_TYPE_RAY_ANY_HIT;
1430 case 4: return SHADER_TYPE_RAY_INTERSECTION;
1431 case 5: return SHADER_TYPE_CALLABLE;
1432
1433 default:
1434 UNEXPECTED("Index ", Index, " is not a valid ray tracing pipeline shader index");
1435 return SHADER_TYPE_UNKNOWN;
1436 }
14241437
14251438 default:
14261439 UNEXPECTED("Unexpected pipeline type");
3838 #include "EngineMemory.h"
3939 #include "GraphicsAccessories.hpp"
4040 #include "LinearAllocator.hpp"
41 #include "HashUtils.hpp"
4142
4243 namespace Diligent
4344 {
4445
4546 void ValidateGraphicsPipelineCreateInfo(const GraphicsPipelineStateCreateInfo& CreateInfo) noexcept(false);
4647 void ValidateComputePipelineCreateInfo(const ComputePipelineStateCreateInfo& CreateInfo) noexcept(false);
48 void ValidateRayTracingPipelineCreateInfo(const RayTracingPipelineStateCreateInfo& CreateInfo) noexcept(false);
4749
4850 void CorrectGraphicsPipelineDesc(GraphicsPipelineDesc& GraphicsPipeline) noexcept;
4951
105107 PipelineStateBase{pRefCounters, pDevice, ComputePipelineCI.PSODesc, bIsDeviceInternal}
106108 {
107109 ValidateComputePipelineCreateInfo(ComputePipelineCI);
110 }
111
112 /// \param pRefCounters - Reference counters object that controls the lifetime of this PSO
113 /// \param pDevice - Pointer to the device.
114 /// \param RayTracingPipelineCI - Ray tracing pipeline create information.
115 /// \param bIsDeviceInternal - Flag indicating if the pipeline state is an internal device object and
116 /// must not keep a strong reference to the device.
117 PipelineStateBase(IReferenceCounters* pRefCounters,
118 RenderDeviceImplType* pDevice,
119 const RayTracingPipelineStateCreateInfo& RayTracingPipelineCI,
120 bool bIsDeviceInternal = false) :
121 PipelineStateBase{pRefCounters, pDevice, RayTracingPipelineCI.PSODesc, bIsDeviceInternal}
122 {
123 ValidateRayTracingPipelineCreateInfo(ComputePipelineCI);
108124 }
109125
110126
129145 */
130146 }
131147
148 void Destruct()
149 {
150 if (this->m_Desc.IsRayTracingPipeline() && m_pRayTracingPipelineData)
151 {
152 m_pRayTracingPipelineData->~RayTracingPipelineData();
153 m_pRayTracingPipelineData = nullptr;
154 }
155 }
156
132157 IMPLEMENT_QUERY_INTERFACE_IN_PLACE(IID_PipelineState, TDeviceObjectBase)
133158
134159 Uint32 GetBufferStride(Uint32 BufferSlot) const
158183 return *m_pGraphicsPipelineDesc;
159184 }
160185
186 virtual const RayTracingPipelineDesc& DILIGENT_CALL_TYPE GetRayTracingPipelineDesc() const override final
187 {
188 VERIFY_EXPR(this->m_Desc.IsRayTracingPipeline());
189 VERIFY_EXPR(m_pRayTracingPipelineData != nullptr);
190 return m_pRayTracingPipelineData->Desc;
191 }
192
193 virtual Uint32 DILIGENT_CALL_TYPE GetShaderGroupCount() const override final
194 {
195 VERIFY_EXPR(this->m_Desc.IsRayTracingPipeline());
196 VERIFY_EXPR(m_pRayTracingPipelineData != nullptr);
197 return static_cast<Uint32>(m_pRayTracingPipelineData->NameToGroupIndex.size());
198 }
199
200 static constexpr Uint32 InvalidShaderGroupIndex = ~0u;
201
202 virtual Uint32 DILIGENT_CALL_TYPE GetShaderGroupIndex(const char* Name) const override final
203 {
204 VERIFY_EXPR(Name != nullptr && Name[0] != '\0');
205 VERIFY_EXPR(this->m_Desc.IsRayTracingPipeline());
206 VERIFY_EXPR(m_pRayTracingPipelineData != nullptr);
207
208 auto iter = m_pRayTracingPipelineData->NameToGroupIndex.find(Name);
209 if (iter != m_pRayTracingPipelineData->NameToGroupIndex.end())
210 return iter->second;
211
212 UNEXPECTED("Can't find shader group with specified name");
213 return InvalidShaderGroupIndex;
214 }
215
216 inline void CopyShaderHandle(const char* Name, void* pData, Uint32 DataSize) const
217 {
218 VERIFY_EXPR(Name != nullptr && Name[0] != '\0');
219 VERIFY_EXPR(this->m_Desc.IsRayTracingPipeline());
220 VERIFY_EXPR(m_pRayTracingPipelineData != nullptr);
221
222 const auto ShaderHandleSize = m_pRayTracingPipelineData->ShaderHandleSize;
223 VERIFY_EXPR(ShaderHandleSize <= DataSize);
224
225 auto iter = m_pRayTracingPipelineData->NameToGroupIndex.find(Name);
226 if (iter != m_pRayTracingPipelineData->NameToGroupIndex.end())
227 {
228 VERIFY_EXPR(ShaderHandleSize * (iter->second + 1) <= m_pRayTracingPipelineData->ShaderDataSize);
229 std::memcpy(pData, &m_pRayTracingPipelineData->Shaders[ShaderHandleSize * iter->second], ShaderHandleSize);
230 return;
231 }
232 UNEXPECTED("Can't find shader group with specified name");
233 }
234
161235 protected:
236 using TNameToGroupIndexMap = std::unordered_map<HashMapStringKey, Uint32, HashMapStringKey::Hasher>;
237
162238 Int8 GetStaticVariableCountHelper(SHADER_TYPE ShaderType, const std::array<Int8, MAX_SHADERS_IN_PIPELINE>& ResourceLayoutIndex) const
163239 {
164240 if (!IsConsistentShaderType(ShaderType, this->m_Desc.PipelineType))
236312 }
237313
238314 MemPool.AddSpace<Uint32>(m_BufferSlotsUsed);
315
316 static_assert(std::is_trivially_destructible<decltype(*this->m_pGraphicsPipelineDesc)>::value, "add destructor for this object");
317 static_assert(std::is_trivially_destructible<decltype(*InputLayout.LayoutElements)>::value, "add destructor for this object");
239318 }
240319
241320 void ReserveSpaceForPipelineDesc(const ComputePipelineStateCreateInfo& CreateInfo,
242321 LinearAllocator& MemPool) const noexcept
243322 {
244323 ReserveResourceLayout(CreateInfo.PSODesc.ResourceLayout, MemPool);
324 }
325
326 void ReserveSpaceForPipelineDesc(const RayTracingPipelineStateCreateInfo& CreateInfo,
327 Uint32 ShaderHandleSize,
328 LinearAllocator& MemPool) const noexcept
329 {
330 ReserveResourceLayout(CreateInfo.PSODesc.ResourceLayout, MemPool);
331
332 for (Uint32 i = 0; i < CreateInfo.GeneralShaderCount; ++i)
333 {
334 MemPool.AddSpaceForString(CreateInfo.pGeneralShaders[i].Name);
335 }
336 for (Uint32 i = 0; i < CreateInfo.TriangleHitShaderCount; ++i)
337 {
338 MemPool.AddSpaceForString(CreateInfo.pTriangleHitShaders[i].Name);
339 }
340 for (Uint32 i = 0; i < CreateInfo.ProceduralHitShaderCount; ++i)
341 {
342 MemPool.AddSpaceForString(CreateInfo.pProceduralHitShaders[i].Name);
343 }
344
345 size_t RTDataSize = sizeof(RayTracingPipelineData);
346 // reserve size for shader handles
347 RTDataSize += ShaderHandleSize * (CreateInfo.GeneralShaderCount + CreateInfo.TriangleHitShaderCount + CreateInfo.ProceduralHitShaderCount);
348 // 1 byte reserved to avoid compiler errors on zero sized arrays
349 RTDataSize -= sizeof(RayTracingPipelineData::Shaders);
350 MemPool.AddSpace(RTDataSize, alignof(RayTracingPipelineData));
245351 }
246352
247353
250356 TShaderStages& ShaderStages)
251357 {
252358 VERIFY(m_NumShaderStages == 0, "The number of shader stages is not zero! ExtractShaders must only be called once.");
359 VERIFY_EXPR(this->m_Desc.IsAnyGraphicsPipeline());
253360
254361 ShaderStages.clear();
255362 auto AddShaderStage = [&](IShader* pShader) {
296403 TShaderStages& ShaderStages)
297404 {
298405 VERIFY(m_NumShaderStages == 0, "The number of shader stages is not zero! ExtractShaders must only be called once.");
406 VERIFY_EXPR(this->m_Desc.IsComputePipeline());
299407
300408 ShaderStages.clear();
301409
305413
306414 ShaderStages.emplace_back(SHADER_TYPE_COMPUTE, ValidatedCast<ShaderImplType>(CreateInfo.pCS));
307415 m_ShaderStageTypes[m_NumShaderStages++] = SHADER_TYPE_COMPUTE;
416
417 VERIFY_EXPR(!ShaderStages.empty() && ShaderStages.size() == m_NumShaderStages);
418 }
419
420 template <typename ShaderImplType, typename TShaderStages>
421 void ExtractShaders(const RayTracingPipelineStateCreateInfo& CreateInfo,
422 TShaderStages& ShaderStages)
423 {
424 VERIFY(m_NumShaderStages == 0, "The number of shader stages is not zero! ExtractShaders must only be called once.");
425 VERIFY_EXPR(this->m_Desc.IsRayTracingPipeline());
426
427 std::unordered_set<IShader*> UniqueShaders;
428
429 auto AddShaderStage = [&ShaderStages, &UniqueShaders](IShader* pShader) {
430 if (pShader != nullptr && UniqueShaders.insert(pShader).second)
431 {
432 auto ShaderType = pShader->GetDesc().ShaderType;
433 ShaderStages[GetShaderTypePipelineIndex(ShaderType, PIPELINE_TYPE_RAY_TRACING)].Append(ValidatedCast<ShaderImplType>(pShader));
434 }
435 };
436
437 ShaderStages.clear();
438 ShaderStages.resize(6);
439 ShaderStages[GetShaderTypePipelineIndex(SHADER_TYPE_RAY_GEN, PIPELINE_TYPE_RAY_TRACING)].Type = SHADER_TYPE_RAY_GEN;
440 ShaderStages[GetShaderTypePipelineIndex(SHADER_TYPE_RAY_MISS, PIPELINE_TYPE_RAY_TRACING)].Type = SHADER_TYPE_RAY_MISS;
441 ShaderStages[GetShaderTypePipelineIndex(SHADER_TYPE_RAY_CLOSEST_HIT, PIPELINE_TYPE_RAY_TRACING)].Type = SHADER_TYPE_RAY_CLOSEST_HIT;
442 ShaderStages[GetShaderTypePipelineIndex(SHADER_TYPE_RAY_ANY_HIT, PIPELINE_TYPE_RAY_TRACING)].Type = SHADER_TYPE_RAY_ANY_HIT;
443 ShaderStages[GetShaderTypePipelineIndex(SHADER_TYPE_RAY_INTERSECTION, PIPELINE_TYPE_RAY_TRACING)].Type = SHADER_TYPE_RAY_INTERSECTION;
444 ShaderStages[GetShaderTypePipelineIndex(SHADER_TYPE_CALLABLE, PIPELINE_TYPE_RAY_TRACING)].Type = SHADER_TYPE_CALLABLE;
445
446 for (Uint32 i = 0; i < CreateInfo.GeneralShaderCount; ++i)
447 {
448 AddShaderStage(CreateInfo.pGeneralShaders[i].pShader);
449 }
450 for (Uint32 i = 0; i < CreateInfo.TriangleHitShaderCount; ++i)
451 {
452 AddShaderStage(CreateInfo.pTriangleHitShaders[i].pClosestHitShader);
453 AddShaderStage(CreateInfo.pTriangleHitShaders[i].pAnyHitShader);
454 }
455 for (Uint32 i = 0; i < CreateInfo.ProceduralHitShaderCount; ++i)
456 {
457 AddShaderStage(CreateInfo.pProceduralHitShaders[i].pIntersectionShader);
458 AddShaderStage(CreateInfo.pProceduralHitShaders[i].pClosestHitShader);
459 AddShaderStage(CreateInfo.pProceduralHitShaders[i].pAnyHitShader);
460 }
461
462 if (ShaderStages[GetShaderTypePipelineIndex(SHADER_TYPE_RAY_GEN, PIPELINE_TYPE_RAY_TRACING)].Count() == 0)
463 LOG_ERROR_AND_THROW("At least one shader with type SHADER_TYPE_RAY_GEN must be provided");
464
465 if (ShaderStages[GetShaderTypePipelineIndex(SHADER_TYPE_RAY_MISS, PIPELINE_TYPE_RAY_TRACING)].Count() == 0)
466 LOG_ERROR_AND_THROW("At least one shader with type SHADER_TYPE_RAY_MISS must be provided");
467
468 // remove empty stages
469 for (auto iter = ShaderStages.begin(); iter != ShaderStages.end();)
470 {
471 if (iter->Count() == 0)
472 {
473 iter = ShaderStages.erase(iter);
474 continue;
475 }
476
477 m_ShaderStageTypes[m_NumShaderStages++] = iter->Type;
478 ++iter;
479 }
308480
309481 VERIFY_EXPR(!ShaderStages.empty() && ShaderStages.size() == m_NumShaderStages);
310482 }
446618 CopyResourceLayout(CreateInfo.PSODesc.ResourceLayout, this->m_Desc.ResourceLayout, MemPool);
447619 }
448620
621 void InitializePipelineDesc(const RayTracingPipelineStateCreateInfo& CreateInfo,
622 Uint32 ShaderHandleSize,
623 TNameToGroupIndexMap&& NameToGroupIndex,
624 LinearAllocator& MemPool) noexcept
625 {
626 CopyResourceLayout(CreateInfo.PSODesc.ResourceLayout, this->m_Desc.ResourceLayout, MemPool);
627
628 size_t RTDataSize = sizeof(RayTracingPipelineData);
629 // reserve size for shader handles
630 const Uint32 ShaderDataSize = ShaderHandleSize * (CreateInfo.GeneralShaderCount + CreateInfo.TriangleHitShaderCount + CreateInfo.ProceduralHitShaderCount);
631 RTDataSize += ShaderDataSize;
632 // 1 byte reserved to avoid compiler errors on zero sized arrays
633 RTDataSize -= sizeof(RayTracingPipelineData::Shaders);
634
635 this->m_pRayTracingPipelineData = static_cast<RayTracingPipelineData*>(MemPool.Allocate(RTDataSize, alignof(RayTracingPipelineData)));
636 new (this->m_pRayTracingPipelineData) RayTracingPipelineData{};
637 this->m_pRayTracingPipelineData->ShaderHandleSize = ShaderHandleSize;
638 this->m_pRayTracingPipelineData->Desc = CreateInfo.RayTracingPipeline;
639 this->m_pRayTracingPipelineData->ShaderDataSize = ShaderDataSize;
640 this->m_pRayTracingPipelineData->NameToGroupIndex = std::move(NameToGroupIndex);
641 }
642
449643 private:
450644 static void ReserveResourceLayout(const PipelineResourceLayoutDesc& SrcLayout, LinearAllocator& MemPool) noexcept
451645 {
468662 MemPool.AddSpaceForString(SrcLayout.ImmutableSamplers[i].SamplerOrTextureName);
469663 }
470664 }
665
666 static_assert(std::is_trivially_destructible<decltype(*SrcLayout.Variables)>::value, "add destructor for this object");
667 static_assert(std::is_trivially_destructible<decltype(*SrcLayout.ImmutableSamplers)>::value, "add destructor for this object");
471668 }
472669
473670 static void CopyResourceLayout(const PipelineResourceLayoutDesc& SrcLayout, PipelineResourceLayoutDesc& DstLayout, LinearAllocator& MemPool)
524721
525722 RefCntAutoPtr<IRenderPass> m_pRenderPass; ///< Strong reference to the render pass object
526723
527 GraphicsPipelineDesc* m_pGraphicsPipelineDesc = nullptr;
724 struct RayTracingPipelineData
725 {
726 RayTracingPipelineDesc Desc;
727 TNameToGroupIndexMap NameToGroupIndex;
728 Uint32 ShaderHandleSize;
729 Uint32 ShaderDataSize;
730 Uint8 Shaders[1];
731 };
732
733 union
734 {
735 GraphicsPipelineDesc* m_pGraphicsPipelineDesc;
736 RayTracingPipelineData* m_pRayTracingPipelineData;
737 };
528738 };
529739
530740 } // namespace Diligent
3838 /// Diligent API Info. This tructure can be used to verify API compatibility.
3939 struct APIInfo
4040 {
41 size_t StructSize DEFAULT_INITIALIZER(0);
42 int APIVersion DEFAULT_INITIALIZER(0);
43 size_t RenderTargetBlendDescSize DEFAULT_INITIALIZER(0);
44 size_t BlendStateDescSize DEFAULT_INITIALIZER(0);
45 size_t BufferDescSize DEFAULT_INITIALIZER(0);
46 size_t BufferDataSize DEFAULT_INITIALIZER(0);
47 size_t BufferFormatSize DEFAULT_INITIALIZER(0);
48 size_t BufferViewDescSize DEFAULT_INITIALIZER(0);
49 size_t StencilOpDescSize DEFAULT_INITIALIZER(0);
50 size_t DepthStencilStateDescSize DEFAULT_INITIALIZER(0);
51 size_t SamplerCapsSize DEFAULT_INITIALIZER(0);
52 size_t TextureCapsSize DEFAULT_INITIALIZER(0);
53 size_t DeviceCapsSize DEFAULT_INITIALIZER(0);
54 size_t DrawAttribsSize DEFAULT_INITIALIZER(0);
55 size_t DispatchComputeAttribsSize DEFAULT_INITIALIZER(0);
56 size_t ViewportSize DEFAULT_INITIALIZER(0);
57 size_t RectSize DEFAULT_INITIALIZER(0);
58 size_t CopyTextureAttribsSize DEFAULT_INITIALIZER(0);
59 size_t DeviceObjectAttribsSize DEFAULT_INITIALIZER(0);
60 size_t GraphicsAdapterInfoSize DEFAULT_INITIALIZER(0);
61 size_t DisplayModeAttribsSize DEFAULT_INITIALIZER(0);
62 size_t SwapChainDescSize DEFAULT_INITIALIZER(0);
63 size_t FullScreenModeDescSize DEFAULT_INITIALIZER(0);
64 size_t EngineCreateInfoSize DEFAULT_INITIALIZER(0);
65 size_t EngineGLCreateInfoSize DEFAULT_INITIALIZER(0);
66 size_t EngineD3D11CreateInfoSize DEFAULT_INITIALIZER(0);
67 size_t EngineD3D12CreateInfoSize DEFAULT_INITIALIZER(0);
68 size_t EngineVkCreateInfoSize DEFAULT_INITIALIZER(0);
69 size_t EngineMtlCreateInfoSize DEFAULT_INITIALIZER(0);
70 size_t BoxSize DEFAULT_INITIALIZER(0);
71 size_t TextureFormatAttribsSize DEFAULT_INITIALIZER(0);
72 size_t TextureFormatInfoSize DEFAULT_INITIALIZER(0);
73 size_t TextureFormatInfoExtSize DEFAULT_INITIALIZER(0);
74 size_t StateTransitionDescSize DEFAULT_INITIALIZER(0);
75 size_t LayoutElementSize DEFAULT_INITIALIZER(0);
76 size_t InputLayoutDescSize DEFAULT_INITIALIZER(0);
77 size_t SampleDescSize DEFAULT_INITIALIZER(0);
78 size_t ShaderResourceVariableDescSize DEFAULT_INITIALIZER(0);
79 size_t ImmutableSamplerDescSize DEFAULT_INITIALIZER(0);
80 size_t PipelineResourceLayoutDescSize DEFAULT_INITIALIZER(0);
81 size_t GraphicsPipelineDescSize DEFAULT_INITIALIZER(0);
82 size_t GraphicsPipelineStateCreateInfoSize DEFAULT_INITIALIZER(0);
83 size_t ComputePipelineStateCreateInfoSize DEFAULT_INITIALIZER(0);
84 size_t PipelineStateDescSize DEFAULT_INITIALIZER(0);
85 size_t RasterizerStateDescSize DEFAULT_INITIALIZER(0);
86 size_t ResourceMappingEntrySize DEFAULT_INITIALIZER(0);
87 size_t ResourceMappingDescSize DEFAULT_INITIALIZER(0);
88 size_t SamplerDescSize DEFAULT_INITIALIZER(0);
89 size_t ShaderDescSize DEFAULT_INITIALIZER(0);
90 size_t ShaderMacroSize DEFAULT_INITIALIZER(0);
91 size_t ShaderCreateInfoSize DEFAULT_INITIALIZER(0);
92 size_t ShaderResourceDescSize DEFAULT_INITIALIZER(0);
93 size_t DepthStencilClearValueSize DEFAULT_INITIALIZER(0);
94 size_t OptimizedClearValueSize DEFAULT_INITIALIZER(0);
95 size_t TextureDescSize DEFAULT_INITIALIZER(0);
96 size_t TextureSubResDataSize DEFAULT_INITIALIZER(0);
97 size_t TextureDataSize DEFAULT_INITIALIZER(0);
98 size_t MappedTextureSubresourceSize DEFAULT_INITIALIZER(0);
99 size_t TextureViewDescSize DEFAULT_INITIALIZER(0);
41 size_t StructSize DEFAULT_INITIALIZER(0);
42 int APIVersion DEFAULT_INITIALIZER(0);
43 size_t RenderTargetBlendDescSize DEFAULT_INITIALIZER(0);
44 size_t BlendStateDescSize DEFAULT_INITIALIZER(0);
45 size_t BufferDescSize DEFAULT_INITIALIZER(0);
46 size_t BufferDataSize DEFAULT_INITIALIZER(0);
47 size_t BufferFormatSize DEFAULT_INITIALIZER(0);
48 size_t BufferViewDescSize DEFAULT_INITIALIZER(0);
49 size_t StencilOpDescSize DEFAULT_INITIALIZER(0);
50 size_t DepthStencilStateDescSize DEFAULT_INITIALIZER(0);
51 size_t SamplerCapsSize DEFAULT_INITIALIZER(0);
52 size_t TextureCapsSize DEFAULT_INITIALIZER(0);
53 size_t DeviceCapsSize DEFAULT_INITIALIZER(0);
54 size_t DrawAttribsSize DEFAULT_INITIALIZER(0);
55 size_t DispatchComputeAttribsSize DEFAULT_INITIALIZER(0);
56 size_t ViewportSize DEFAULT_INITIALIZER(0);
57 size_t RectSize DEFAULT_INITIALIZER(0);
58 size_t CopyTextureAttribsSize DEFAULT_INITIALIZER(0);
59 size_t DeviceObjectAttribsSize DEFAULT_INITIALIZER(0);
60 size_t GraphicsAdapterInfoSize DEFAULT_INITIALIZER(0);
61 size_t DisplayModeAttribsSize DEFAULT_INITIALIZER(0);
62 size_t SwapChainDescSize DEFAULT_INITIALIZER(0);
63 size_t FullScreenModeDescSize DEFAULT_INITIALIZER(0);
64 size_t EngineCreateInfoSize DEFAULT_INITIALIZER(0);
65 size_t EngineGLCreateInfoSize DEFAULT_INITIALIZER(0);
66 size_t EngineD3D11CreateInfoSize DEFAULT_INITIALIZER(0);
67 size_t EngineD3D12CreateInfoSize DEFAULT_INITIALIZER(0);
68 size_t EngineVkCreateInfoSize DEFAULT_INITIALIZER(0);
69 size_t EngineMtlCreateInfoSize DEFAULT_INITIALIZER(0);
70 size_t BoxSize DEFAULT_INITIALIZER(0);
71 size_t TextureFormatAttribsSize DEFAULT_INITIALIZER(0);
72 size_t TextureFormatInfoSize DEFAULT_INITIALIZER(0);
73 size_t TextureFormatInfoExtSize DEFAULT_INITIALIZER(0);
74 size_t StateTransitionDescSize DEFAULT_INITIALIZER(0);
75 size_t LayoutElementSize DEFAULT_INITIALIZER(0);
76 size_t InputLayoutDescSize DEFAULT_INITIALIZER(0);
77 size_t SampleDescSize DEFAULT_INITIALIZER(0);
78 size_t ShaderResourceVariableDescSize DEFAULT_INITIALIZER(0);
79 size_t ImmutableSamplerDescSize DEFAULT_INITIALIZER(0);
80 size_t PipelineResourceLayoutDescSize DEFAULT_INITIALIZER(0);
81 size_t PipelineStateDescSize DEFAULT_INITIALIZER(0);
82 size_t GraphicsPipelineDescSize DEFAULT_INITIALIZER(0);
83 size_t GraphicsPipelineStateCreateInfoSize DEFAULT_INITIALIZER(0);
84 size_t ComputePipelineStateCreateInfoSize DEFAULT_INITIALIZER(0);
85 size_t RayTracingPipelineDescSize DEFAULT_INITIALIZER(0);
86 size_t RayTracingPipelineStateCreateInfoSize DEFAULT_INITIALIZER(0);
87 size_t RasterizerStateDescSize DEFAULT_INITIALIZER(0);
88 size_t ResourceMappingEntrySize DEFAULT_INITIALIZER(0);
89 size_t ResourceMappingDescSize DEFAULT_INITIALIZER(0);
90 size_t SamplerDescSize DEFAULT_INITIALIZER(0);
91 size_t ShaderDescSize DEFAULT_INITIALIZER(0);
92 size_t ShaderMacroSize DEFAULT_INITIALIZER(0);
93 size_t ShaderCreateInfoSize DEFAULT_INITIALIZER(0);
94 size_t ShaderResourceDescSize DEFAULT_INITIALIZER(0);
95 size_t DepthStencilClearValueSize DEFAULT_INITIALIZER(0);
96 size_t OptimizedClearValueSize DEFAULT_INITIALIZER(0);
97 size_t TextureDescSize DEFAULT_INITIALIZER(0);
98 size_t TextureSubResDataSize DEFAULT_INITIALIZER(0);
99 size_t TextureDataSize DEFAULT_INITIALIZER(0);
100 size_t MappedTextureSubresourceSize DEFAULT_INITIALIZER(0);
101 size_t TextureViewDescSize DEFAULT_INITIALIZER(0);
100102 };
101103 typedef struct APIInfo APIInfo;
102104
5050 static const Uint32 MAX_VIEWPORTS = DILIGENT_MAX_VIEWPORTS;
5151
5252 /// Maximum number of shader stages in a pipeline.
53 /// (Vertex, Hull, Domain, Geometry, Pixel) or (Amplification, Mesh, Pixel), or (Compute)
54 static const Uint32 MAX_SHADERS_IN_PIPELINE = 5;
53 /// (Vertex, Hull, Domain, Geometry, Pixel) or (Amplification, Mesh, Pixel), or (Compute) or (RayGen, Miss, ClosestHit, AnyHit, Intersection, Callable)
54 static const Uint32 MAX_SHADERS_IN_PIPELINE = 6;
5555
5656 // clang-format on
5757
21162116 Uint32 NumUniformTexelBufferDescriptors DEFAULT_INITIALIZER(0);
21172117 Uint32 NumStorageTexelBufferDescriptors DEFAULT_INITIALIZER(0);
21182118 Uint32 NumInputAttachmentDescriptors DEFAULT_INITIALIZER(0);
2119 Uint32 NumAccelStructDescriptors DEFAULT_INITIALIZER(0);
21192120
21202121 #if DILIGENT_CPP_INTERFACE
21212122 VulkanDescriptorPoolSize()noexcept {}
21292130 Uint32 _NumStorageBufferDescriptors,
21302131 Uint32 _NumUniformTexelBufferDescriptors,
21312132 Uint32 _NumStorageTexelBufferDescriptors,
2132 Uint32 _NumInputAttachmentDescriptors)noexcept :
2133 Uint32 _NumInputAttachmentDescriptors,
2134 Uint32 _NumAccelStructDescriptors)noexcept :
21332135 MaxDescriptorSets {_MaxDescriptorSets },
21342136 NumSeparateSamplerDescriptors {_NumSeparateSamplerDescriptors },
21352137 NumCombinedSamplerDescriptors {_NumCombinedSamplerDescriptors },
21392141 NumStorageBufferDescriptors {_NumStorageBufferDescriptors },
21402142 NumUniformTexelBufferDescriptors{_NumUniformTexelBufferDescriptors},
21412143 NumStorageTexelBufferDescriptors{_NumStorageTexelBufferDescriptors},
2142 NumInputAttachmentDescriptors {_NumInputAttachmentDescriptors }
2144 NumInputAttachmentDescriptors {_NumInputAttachmentDescriptors },
2145 NumAccelStructDescriptors {_NumAccelStructDescriptors }
21432146 {
21442147 // On clang aggregate initialization fails to compile if
21452148 // structure members have default initializers
21772180 /// the engine creates another one.
21782181 VulkanDescriptorPoolSize MainDescriptorPoolSize
21792182 #if DILIGENT_CPP_INTERFACE
2180 //Max SepSm CmbSm SmpImg StrImg UB SB UTxB StTxB InptAtt
2181 {8192, 1024, 8192, 8192, 1024, 4096, 4096, 1024, 1024, 256}
2183 //Max SepSm CmbSm SmpImg StrImg UB SB UTxB StTxB InptAtt AccelSt
2184 {8192, 1024, 8192, 8192, 1024, 4096, 4096, 1024, 1024, 256, 256}
21822185 #endif
21832186 ;
21842187
21892192
21902193 VulkanDescriptorPoolSize DynamicDescriptorPoolSize
21912194 #if DILIGENT_CPP_INTERFACE
2192 //Max SepSm CmbSm SmpImg StrImg UB SB UTxB StTxB InptAtt
2193 {2048, 256, 2048, 2048, 256, 1024, 1024, 256, 256, 64}
2195 //Max SepSm CmbSm SmpImg StrImg UB SB UTxB StTxB InptAtt AccelSt
2196 {2048, 256, 2048, 2048, 256, 1024, 1024, 256, 256, 64, 64}
21942197 #endif
21952198 ;
21962199
214214 typedef struct GraphicsPipelineDesc GraphicsPipelineDesc;
215215
216216
217 /// Compute pipeline state description
218
219 /// This structure describes the compute pipeline state and is part of the PipelineStateDesc structure.
220 struct ComputePipelineDesc
221 {
222 /// Compute shader to be used with the pipeline
223 IShader* pCS DEFAULT_INITIALIZER(nullptr);
224 };
225 typedef struct ComputePipelineDesc ComputePipelineDesc;
226
227217 /// AZ TODO
228218 struct RayTracingGeneralShaderGroup
229219 {
230220 /// AZ TODO
231 const char* Name DEFAULT_INITIALIZER(nullptr);
232
233 /// AZ TODO
234 IShader* Shader DEFAULT_INITIALIZER(nullptr);
221 const char* Name DEFAULT_INITIALIZER(nullptr);
222
223 /// AZ TODO
224 IShader* pShader DEFAULT_INITIALIZER(nullptr);
235225 };
236226 typedef struct RayTracingGeneralShaderGroup RayTracingGeneralShaderGroup;
237227
239229 struct RayTracingTriangleHitShaderGroup
240230 {
241231 /// AZ TODO
242 const char* Name DEFAULT_INITIALIZER(nullptr);
243
244 /// AZ TODO
245 IShader* ClosestHitShader DEFAULT_INITIALIZER(nullptr);
246
247 /// AZ TODO
248 IShader* AnyHitShader DEFAULT_INITIALIZER(nullptr); // can be null
232 const char* Name DEFAULT_INITIALIZER(nullptr);
233
234 /// AZ TODO
235 IShader* pClosestHitShader DEFAULT_INITIALIZER(nullptr);
236
237 /// AZ TODO
238 IShader* pAnyHitShader DEFAULT_INITIALIZER(nullptr); // can be null
249239 };
250240 typedef struct RayTracingTriangleHitShaderGroup RayTracingTriangleHitShaderGroup;
251241
253243 struct RayTracingProceduralHitShaderGroup
254244 {
255245 /// AZ TODO
256 const char* Name DEFAULT_INITIALIZER(nullptr);
257
258 /// AZ TODO
259 IShader* IntersectionShader DEFAULT_INITIALIZER(nullptr);
260
261 /// AZ TODO
262 IShader* ClosestHitShader DEFAULT_INITIALIZER(nullptr); // can be null
263
264 /// AZ TODO
265 IShader* AnyHitShader DEFAULT_INITIALIZER(nullptr); // can be null
246 const char* Name DEFAULT_INITIALIZER(nullptr);
247
248 /// AZ TODO
249 IShader* pIntersectionShader DEFAULT_INITIALIZER(nullptr);
250
251 /// AZ TODO
252 IShader* pClosestHitShader DEFAULT_INITIALIZER(nullptr); // can be null
253
254 /// AZ TODO
255 IShader* pAnyHitShader DEFAULT_INITIALIZER(nullptr); // can be null
266256 };
267257 typedef struct RayTracingProceduralHitShaderGroup RayTracingProceduralHitShaderGroup;
268258
270260 struct RayTracingPipelineDesc
271261 {
272262 /// AZ TODO
273 const RayTracingGeneralShaderGroup* pGeneralShaders DEFAULT_INITIALIZER(nullptr);
274
275 /// AZ TODO
276 const RayTracingTriangleHitShaderGroup* pTriangleHitShaders DEFAULT_INITIALIZER(nullptr);
277
278 /// AZ TODO
279 const RayTracingProceduralHitShaderGroup* pProceduralHitShaders DEFAULT_INITIALIZER(nullptr);
280
281 /// AZ TODO
282 Uint16 GeneralShaderCount DEFAULT_INITIALIZER(0);
283
284 /// AZ TODO
285 Uint16 TriangleHitShaderCount DEFAULT_INITIALIZER(0);
286
287 /// AZ TODO
288 Uint16 ProceduralHitShaderCount DEFAULT_INITIALIZER(0);
289
290 /// AZ TODO
291 Uint8 MaxRecursionDepth DEFAULT_INITIALIZER(0); // must be 0..31 (check current device limits)
263 Uint8 MaxRecursionDepth DEFAULT_INITIALIZER(0); // must be 0..31 (check current device limits)
292264 };
293265 typedef struct RayTracingPipelineDesc RayTracingPipelineDesc;
294266
307279
308280 /// Ray tracing pipeline, which is used by IDeviceContext::TraceRays().
309281 PIPELINE_TYPE_RAY_TRACING,
282
283 PIPELINE_TYPE_LAST = PIPELINE_TYPE_RAY_TRACING
310284 };
311285
312286
331305 #if DILIGENT_CPP_INTERFACE
332306 bool IsAnyGraphicsPipeline() const { return PipelineType == PIPELINE_TYPE_GRAPHICS || PipelineType == PIPELINE_TYPE_MESH; }
333307 bool IsComputePipeline() const { return PipelineType == PIPELINE_TYPE_COMPUTE; }
308 bool IsRayTracingPipeline() const { return PipelineType == PIPELINE_TYPE_RAY_TRACING; }
334309 #endif
335310 };
336311 typedef struct PipelineStateDesc PipelineStateDesc;
419394 typedef struct ComputePipelineStateCreateInfo ComputePipelineStateCreateInfo;
420395
421396
397 /// Ray tracing pipeline state description.
398 struct RayTracingPipelineStateCreateInfo DILIGENT_DERIVE(PipelineStateCreateInfo)
399
400 /// AZ TODO
401 RayTracingPipelineDesc RayTracingPipeline;
402
403 /// AZ TODO
404 const RayTracingGeneralShaderGroup* pGeneralShaders DEFAULT_INITIALIZER(nullptr);
405
406 /// AZ TODO
407 const RayTracingTriangleHitShaderGroup* pTriangleHitShaders DEFAULT_INITIALIZER(nullptr); // can be null
408
409 /// AZ TODO
410 const RayTracingProceduralHitShaderGroup* pProceduralHitShaders DEFAULT_INITIALIZER(nullptr); // can be null
411
412 /// AZ TODO
413 Uint16 GeneralShaderCount DEFAULT_INITIALIZER(0);
414
415 /// AZ TODO
416 Uint16 TriangleHitShaderCount DEFAULT_INITIALIZER(0);
417
418 /// AZ TODO
419 Uint16 ProceduralHitShaderCount DEFAULT_INITIALIZER(0);
420 };
421 typedef struct RayTracingPipelineStateCreateInfo RayTracingPipelineStateCreateInfo;
422
423
422424 // {06084AE5-6A71-4FE8-84B9-395DD489A28C}
423425 static const struct INTERFACE_ID IID_PipelineState =
424426 {0x6084ae5, 0x6a71, 0x4fe8, {0x84, 0xb9, 0x39, 0x5d, 0xd4, 0x89, 0xa2, 0x8c}};
443445 /// Returns the graphics pipeline description used to create the object.
444446 /// This method must only be called for a graphics or mesh pipeline.
445447 VIRTUAL const GraphicsPipelineDesc REF METHOD(GetGraphicsPipelineDesc)(THIS) CONST PURE;
448
449 /// Returns the ray tracing pipeline description used to create the object.
450 /// This method must only be called for a ray tracing pipeline.
451 VIRTUAL const RayTracingPipelineDesc REF METHOD(GetRayTracingPipelineDesc)(THIS) CONST PURE;
446452
447453 /// Binds resources for all shaders in the pipeline state
448454
521527 /// into account vertex shader input layout, number of outputs, etc.
522528 VIRTUAL bool METHOD(IsCompatibleWith)(THIS_
523529 const struct IPipelineState* pPSO) CONST PURE;
530
531 /// AZ TODO
532 VIRTUAL Uint32 METHOD(GetShaderGroupIndex)(THIS_
533 const char* Name) CONST PURE;
534
535 /// AZ TODO
536 VIRTUAL Uint32 METHOD(GetShaderGroupCount)(THIS) CONST PURE;
524537 };
525538 DILIGENT_END_INTERFACE
526539
533546 # define IPipelineState_GetDesc(This) (const struct PipelineStateDesc*)IDeviceObject_GetDesc(This)
534547
535548 # define IPipelineState_GetGraphicsPipelineDesc(This) CALL_IFACE_METHOD(PipelineState, GetGraphicsPipelineDesc, This)
549 # define IPipelineState_GetRayTracingPipelineDesc(This) CALL_IFACE_METHOD(PipelineState, GetRayTracingPipelineDesc, This)
536550 # define IPipelineState_BindStaticResources(This, ...) CALL_IFACE_METHOD(PipelineState, BindStaticResources, This, __VA_ARGS__)
537551 # define IPipelineState_GetStaticVariableCount(This, ...) CALL_IFACE_METHOD(PipelineState, GetStaticVariableCount, This, __VA_ARGS__)
538552 # define IPipelineState_GetStaticVariableByName(This, ...) CALL_IFACE_METHOD(PipelineState, GetStaticVariableByName, This, __VA_ARGS__)
539553 # define IPipelineState_GetStaticVariableByIndex(This, ...) CALL_IFACE_METHOD(PipelineState, GetStaticVariableByIndex, This, __VA_ARGS__)
540554 # define IPipelineState_CreateShaderResourceBinding(This, ...) CALL_IFACE_METHOD(PipelineState, CreateShaderResourceBinding, This, __VA_ARGS__)
541555 # define IPipelineState_IsCompatibleWith(This, ...) CALL_IFACE_METHOD(PipelineState, IsCompatibleWith, This, __VA_ARGS__)
556 # define IPipelineState_GetShaderGroupIndex(This, ...) CALL_IFACE_METHOD(PipelineState, GetShaderGroupIndex, This, __VA_ARGS__)
557 # define IPipelineState_GetShaderGroupCount(This) CALL_IFACE_METHOD(PipelineState, GetShaderGroupCount, This)
542558
543559 // clang-format on
544560
176176 VIRTUAL void METHOD(CreateComputePipelineState)(THIS_
177177 const ComputePipelineStateCreateInfo REF PSOCreateInfo,
178178 IPipelineState** ppPipelineState) PURE;
179
180 /// Creates a new ray tracing pipeline state object
181
182 /// \param [in] PSOCreateInfo - Ray tracing pipeline state create info, see Diligent::RayTracingPipelineStateCreateInfo for details.
183 /// \param [out] ppPipelineState - Address of the memory location where the pointer to the
184 /// pipeline state interface will be stored.
185 /// The function calls AddRef(), so that the new object will contain
186 /// one reference.
187 VIRTUAL void METHOD(CreateRayTracingPipelineState)(THIS_
188 const RayTracingPipelineStateCreateInfo REF PSOCreateInfo,
189 IPipelineState** ppPipelineState) PURE;
179190
180191 /// Creates a new fence object
181192
321332
322333 // clang-format off
323334
324 # define IRenderDevice_CreateBuffer(This, ...) CALL_IFACE_METHOD(RenderDevice, CreateBuffer, This, __VA_ARGS__)
325 # define IRenderDevice_CreateShader(This, ...) CALL_IFACE_METHOD(RenderDevice, CreateShader, This, __VA_ARGS__)
326 # define IRenderDevice_CreateTexture(This, ...) CALL_IFACE_METHOD(RenderDevice, CreateTexture, This, __VA_ARGS__)
327 # define IRenderDevice_CreateSampler(This, ...) CALL_IFACE_METHOD(RenderDevice, CreateSampler, This, __VA_ARGS__)
328 # define IRenderDevice_CreateResourceMapping(This, ...) CALL_IFACE_METHOD(RenderDevice, CreateResourceMapping, This, __VA_ARGS__)
329 # define IRenderDevice_CreateGraphicsPipelineState(This, ...) CALL_IFACE_METHOD(RenderDevice, CreateGraphicsPipelineState, This, __VA_ARGS__)
330 # define IRenderDevice_CreateComputePipelineState(This, ...) CALL_IFACE_METHOD(RenderDevice, CreateComputePipelineState, This, __VA_ARGS__)
331 # define IRenderDevice_CreateFence(This, ...) CALL_IFACE_METHOD(RenderDevice, CreateFence, This, __VA_ARGS__)
332 # define IRenderDevice_CreateQuery(This, ...) CALL_IFACE_METHOD(RenderDevice, CreateQuery, This, __VA_ARGS__)
333 # define IRenderDevice_GetDeviceCaps(This) CALL_IFACE_METHOD(RenderDevice, GetDeviceCaps, This)
334 # define IRenderDevice_GetTextureFormatInfo(This, ...) CALL_IFACE_METHOD(RenderDevice, GetTextureFormatInfo, This, __VA_ARGS__)
335 # define IRenderDevice_GetTextureFormatInfoExt(This, ...) CALL_IFACE_METHOD(RenderDevice, GetTextureFormatInfoExt, This, __VA_ARGS__)
336 # define IRenderDevice_ReleaseStaleResources(This, ...) CALL_IFACE_METHOD(RenderDevice, ReleaseStaleResources, This, __VA_ARGS__)
337 # define IRenderDevice_IdleGPU(This) CALL_IFACE_METHOD(RenderDevice, IdleGPU, This)
338 # define IRenderDevice_GetEngineFactory(This) CALL_IFACE_METHOD(RenderDevice, GetEngineFactory, This)
335 # define IRenderDevice_CreateBuffer(This, ...) CALL_IFACE_METHOD(RenderDevice, CreateBuffer, This, __VA_ARGS__)
336 # define IRenderDevice_CreateShader(This, ...) CALL_IFACE_METHOD(RenderDevice, CreateShader, This, __VA_ARGS__)
337 # define IRenderDevice_CreateTexture(This, ...) CALL_IFACE_METHOD(RenderDevice, CreateTexture, This, __VA_ARGS__)
338 # define IRenderDevice_CreateSampler(This, ...) CALL_IFACE_METHOD(RenderDevice, CreateSampler, This, __VA_ARGS__)
339 # define IRenderDevice_CreateResourceMapping(This, ...) CALL_IFACE_METHOD(RenderDevice, CreateResourceMapping, This, __VA_ARGS__)
340 # define IRenderDevice_CreateGraphicsPipelineState(This, ...) CALL_IFACE_METHOD(RenderDevice, CreateGraphicsPipelineState, This, __VA_ARGS__)
341 # define IRenderDevice_CreateComputePipelineState(This, ...) CALL_IFACE_METHOD(RenderDevice, CreateComputePipelineState, This, __VA_ARGS__)
342 # define IRenderDevice_CreateRayTracingPipelineState(This, ...) CALL_IFACE_METHOD(RenderDevice, CreateRayTracingPipelineState, This, __VA_ARGS__)
343 # define IRenderDevice_CreateFence(This, ...) CALL_IFACE_METHOD(RenderDevice, CreateFence, This, __VA_ARGS__)
344 # define IRenderDevice_CreateQuery(This, ...) CALL_IFACE_METHOD(RenderDevice, CreateQuery, This, __VA_ARGS__)
345 # define IRenderDevice_GetDeviceCaps(This) CALL_IFACE_METHOD(RenderDevice, GetDeviceCaps, This)
346 # define IRenderDevice_GetTextureFormatInfo(This, ...) CALL_IFACE_METHOD(RenderDevice, GetTextureFormatInfo, This, __VA_ARGS__)
347 # define IRenderDevice_GetTextureFormatInfoExt(This, ...) CALL_IFACE_METHOD(RenderDevice, GetTextureFormatInfoExt, This, __VA_ARGS__)
348 # define IRenderDevice_ReleaseStaleResources(This, ...) CALL_IFACE_METHOD(RenderDevice, ReleaseStaleResources, This, __VA_ARGS__)
349 # define IRenderDevice_IdleGPU(This) CALL_IFACE_METHOD(RenderDevice, IdleGPU, This)
350 # define IRenderDevice_GetEngineFactory(This) CALL_IFACE_METHOD(RenderDevice, GetEngineFactory, This)
339351
340352 // clang-format on
341353
108108
109109 /// Legacy HLSL compiler (FXC) for Direct3D11 and Direct3D12 supporting shader models up to 5.1.
110110 SHADER_COMPILER_FXC,
111
112 SHADER_COMPILER_LAST = SHADER_COMPILER_FXC
111113 };
112114
113115
353355 /// Input attachment in a render pass
354356 SHADER_RESOURCE_TYPE_INPUT_ATTACHMENT,
355357
356 SHADER_RESOURCE_TYPE_LAST = SHADER_RESOURCE_TYPE_INPUT_ATTACHMENT
358 /// AZ TODO
359 SHADER_RESOURCE_TYPE_ACCEL_STRUCT,
360
361 SHADER_RESOURCE_TYPE_LAST = SHADER_RESOURCE_TYPE_ACCEL_STRUCT
357362 };
358363 // clang-format on
359364
8888 INIT_STRUCTURE_SIZE(ShaderResourceVariableDesc);
8989 INIT_STRUCTURE_SIZE(ImmutableSamplerDesc);
9090 INIT_STRUCTURE_SIZE(PipelineResourceLayoutDesc);
91 INIT_STRUCTURE_SIZE(PipelineStateDesc);
9192 INIT_STRUCTURE_SIZE(GraphicsPipelineDesc);
9293 INIT_STRUCTURE_SIZE(GraphicsPipelineStateCreateInfo);
9394 INIT_STRUCTURE_SIZE(ComputePipelineStateCreateInfo);
94 INIT_STRUCTURE_SIZE(PipelineStateDesc);
95 INIT_STRUCTURE_SIZE(RayTracingPipelineDesc);
96 INIT_STRUCTURE_SIZE(RayTracingPipelineStateCreateInfo);
9597 INIT_STRUCTURE_SIZE(RasterizerStateDesc);
9698 INIT_STRUCTURE_SIZE(ResourceMappingEntry);
9799 INIT_STRUCTURE_SIZE(ResourceMappingDesc);
247247
248248 VALIDATE_SHADER_TYPE(CreateInfo.pCS, SHADER_TYPE_COMPUTE, "compute");
249249 }
250
251 void ValidateRayTracingPipelineCreateInfo(const RayTracingPipelineStateCreateInfo& CreateInfo) noexcept(false)
252 {
253 #ifdef DILIGENT_DEVELOPMENT
254 const auto& PSODesc = CreateInfo.PSODesc;
255 if (PSODesc.PipelineType != PIPELINE_TYPE_RAY_TRACING)
256 LOG_PSO_ERROR_AND_THROW("Pipeline type must be RAY_TRACING");
257
258 for (Uint32 i = 0; i < CreateInfo.GeneralShaderCount; ++i)
259 {
260 const auto& Group = CreateInfo.pGeneralShaders[i];
261 if (Group.pShader == nullptr)
262 LOG_PSO_ERROR_AND_THROW("pGeneralShaders[", i, "].pShader must not be null");
263 if (Group.Name == nullptr)
264 LOG_PSO_ERROR_AND_THROW("pGeneralShaders[", i, "].Name must not be null");
265
266 switch (Group.pShader->GetDesc().ShaderType)
267 {
268 case SHADER_TYPE_RAY_GEN:
269 case SHADER_TYPE_RAY_MISS:
270 case SHADER_TYPE_RAY_CLOSEST_HIT: break;
271 default:
272 LOG_ERROR_AND_THROW(GetShaderTypeLiteralName(Group.pShader->GetDesc().ShaderType), " is not a valid type for ray tracing general shader");
273 }
274 }
275
276 for (Uint32 i = 0; i < CreateInfo.TriangleHitShaderCount; ++i)
277 {
278 const auto& Group = CreateInfo.pTriangleHitShaders[i];
279 if (Group.pClosestHitShader == nullptr)
280 LOG_PSO_ERROR_AND_THROW("pTriangleHitShaders[", i, "].pClosestHitShader must not be null");
281 if (Group.Name == nullptr)
282 LOG_PSO_ERROR_AND_THROW("pTriangleHitShaders[", i, "].Name must not be null");
283
284 VALIDATE_SHADER_TYPE(Group.pClosestHitShader, SHADER_TYPE_RAY_CLOSEST_HIT, "ray tracing triangle closes hit");
285
286 if (Group.pAnyHitShader != nullptr)
287 VALIDATE_SHADER_TYPE(Group.pAnyHitShader, SHADER_TYPE_RAY_ANY_HIT, "ray tracing triangle any hit");
288 }
289
290 for (Uint32 i = 0; i < CreateInfo.ProceduralHitShaderCount; ++i)
291 {
292 const auto& Group = CreateInfo.pProceduralHitShaders[i];
293 if (Group.pIntersectionShader == nullptr)
294 LOG_PSO_ERROR_AND_THROW("pProceduralHitShaders[", i, "].pIntersectionShader must not be null");
295 if (Group.Name == nullptr)
296 LOG_PSO_ERROR_AND_THROW("pProceduralHitShaders[", i, "].Name must not be null");
297
298 VALIDATE_SHADER_TYPE(Group.pIntersectionShader, SHADER_TYPE_RAY_INTERSECTION, "ray tracing procedural intersection");
299
300 if (Group.pClosestHitShader != nullptr)
301 VALIDATE_SHADER_TYPE(Group.pClosestHitShader, SHADER_TYPE_RAY_CLOSEST_HIT, "ray tracing procedural closest hit");
302 if (Group.pAnyHitShader != nullptr)
303 VALIDATE_SHADER_TYPE(Group.pAnyHitShader, SHADER_TYPE_RAY_ANY_HIT, "ray tracing procedural any hit");
304 }
305 #endif // DILIGENT_DEVELOPMENT
306 }
307
250308 #undef VALIDATE_SHADER_TYPE
251309 #undef LOG_PSO_ERROR_AND_THROW
252310
165165
166166 // Resource layout index in m_pStaticResourceLayouts array for every shader stage,
167167 // indexed by the shader type pipeline index (returned by GetShaderTypePipelineIndex)
168 std::array<Int8, MAX_SHADERS_IN_PIPELINE> m_ResourceLayoutIndex = {-1, -1, -1, -1, -1};
168 std::array<Int8, MAX_SHADERS_IN_PIPELINE> m_ResourceLayoutIndex = {-1, -1, -1, -1, -1, -1};
169169
170170 std::array<Uint16, MAX_SHADERS_IN_PIPELINE + 1> m_ImmutableSamplerOffsets = {};
171171 struct ImmutableSamplerInfo
7676 virtual void DILIGENT_CALL_TYPE CreateComputePipelineState(const ComputePipelineStateCreateInfo& PSOCreateInfo,
7777 IPipelineState** ppPipelineState) override final;
7878
79 /// Implementation of IRenderDevice::CreateRayTracingPipelineState() in Direct3D11 backend.
80 virtual void DILIGENT_CALL_TYPE CreateRayTracingPipelineState(const RayTracingPipelineStateCreateInfo& PSOCreateInfo,
81 IPipelineState** ppPipelineState) override final;
82
7983 /// Implementation of IRenderDevice::CreateFence() in Direct3D11 backend.
8084 virtual void DILIGENT_CALL_TYPE CreateFence(const FenceDesc& Desc,
8185 IFence** ppFence) override final;
109109
110110 // Resource layout index in m_pResourceLayouts array for every shader stage,
111111 // indexed by the shader type pipeline index (returned by GetShaderTypePipelineIndex)
112 std::array<Int8, MAX_SHADERS_IN_PIPELINE> m_ResourceLayoutIndex = {-1, -1, -1, -1, -1};
112 std::array<Int8, MAX_SHADERS_IN_PIPELINE> m_ResourceLayoutIndex = {-1, -1, -1, -1, -1, -1};
113113
114114 Uint8 m_NumActiveShaders = 0;
115115
202202
203203 void PipelineStateD3D11Impl::Destruct()
204204 {
205 TPipelineStateBase::Destruct();
206
205207 if (m_pStaticResourceLayouts != nullptr)
206208 {
207209 for (Uint32 l = 0; l < GetNumShaderStages(); ++l)
100100 sizeof(FenceD3D11Impl),
101101 sizeof(QueryD3D11Impl),
102102 sizeof(RenderPassD3D11Impl),
103 sizeof(FramebufferD3D11Impl)
103 sizeof(FramebufferD3D11Impl),
104 0,
105 0,
106 0
104107 }
105108 },
106109 m_EngineAttribs{EngineAttribs},
107110 m_pd3d11Device {pd3d11Device }
108111 // clang-format on
109112 {
113 static_assert(sizeof(DeviceObjectSizes) == sizeof(size_t) * 15, "Please add new objects to DeviceObjectSizes constructor");
114
110115 m_DeviceCaps.DevType = RENDER_DEVICE_TYPE_D3D11;
111116 auto FeatureLevel = m_pd3d11Device->GetFeatureLevel();
112117 switch (FeatureLevel)
408413 CreatePipelineState(PSOCreateInfo, ppPipelineState);
409414 }
410415
416 void RenderDeviceD3D11Impl::CreateRayTracingPipelineState(const RayTracingPipelineStateCreateInfo& PSOCreateInfo, IPipelineState** ppPipelineState)
417 {
418 UNSUPPORTED("CreateRayTracingPipelineState is not supported in DirectX 11");
419 *ppPipelineState = nullptr;
420 }
421
411422 void RenderDeviceD3D11Impl::CreateFence(const FenceDesc& Desc, IFence** ppFence)
412423 {
413424 CreateDeviceObject("Fence", Desc, ppFence,
291291 new (&GetResource<BuffUAVBindInfo>(bufUav++)) BuffUAVBindInfo(BuffUAV, *this, VarType);
292292 NumUAVSlots = std::max(NumUAVSlots, Uint32{BuffUAV.BindPoint} + Uint32{BuffUAV.BindCount});
293293 }
294 },
295
296 [&](const D3DShaderResourceAttribs&, Uint32) //
297 {
298 UNEXPECTED("acceleration structure is not supported in DirectX 11");
294299 });
295300
296301 // clang-format off
9393 Resources.m_MaxSRVBindPoint = std::max(Resources.m_MaxSRVBindPoint, static_cast<MaxBindPointType>(TexAttribs.BindPoint + TexAttribs.BindCount - 1));
9494 }
9595
96 void OnNewAccelStruct(const D3DShaderResourceAttribs& ASAttribs)
97 {
98 UNEXPECTED("Acceleration structure is not supported in DirectX 11");
99 }
100
96101 ~NewResourceHandler()
97102 {
98103 }
438443 return;
439444 }
440445 }
446 },
447
448 [&](const D3DShaderResourceAttribs&, Uint32) //
449 {
450 UNEXPECTED("acceleration structure is not supported in DirectX 11");
441451 } // clang-format off
442452 ); // clang-format on
443453 }
182182 {
183183 if (pPSO != m_pCurPipelineState)
184184 {
185 m_pCommandList->SetPipelineState(m_pCurPipelineState = pPSO);
185 m_pCommandList->SetPipelineState(pPSO);
186 m_pCurPipelineState = pPSO;
186187 }
187188 }
188189
217218 CComPtr<ID3D12GraphicsCommandList> m_pCommandList;
218219 CComPtr<ID3D12CommandAllocator> m_pCurrentAllocator;
219220
220 ID3D12PipelineState* m_pCurPipelineState = nullptr;
221 void* m_pCurPipelineState = nullptr;
221222 ID3D12RootSignature* m_pCurGraphicsRootSignature = nullptr;
222223 ID3D12RootSignature* m_pCurComputeRootSignature = nullptr;
223224
5252
5353 PipelineStateD3D12Impl(IReferenceCounters* pRefCounters, RenderDeviceD3D12Impl* pDeviceD3D12, const GraphicsPipelineStateCreateInfo& CreateInfo);
5454 PipelineStateD3D12Impl(IReferenceCounters* pRefCounters, RenderDeviceD3D12Impl* pDeviceD3D12, const ComputePipelineStateCreateInfo& CreateInfo);
55 PipelineStateD3D12Impl(IReferenceCounters* pRefCounters, RenderDeviceD3D12Impl* pDeviceD3D12, const RayTracingPipelineStateCreateInfo& CreateInfo);
5556 ~PipelineStateD3D12Impl();
5657
5758 virtual void DILIGENT_CALL_TYPE QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface) override final;
7576 virtual bool DILIGENT_CALL_TYPE IsCompatibleWith(const IPipelineState* pPSO) const override final;
7677
7778 /// Implementation of IPipelineStateD3D12::GetD3D12PipelineState().
78 virtual ID3D12PipelineState* DILIGENT_CALL_TYPE GetD3D12PipelineState() const override final { return m_pd3d12PSO; }
79 virtual ID3D12PipelineState* DILIGENT_CALL_TYPE GetD3D12PipelineState() const override final { return static_cast<ID3D12PipelineState*>(m_pd3d12PSO.p); }
80
81 /// Implementation of IPipelineStateD3D12::GetD3D12StateObject().
82 virtual ID3D12StateObject* DILIGENT_CALL_TYPE GetD3D12StateObject() const override final { return static_cast<ID3D12StateObject*>(m_pd3d12PSO.p); }
7983
8084 /// Implementation of IPipelineStateD3D12::GetD3D12RootSignature().
8185 virtual ID3D12RootSignature* DILIGENT_CALL_TYPE GetD3D12RootSignature() const override final { return m_RootSig.GetD3D12RootSignature(); }
120124 }
121125
122126 private:
123 struct D3D12PipelineShaderStageInfo
127 struct ShaderStageInfo
124128 {
125 const SHADER_TYPE Type;
126 ShaderD3D12Impl* const pShader;
127 D3D12PipelineShaderStageInfo(SHADER_TYPE _Type,
128 ShaderD3D12Impl* _pShader) :
129 Type{_Type},
130 pShader{_pShader}
131 {}
129 ShaderStageInfo() {}
130 ShaderStageInfo(SHADER_TYPE _Type, ShaderD3D12Impl* _pShader);
131
132 void Append(ShaderD3D12Impl* pShader);
133 size_t Count() const;
134
135 SHADER_TYPE Type;
136 std::vector<ShaderD3D12Impl*> Shaders;
132137 };
138 using TShaderStages = std::vector<ShaderStageInfo>;
133139
134140 template <typename PSOCreateInfoType>
135 void InitInternalObjects(const PSOCreateInfoType& CreateInfo, std::vector<D3D12PipelineShaderStageInfo>& ShaderStages);
136
137 void InitResourceLayouts(const PipelineStateCreateInfo& CreateInfo,
138 std::vector<D3D12PipelineShaderStageInfo>& ShaderStages);
141 void InitInternalObjects(const PSOCreateInfoType& CreateInfo, TShaderStages& ShaderStages);
142 void InitResourceLayouts(const PipelineStateCreateInfo& CreateInfo, TShaderStages& ShaderStages);
139143
140144 void Destruct();
141145
142 CComPtr<ID3D12PipelineState> m_pd3d12PSO;
143 RootSignature m_RootSig;
146 CComPtr<ID3D12DeviceChild> m_pd3d12PSO;
147 RootSignature m_RootSig;
144148
145149 // Must be defined before default SRB
146150 SRBMemoryAllocator m_SRBMemAllocator;
151155
152156 // Resource layout index in m_pShaderResourceLayouts array for every shader stage,
153157 // indexed by the shader type pipeline index (returned by GetShaderTypePipelineIndex)
154 std::array<Int8, MAX_SHADERS_IN_PIPELINE> m_ResourceLayoutIndex = {-1, -1, -1, -1, -1};
158 std::array<Int8, MAX_SHADERS_IN_PIPELINE> m_ResourceLayoutIndex = {-1, -1, -1, -1, -1, -1};
155159 };
156160
157161 } // namespace Diligent
6767 /// Implementation of IRenderDevice::CreateComputePipelineState() in Direct3D12 backend.
6868 virtual void DILIGENT_CALL_TYPE CreateComputePipelineState(const ComputePipelineStateCreateInfo& PSOCreateInfo, IPipelineState** ppPipelineState) override final;
6969
70 /// Implementation of IRenderDevice::CreateRayTracingPipelineState() in Direct3D12 backend.
71 virtual void DILIGENT_CALL_TYPE CreateRayTracingPipelineState(const RayTracingPipelineStateCreateInfo& PSOCreateInfo, IPipelineState** ppPipelineState) override final;
72
7073 /// Implementation of IRenderDevice::CreateBuffer() in Direct3D12 backend.
7174 virtual void DILIGENT_CALL_TYPE CreateBuffer(const BufferDesc& BuffDesc,
7275 const BufferData* pBuffData,
168171
169172 IDXCompiler* GetDxCompiler() const { return m_pDxCompiler.get(); }
170173
171 #ifdef D3D12_H_HAS_MESH_SHADER
172174 ID3D12Device2* GetD3D12Device2();
173 #endif
175 ID3D12Device5* GetD3D12Device5();
174176
175177 ShaderVersion GetMaxShaderModel() const;
176178 D3D_FEATURE_LEVEL GetD3DFeatureLevel() const;
184186
185187 CComPtr<ID3D12Device> m_pd3d12Device;
186188
187 #ifdef D3D12_H_HAS_MESH_SHADER
188189 CComPtr<ID3D12Device2> m_pd3d12Device2;
189 #endif
190 CComPtr<ID3D12Device5> m_pd3d12Device5;
190191
191192 EngineD3D12CreateInfo m_EngineAttribs;
192193
3535 namespace Diligent
3636 {
3737
38 SHADER_TYPE ShaderTypeFromShaderVisibility(D3D12_SHADER_VISIBILITY ShaderVisibility);
3938 D3D12_SHADER_VISIBILITY GetShaderVisibility(SHADER_TYPE ShaderType);
4039 D3D12_DESCRIPTOR_HEAP_TYPE dbgHeapTypeFromRangeType(D3D12_DESCRIPTOR_RANGE_TYPE RangeType);
4140
513512 class CommandContext& Ctx,
514513 bool IsCompute,
515514 bool ValidateStates) const;
515
516 #ifdef DILIGENT_DEBUG
517 SHADER_TYPE m_DbgShaderStages = SHADER_TYPE_UNKNOWN;
518 #endif
516519 };
517520
518521 void RootSignature::CommitRootViews(ShaderResourceCacheD3D12& ResourceCache,
533536
534537 SHADER_TYPE dbgShaderType = SHADER_TYPE_UNKNOWN;
535538 #ifdef DILIGENT_DEBUG
536 {
537 auto& Param = static_cast<const D3D12_ROOT_PARAMETER&>(RootView);
538 VERIFY_EXPR(Param.ParameterType == D3D12_ROOT_PARAMETER_TYPE_CBV);
539 dbgShaderType = ShaderTypeFromShaderVisibility(Param.ShaderVisibility);
540 }
539 dbgShaderType = m_DbgShaderStages;
541540 #endif
542541
543542 auto& Res = ResourceCache.GetRootTable(RootInd).GetResource(0, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, dbgShaderType);
3333 #include "ShaderD3D12.h"
3434 #include "ShaderBase.hpp"
3535 #include "ShaderD3DBase.hpp"
36 #include "ShaderResourceLayoutD3D12.hpp"
3736 #include "RenderDeviceD3D12Impl.hpp"
38 #include "ShaderVariableD3D12.hpp"
37 #include "ShaderResourcesD3D12.hpp"
3938
4039 namespace Diligent
4140 {
7372 ResourceDesc = m_pShaderResources->GetHLSLShaderResourceDesc(Index);
7473 }
7574
76 ID3DBlob* GetShaderByteCode() { return m_pShaderByteCode; }
75 ID3DBlob* GetShaderByteCode() { return m_pShaderByteCode; }
76 const Char* GetEntryPoint() const { return m_EntryPoint.c_str(); }
7777
7878 const std::shared_ptr<const ShaderResourcesD3D12>& GetShaderResources() const { return m_pShaderResources; }
7979
8181 // ShaderResources class instance must be referenced through the shared pointer, because
8282 // it is referenced by ShaderResourceLayoutD3D12 class instances
8383 std::shared_ptr<const ShaderResourcesD3D12> m_pShaderResources;
84
85 String m_EntryPoint;
8486 };
8587
8688 } // namespace Diligent
8484
8585 // Resource layout index in m_ShaderResourceCache array for every shader stage,
8686 // indexed by the shader type pipeline index (returned by GetShaderTypePipelineIndex)
87 std::array<Int8, MAX_SHADERS_IN_PIPELINE> m_ResourceLayoutIndex = {-1, -1, -1, -1, -1};
87 std::array<Int8, MAX_SHADERS_IN_PIPELINE> m_ResourceLayoutIndex = {-1, -1, -1, -1, -1, -1};
8888
8989 bool m_bStaticResourcesInitialized = false;
9090 const Uint8 m_NumShaders = 0;
9696 TexUAV,
9797 BufUAV,
9898 Sampler,
99 AccelStruct,
99100 NumTypes
100101 };
101102
165166 const SHADER_TYPE dbgRefShaderType) const
166167 {
167168 VERIFY(m_dbgHeapType == dbgDescriptorHeapType, "Incosistent descriptor heap type");
168 VERIFY(m_dbgShaderType == dbgRefShaderType, "Incosistent shader type");
169 VERIFY((m_dbgShaderType & dbgRefShaderType) == dbgRefShaderType, "Incosistent shader type");
169170
170171 VERIFY(OffsetFromTableStart < m_NumResources, "Root table is not large enough to store descriptor at offset ", OffsetFromTableStart);
171172 return m_pResources[OffsetFromTableStart];
102102 #include "ShaderBase.hpp"
103103 #include "ShaderResourcesD3D12.hpp"
104104 #include "ShaderResourceCacheD3D12.hpp"
105 #include "ShaderD3D12Impl.hpp"
105106
106107 namespace Diligent
107108 {
120121 // - initialize reference layouts that address all types of resources (static, mutable, dynamic).
121122 // Root indices and descriptor table offsets are assigned during the initialization;
122123 // no shader resource cache is provided
123 void Initialize(ID3D12Device* pd3d12Device,
124 PIPELINE_TYPE PipelineType,
125 const PipelineResourceLayoutDesc& ResourceLayout,
126 std::shared_ptr<const ShaderResourcesD3D12> pSrcResources,
127 IMemoryAllocator& LayoutDataAllocator,
128 const SHADER_RESOURCE_VARIABLE_TYPE* const VarTypes,
129 Uint32 NumAllowedTypes,
130 ShaderResourceCacheD3D12* pResourceCache,
131 class RootSignature* pRootSig);
124 void Initialize(ID3D12Device* pd3d12Device,
125 PIPELINE_TYPE PipelineType,
126 const PipelineResourceLayoutDesc& ResourceLayout,
127 const std::vector<ShaderD3D12Impl*>& Shaders,
128 IMemoryAllocator& LayoutDataAllocator,
129 const SHADER_RESOURCE_VARIABLE_TYPE* const VarTypes,
130 Uint32 NumAllowedTypes,
131 ShaderResourceCacheD3D12* pResourceCache,
132 class RootSignature* pRootSig);
132133
133134 // clang-format off
134135 ShaderResourceLayoutD3D12 (const ShaderResourceLayoutD3D12&) = delete;
164165 static_assert( static_cast<int>(CachedResourceType::NumTypes) < (1 << ResourceTypeBits), "3 bits is not enough to store CachedResourceType");
165166
166167 /* 0 */ const ShaderResourceLayoutD3D12& ParentResLayout;
167 /* 8 */ const D3DShaderResourceAttribs& Attribs;
168168 /*16 */ const Uint32 OffsetFromTableStart;
169169 /*20.0*/ const Uint16 ResourceType : ResourceTypeBits; // | 0 1 2 |
170170 /*20.3*/ const Uint16 VariableType : VariableTypeBits; // | 3 4 |
171171 /*20.5*/ const Uint16 RootIndex : RootIndexBits; // | 5 6 7 ... 15 |
172172 /*22 */ const Uint16 SamplerId;
173 /*24 */ // End of data
173 /* */ const char* const Name;
174 /* */ const Uint16 BindCount;
175 /* */ const Uint16 BindPoint;
176 /* */ const Uint8 InputType;
177 /* */ const Uint8 SRVDimension;
178 /* */ // End of data
174179
175180 // clang-format on
176181
177182 D3D12Resource(const ShaderResourceLayoutD3D12& _ParentLayout,
178 const D3DShaderResourceAttribs& _Attribs,
179183 SHADER_RESOURCE_VARIABLE_TYPE _VariableType,
180184 CachedResourceType _ResType,
181185 Uint32 _RootIndex,
182186 Uint32 _OffsetFromTableStart,
183 Uint32 _SamplerId) noexcept :
187 Uint32 _SamplerId,
188 const char* _Name,
189 Uint32 _BindCount,
190 Uint32 _BindPoint,
191 D3D_SHADER_INPUT_TYPE _InputType,
192 D3D_SRV_DIMENSION _SRVDimension) noexcept :
184193 // clang-format off
185194 ParentResLayout {_ParentLayout },
186 Attribs {_Attribs },
187195 ResourceType {static_cast<Uint16>(_ResType) },
188196 VariableType {static_cast<Uint16>(_VariableType)},
189197 RootIndex {static_cast<Uint16>(_RootIndex) },
190198 SamplerId {static_cast<Uint16>(_SamplerId) },
191 OffsetFromTableStart{ _OffsetFromTableStart }
199 OffsetFromTableStart{ _OffsetFromTableStart },
200 Name {_Name},
201 BindCount {static_cast<Uint16>(_BindCount) },
202 BindPoint {static_cast<Uint16>(_BindPoint) },
203 InputType {static_cast<Uint8>(_InputType) },
204 SRVDimension {static_cast<Uint8>(_SRVDimension) }
192205 // clang-format on
193206 {
194207 VERIFY(IsValidOffset(), "Offset must be valid");
197210 VERIFY(_VariableType < (1 << VariableTypeBits), "Variable type is out of representable range");
198211 VERIFY(_SamplerId == InvalidSamplerId || _SamplerId <= MaxSamplerId, "Sampler id (", _SamplerId, ") exceeds max allowed value (", MaxSamplerId, ")");
199212 VERIFY(_SamplerId == InvalidSamplerId || GetResType() == CachedResourceType::TexSRV, "A sampler can only be assigned to a Texture SRV");
213 VERIFY(_BindCount <= std::numeric_limits<decltype(BindCount)>::max(), "BindCount (", _BindCount, ") exceeds max representable value ", std::numeric_limits<decltype(BindCount)>::max());
214 VERIFY(_BindPoint <= std::numeric_limits<decltype(BindPoint)>::max(), "BindPoint (", _BindPoint, ") exceeds max representable value ", std::numeric_limits<decltype(BindPoint)>::max());
215 VERIFY(_InputType <= std::numeric_limits<decltype(InputType)>::max(), "InputType (", _InputType, ") exceeds max representable value ", std::numeric_limits<decltype(InputType)>::max());
216 VERIFY(_SRVDimension <= std::numeric_limits<decltype(SRVDimension)>::max(), "SRVDimension (", _SRVDimension, ") exceeds max representable value ", std::numeric_limits<decltype(SRVDimension)>::max());
200217 }
201218
202219 bool IsBound(Uint32 ArrayIndex,
214231
215232 CachedResourceType GetResType() const { return static_cast<CachedResourceType>(ResourceType); }
216233 SHADER_RESOURCE_VARIABLE_TYPE GetVariableType() const { return static_cast<SHADER_RESOURCE_VARIABLE_TYPE>(VariableType); }
234 HLSLShaderResourceDesc GetHLSLResourceDesc() const;
235
236 bool IsValidBindPoint() const
237 {
238 return BindPoint != D3DShaderResourceAttribs::InvalidBindPoint;
239 }
240
241 String GetPrintName(Uint32 ArrayInd) const
242 {
243 VERIFY_EXPR(ArrayInd < BindCount);
244 if (BindCount > 1)
245 return String(Name) + '[' + std::to_string(ArrayInd) + ']';
246 else
247 return Name;
248 }
249
250 D3D_SHADER_INPUT_TYPE GetInputType() const
251 {
252 return static_cast<D3D_SHADER_INPUT_TYPE>(InputType);
253 }
254
255 D3D_SRV_DIMENSION GetSRVDimension() const
256 {
257 return static_cast<D3D_SRV_DIMENSION>(SRVDimension);
258 }
259
260 RESOURCE_DIMENSION GetResourceDimension() const;
261
262 bool IsMultisample() const;
217263
218264 private:
219265 void CacheCB(IDeviceObject* pBuffer,
236282 ShaderResourceCacheD3D12::Resource& DstSam,
237283 Uint32 ArrayIndex,
238284 D3D12_CPU_DESCRIPTOR_HANDLE ShdrVisibleHeapCPUDescriptorHandle) const;
285
286 void CacheAccelStruct(IDeviceObject* pTLAS,
287 ShaderResourceCacheD3D12::Resource& DstRes,
288 Uint32 ArrayIndex,
289 D3D12_CPU_DESCRIPTOR_HANDLE ShdrVisibleHeapCPUDescriptorHandle) const;
239290 };
240291
241292 void CopyStaticResourceDesriptorHandles(const ShaderResourceCacheD3D12& SrcCache,
271322 return GetResource(GetSamplerOffset(VarType, s));
272323 }
273324
274 const bool IsUsingSeparateSamplers() const { return !m_pResources->IsUsingCombinedTextureSamplers(); }
275
276 SHADER_TYPE GetShaderType() const { return m_pResources->GetShaderType(); }
277
278 const ShaderResourcesD3D12& GetResources() const { return *m_pResources; }
325 const bool IsUsingSeparateSamplers() const { return m_IsUsingSeparateSamplers; }
326
327 SHADER_TYPE GetShaderType() const { return m_ShaderType; }
279328
280329 private:
281330 const D3D12Resource& GetAssignedSampler(const D3D12Resource& TexSrv) const;
283332
284333 const Char* GetShaderName() const
285334 {
286 return m_pResources->GetShaderName();
335 return ""; // AZ TODO
287336 }
288337
289338
352401 /* 16 */ std::array<Uint16, SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES + 1> m_CbvSrvUavOffsets = {};
353402 /* 24 */ std::array<Uint16, SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES + 1> m_SamplersOffsets = {};
354403
355 /* 32 */ IObject& m_Owner;
356 /* 48 */ CComPtr<ID3D12Device> m_pd3d12Device;
357 // We must use shared_ptr to reference ShaderResources instance, because
358 // there may be multiple objects referencing the same set of resources
359 /* 48 */ std::shared_ptr<const ShaderResourcesD3D12> m_pResources;
404 /* 24 */ StringPool m_StringPool;
405 /* 32 */ IObject& m_Owner;
406 /* 48 */ CComPtr<ID3D12Device> m_pd3d12Device;
407 /* */ SHADER_TYPE m_ShaderType = SHADER_TYPE_UNKNOWN;
408 /* */ bool m_IsUsingSeparateSamplers = false;
360409 /* 64 */ // End of data
361410
362411 // clang-format on
185185
186186 virtual void DILIGENT_CALL_TYPE SetArray(IDeviceObject* const* ppObjects, Uint32 FirstElement, Uint32 NumElements) override final
187187 {
188 VerifyAndCorrectSetArrayArguments(m_Resource.Attribs.Name, m_Resource.Attribs.BindCount, FirstElement, NumElements);
188 VerifyAndCorrectSetArrayArguments(m_Resource.Name, m_Resource.BindCount, FirstElement, NumElements);
189189 for (Uint32 Elem = 0; Elem < NumElements; ++Elem)
190190 m_Resource.BindResource(ppObjects[Elem], FirstElement + Elem, m_ParentManager.m_ResourceCache);
191191 }
197197
198198 virtual HLSLShaderResourceDesc DILIGENT_CALL_TYPE GetHLSLResourceDesc() const override final
199199 {
200 return m_Resource.Attribs.GetHLSLResourceDesc();
200 return m_Resource.GetHLSLResourceDesc();
201201 }
202202
203203 virtual Uint32 DILIGENT_CALL_TYPE GetIndex() const override final
5353 /// so Release() must not be called.
5454 VIRTUAL ID3D12PipelineState* METHOD(GetD3D12PipelineState)(THIS) CONST PURE;
5555
56 /// Returns ID3D12StateObject interface of the internal D3D12 state object for ray tracing.
57
58 /// The method does *NOT* call AddRef() on the returned interface,
59 /// so Release() must not be called.
60 VIRTUAL ID3D12StateObject* METHOD(GetD3D12StateObject)(THIS) CONST PURE;
61
5662 /// Returns a pointer to the root signature object associated with this pipeline state.
5763
5864 /// The method does *NOT* call AddRef() on the returned interface,
218218
219219 TDeviceContextBase::SetPipelineState(pPipelineStateD3D12, 0 /*Dummy*/);
220220
221 auto& CmdCtx = GetCmdContext();
222 auto* pd3d12PSO = pPipelineStateD3D12->GetD3D12PipelineState();
221 auto& CmdCtx = GetCmdContext();
223222
224223 switch (PSODesc.PipelineType)
225224 {
228227 {
229228 auto& GraphicsPipeline = pPipelineStateD3D12->GetGraphicsPipelineDesc();
230229 auto& GraphicsCtx = CmdCtx.AsGraphicsContext();
230 auto* pd3d12PSO = pPipelineStateD3D12->GetD3D12PipelineState();
231231 GraphicsCtx.SetPipelineState(pd3d12PSO);
232232
233233 if (PSODesc.PipelineType == PIPELINE_TYPE_GRAPHICS)
253253 }
254254 break;
255255 }
256
257256 case PIPELINE_TYPE_COMPUTE:
258257 {
258 auto* pd3d12PSO = pPipelineStateD3D12->GetD3D12PipelineState();
259259 CmdCtx.AsComputeContext().SetPipelineState(pd3d12PSO);
260260 break;
261261 }
262
262 case PIPELINE_TYPE_RAY_TRACING:
263 {
264 break;
265 }
263266 default:
264267 UNEXPECTED("unknown pipeline type");
265268 }
3636 #include "EngineMemory.h"
3737 #include "StringTools.hpp"
3838 #include "ShaderVariableD3D12.hpp"
39 #include "DynamicLinearAllocator.hpp"
3940
4041 namespace Diligent
4142 {
6970 # pragma warning(pop)
7071 #endif
7172
72 } // namespace
7373
7474 class PrimitiveTopology_To_D3D12_PRIMITIVE_TOPOLOGY_TYPE
7575 {
9797 std::array<D3D12_PRIMITIVE_TOPOLOGY_TYPE, PRIMITIVE_TOPOLOGY_NUM_TOPOLOGIES> m_Map;
9898 };
9999
100
101 template <typename TNameToGroupIndexMap>
102 void BuildRTPipelineDescription(const RayTracingPipelineStateCreateInfo& CreateInfo,
103 TNameToGroupIndexMap& NameToGroupIndex,
104 std::vector<D3D12_STATE_SUBOBJECT>& Subobjects,
105 DynamicLinearAllocator& TempPool,
106 LinearAllocator& MemPool)
107 {
108 #define LOG_PSO_ERROR_AND_THROW(...) LOG_ERROR_AND_THROW("Description of ray tracing PSO '", CreateInfo.PSODesc.Name, "' is invalid: ", ##__VA_ARGS__)
109
110 Uint32 ShaderIndex = 0;
111 Uint32 GroupIndex = 0;
112 std::unordered_map<IShader*, LPCWSTR> UniqueShaders;
113
114 const auto ShaderIndexToStr = [&TempPool](Uint32 Index) -> LPCWSTR {
115 const Uint32 Len = sizeof(Index) * 2;
116 auto* Dst = TempPool.Allocate<WCHAR>(Len + 1);
117 for (Uint32 i = 0; i < Len; ++i)
118 {
119 Uint32 c = Index & 0xF;
120 Dst[i] = static_cast<WCHAR>(c < 10 ? '0' + c : 'A' + c - 10);
121 Index >>= 4;
122 }
123 Dst[Len] = 0;
124 return Dst;
125 };
126
127 const auto AddDxilLib = [&](IShader* pShader, const char* Name) -> LPCWSTR {
128 if (pShader != nullptr)
129 {
130 auto Result = UniqueShaders.emplace(pShader, nullptr);
131 if (Result.second)
132 {
133 auto& LibDesc = *TempPool.Allocate<D3D12_DXIL_LIBRARY_DESC>();
134 auto& ExportDesc = *TempPool.Allocate<D3D12_EXPORT_DESC>();
135 auto* pShaderD3D12 = ValidatedCast<ShaderD3D12Impl>(pShader);
136
137 LibDesc.DXILLibrary.BytecodeLength = pShaderD3D12->GetShaderByteCode()->GetBufferSize();
138 LibDesc.DXILLibrary.pShaderBytecode = pShaderD3D12->GetShaderByteCode()->GetBufferPointer();
139 LibDesc.NumExports = 1;
140 LibDesc.pExports = &ExportDesc;
141
142 ExportDesc.Flags = D3D12_EXPORT_FLAG_NONE;
143 ExportDesc.ExportToRename = TempPool.CopyWString(pShaderD3D12->GetEntryPoint());
144
145 if (Name != nullptr)
146 ExportDesc.Name = TempPool.CopyWString(Name);
147 else
148 ExportDesc.Name = ShaderIndexToStr(++ShaderIndex);
149
150 Subobjects.push_back({D3D12_STATE_SUBOBJECT_TYPE_DXIL_LIBRARY, &LibDesc});
151
152 Result.first->second = ExportDesc.Name;
153 return ExportDesc.Name;
154 }
155 else
156 return Result.first->second;
157 }
158 return nullptr;
159 };
160
161 for (Uint32 i = 0; i < CreateInfo.GeneralShaderCount; ++i)
162 {
163 AddDxilLib(CreateInfo.pGeneralShaders[i].pShader, CreateInfo.pGeneralShaders[i].Name);
164
165 bool IsUniqueName = NameToGroupIndex.emplace(HashMapStringKey{MemPool.CopyString(CreateInfo.pGeneralShaders[i].Name)}, GroupIndex++).second;
166 if (!IsUniqueName)
167 LOG_PSO_ERROR_AND_THROW("pGeneralShaders[", i, "].Name must be unique");
168 }
169
170 for (Uint32 i = 0; i < CreateInfo.TriangleHitShaderCount; ++i)
171 {
172 auto& HitGroupDesc = *TempPool.Allocate<D3D12_HIT_GROUP_DESC>();
173 HitGroupDesc.HitGroupExport = TempPool.CopyWString(CreateInfo.pTriangleHitShaders[i].Name);
174 HitGroupDesc.Type = D3D12_HIT_GROUP_TYPE_TRIANGLES;
175 HitGroupDesc.ClosestHitShaderImport = AddDxilLib(CreateInfo.pTriangleHitShaders[i].pClosestHitShader, nullptr);
176 HitGroupDesc.AnyHitShaderImport = AddDxilLib(CreateInfo.pTriangleHitShaders[i].pAnyHitShader, nullptr);
177 HitGroupDesc.IntersectionShaderImport = nullptr;
178
179 Subobjects.push_back({D3D12_STATE_SUBOBJECT_TYPE_HIT_GROUP, &HitGroupDesc});
180
181 bool IsUniqueName = NameToGroupIndex.emplace(HashMapStringKey{MemPool.CopyString(CreateInfo.pTriangleHitShaders[i].Name)}, GroupIndex++).second;
182 if (!IsUniqueName)
183 LOG_PSO_ERROR_AND_THROW("pTriangleHitShaders[", i, "].Name must be unique");
184 }
185
186 for (Uint32 i = 0; i < CreateInfo.ProceduralHitShaderCount; ++i)
187 {
188 auto& HitGroupDesc = *TempPool.Allocate<D3D12_HIT_GROUP_DESC>();
189 HitGroupDesc.HitGroupExport = TempPool.CopyWString(CreateInfo.pProceduralHitShaders[i].Name);
190 HitGroupDesc.Type = D3D12_HIT_GROUP_TYPE_PROCEDURAL_PRIMITIVE;
191 HitGroupDesc.ClosestHitShaderImport = AddDxilLib(CreateInfo.pProceduralHitShaders[i].pClosestHitShader, nullptr);
192 HitGroupDesc.AnyHitShaderImport = AddDxilLib(CreateInfo.pProceduralHitShaders[i].pAnyHitShader, nullptr);
193 HitGroupDesc.IntersectionShaderImport = AddDxilLib(CreateInfo.pProceduralHitShaders[i].pIntersectionShader, nullptr);
194
195 Subobjects.push_back({D3D12_STATE_SUBOBJECT_TYPE_HIT_GROUP, &HitGroupDesc});
196
197 bool IsUniqueName = NameToGroupIndex.emplace(HashMapStringKey{MemPool.CopyString(CreateInfo.pProceduralHitShaders[i].Name)}, GroupIndex++).second;
198 if (!IsUniqueName)
199 LOG_PSO_ERROR_AND_THROW("pProceduralHitShaders[", i, "].Name must be unique");
200 }
201
202 VERIFY_EXPR(Uint32(CreateInfo.GeneralShaderCount + CreateInfo.TriangleHitShaderCount + CreateInfo.ProceduralHitShaderCount) == GroupIndex);
203
204 if (CreateInfo.RayTracingPipeline.MaxRecursionDepth > D3D12_RAYTRACING_MAX_DECLARABLE_TRACE_RECURSION_DEPTH)
205 LOG_PSO_ERROR_AND_THROW("MaxRecursionDepth must be less than equal to ", D3D12_RAYTRACING_MAX_DECLARABLE_TRACE_RECURSION_DEPTH);
206
207 auto& PipelineConfig = *TempPool.Allocate<D3D12_RAYTRACING_PIPELINE_CONFIG>();
208 // for compatibility with Vulkan set minimal recursion depth to 1
209 PipelineConfig.MaxTraceRecursionDepth = std::max<Uint32>(1, CreateInfo.RayTracingPipeline.MaxRecursionDepth);
210 Subobjects.push_back({D3D12_STATE_SUBOBJECT_TYPE_RAYTRACING_PIPELINE_CONFIG, &PipelineConfig});
211
212 auto& ShaderConfig = *TempPool.Allocate<D3D12_RAYTRACING_SHADER_CONFIG>();
213 ShaderConfig.MaxAttributeSizeInBytes = D3D12_RAYTRACING_MAX_ATTRIBUTE_SIZE_IN_BYTES;
214 ShaderConfig.MaxPayloadSizeInBytes = 32; // AZ TODO
215 Subobjects.push_back({D3D12_STATE_SUBOBJECT_TYPE_RAYTRACING_SHADER_CONFIG, &ShaderConfig});
216 #undef LOG_PSO_ERROR_AND_THROW
217 }
218
219 template <typename TNameToGroupIndexMap>
220 void GetShaderIdentifiers(ID3D12StateObject* pSO,
221 const RayTracingPipelineStateCreateInfo& CreateInfo,
222 const TNameToGroupIndexMap& NameToGroupIndex,
223 Uint8* ShaderData)
224 {
225 const Uint32 ShaderIdentifierSize = D3D12_SHADER_IDENTIFIER_SIZE_IN_BYTES;
226
227 WCHAR TempName[256] = {};
228 auto ConvertWStr = [&TempName](const char* Src) {
229 Uint32 i = 0;
230 for (; i < _countof(TempName) && Src[i] != 0; ++i)
231 TempName[i] = static_cast<WCHAR>(Src[i]);
232 TempName[i] = 0;
233 return TempName;
234 };
235
236 CComPtr<ID3D12StateObjectProperties> pStateObjectProperties;
237 auto hr = pSO->QueryInterface(IID_PPV_ARGS(&pStateObjectProperties));
238 if (FAILED(hr))
239 LOG_ERROR_AND_THROW("Failed to get state object properties");
240
241 for (Uint32 i = 0; i < CreateInfo.GeneralShaderCount; ++i)
242 {
243 auto iter = NameToGroupIndex.find(CreateInfo.pGeneralShaders[i].Name);
244 if (iter == NameToGroupIndex.end())
245 LOG_ERROR_AND_THROW("Failed to get shader group index by name");
246
247 WCHAR* ShaderName = ConvertWStr(CreateInfo.pGeneralShaders[i].Name);
248 const void* ShaderID = pStateObjectProperties->GetShaderIdentifier(ShaderName);
249 if (ShaderID == nullptr)
250 LOG_ERROR_AND_THROW("Failed to get shader identifier");
251
252 std::memcpy(&ShaderData[ShaderIdentifierSize * iter->second], ShaderID, ShaderIdentifierSize);
253 }
254 for (Uint32 i = 0; i < CreateInfo.TriangleHitShaderCount; ++i)
255 {
256 auto iter = NameToGroupIndex.find(CreateInfo.pTriangleHitShaders[i].Name);
257 if (iter == NameToGroupIndex.end())
258 LOG_ERROR_AND_THROW("Failed to get shader group index by name");
259
260 WCHAR* ShaderName = ConvertWStr(CreateInfo.pTriangleHitShaders[i].Name);
261 const void* ShaderID = pStateObjectProperties->GetShaderIdentifier(ShaderName);
262 if (ShaderID == nullptr)
263 LOG_ERROR_AND_THROW("Failed to get shader identifier");
264
265 std::memcpy(&ShaderData[ShaderIdentifierSize * iter->second], ShaderID, ShaderIdentifierSize);
266 }
267 for (Uint32 i = 0; i < CreateInfo.ProceduralHitShaderCount; ++i)
268 {
269 auto iter = NameToGroupIndex.find(CreateInfo.pProceduralHitShaders[i].Name);
270 if (iter == NameToGroupIndex.end())
271 LOG_ERROR_AND_THROW("Failed to get shader group index by name");
272
273 WCHAR* ShaderName = ConvertWStr(CreateInfo.pProceduralHitShaders[i].Name);
274 const void* ShaderID = pStateObjectProperties->GetShaderIdentifier(ShaderName);
275 if (ShaderID == nullptr)
276 LOG_ERROR_AND_THROW("Failed to get shader identifier");
277
278 std::memcpy(&ShaderData[ShaderIdentifierSize * iter->second], ShaderID, ShaderIdentifierSize);
279 }
280 }
281
282 } // namespace
283
284
285 PipelineStateD3D12Impl::ShaderStageInfo::ShaderStageInfo(SHADER_TYPE _Type, ShaderD3D12Impl* _pShader) :
286 Type{_Type}
287 {
288 Shaders.push_back(_pShader);
289 }
290
291 void PipelineStateD3D12Impl::ShaderStageInfo::Append(ShaderD3D12Impl* pShader)
292 {
293 Shaders.push_back(pShader);
294 }
295
296 size_t PipelineStateD3D12Impl::ShaderStageInfo::Count() const
297 {
298 return Shaders.size();
299 }
300
301
100302 template <typename PSOCreateInfoType>
101 void PipelineStateD3D12Impl::InitInternalObjects(const PSOCreateInfoType& CreateInfo,
102 std::vector<D3D12PipelineShaderStageInfo>& ShaderStages)
303 void PipelineStateD3D12Impl::InitInternalObjects(const PSOCreateInfoType& CreateInfo,
304 TShaderStages& ShaderStages)
103305 {
104306 m_ResourceLayoutIndex.fill(-1);
105307
150352 {
151353 try
152354 {
153 std::vector<D3D12PipelineShaderStageInfo> ShaderStages;
154
355 TShaderStages ShaderStages;
155356 InitInternalObjects(CreateInfo, ShaderStages);
156357
157358 auto pd3d12Device = pDeviceD3D12->GetD3D12Device();
163364
164365 for (const auto& Stage : ShaderStages)
165366 {
166 auto* pShaderD3D12 = Stage.pShader;
367 VERIFY_EXPR(Stage.Shaders.size() == 1);
368 auto* pShaderD3D12 = Stage.Shaders[0];
167369 auto ShaderType = pShaderD3D12->GetDesc().ShaderType;
168370 VERIFY_EXPR(ShaderType == Stage.Type);
169371
170372 D3D12_SHADER_BYTECODE* pd3d12ShaderBytecode = nullptr;
171373 switch (ShaderType)
172374 {
173 // clang-format off
174 case SHADER_TYPE_VERTEX: pd3d12ShaderBytecode = &d3d12PSODesc.VS; break;
175 case SHADER_TYPE_PIXEL: pd3d12ShaderBytecode = &d3d12PSODesc.PS; break;
176 case SHADER_TYPE_GEOMETRY: pd3d12ShaderBytecode = &d3d12PSODesc.GS; break;
177 case SHADER_TYPE_HULL: pd3d12ShaderBytecode = &d3d12PSODesc.HS; break;
178 case SHADER_TYPE_DOMAIN: pd3d12ShaderBytecode = &d3d12PSODesc.DS; break;
375 // clang-format off
376 case SHADER_TYPE_VERTEX: pd3d12ShaderBytecode = &d3d12PSODesc.VS; break;
377 case SHADER_TYPE_PIXEL: pd3d12ShaderBytecode = &d3d12PSODesc.PS; break;
378 case SHADER_TYPE_GEOMETRY: pd3d12ShaderBytecode = &d3d12PSODesc.GS; break;
379 case SHADER_TYPE_HULL: pd3d12ShaderBytecode = &d3d12PSODesc.HS; break;
380 case SHADER_TYPE_DOMAIN: pd3d12ShaderBytecode = &d3d12PSODesc.DS; break;
179381 // clang-format on
180382 default: UNEXPECTED("Unexpected shader type");
181383 }
236438 // The only valid bit is D3D12_PIPELINE_STATE_FLAG_TOOL_DEBUG, which can only be set on WARP devices.
237439 d3d12PSODesc.Flags = D3D12_PIPELINE_STATE_FLAG_NONE;
238440
239 HRESULT hr = pd3d12Device->CreateGraphicsPipelineState(&d3d12PSODesc, __uuidof(ID3D12PipelineState), reinterpret_cast<void**>(static_cast<ID3D12PipelineState**>(&m_pd3d12PSO)));
441 CComPtr<ID3D12PipelineState> pPSO;
442 HRESULT hr = pd3d12Device->CreateGraphicsPipelineState(&d3d12PSODesc, IID_PPV_ARGS(&pPSO));
240443 if (FAILED(hr))
241444 LOG_ERROR_AND_THROW("Failed to create pipeline state");
445
446 m_pd3d12PSO = pPSO;
242447 }
243448
244449 #ifdef D3D12_H_HAS_MESH_SHADER
267472
268473 for (const auto& Stage : ShaderStages)
269474 {
270 auto* pShaderD3D12 = Stage.pShader;
475 VERIFY_EXPR(Stage.Shaders.size() == 1);
476 auto* pShaderD3D12 = Stage.Shaders[0];
271477 auto ShaderType = pShaderD3D12->GetDesc().ShaderType;
272478 VERIFY_EXPR(ShaderType == Stage.Type);
273479
274480 D3D12_SHADER_BYTECODE* pd3d12ShaderBytecode = nullptr;
275481 switch (ShaderType)
276482 {
277 // clang-format off
278 case SHADER_TYPE_AMPLIFICATION: pd3d12ShaderBytecode = &d3d12PSODesc.AS; break;
279 case SHADER_TYPE_MESH: pd3d12ShaderBytecode = &d3d12PSODesc.MS; break;
280 case SHADER_TYPE_PIXEL: pd3d12ShaderBytecode = &d3d12PSODesc.PS; break;
483 // clang-format off
484 case SHADER_TYPE_AMPLIFICATION: pd3d12ShaderBytecode = &d3d12PSODesc.AS; break;
485 case SHADER_TYPE_MESH: pd3d12ShaderBytecode = &d3d12PSODesc.MS; break;
486 case SHADER_TYPE_PIXEL: pd3d12ShaderBytecode = &d3d12PSODesc.PS; break;
281487 // clang-format on
282488 default: UNEXPECTED("Unexpected shader type");
283489 }
320526 streamDesc.SizeInBytes = sizeof(d3d12PSODesc);
321527 streamDesc.pPipelineStateSubobjectStream = &d3d12PSODesc;
322528
323 auto* device2 = pDeviceD3D12->GetD3D12Device2();
324
325 CHECK_D3D_RESULT_THROW(device2->CreatePipelineState(&streamDesc, IID_PPV_ARGS(&m_pd3d12PSO)), "Failed to create pipeline state");
529 auto* device2 = pDeviceD3D12->GetD3D12Device2();
530 CComPtr<ID3D12PipelineState> pPSO;
531 HRESULT hr = device2->CreatePipelineState(&streamDesc, IID_PPV_ARGS(&pPSO));
532 if (FAILED(hr))
533 LOG_ERROR_AND_THROW("Failed to create pipeline state");
534
535 m_pd3d12PSO = pPSO;
326536 }
327537 #endif // D3D12_H_HAS_MESH_SHADER
328538 else
354564 {
355565 try
356566 {
357 std::vector<D3D12PipelineShaderStageInfo> ShaderStages;
358
567 TShaderStages ShaderStages;
359568 InitInternalObjects(CreateInfo, ShaderStages);
360569
361570 auto pd3d12Device = pDeviceD3D12->GetD3D12Device();
363572 D3D12_COMPUTE_PIPELINE_STATE_DESC d3d12PSODesc = {};
364573
365574 VERIFY_EXPR(ShaderStages[0].Type == SHADER_TYPE_COMPUTE);
366 auto* pByteCode = ShaderStages[0].pShader->GetShaderByteCode();
575 VERIFY_EXPR(ShaderStages[0].Shaders.size() == 1);
576 auto* pByteCode = ShaderStages[0].Shaders[0]->GetShaderByteCode();
367577 d3d12PSODesc.CS.pShaderBytecode = pByteCode->GetBufferPointer();
368578 d3d12PSODesc.CS.BytecodeLength = pByteCode->GetBufferSize();
369579
380590
381591 d3d12PSODesc.pRootSignature = m_RootSig.GetD3D12RootSignature();
382592
383 HRESULT hr = pd3d12Device->CreateComputePipelineState(&d3d12PSODesc, __uuidof(ID3D12PipelineState), reinterpret_cast<void**>(static_cast<ID3D12PipelineState**>(&m_pd3d12PSO)));
593 CComPtr<ID3D12PipelineState> pPSO;
594 HRESULT hr = pd3d12Device->CreateComputePipelineState(&d3d12PSODesc, IID_PPV_ARGS(&pPSO));
384595 if (FAILED(hr))
385596 LOG_ERROR_AND_THROW("Failed to create pipeline state");
597
598 m_pd3d12PSO = pPSO;
386599
387600 if (*m_Desc.Name != 0)
388601 {
400613 }
401614 }
402615
616 PipelineStateD3D12Impl::PipelineStateD3D12Impl(IReferenceCounters* pRefCounters,
617 RenderDeviceD3D12Impl* pDeviceD3D12,
618 const RayTracingPipelineStateCreateInfo& CreateInfo) :
619 TPipelineStateBase{pRefCounters, pDeviceD3D12, CreateInfo.PSODesc},
620 m_SRBMemAllocator{GetRawAllocator()}
621 {
622 try
623 {
624 m_ResourceLayoutIndex.fill(-1);
625
626 TShaderStages ShaderStages;
627 ExtractShaders<ShaderD3D12Impl>(CreateInfo, ShaderStages);
628
629 TNameToGroupIndexMap NameToGroupIndex;
630 std::vector<D3D12_STATE_SUBOBJECT> Subobjects;
631 const Uint32 ShaderIdentifierSize = D3D12_SHADER_IDENTIFIER_SIZE_IN_BYTES;
632 DynamicLinearAllocator TempPool{GetRawAllocator(), 4 << 10};
633 LinearAllocator MemPool{GetRawAllocator()};
634
635 const auto NumShaderStages = GetNumShaderStages();
636 VERIFY_EXPR(NumShaderStages > 0 && NumShaderStages == ShaderStages.size());
637
638 MemPool.AddSpace<ShaderResourceCacheD3D12>(NumShaderStages);
639 MemPool.AddSpace<ShaderResourceLayoutD3D12>(NumShaderStages * 2);
640 MemPool.AddSpace<ShaderVariableManagerD3D12>(NumShaderStages);
641
642 ReserveSpaceForPipelineDesc(CreateInfo, ShaderIdentifierSize, MemPool);
643
644 MemPool.Reserve();
645
646 m_pStaticResourceCaches = MemPool.ConstructArray<ShaderResourceCacheD3D12>(NumShaderStages, ShaderResourceCacheD3D12::DbgCacheContentType::StaticShaderResources);
647
648 // The memory is now owned by PipelineStateD3D12Impl and will be freed by Destruct().
649 auto* Ptr = MemPool.ReleaseOwnership();
650 VERIFY_EXPR(Ptr == m_pStaticResourceCaches);
651 (void)Ptr;
652
653 m_pShaderResourceLayouts = MemPool.ConstructArray<ShaderResourceLayoutD3D12>(NumShaderStages * 2, std::ref(*this));
654
655 m_pStaticVarManagers = MemPool.Allocate<ShaderVariableManagerD3D12>(NumShaderStages);
656 for (Uint32 s = 0; s < NumShaderStages; ++s)
657 new (m_pStaticVarManagers + s) ShaderVariableManagerD3D12{*this, GetStaticShaderResCache(s)};
658
659 BuildRTPipelineDescription(CreateInfo, NameToGroupIndex, Subobjects, TempPool, MemPool);
660 InitializePipelineDesc(CreateInfo, ShaderIdentifierSize, std::move(NameToGroupIndex), MemPool);
661
662 m_RootSig.AllocateImmutableSamplers(CreateInfo.PSODesc.ResourceLayout);
663
664 // It is important to construct all objects before initializing them because if an exception is thrown,
665 // destructors will be called for all objects
666
667 InitResourceLayouts(CreateInfo, ShaderStages);
668
669 D3D12_GLOBAL_ROOT_SIGNATURE GlobalRoot;
670 GlobalRoot.pGlobalRootSignature = m_RootSig.GetD3D12RootSignature();
671 Subobjects.push_back({D3D12_STATE_SUBOBJECT_TYPE_GLOBAL_ROOT_SIGNATURE, &GlobalRoot});
672
673 D3D12_STATE_OBJECT_DESC RTPipelineDesc;
674 RTPipelineDesc.Type = D3D12_STATE_OBJECT_TYPE_RAYTRACING_PIPELINE;
675 RTPipelineDesc.NumSubobjects = static_cast<UINT>(Subobjects.size());
676 RTPipelineDesc.pSubobjects = Subobjects.data();
677
678 auto pd3d12Device = pDeviceD3D12->GetD3D12Device5();
679 CComPtr<ID3D12StateObject> pSO;
680 HRESULT hr = pd3d12Device->CreateStateObject(&RTPipelineDesc, IID_PPV_ARGS(&pSO));
681 if (FAILED(hr))
682 LOG_ERROR_AND_THROW("Failed to create ray tracing state object");
683
684 m_pd3d12PSO = pSO;
685
686 GetShaderIdentifiers(pSO, CreateInfo, m_pRayTracingPipelineData->NameToGroupIndex, m_pRayTracingPipelineData->Shaders);
687
688 if (*m_Desc.Name != 0)
689 {
690 m_pd3d12PSO->SetName(WidenString(m_Desc.Name).c_str());
691 String RootSignatureDesc("Root signature for PSO '");
692 RootSignatureDesc.append(m_Desc.Name);
693 RootSignatureDesc.push_back('\'');
694 m_RootSig.GetD3D12RootSignature()->SetName(WidenString(RootSignatureDesc).c_str());
695 }
696 }
697 catch (...)
698 {
699 Destruct();
700 throw;
701 }
702 }
703
403704 PipelineStateD3D12Impl::~PipelineStateD3D12Impl()
404705 {
405706 Destruct();
407708
408709 void PipelineStateD3D12Impl::Destruct()
409710 {
711 TPipelineStateBase::Destruct();
712
410713 auto& ShaderResLayoutAllocator = GetRawAllocator();
411714 for (Uint32 s = 0; s < GetNumShaderStages(); ++s)
412715 {
443746 IMPLEMENT_QUERY_INTERFACE(PipelineStateD3D12Impl, IID_PipelineStateD3D12, TPipelineStateBase)
444747
445748
446 void PipelineStateD3D12Impl::InitResourceLayouts(const PipelineStateCreateInfo& CreateInfo,
447 std::vector<D3D12PipelineShaderStageInfo>& ShaderStages)
749 void PipelineStateD3D12Impl::InitResourceLayouts(const PipelineStateCreateInfo& CreateInfo,
750 TShaderStages& ShaderStages)
448751 {
449752 auto pd3d12Device = GetDevice()->GetD3D12Device();
450753 const auto& ResourceLayout = m_Desc.ResourceLayout;
451754
452 #ifdef DILIGENT_DEVELOPMENT
755 // AZ TODO
756 #if 0 //def DILIGENT_DEVELOPMENT
453757 {
454758 const ShaderResources* pResources[MAX_SHADERS_IN_PIPELINE] = {};
455759 for (size_t s = 0; s < ShaderStages.size(); ++s)
456760 {
457 const auto* pShader = ShaderStages[s].pShader;
761 const auto* pShader = ShaderStages[s].Shaders[0];
458762 pResources[s] = &(*pShader->GetShaderResources());
459763 }
460764 ShaderResources::DvpVerifyResourceLayout(ResourceLayout, pResources, GetNumShaderStages(),
465769
466770 for (size_t s = 0; s < ShaderStages.size(); ++s)
467771 {
468 auto* pShaderD3D12 = ShaderStages[s].pShader;
469 auto ShaderType = pShaderD3D12->GetDesc().ShaderType;
470 auto ShaderInd = GetShaderTypePipelineIndex(ShaderType, m_Desc.PipelineType);
772 auto Shaders = ShaderStages[s].Shaders;
773 auto ShaderType = ShaderStages[s].Type;
774 auto ShaderInd = GetShaderTypePipelineIndex(ShaderType, m_Desc.PipelineType);
471775
472776 m_ResourceLayoutIndex[ShaderInd] = static_cast<Int8>(s);
473777
475779 pd3d12Device,
476780 m_Desc.PipelineType,
477781 ResourceLayout,
478 pShaderD3D12->GetShaderResources(),
782 Shaders,
479783 GetRawAllocator(),
480784 nullptr,
481785 0,
488792 pd3d12Device,
489793 m_Desc.PipelineType,
490794 ResourceLayout,
491 pShaderD3D12->GetShaderResources(),
795 Shaders,
492796 GetRawAllocator(),
493797 StaticVarType,
494798 _countof(StaticVarType),
549853
550854 auto IsSameRootSignature = m_RootSig.IsSameAs(pPSOD3D12->m_RootSig);
551855
552 #ifdef DILIGENT_DEBUG
856 // AZ TODO
857 #if 0 //def DILIGENT_DEBUG
553858 {
554859 bool IsCompatibleShaders = true;
555860 if (GetNumShaderStages() != pPSOD3D12->GetNumShaderStages())
600905 {
601906 if (Attrib.CommitResources)
602907 {
603 if (m_Desc.IsComputePipeline())
908 if (m_Desc.IsAnyGraphicsPipeline())
909 CmdCtx.AsGraphicsContext().SetRootSignature(GetD3D12RootSignature());
910 else
604911 CmdCtx.AsComputeContext().SetRootSignature(GetD3D12RootSignature());
605 else
606 CmdCtx.AsGraphicsContext().SetRootSignature(GetD3D12RootSignature());
607912 }
608913 return nullptr;
609914 }
629934 auto& ResourceCache = pResBindingD3D12Impl->GetResourceCache();
630935 if (Attrib.CommitResources)
631936 {
632 if (m_Desc.IsComputePipeline())
937 if (m_Desc.IsAnyGraphicsPipeline())
938 CmdCtx.AsGraphicsContext().SetRootSignature(GetD3D12RootSignature());
939 else
633940 CmdCtx.AsComputeContext().SetRootSignature(GetD3D12RootSignature());
941
942 if (Attrib.TransitionResources)
943 {
944 (m_RootSig.*m_RootSig.TransitionAndCommitDescriptorHandles)(m_pDevice, ResourceCache, CmdCtx, !m_Desc.IsAnyGraphicsPipeline(), Attrib.ValidateStates);
945 }
634946 else
635 CmdCtx.AsGraphicsContext().SetRootSignature(GetD3D12RootSignature());
636
637 if (Attrib.TransitionResources)
638 {
639 (m_RootSig.*m_RootSig.TransitionAndCommitDescriptorHandles)(m_pDevice, ResourceCache, CmdCtx, m_Desc.IsComputePipeline(), Attrib.ValidateStates);
640 }
641 else
642 {
643 (m_RootSig.*m_RootSig.CommitDescriptorHandles)(m_pDevice, ResourceCache, CmdCtx, m_Desc.IsComputePipeline(), Attrib.ValidateStates);
947 {
948 (m_RootSig.*m_RootSig.CommitDescriptorHandles)(m_pDevice, ResourceCache, CmdCtx, !m_Desc.IsAnyGraphicsPipeline(), Attrib.ValidateStates);
644949 }
645950 }
646951 else
652957 // Process only non-dynamic buffers at this point. Dynamic buffers will be handled by the Draw/Dispatch command.
653958 m_RootSig.CommitRootViews(ResourceCache,
654959 CmdCtx,
655 m_Desc.IsComputePipeline(),
960 !m_Desc.IsAnyGraphicsPipeline(),
656961 Attrib.CtxId,
657962 pDeviceCtx,
658963 Attrib.CommitResources, // CommitViews
8888 return FeatureLevelsData.MaxSupportedFeatureLevel;
8989 }
9090
91 #ifdef D3D12_H_HAS_MESH_SHADER
9291 ID3D12Device2* RenderDeviceD3D12Impl::GetD3D12Device2()
9392 {
9493 if (!m_pd3d12Device2)
9796 }
9897 return m_pd3d12Device2;
9998 }
100 #endif
99
100 ID3D12Device5* RenderDeviceD3D12Impl::GetD3D12Device5()
101 {
102 if (!m_pd3d12Device5)
103 {
104 CHECK_D3D_RESULT_THROW(m_pd3d12Device->QueryInterface(IID_PPV_ARGS(&m_pd3d12Device5)), "Failed to get ID3D12Device5");
105 }
106 return m_pd3d12Device5;
107 }
101108
102109 RenderDeviceD3D12Impl::RenderDeviceD3D12Impl(IReferenceCounters* pRefCounters,
103110 IMemoryAllocator& RawMemAllocator,
153160 m_pDxCompiler {CreateDXCompiler(DXCompilerTarget::Direct3D12, EngineCI.pDxCompilerPath)}
154161 // clang-format on
155162 {
163 static_assert(sizeof(DeviceObjectSizes) == sizeof(size_t) * 15, "Please add new objects to DeviceObjectSizes constructor");
164
156165 try
157166 {
158167 m_DeviceCaps.DevType = RENDER_DEVICE_TYPE_D3D12;
202211 // Header may not have constants for D3D_SHADER_MODEL_6_1 and above.
203212 const D3D_SHADER_MODEL Models[] = //
204213 {
205 static_cast<D3D_SHADER_MODEL>(0x65), // minimum required for mesh shader
214 static_cast<D3D_SHADER_MODEL>(0x65), // minimum required for mesh shader and DXR 1.1
206215 static_cast<D3D_SHADER_MODEL>(0x64),
207 static_cast<D3D_SHADER_MODEL>(0x63),
216 static_cast<D3D_SHADER_MODEL>(0x63), // minimum required for DXR 1.0
208217 static_cast<D3D_SHADER_MODEL>(0x62),
209218 static_cast<D3D_SHADER_MODEL>(0x61),
210219 D3D_SHADER_MODEL_6_0 //
250259
251260 m_DeviceCaps.Features.MeshShaders = MeshShadersSupported ? DEVICE_FEATURE_STATE_ENABLED : DEVICE_FEATURE_STATE_DISABLED;
252261
253 // AZ TODO: ray tracing
262 {
263 D3D12_FEATURE_DATA_D3D12_OPTIONS5 d3d12Features = {};
264 if (SUCCEEDED(m_pd3d12Device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS5, &d3d12Features, sizeof(d3d12Features))))
265 {
266 if (d3d12Features.RaytracingTier >= D3D12_RAYTRACING_TIER_1_0)
267 {
268 m_DeviceCaps.Features.RayTracing = DEVICE_FEATURE_STATE_ENABLED;
269 }
270 }
271 }
254272
255273 {
256274 D3D12_FEATURE_DATA_D3D12_OPTIONS d3d12Features = {};
293311 CHECK_REQUIRED_FEATURE(ShaderInt8, "8-bit shader operations are");
294312 CHECK_REQUIRED_FEATURE(ResourceBuffer8BitAccess, "8-bit resoure buffer access is");
295313 CHECK_REQUIRED_FEATURE(UniformBuffer8BitAccess, "8-bit uniform buffer access is");
314
315 CHECK_REQUIRED_FEATURE(RayTracing, "ray tracing is");
296316 // clang-format on
297317 #undef CHECK_REQUIRED_FEATURE
298318
557577 CreatePipelineState(PSOCreateInfo, ppPipelineState);
558578 }
559579
580 void RenderDeviceD3D12Impl::CreateRayTracingPipelineState(const RayTracingPipelineStateCreateInfo& PSOCreateInfo, IPipelineState** ppPipelineState)
581 {
582 CreatePipelineState(PSOCreateInfo, ppPipelineState);
583 }
584
560585 void RenderDeviceD3D12Impl::CreateBufferFromD3DResource(ID3D12Resource* pd3d12Buffer, const BufferDesc& BuffDesc, RESOURCE_STATE InitialState, IBuffer** ppBuffer)
561586 {
562587 CreateDeviceObject("buffer", BuffDesc, ppBuffer,
182182 D3D12_SHADER_VISIBILITY_ALL, // 5
183183 #ifdef D3D12_H_HAS_MESH_SHADER
184184 D3D12_SHADER_VISIBILITY_AMPLIFICATION, // 6
185 D3D12_SHADER_VISIBILITY_MESH // 7
186 #endif
185 D3D12_SHADER_VISIBILITY_MESH, // 7
186 #else
187 D3D12_SHADER_VISIBILITY(6),
188 D3D12_SHADER_VISIBILITY(7),
189 #endif
190 D3D12_SHADER_VISIBILITY_ALL, // 8
191 D3D12_SHADER_VISIBILITY_ALL, // 9
192 D3D12_SHADER_VISIBILITY_ALL, // 10
193 D3D12_SHADER_VISIBILITY_ALL, // 11
194 D3D12_SHADER_VISIBILITY_ALL, // 12
195 D3D12_SHADER_VISIBILITY_ALL, // 13
187196 };
188197 // clang-format on
189198 D3D12_SHADER_VISIBILITY GetShaderVisibility(SHADER_TYPE ShaderType)
191200 auto ShaderInd = GetShaderTypeIndex(ShaderType);
192201 auto ShaderVisibility = ShaderTypeInd2ShaderVisibilityMap[ShaderInd];
193202 #ifdef DILIGENT_DEBUG
203 static_assert(SHADER_TYPE_LAST == SHADER_TYPE_CALLABLE, "Please update the switch below to handle the new shader type");
194204 switch (ShaderType)
195205 {
196206 // clang-format off
197 case SHADER_TYPE_VERTEX: VERIFY_EXPR(ShaderVisibility == D3D12_SHADER_VISIBILITY_VERTEX); break;
198 case SHADER_TYPE_PIXEL: VERIFY_EXPR(ShaderVisibility == D3D12_SHADER_VISIBILITY_PIXEL); break;
199 case SHADER_TYPE_GEOMETRY: VERIFY_EXPR(ShaderVisibility == D3D12_SHADER_VISIBILITY_GEOMETRY); break;
200 case SHADER_TYPE_HULL: VERIFY_EXPR(ShaderVisibility == D3D12_SHADER_VISIBILITY_HULL); break;
201 case SHADER_TYPE_DOMAIN: VERIFY_EXPR(ShaderVisibility == D3D12_SHADER_VISIBILITY_DOMAIN); break;
202 case SHADER_TYPE_COMPUTE: VERIFY_EXPR(ShaderVisibility == D3D12_SHADER_VISIBILITY_ALL); break;
207 case SHADER_TYPE_VERTEX: VERIFY_EXPR(ShaderVisibility == D3D12_SHADER_VISIBILITY_VERTEX); break;
208 case SHADER_TYPE_PIXEL: VERIFY_EXPR(ShaderVisibility == D3D12_SHADER_VISIBILITY_PIXEL); break;
209 case SHADER_TYPE_GEOMETRY: VERIFY_EXPR(ShaderVisibility == D3D12_SHADER_VISIBILITY_GEOMETRY); break;
210 case SHADER_TYPE_HULL: VERIFY_EXPR(ShaderVisibility == D3D12_SHADER_VISIBILITY_HULL); break;
211 case SHADER_TYPE_DOMAIN: VERIFY_EXPR(ShaderVisibility == D3D12_SHADER_VISIBILITY_DOMAIN); break;
212 case SHADER_TYPE_COMPUTE: VERIFY_EXPR(ShaderVisibility == D3D12_SHADER_VISIBILITY_ALL); break;
203213 # ifdef D3D12_H_HAS_MESH_SHADER
204 case SHADER_TYPE_AMPLIFICATION: VERIFY_EXPR(ShaderVisibility == D3D12_SHADER_VISIBILITY_AMPLIFICATION); break;
205 case SHADER_TYPE_MESH: VERIFY_EXPR(ShaderVisibility == D3D12_SHADER_VISIBILITY_MESH); break;
214 case SHADER_TYPE_AMPLIFICATION: VERIFY_EXPR(ShaderVisibility == D3D12_SHADER_VISIBILITY_AMPLIFICATION); break;
215 case SHADER_TYPE_MESH: VERIFY_EXPR(ShaderVisibility == D3D12_SHADER_VISIBILITY_MESH); break;
206216 # endif
217 case SHADER_TYPE_RAY_GEN:
218 case SHADER_TYPE_RAY_MISS:
219 case SHADER_TYPE_RAY_CLOSEST_HIT:
220 case SHADER_TYPE_RAY_ANY_HIT:
221 case SHADER_TYPE_RAY_INTERSECTION:
222 case SHADER_TYPE_CALLABLE: VERIFY_EXPR(ShaderVisibility == D3D12_SHADER_VISIBILITY_ALL); break;
207223 // clang-format on
208224 default: LOG_ERROR("Unknown shader type (", ShaderType, ")"); break;
209225 }
210226 #endif
211227 return ShaderVisibility;
212228 }
213
214 // clang-format off
215 static SHADER_TYPE ShaderVisibility2ShaderTypeMap[] =
216 {
217 SHADER_TYPE_COMPUTE, // D3D12_SHADER_VISIBILITY_ALL = 0
218 SHADER_TYPE_VERTEX, // D3D12_SHADER_VISIBILITY_VERTEX = 1
219 SHADER_TYPE_HULL, // D3D12_SHADER_VISIBILITY_HULL = 2
220 SHADER_TYPE_DOMAIN, // D3D12_SHADER_VISIBILITY_DOMAIN = 3
221 SHADER_TYPE_GEOMETRY, // D3D12_SHADER_VISIBILITY_GEOMETRY = 4
222 SHADER_TYPE_PIXEL, // D3D12_SHADER_VISIBILITY_PIXEL = 5
223 SHADER_TYPE_AMPLIFICATION, // D3D12_SHADER_VISIBILITY_AMPLIFICATION = 6
224 SHADER_TYPE_MESH // D3D12_SHADER_VISIBILITY_MESH = 7
225 };
226 // clang-format on
227
228 SHADER_TYPE ShaderTypeFromShaderVisibility(D3D12_SHADER_VISIBILITY ShaderVisibility)
229 {
230 VERIFY_EXPR(uint32_t(ShaderVisibility) < _countof(ShaderVisibility2ShaderTypeMap));
231 auto ShaderType = ShaderVisibility2ShaderTypeMap[ShaderVisibility];
232 #ifdef DILIGENT_DEBUG
233 switch (ShaderVisibility)
234 {
235 // clang-format off
236 case D3D12_SHADER_VISIBILITY_VERTEX: VERIFY_EXPR(ShaderType == SHADER_TYPE_VERTEX); break;
237 case D3D12_SHADER_VISIBILITY_PIXEL: VERIFY_EXPR(ShaderType == SHADER_TYPE_PIXEL); break;
238 case D3D12_SHADER_VISIBILITY_GEOMETRY: VERIFY_EXPR(ShaderType == SHADER_TYPE_GEOMETRY); break;
239 case D3D12_SHADER_VISIBILITY_HULL: VERIFY_EXPR(ShaderType == SHADER_TYPE_HULL); break;
240 case D3D12_SHADER_VISIBILITY_DOMAIN: VERIFY_EXPR(ShaderType == SHADER_TYPE_DOMAIN); break;
241 case D3D12_SHADER_VISIBILITY_ALL: VERIFY_EXPR(ShaderType == SHADER_TYPE_COMPUTE); break;
242 # ifdef D3D12_H_HAS_MESH_SHADER
243 case D3D12_SHADER_VISIBILITY_AMPLIFICATION: VERIFY_EXPR(ShaderType == SHADER_TYPE_AMPLIFICATION); break;
244 case D3D12_SHADER_VISIBILITY_MESH: VERIFY_EXPR(ShaderType == SHADER_TYPE_MESH); break;
245 # endif
246 // clang-format on
247 default: LOG_ERROR("Unknown shader visibility (", ShaderVisibility, ")"); break;
248 }
249 #endif
250 return ShaderType;
251 }
252
253229
254230 // clang-format off
255231 static D3D12_DESCRIPTOR_HEAP_TYPE RangeType2HeapTypeMap[]
286262 const char* SamplerSuffix,
287263 const D3DShaderResourceAttribs& SamplerAttribs)
288264 {
265 #ifdef DILIGENT_DEBUG
266 m_DbgShaderStages |= ShaderType;
267 #endif
268
289269 auto ShaderVisibility = GetShaderVisibility(ShaderType);
290270 auto SamplerFound = false;
291271 for (auto& ImtblSmplr : m_ImmutableSamplers)
318298 Uint32& OffsetFromTableStart // Output parameter
319299 )
320300 {
301 #ifdef DILIGENT_DEBUG
302 m_DbgShaderStages |= ShaderType;
303 #endif
304
321305 const auto ShaderVisibility = GetShaderVisibility(ShaderType);
322306 if (RangeType == D3D12_DESCRIPTOR_RANGE_TYPE_CBV && ShaderResAttribs.BindCount == 1)
323307 {
563547 CComPtr<ID3DBlob> signature;
564548 CComPtr<ID3DBlob> error;
565549 HRESULT hr = D3D12SerializeRootSignature(&rootSignatureDesc, D3D_ROOT_SIGNATURE_VERSION_1, &signature, &error);
566 hr = pd3d12Device->CreateRootSignature(0, signature->GetBufferPointer(), signature->GetBufferSize(), __uuidof(m_pd3d12RootSignature), reinterpret_cast<void**>(static_cast<ID3D12RootSignature**>(&m_pd3d12RootSignature)));
550 CHECK_D3D_RESULT_THROW(hr, "Failed to serialize root signature");
551
552 hr = pd3d12Device->CreateRootSignature(0, signature->GetBufferPointer(), signature->GetBufferSize(), __uuidof(m_pd3d12RootSignature), reinterpret_cast<void**>(static_cast<ID3D12RootSignature**>(&m_pd3d12RootSignature)));
567553 CHECK_D3D_RESULT_THROW(hr, "Failed to create root signature");
568554
569555 bool bHasDynamicDescriptors = m_TotalSrvCbvUavSlots[SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC] != 0 || m_TotalSamplerSlots[SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC] != 0;
657643 const auto& D3D12RootParam = static_cast<const D3D12_ROOT_PARAMETER&>(RootParam);
658644 auto& RootTableCache = ResourceCache.GetRootTable(RootParam.GetRootIndex());
659645
660 SHADER_TYPE dbgShaderType = SHADER_TYPE_UNKNOWN;
661 #ifdef DILIGENT_DEBUG
662 dbgShaderType = ShaderTypeFromShaderVisibility(D3D12RootParam.ShaderVisibility);
663 #endif
664646 VERIFY_EXPR(D3D12RootParam.ParameterType == D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE);
665647
666648 auto TableSize = RootParam.GetDescriptorTableSize();
669651 auto HeapType = HeapTypeFromRangeType(D3D12RootParam.DescriptorTable.pDescriptorRanges[0].RangeType);
670652
671653 #ifdef DILIGENT_DEBUG
672 RootTableCache.SetDebugAttribs(TableSize, HeapType, dbgShaderType);
654 RootTableCache.SetDebugAttribs(TableSize, HeapType, m_DbgShaderStages);
673655 #endif
674656
675657 // Space for dynamic variables is allocated at every draw call
701683 // Root views are not assigned valid table start offset
702684 VERIFY_EXPR(RootTableCache.m_TableStartOffset == ShaderResourceCacheD3D12::InvalidDescriptorOffset);
703685
704 SHADER_TYPE dbgShaderType = ShaderTypeFromShaderVisibility(D3D12RootParam.ShaderVisibility);
705686 VERIFY_EXPR(D3D12RootParam.ParameterType == D3D12_ROOT_PARAMETER_TYPE_CBV);
706 RootTableCache.SetDebugAttribs(1, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, dbgShaderType);
687 RootTableCache.SetDebugAttribs(1, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, m_DbgShaderStages);
707688 }
708689 #endif
709690
717698 ShaderResourceCacheD3D12::Resource& Res,
718699 D3D12_DESCRIPTOR_RANGE_TYPE RangeType)
719700 {
701 static_assert(static_cast<int>(CachedResourceType::NumTypes) == 7, "Please update this function to handle the new resource type");
720702 switch (Res.Type)
721703 {
722704 case CachedResourceType::CBV:
781763 VERIFY(RangeType == D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER, "Unexpected descriptor range type");
782764 break;
783765
766 case CachedResourceType::AccelStruct:
767 {
768 }
769 break;
770
784771 default:
785772 // Resource not bound
786773 VERIFY(Res.Type == CachedResourceType::Unknown, "Unexpected resource type");
793780 void RootSignature::DvpVerifyResourceState(const ShaderResourceCacheD3D12::Resource& Res,
794781 D3D12_DESCRIPTOR_RANGE_TYPE RangeType)
795782 {
783 static_assert(static_cast<int>(CachedResourceType::NumTypes) == 7, "Please update this function to handle the new resource type");
796784 switch (Res.Type)
797785 {
798786 case CachedResourceType::CBV:
878866 case CachedResourceType::Sampler:
879867 VERIFY(RangeType == D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER, "Unexpected descriptor range type");
880868 break;
869
870 case CachedResourceType::AccelStruct:
871 {
872 }
873 break;
881874
882875 default:
883876 // Resource not bound
921914 const auto& range = D3D12Param.DescriptorTable.pDescriptorRanges[r];
922915 for (UINT d = 0; d < range.NumDescriptors; ++d)
923916 {
924 SHADER_TYPE dbgShaderType = SHADER_TYPE_UNKNOWN;
925917 #ifdef DILIGENT_DEBUG
926 dbgShaderType = ShaderTypeFromShaderVisibility(D3D12Param.ShaderVisibility);
927918 VERIFY(dbgHeapType == HeapTypeFromRangeType(range.RangeType), "Mistmatch between descriptor heap type and descriptor range type");
928919 #endif
929920 auto OffsetFromTableStart = range.OffsetInDescriptorsFromTableStart + d;
930 auto& Res = ResourceCache.GetRootTable(RootInd).GetResource(OffsetFromTableStart, dbgHeapType, dbgShaderType);
921 auto& Res = ResourceCache.GetRootTable(RootInd).GetResource(OffsetFromTableStart, dbgHeapType, SHADER_TYPE_UNKNOWN);
931922
932923 Operation(OffsetFromTableStart, range, Res);
933924 }
9393 pRenderDeviceD3D12,
9494 ShaderCI.Desc
9595 },
96 ShaderD3DBase{ShaderCI, GetD3D12ShaderModel(pRenderDeviceD3D12, ShaderCI.HLSLVersion, ShaderCI.ShaderCompiler), pRenderDeviceD3D12->GetDxCompiler()}
96 ShaderD3DBase{ShaderCI, GetD3D12ShaderModel(pRenderDeviceD3D12, ShaderCI.HLSLVersion, ShaderCI.ShaderCompiler), pRenderDeviceD3D12->GetDxCompiler()},
97 m_EntryPoint{ShaderCI.EntryPoint}
9798 // clang-format on
9899 {
99100 // Load shader resources
5656 ResTypeToD3D12DescrRangeType()
5757 {
5858 // clang-format off
59 m_Map[(size_t)CachedResourceType::CBV] = D3D12_DESCRIPTOR_RANGE_TYPE_CBV;
60 m_Map[(size_t)CachedResourceType::TexSRV] = D3D12_DESCRIPTOR_RANGE_TYPE_SRV;
61 m_Map[(size_t)CachedResourceType::BufSRV] = D3D12_DESCRIPTOR_RANGE_TYPE_SRV;
62 m_Map[(size_t)CachedResourceType::TexUAV] = D3D12_DESCRIPTOR_RANGE_TYPE_UAV;
63 m_Map[(size_t)CachedResourceType::BufUAV] = D3D12_DESCRIPTOR_RANGE_TYPE_UAV;
64 m_Map[(size_t)CachedResourceType::Sampler] = D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER;
59 m_Map[(size_t)CachedResourceType::CBV] = D3D12_DESCRIPTOR_RANGE_TYPE_CBV;
60 m_Map[(size_t)CachedResourceType::TexSRV] = D3D12_DESCRIPTOR_RANGE_TYPE_SRV;
61 m_Map[(size_t)CachedResourceType::BufSRV] = D3D12_DESCRIPTOR_RANGE_TYPE_SRV;
62 m_Map[(size_t)CachedResourceType::TexUAV] = D3D12_DESCRIPTOR_RANGE_TYPE_UAV;
63 m_Map[(size_t)CachedResourceType::BufUAV] = D3D12_DESCRIPTOR_RANGE_TYPE_UAV;
64 m_Map[(size_t)CachedResourceType::Sampler] = D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER;
65 m_Map[(size_t)CachedResourceType::AccelStruct] = D3D12_DESCRIPTOR_RANGE_TYPE_SRV;
6566 // clang-format on
6667 }
6768
112113
113114 // http://diligentgraphics.com/diligent-engine/architecture/d3d12/shader-resource-layout#Initializing-Shader-Resource-Layouts-and-Root-Signature-in-a-Pipeline-State-Object
114115 // http://diligentgraphics.com/diligent-engine/architecture/d3d12/shader-resource-cache#Initializing-Shader-Resource-Layouts-in-a-Pipeline-State
115 void ShaderResourceLayoutD3D12::Initialize(ID3D12Device* pd3d12Device,
116 PIPELINE_TYPE PipelineType,
117 const PipelineResourceLayoutDesc& ResourceLayout,
118 std::shared_ptr<const ShaderResourcesD3D12> pSrcResources,
119 IMemoryAllocator& LayoutDataAllocator,
120 const SHADER_RESOURCE_VARIABLE_TYPE* const AllowedVarTypes,
121 Uint32 NumAllowedTypes,
122 ShaderResourceCacheD3D12* pResourceCache,
123 RootSignature* pRootSig)
116 void ShaderResourceLayoutD3D12::Initialize(ID3D12Device* pd3d12Device,
117 PIPELINE_TYPE PipelineType,
118 const PipelineResourceLayoutDesc& ResourceLayout,
119 const std::vector<ShaderD3D12Impl*>& Shaders,
120 IMemoryAllocator& LayoutDataAllocator,
121 const SHADER_RESOURCE_VARIABLE_TYPE* const AllowedVarTypes,
122 Uint32 NumAllowedTypes,
123 ShaderResourceCacheD3D12* pResourceCache,
124 RootSignature* pRootSig)
124125 {
125126 m_pd3d12Device = pd3d12Device;
126 m_pResources = std::move(pSrcResources);
127127
128128 VERIFY_EXPR((pResourceCache != nullptr) ^ (pRootSig != nullptr));
129 VERIFY_EXPR(Shaders.size() > 0);
129130
130131 const Uint32 AllowedTypeBits = GetAllowedTypeBits(AllowedVarTypes, NumAllowedTypes);
131132
132133 std::array<Uint32, SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES> CbvSrvUavCount = {};
133134 std::array<Uint32, SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES> SamplerCount = {};
134135
136 std::unordered_map<HashMapStringKey, Uint32, HashMapStringKey::Hasher> ResourceNameToIndex;
137
135138 // Count number of resources to allocate all needed memory
136 m_pResources->ProcessResources(
137 [&](const D3DShaderResourceAttribs& CB, Uint32) //
138 {
139 auto VarType = m_pResources->FindVariableType(CB, ResourceLayout);
139 m_IsUsingSeparateSamplers = !Shaders[0]->GetShaderResources()->IsUsingCombinedTextureSamplers();
140 m_ShaderType = Shaders[0]->GetDesc().ShaderType;
141 size_t StringPoolSize = 0;
142
143 for (auto* pShader : Shaders)
144 {
145 auto pResources = pShader->GetShaderResources();
146 VERIFY_EXPR(pResources->GetShaderType() == m_ShaderType);
147 const auto HandleResType = [&](const auto& Res, Uint32) //
148 {
149 auto VarType = pResources->FindVariableType(Res, ResourceLayout);
140150 if (IsAllowedType(VarType, AllowedTypeBits))
141 ++CbvSrvUavCount[VarType];
142 },
143 [&](const D3DShaderResourceAttribs& Sam, Uint32) //
144 {
145 auto VarType = m_pResources->FindVariableType(Sam, ResourceLayout);
146 if (IsAllowedType(VarType, AllowedTypeBits))
147 {
148 constexpr bool LogImtblSamplerArrayError = true;
149
150 auto ImtblSamplerInd = m_pResources->FindImmutableSampler(Sam, ResourceLayout, LogImtblSamplerArrayError);
151 // Skip immutable samplers
152 if (ImtblSamplerInd < 0)
153 ++SamplerCount[VarType];
154 }
155 },
156 [&](const D3DShaderResourceAttribs& TexSRV, Uint32) //
157 {
158 auto VarType = m_pResources->FindVariableType(TexSRV, ResourceLayout);
159 if (IsAllowedType(VarType, AllowedTypeBits))
160 {
161 ++CbvSrvUavCount[VarType];
162 if (TexSRV.IsCombinedWithSampler())
163 {
164 const auto& SamplerAttribs = m_pResources->GetCombinedSampler(TexSRV);
165 auto SamplerVarType = m_pResources->FindVariableType(SamplerAttribs, ResourceLayout);
166 DEV_CHECK_ERR(SamplerVarType == VarType,
167 "The type (", GetShaderVariableTypeLiteralName(VarType), ") of texture SRV variable '", TexSRV.Name,
168 "' is not consistent with the type (", GetShaderVariableTypeLiteralName(SamplerVarType),
169 ") of the sampler '", SamplerAttribs.Name, "' that is assigned to it");
170 (void)SamplerVarType;
171 }
172 }
173 },
174 [&](const D3DShaderResourceAttribs& TexUAV, Uint32) //
175 {
176 auto VarType = m_pResources->FindVariableType(TexUAV, ResourceLayout);
177 if (IsAllowedType(VarType, AllowedTypeBits))
178 ++CbvSrvUavCount[VarType];
179 },
180 [&](const D3DShaderResourceAttribs& BufSRV, Uint32) //
181 {
182 auto VarType = m_pResources->FindVariableType(BufSRV, ResourceLayout);
183 if (IsAllowedType(VarType, AllowedTypeBits))
184 ++CbvSrvUavCount[VarType];
185 },
186 [&](const D3DShaderResourceAttribs& BufUAV, Uint32) //
187 {
188 auto VarType = m_pResources->FindVariableType(BufUAV, ResourceLayout);
189 if (IsAllowedType(VarType, AllowedTypeBits))
190 ++CbvSrvUavCount[VarType];
191 } //
192 );
151 {
152 bool IsUniqueName = ResourceNameToIndex.emplace(HashMapStringKey{Res.Name}, ~0u).second;
153 if (IsUniqueName)
154 {
155 StringPoolSize += strlen(Res.Name) + 1;
156 ++CbvSrvUavCount[VarType];
157 }
158 }
159 };
160 pResources->ProcessResources(
161 HandleResType,
162 [&](const D3DShaderResourceAttribs& Sam, Uint32) //
163 {
164 auto VarType = pResources->FindVariableType(Sam, ResourceLayout);
165 if (IsAllowedType(VarType, AllowedTypeBits))
166 {
167 constexpr bool LogImtblSamplerArrayError = true;
168
169 auto ImtblSamplerInd = pResources->FindImmutableSampler(Sam, ResourceLayout, LogImtblSamplerArrayError);
170 // Skip immutable samplers
171 if (ImtblSamplerInd < 0)
172 {
173 bool IsUniqueName = ResourceNameToIndex.emplace(HashMapStringKey{Sam.Name}, ~0u).second;
174 if (IsUniqueName)
175 {
176 StringPoolSize += strlen(Sam.Name) + 1;
177 ++SamplerCount[VarType];
178 }
179 }
180 }
181 },
182 [&](const D3DShaderResourceAttribs& TexSRV, Uint32) //
183 {
184 auto VarType = pResources->FindVariableType(TexSRV, ResourceLayout);
185 if (IsAllowedType(VarType, AllowedTypeBits))
186 {
187 bool IsUniqueName = ResourceNameToIndex.emplace(HashMapStringKey{TexSRV.Name}, ~0u).second;
188 if (IsUniqueName)
189 {
190 StringPoolSize += strlen(TexSRV.Name) + 1;
191 ++CbvSrvUavCount[VarType];
192 if (TexSRV.IsCombinedWithSampler())
193 {
194 const auto& SamplerAttribs = pResources->GetCombinedSampler(TexSRV);
195 auto SamplerVarType = pResources->FindVariableType(SamplerAttribs, ResourceLayout);
196 DEV_CHECK_ERR(SamplerVarType == VarType,
197 "The type (", GetShaderVariableTypeLiteralName(VarType), ") of texture SRV variable '", TexSRV.Name,
198 "' is not consistent with the type (", GetShaderVariableTypeLiteralName(SamplerVarType),
199 ") of the sampler '", SamplerAttribs.Name, "' that is assigned to it");
200 (void)SamplerVarType;
201 }
202 }
203 }
204 },
205 HandleResType,
206 HandleResType,
207 HandleResType,
208 HandleResType);
209 }
193210
194211 AllocateMemory(LayoutDataAllocator, CbvSrvUavCount, SamplerCount);
195212
196 std::array<Uint32, SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES> CurrCbvSrvUav = {};
197 std::array<Uint32, SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES> CurrSampler = {};
198
199 Uint32 StaticResCacheTblSizes[4] = {0, 0, 0, 0};
213 m_StringPool.Reserve(StringPoolSize, GetRawAllocator());
214
215 std::array<Uint32, SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES> CurrCbvSrvUav = {};
216 std::array<Uint32, SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES> CurrSampler = {};
217 std::array<Uint32, D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER + 1> StaticResCacheTblSizes = {};
200218
201219 auto AddResource = [&](const D3DShaderResourceAttribs& Attribs,
202220 CachedResourceType ResType,
203221 SHADER_RESOURCE_VARIABLE_TYPE VarType,
204222 Uint32 SamplerId = D3D12Resource::InvalidSamplerId) //
205223 {
206 Uint32 RootIndex = D3D12Resource::InvalidRootIndex;
207 Uint32 Offset = D3D12Resource::InvalidOffset;
208
209 D3D12_DESCRIPTOR_RANGE_TYPE DescriptorRangeType = GetDescriptorRangeType(ResType);
210
211 if (pRootSig)
212 {
213 pRootSig->AllocateResourceSlot(m_pResources->GetShaderType(), PipelineType, Attribs, VarType, DescriptorRangeType, RootIndex, Offset);
214 VERIFY(RootIndex <= D3D12Resource::MaxRootIndex, "Root index excceeds allowed limit");
224 auto ResIter = ResourceNameToIndex.find(HashMapStringKey{Attribs.Name});
225 VERIFY_EXPR(ResIter != ResourceNameToIndex.end());
226
227 if (ResIter->second == ~0u)
228 {
229 Uint32 RootIndex = D3D12Resource::InvalidRootIndex;
230 Uint32 Offset = D3D12Resource::InvalidOffset;
231
232 D3D12_DESCRIPTOR_RANGE_TYPE DescriptorRangeType = GetDescriptorRangeType(ResType);
233
234 if (pRootSig)
235 {
236 pRootSig->AllocateResourceSlot(GetShaderType(), PipelineType, Attribs, VarType, DescriptorRangeType, RootIndex, Offset);
237 VERIFY(RootIndex <= D3D12Resource::MaxRootIndex, "Root index excceeds allowed limit");
238 }
239 else
240 {
241 // If root signature is not provided - use artifial root signature to store
242 // static shader resources:
243 // SRVs at root index D3D12_DESCRIPTOR_RANGE_TYPE_SRV (0)
244 // UAVs at root index D3D12_DESCRIPTOR_RANGE_TYPE_UAV (1)
245 // CBVs at root index D3D12_DESCRIPTOR_RANGE_TYPE_CBV (2)
246 // Samplers at root index D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER (3)
247
248 // http://diligentgraphics.com/diligent-engine/architecture/d3d12/shader-resource-layout#Initializing-Special-Resource-Layout-for-Managing-Static-Shader-Resources
249
250 VERIFY_EXPR(pResourceCache != nullptr);
251
252 RootIndex = DescriptorRangeType;
253 Offset = Attribs.BindPoint;
254 // Resources in the static resource cache are indexed by the bind point
255 StaticResCacheTblSizes[RootIndex] = std::max(StaticResCacheTblSizes[RootIndex], Offset + Attribs.BindCount);
256 }
257 VERIFY(RootIndex !=