git.s-ol.nu ~forks/DiligentCore / f8be662
A number of updates/fixes to PSO refactor merge assiduous 10 months ago
51 changed file(s) with 1031 addition(s) and 1090 deletion(s). Raw diff Collapse all Expand all
3232 interface/Timer.hpp
3333 interface/UniqueIdentifier.hpp
3434 interface/ValidatedCast.hpp
35 interface/Definitions.hpp
35 interface/CompilerDefinitions.h
3636 )
3737
3838 set(SOURCE
3232 #pragma once
3333
3434 #include "PlatformDefinitions.h"
35 #include "Definitions.hpp"
3635 #include "BasicTypes.h"
3736 #include "Errors.hpp"
3837 #include "FileWrapper.hpp"
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 NODISCARD [[nodiscard]]
32 # else
33 # define NODISCARD
34 # endif
35 #endif // _MSC_VER
36
37 #ifdef __clang__
38 # if __has_feature(cxx_attributes)
39 # define NODISCARD [[nodiscard]]
40 # else
41 # define NODISCARD
42 # endif
43 #endif // __clang__
44
45 #ifdef __GNUC__
46 # if __has_cpp_attribute(nodiscard)
47 # define NODISCARD [[nodiscard]]
48 # else
49 # define NODISCARD
50 # endif
51 #endif // __GNUC__
+0
-52
Common/interface/Definitions.hpp less more
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__
3434 #include "../../Primitives/interface/BasicTypes.h"
3535 #include "../../Primitives/interface/MemoryAllocator.h"
3636 #include "../../Platforms/Basic/interface/DebugUtilities.hpp"
37 #include "Definitions.hpp"
37 #include "CompilerDefinitions.h"
3838 #include "Align.hpp"
3939
4040 namespace Diligent
4141 {
4242
43 /// Implementation of a linear allocator on a fixed memory pages
43 /// Implementation of a linear allocator on fixed memory pages
4444 class DynamicLinearAllocator
4545 {
4646 public:
5454 explicit DynamicLinearAllocator(IMemoryAllocator& Allocator, Uint32 BlockSize = 4 << 10) :
5555 m_pAllocator{&Allocator},
5656 m_BlockSize{BlockSize}
57 {}
57 {
58 VERIFY(IsPowerOfTwo(BlockSize), "Block size (", BlockSize, ") is not power of two");
59 }
5860
5961 ~DynamicLinearAllocator()
6062 {
6567 {
6668 for (auto& block : m_Blocks)
6769 {
68 m_pAllocator->Free(block.Page);
70 m_pAllocator->Free(block.Data);
6971 }
7072 m_Blocks.clear();
7173
7678 {
7779 for (auto& block : m_Blocks)
7880 {
79 block.Size = 0;
80 }
81 }
82
83 NDDISCARD void* Allocate(size_t size, size_t align)
81 block.CurrPtr = block.Data;
82 }
83 }
84
85 NODISCARD void* Allocate(size_t size, size_t align)
8486 {
8587 if (size == 0)
8688 return nullptr;
8789
8890 for (auto& block : m_Blocks)
8991 {
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))
92 auto* Ptr = Align(block.CurrPtr, align);
93 if (Ptr + size <= block.Data + block.Size)
9394 {
94 block.Size = offset + size;
95 return block.Page + offset;
95 block.CurrPtr = Ptr + size;
96 return Ptr;
9697 }
9798 }
9899
99 // create new block
100 // Create a new block
100101 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;
102 while (BlockSize < size + align - 1)
103 BlockSize *= 2;
104 m_Blocks.emplace_back(m_pAllocator->Allocate(BlockSize, "dynamic linear allocator page", __FILE__, __LINE__), BlockSize);
105
106 auto& block = m_Blocks.back();
107 auto* Ptr = Align(block.Data, align);
108 VERIFY(Ptr + size <= block.Data + block.Size, "Not enough space in the new block - this is a bug");
109 block.CurrPtr = Ptr + size;
110 return Ptr;
108111 }
109112
110113 template <typename T>
111 NDDISCARD T* Allocate(size_t count = 1)
114 NODISCARD T* Allocate(size_t count = 1)
112115 {
113116 return reinterpret_cast<T*>(Allocate(sizeof(T) * count, alignof(T)));
114117 }
115118
116119 template <typename T, typename... Args>
117 NDDISCARD T* Construct(Args&&... args)
120 NODISCARD T* Construct(Args&&... args)
118121 {
119122 T* Ptr = Allocate<T>(1);
120123 new (Ptr) T{std::forward<Args>(args)...};
122125 }
123126
124127 template <typename T, typename... Args>
125 NDDISCARD T* ConstructArray(size_t count, const Args&... args)
128 NODISCARD T* ConstructArray(size_t count, const Args&... args)
126129 {
127130 T* Ptr = Allocate<T>(count);
128131 for (size_t i = 0; i < count; ++i)
133136 }
134137
135138 template <typename T>
136 NDDISCARD T* CopyArray(const T* Src, size_t count)
139 NODISCARD T* CopyArray(const T* Src, size_t count)
137140 {
138141 T* Dst = Allocate<T>(count);
139142 for (size_t i = 0; i < count; ++i)
143146 return Dst;
144147 }
145148
146 NDDISCARD Char* CopyString(const Char* Str)
149 NODISCARD Char* CopyString(const Char* Str, size_t len = 0)
147150 {
148151 if (Str == nullptr)
149152 return nullptr;
150153
151 size_t len = strlen(Str) + 1;
152 Char* Dst = Allocate<Char>(len + 1);
154 if (len == 0)
155 len = strlen(Str);
156 else
157 VERIFY_EXPR(len <= strlen(Str));
158
159 Char* Dst = Allocate<Char>(len + 1);
153160 std::memcpy(Dst, Str, sizeof(Char) * len);
154161 Dst[len] = 0;
155162 return Dst;
156163 }
157164
158 NDDISCARD wchar_t* CopyWString(const char* Str)
165 NODISCARD wchar_t* CopyWString(const char* Str)
159166 {
160167 if (Str == nullptr)
161168 return nullptr;
162169
163 size_t len = strlen(Str) + 1;
170 size_t len = strlen(Str);
164171 auto* Dst = Allocate<wchar_t>(len + 1);
165172 for (size_t i = 0; i < len; ++i)
166173 {
170177 return Dst;
171178 }
172179
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 NODISCARD Char* CopyString(const String& Str)
181 {
182 return CopyString(Str.c_str(), Str.length());
180183 }
181184
182185 private:
183186 struct Block
184187 {
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} {}
188 uint8_t* const Data = nullptr;
189 size_t const Size = 0;
190 uint8_t* CurrPtr = nullptr;
191
192 Block(void* _Data, size_t _Size) :
193 Data{static_cast<uint8_t*>(_Data)}, Size{_Size}, CurrPtr{Data} {}
191194 };
192195
193196 std::vector<Block> m_Blocks;
194 Uint32 m_BlockSize = 4 << 10;
197 const Uint32 m_BlockSize = 4 << 10;
195198 IMemoryAllocator* m_pAllocator = nullptr;
196199 };
197200
3434 #include "../../Primitives/interface/BasicTypes.h"
3535 #include "../../Primitives/interface/MemoryAllocator.h"
3636 #include "../../Platforms/Basic/interface/DebugUtilities.hpp"
37 #include "Definitions.hpp"
37 #include "CompilerDefinitions.h"
3838 #include "Align.hpp"
3939
4040 namespace Diligent
8080 Reset();
8181 }
8282
83 NDDISCARD void* Release()
83 NODISCARD void* Release()
8484 {
8585 void* Ptr = m_pDataStart;
8686 Reset();
8787 return Ptr;
8888 }
8989
90 NDDISCARD void* ReleaseOwnership() noexcept
90 NODISCARD void* ReleaseOwnership() noexcept
9191 {
9292 m_pAllocator = nullptr;
9393 return GetDataPtr();
9494 }
9595
96 NDDISCARD void* GetDataPtr() const noexcept
96 NODISCARD void* GetDataPtr() const noexcept
9797 {
9898 return m_pDataStart;
9999 }
168168 m_CurrAlignment = sizeof(void*);
169169 }
170170
171 NDDISCARD void* Allocate(size_t size, size_t alignment)
171 NODISCARD void* Allocate(size_t size, size_t alignment)
172172 {
173173 VERIFY(size == 0 || m_pDataStart != nullptr, "Memory has not been allocated");
174174 VERIFY(IsPowerOfTwo(alignment), "Alignment is not a power of two!");
201201 }
202202
203203 template <typename T>
204 NDDISCARD T* Allocate(size_t count = 1)
204 NODISCARD T* Allocate(size_t count = 1)
205205 {
206206 return reinterpret_cast<T*>(Allocate(sizeof(T) * count, alignof(T)));
207207 }
208208
209209 template <typename T, typename... Args>
210 NDDISCARD T* Construct(Args&&... args)
210 NODISCARD T* Construct(Args&&... args)
211211 {
212212 T* Ptr = Allocate<T>();
213213 new (Ptr) T{std::forward<Args>(args)...};
215215 }
216216
217217 template <typename T, typename... Args>
218 NDDISCARD T* ConstructArray(size_t count, const Args&... args)
218 NODISCARD T* ConstructArray(size_t count, const Args&... args)
219219 {
220220 T* Ptr = Allocate<T>(count);
221221 for (size_t i = 0; i < count; ++i)
226226 }
227227
228228 template <typename T>
229 NDDISCARD T* Copy(const T& Src)
229 NODISCARD T* Copy(const T& Src)
230230 {
231231 return Construct<T>(Src);
232232 }
233233
234234 template <typename T>
235 NDDISCARD T* CopyArray(const T* Src, size_t count)
235 NODISCARD T* CopyArray(const T* Src, size_t count)
236236 {
237237 T* Dst = Allocate<T>(count);
238238 for (size_t i = 0; i < count; ++i)
242242 return Dst;
243243 }
244244
245 NDDISCARD Char* CopyString(const char* Str)
245 NODISCARD Char* CopyString(const char* Str)
246246 {
247247 if (Str == nullptr)
248248 return nullptr;
264264 return Ptr;
265265 }
266266
267 NDDISCARD Char* CopyString(const std::string& Str)
267 NODISCARD Char* CopyString(const std::string& Str)
268268 {
269269 return CopyString(Str.c_str());
270270 }
271271
272 NDDISCARD size_t GetCurrentSize() const
273 {
272 NODISCARD size_t GetCurrentSize() const
273 {
274 VERIFY(m_pDataStart != nullptr, "Memory has not been allocated");
274275 return static_cast<size_t>(m_pCurrPtr - m_pDataStart);
275276 }
276277
277 NDDISCARD size_t GetReservedSize() const
278 NODISCARD size_t GetReservedSize() const
278279 {
279280 return m_ReservedSize;
280281 }
10861086 const char* GetQueryTypeString(QUERY_TYPE QueryType)
10871087 {
10881088 static_assert(QUERY_TYPE_NUM_TYPES == 6, "Not all QUERY_TYPE enum values are handled");
1089 // clang-format off
1090 switch(QueryType)
1091 {
1089 switch (QueryType)
1090 {
1091 // clang-format off
10921092 case QUERY_TYPE_UNDEFINED: return "QUERY_TYPE_UNDEFINED";
10931093 case QUERY_TYPE_OCCLUSION: return "QUERY_TYPE_OCCLUSION";
10941094 case QUERY_TYPE_BINARY_OCCLUSION: return "QUERY_TYPE_BINARY_OCCLUSION";
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
1098 // clang-format on
10991099 default:
11001100 UNEXPECTED("Unepxected query type");
11011101 return "Unknown";
11021102 }
1103 // clang-format on
11041103 }
11051104
11061105 const char* GetSurfaceTransformString(SURFACE_TRANSFORM SrfTransform)
11321131 const char* GetPipelineTypeString(PIPELINE_TYPE PipelineType)
11331132 {
11341133 static_assert(PIPELINE_TYPE_LAST == PIPELINE_TYPE_RAY_TRACING, "Please update this function to handle the new pipeline type");
1135 // clang-format off
11361134 switch (PipelineType)
11371135 {
1136 // clang-format off
11381137 case PIPELINE_TYPE_COMPUTE: return "compute";
11391138 case PIPELINE_TYPE_GRAPHICS: return "graphics";
11401139 case PIPELINE_TYPE_MESH: return "mesh";
11411140 case PIPELINE_TYPE_RAY_TRACING: return "ray tracing";
1142
1141 // clang-format on
11431142 default:
11441143 UNEXPECTED("Unexpected pipeline type");
11451144 return "unknown";
11461145 }
1147 // clang-format on
11481146 }
11491147
11501148 const char* GetShaderCompilerTypeString(SHADER_COMPILER Compiler)
11511149 {
11521150 static_assert(SHADER_COMPILER_LAST == SHADER_COMPILER_FXC, "Please update this function to handle the new shader compiler");
1153 // clang-format off
11541151 switch (Compiler)
11551152 {
1153 // clang-format off
11561154 case SHADER_COMPILER_DEFAULT: return "Default";
11571155 case SHADER_COMPILER_GLSLANG: return "glslang";
11581156 case SHADER_COMPILER_DXC: return "DXC";
11591157 case SHADER_COMPILER_FXC: return "FXC";
1160
1158 // clang-format on
11611159 default:
11621160 UNEXPECTED("Unexpected shader compiler");
11631161 return "UNKNOWN";
1164 };
1165 // clang-format on
1162 }
11661163 }
11671164
11681165 Uint32 ComputeMipLevelsCount(Uint32 Width)
13501347 case SHADER_TYPE_VERTEX: // Graphics
13511348 case SHADER_TYPE_AMPLIFICATION: // Mesh
13521349 case SHADER_TYPE_COMPUTE: // Compute
1353 case SHADER_TYPE_RAY_GEN: // RayTracing
1350 case SHADER_TYPE_RAY_GEN: // Ray tracing
13541351 return 0;
13551352
13561353 case SHADER_TYPE_HULL: // Graphics
13591356 return 1;
13601357
13611358 case SHADER_TYPE_DOMAIN: // Graphics
1362 case SHADER_TYPE_RAY_CLOSEST_HIT: // RayTracing
1359 case SHADER_TYPE_RAY_CLOSEST_HIT: // Ray tracing
13631360 return 2;
13641361
13651362 case SHADER_TYPE_GEOMETRY: // Graphics
1366 case SHADER_TYPE_RAY_ANY_HIT: // RayTracing
1363 case SHADER_TYPE_RAY_ANY_HIT: // Ray tracing
13671364 return 3;
13681365
13691366 case SHADER_TYPE_PIXEL: // Graphics or Mesh
1370 case SHADER_TYPE_RAY_INTERSECTION: // RayTracing
1367 case SHADER_TYPE_RAY_INTERSECTION: // Ray tracing
13711368 return 4;
13721369
13731370 case SHADER_TYPE_CALLABLE: // RayTracing
143143 RasterizerStateRegistry.ReportDeletedObject();
144144 DSSRegistry.ReportDeletedObject();
145145 */
146 VERIFY(m_IsDestructed, "This object must be explicitly destructed with Destruct()");
146147 }
147148
148149 void Destruct()
149150 {
150 if (this->m_Desc.IsRayTracingPipeline() && m_pRayTracingPipelineData)
151 VERIFY(!m_IsDestructed, "This object has already been destructed");
152
153 if (this->m_Desc.IsAnyGraphicsPipeline() && m_pGraphicsPipelineDesc != nullptr)
154 {
155 m_pGraphicsPipelineDesc->~GraphicsPipelineDesc();
156 m_pGraphicsPipelineDesc = nullptr;
157 }
158 else if (this->m_Desc.IsRayTracingPipeline() && m_pRayTracingPipelineData != nullptr)
151159 {
152160 m_pRayTracingPipelineData->~RayTracingPipelineData();
153161 m_pRayTracingPipelineData = nullptr;
154162 }
163 #if DILIGENT_DEBUG
164 m_IsDestructed = true;
165 #endif
155166 }
156167
157168 IMPLEMENT_QUERY_INTERFACE_IN_PLACE(IID_PipelineState, TDeviceObjectBase)
313324
314325 MemPool.AddSpace<Uint32>(m_BufferSlotsUsed);
315326
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");
327 static_assert(std::is_trivially_destructible<decltype(*InputLayout.LayoutElements)>::value, "Add destructor for this object to Destruct()");
318328 }
319329
320330 void ReserveSpaceForPipelineDesc(const ComputePipelineStateCreateInfo& CreateInfo,
324334 }
325335
326336 void ReserveSpaceForPipelineDesc(const RayTracingPipelineStateCreateInfo& CreateInfo,
327 Uint32 ShaderHandleSize,
328337 LinearAllocator& MemPool) const noexcept
329338 {
330339 ReserveResourceLayout(CreateInfo.PSODesc.ResourceLayout, MemPool);
344353
345354 size_t RTDataSize = sizeof(RayTracingPipelineData);
346355 // reserve size for shader handles
356 const auto ShaderHandleSize = m_pDevice->GetShaderGroupHandleSize();
347357 RTDataSize += ShaderHandleSize * (CreateInfo.GeneralShaderCount + CreateInfo.TriangleHitShaderCount + CreateInfo.ProceduralHitShaderCount);
348 // 1 byte reserved to avoid compiler errors on zero sized arrays
358 // Extra bytes are reserved to avoid compiler errors on zero-sized arrays
349359 RTDataSize -= sizeof(RayTracingPipelineData::Shaders);
350360 MemPool.AddSpace(RTDataSize, alignof(RayTracingPipelineData));
351361 }
429439 auto AddShaderStage = [&ShaderStages, &UniqueShaders](IShader* pShader) {
430440 if (pShader != nullptr && UniqueShaders.insert(pShader).second)
431441 {
432 auto ShaderType = pShader->GetDesc().ShaderType;
433 ShaderStages[GetShaderTypePipelineIndex(ShaderType, PIPELINE_TYPE_RAY_TRACING)].Append(ValidatedCast<ShaderImplType>(pShader));
442 auto ShaderType = pShader->GetDesc().ShaderType;
443 auto StageInd = GetShaderTypePipelineIndex(ShaderType, PIPELINE_TYPE_RAY_TRACING);
444 auto& Stage = ShaderStages[StageInd];
445 Stage.Append(ValidatedCast<ShaderImplType>(pShader));
446 VERIFY_EXPR(Stage.Type == SHADER_TYPE_UNKNOWN || Stage.Type == ShaderType);
447 Stage.Type = ShaderType;
434448 }
435449 };
436450
437451 ShaderStages.clear();
438452 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;
445453
446454 for (Uint32 i = 0; i < CreateInfo.GeneralShaderCount; ++i)
447455 {
522530 }
523531
524532 const auto& InputLayout = GraphicsPipeline.InputLayout;
525 LayoutElement* pLayoutElements = MemPool.Allocate<LayoutElement>(InputLayout.NumElements);
533 LayoutElement* pLayoutElements = MemPool.ConstructArray<LayoutElement>(InputLayout.NumElements);
526534 for (size_t Elem = 0; Elem < InputLayout.NumElements; ++Elem)
527535 {
528536 const auto& SrcElem = InputLayout.LayoutElements[Elem];
602610 LayoutElem.Stride = Strides[BuffSlot];
603611 }
604612
605 m_pStrides = MemPool.Allocate<Uint32>(m_BufferSlotsUsed);
613 m_pStrides = MemPool.ConstructArray<Uint32>(m_BufferSlotsUsed);
606614
607615 // Set strides for all unused slots to 0
608616 for (Uint32 i = 0; i < m_BufferSlotsUsed; ++i)
619627 }
620628
621629 void InitializePipelineDesc(const RayTracingPipelineStateCreateInfo& CreateInfo,
622 Uint32 ShaderHandleSize,
623630 TNameToGroupIndexMap&& NameToGroupIndex,
624631 LinearAllocator& MemPool) noexcept
625632 {
627634
628635 size_t RTDataSize = sizeof(RayTracingPipelineData);
629636 // reserve size for shader handles
630 const Uint32 ShaderDataSize = ShaderHandleSize * (CreateInfo.GeneralShaderCount + CreateInfo.TriangleHitShaderCount + CreateInfo.ProceduralHitShaderCount);
637 const auto ShaderHandleSize = m_pDevice->GetShaderGroupHandleSize();
638 const auto ShaderDataSize = ShaderHandleSize * (CreateInfo.GeneralShaderCount + CreateInfo.TriangleHitShaderCount + CreateInfo.ProceduralHitShaderCount);
631639 RTDataSize += ShaderDataSize;
632 // 1 byte reserved to avoid compiler errors on zero sized arrays
640 // Extra bytes are reserved to avoid compiler errors on zero-sized arrays
633641 RTDataSize -= sizeof(RayTracingPipelineData::Shaders);
634642
635643 this->m_pRayTracingPipelineData = static_cast<RayTracingPipelineData*>(MemPool.Allocate(RTDataSize, alignof(RayTracingPipelineData)));
663671 }
664672 }
665673
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");
674 static_assert(std::is_trivially_destructible<decltype(*SrcLayout.Variables)>::value, "Add destructor for this object to Destruct()");
675 static_assert(std::is_trivially_destructible<decltype(*SrcLayout.ImmutableSamplers)>::value, "Add destructor for this object to Destruct()");
668676 }
669677
670678 static void CopyResourceLayout(const PipelineResourceLayoutDesc& SrcLayout, PipelineResourceLayoutDesc& DstLayout, LinearAllocator& MemPool)
671679 {
672680 if (SrcLayout.Variables != nullptr)
673681 {
674 auto* Variables = MemPool.Allocate<ShaderResourceVariableDesc>(SrcLayout.NumVariables);
682 auto* Variables = MemPool.ConstructArray<ShaderResourceVariableDesc>(SrcLayout.NumVariables);
675683 DstLayout.Variables = Variables;
676684 for (Uint32 i = 0; i < SrcLayout.NumVariables; ++i)
677685 {
683691
684692 if (SrcLayout.ImmutableSamplers != nullptr)
685693 {
686 auto* ImmutableSamplers = MemPool.Allocate<ImmutableSamplerDesc>(SrcLayout.NumImmutableSamplers);
694 auto* ImmutableSamplers = MemPool.ConstructArray<ImmutableSamplerDesc>(SrcLayout.NumImmutableSamplers);
687695 DstLayout.ImmutableSamplers = ImmutableSamplers;
688696 for (Uint32 i = 0; i < SrcLayout.NumImmutableSamplers; ++i)
689697 {
725733 {
726734 RayTracingPipelineDesc Desc;
727735 TNameToGroupIndexMap NameToGroupIndex;
728 Uint32 ShaderHandleSize;
729 Uint32 ShaderDataSize;
730 Uint8 Shaders[1];
736
737 Uint32 ShaderHandleSize = 0;
738 Uint32 ShaderDataSize = 0;
739
740 Uint8 Shaders[sizeof(void*)] = {}; // The actual array size will be ShaderDataSize
731741 };
742 static_assert(offsetof(RayTracingPipelineData, Shaders) % sizeof(void*) == 0, "Shaders member is expected to be sizeof(void*)-aligned");
732743
733744 union
734745 {
735 GraphicsPipelineDesc* m_pGraphicsPipelineDesc;
746 GraphicsPipelineDesc* m_pGraphicsPipelineDesc = nullptr;
736747 RayTracingPipelineData* m_pRayTracingPipelineData;
737748 };
749
750 #ifdef DILIGENT_DEBUG
751 bool m_IsDestructed = false;
752 #endif
738753 };
739754
740755 } // namespace Diligent
250250
251251 void ValidateRayTracingPipelineCreateInfo(const RayTracingPipelineStateCreateInfo& CreateInfo) noexcept(false)
252252 {
253 #ifdef DILIGENT_DEVELOPMENT
254253 const auto& PSODesc = CreateInfo.PSODesc;
255254 if (PSODesc.PipelineType != PIPELINE_TYPE_RAY_TRACING)
256255 LOG_PSO_ERROR_AND_THROW("Pipeline type must be RAY_TRACING");
281280 if (Group.Name == nullptr)
282281 LOG_PSO_ERROR_AND_THROW("pTriangleHitShaders[", i, "].Name must not be null");
283282
284 VALIDATE_SHADER_TYPE(Group.pClosestHitShader, SHADER_TYPE_RAY_CLOSEST_HIT, "ray tracing triangle closes hit");
283 VALIDATE_SHADER_TYPE(Group.pClosestHitShader, SHADER_TYPE_RAY_CLOSEST_HIT, "ray tracing triangle closest hit");
285284
286285 if (Group.pAnyHitShader != nullptr)
287286 VALIDATE_SHADER_TYPE(Group.pAnyHitShader, SHADER_TYPE_RAY_ANY_HIT, "ray tracing triangle any hit");
302301 if (Group.pAnyHitShader != nullptr)
303302 VALIDATE_SHADER_TYPE(Group.pAnyHitShader, SHADER_TYPE_RAY_ANY_HIT, "ray tracing procedural any hit");
304303 }
305 #endif // DILIGENT_DEVELOPMENT
306304 }
307305
308306 #undef VALIDATE_SHADER_TYPE
166166 // Resource layout index in m_pStaticResourceLayouts array for every shader stage,
167167 // indexed by the shader type pipeline index (returned by GetShaderTypePipelineIndex)
168168 std::array<Int8, MAX_SHADERS_IN_PIPELINE> m_ResourceLayoutIndex = {-1, -1, -1, -1, -1, -1};
169 static_assert(MAX_SHADERS_IN_PIPELINE == 6, "Please update the initializer list above");
169170
170171 std::array<Uint16, MAX_SHADERS_IN_PIPELINE + 1> m_ImmutableSamplerOffsets = {};
171172 struct ImmutableSamplerInfo
110110 // Resource layout index in m_pResourceLayouts array for every shader stage,
111111 // indexed by the shader type pipeline index (returned by GetShaderTypePipelineIndex)
112112 std::array<Int8, MAX_SHADERS_IN_PIPELINE> m_ResourceLayoutIndex = {-1, -1, -1, -1, -1, -1};
113 static_assert(MAX_SHADERS_IN_PIPELINE == 6, "Please update the initializer list above");
113114
114115 Uint8 m_NumActiveShaders = 0;
115116
415415
416416 void RenderDeviceD3D11Impl::CreateRayTracingPipelineState(const RayTracingPipelineStateCreateInfo& PSOCreateInfo, IPipelineState** ppPipelineState)
417417 {
418 UNSUPPORTED("CreateRayTracingPipelineState is not supported in DirectX 11");
418 UNSUPPORTED("Ray tracing is not supported in DirectX 11");
419419 *ppPipelineState = nullptr;
420420 }
421421
447447
448448 [&](const D3DShaderResourceAttribs&, Uint32) //
449449 {
450 UNEXPECTED("acceleration structure is not supported in DirectX 11");
450 UNEXPECTED("Acceleration structure is not supported in DirectX 11");
451451 } // clang-format off
452452 ); // clang-format on
453453 }
7474 D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE AttachmentLoadOpToD3D12BeginningAccessType(ATTACHMENT_LOAD_OP LoadOp);
7575 D3D12_RENDER_PASS_ENDING_ACCESS_TYPE AttachmentStoreOpToD3D12EndingAccessType(ATTACHMENT_STORE_OP StoreOp);
7676
77 D3D12_SHADER_VISIBILITY ShaderTypeToD3D12ShaderVisibility(SHADER_TYPE ShaderType);
78 SHADER_TYPE D3D12ShaderVisibilityToShaderType(D3D12_SHADER_VISIBILITY ShaderVisibility);
79
80
7781 } // namespace Diligent
132132 void Append(ShaderD3D12Impl* pShader);
133133 size_t Count() const;
134134
135 SHADER_TYPE Type;
135 SHADER_TYPE Type = SHADER_TYPE_UNKNOWN;
136136 std::vector<ShaderD3D12Impl*> Shaders;
137137 };
138138 using TShaderStages = std::vector<ShaderStageInfo>;
139139
140 template <typename PSOCreateInfoType>
141 void InitInternalObjects(const PSOCreateInfoType& CreateInfo, TShaderStages& ShaderStages);
140 template <typename PSOCreateInfoType, typename InitPSODescType>
141 void InitInternalObjects(const PSOCreateInfoType& CreateInfo, TShaderStages& ShaderStages, InitPSODescType InitPSODesc);
142142 void InitResourceLayouts(const PipelineStateCreateInfo& CreateInfo, TShaderStages& ShaderStages);
143143
144144 void Destruct();
156156 // Resource layout index in m_pShaderResourceLayouts array for every shader stage,
157157 // indexed by the shader type pipeline index (returned by GetShaderTypePipelineIndex)
158158 std::array<Int8, MAX_SHADERS_IN_PIPELINE> m_ResourceLayoutIndex = {-1, -1, -1, -1, -1, -1};
159 static_assert(MAX_SHADERS_IN_PIPELINE == 6, "Please update the initializer list above");
159160 };
160161
161162 } // namespace Diligent
177177 ShaderVersion GetMaxShaderModel() const;
178178 D3D_FEATURE_LEVEL GetD3DFeatureLevel() const;
179179
180 static Uint32 GetShaderGroupHandleSize()
181 {
182 return D3D12_SHADER_IDENTIFIER_SIZE_IN_BYTES;
183 }
184
180185 private:
181186 template <typename PSOCreateInfoType>
182187 void CreatePipelineState(const PSOCreateInfoType& PSOCreateInfo, IPipelineState** ppPipelineState);
3131 #include <array>
3232 #include "ShaderResourceLayoutD3D12.hpp"
3333 #include "BufferD3D12Impl.hpp"
34 #include "D3D12TypeConversions.hpp"
3435
3536 namespace Diligent
3637 {
3738
38 D3D12_SHADER_VISIBILITY GetShaderVisibility(SHADER_TYPE ShaderType);
3939 D3D12_DESCRIPTOR_HEAP_TYPE dbgHeapTypeFromRangeType(D3D12_DESCRIPTOR_RANGE_TYPE RangeType);
4040
4141 class RootParameter
512512 class CommandContext& Ctx,
513513 bool IsCompute,
514514 bool ValidateStates) const;
515
516 #ifdef DILIGENT_DEBUG
517 SHADER_TYPE m_DbgShaderStages = SHADER_TYPE_UNKNOWN;
518 #endif
519515 };
520516
521517 void RootSignature::CommitRootViews(ShaderResourceCacheD3D12& ResourceCache,
536532
537533 SHADER_TYPE dbgShaderType = SHADER_TYPE_UNKNOWN;
538534 #ifdef DILIGENT_DEBUG
539 dbgShaderType = m_DbgShaderStages;
535 {
536 auto& Param = static_cast<const D3D12_ROOT_PARAMETER&>(RootView);
537 VERIFY_EXPR(Param.ParameterType == D3D12_ROOT_PARAMETER_TYPE_CBV);
538 dbgShaderType = D3D12ShaderVisibilityToShaderType(Param.ShaderVisibility);
539 }
540540 #endif
541541
542542 auto& Res = ResourceCache.GetRootTable(RootInd).GetResource(0, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, dbgShaderType);
8585 // Resource layout index in m_ShaderResourceCache array for every shader stage,
8686 // indexed by the shader type pipeline index (returned by GetShaderTypePipelineIndex)
8787 std::array<Int8, MAX_SHADERS_IN_PIPELINE> m_ResourceLayoutIndex = {-1, -1, -1, -1, -1, -1};
88 static_assert(MAX_SHADERS_IN_PIPELINE == 6, "Please update the initializer list above");
8889
8990 bool m_bStaticResourcesInitialized = false;
9091 const Uint8 m_NumShaders = 0;
166166 const SHADER_TYPE dbgRefShaderType) const
167167 {
168168 VERIFY(m_dbgHeapType == dbgDescriptorHeapType, "Incosistent descriptor heap type");
169 VERIFY((m_dbgShaderType & dbgRefShaderType) == dbgRefShaderType, "Incosistent shader type");
169 VERIFY(dbgRefShaderType == SHADER_TYPE_UNKNOWN || m_dbgShaderType == SHADER_TYPE_UNKNOWN || m_dbgShaderType == dbgRefShaderType, "Incosistent shader type");
170170
171171 VERIFY(OffsetFromTableStart < m_NumResources, "Root table is not large enough to store descriptor at offset ", OffsetFromTableStart);
172172 return m_pResources[OffsetFromTableStart];
4949 // m' == NumSamplers[SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE]
5050 // d' == NumSamplers[SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC]
5151 //
52 // Every D3D12Resource structure holds a reference to D3DShaderResourceAttribs structure from ShaderResourcesD3D12.
53 // ShaderResourceLayoutD3D12 holds shared pointer to ShaderResourcesD3D12 instance. Note that ShaderResourcesD3D12::SamplerId
54 // references a sampler in ShaderResourcesD3D12, while D3D12Resource::SamplerId references a sampler in ShaderResourceLayoutD3D12,
55 // and the two are not necessarily the same
56 //
57 //
58 // ________________SamplerId____________________
59 // | |
60 // _____________________ ______________|_____________________________________________V________
61 // | | unique_ptr | | | | | | |
62 // |ShaderResourcesD3D12 |--------------->| CBs | TexSRVs | TexUAVs | BufSRVs | BufUAVs | Samplers |
63 // |_____________________| |________|___________|___________|___________|___________|____________|
64 // A A A A
65 // | \ / \
66 // |shared_ptr Ref Ref Ref
67 // ________|__________________ ________\________________________/_________________________\________________________________________________
52 //
53 //
54 // ___________________________ ____________________________________________________________________________________________________________
6855 // | | unique_ptr | | | | | | |
6956 // | ShaderResourceLayoutD3D12 |--------------->| D3D12Resource[0] | D3D12Resource[1] | ... | D3D12Resource[smd] | D3D12Resource[smd+1] | ... |
7057 // |___________________________| |__________________|__________________|_______________|____________________|______________________|__________|
7865 // | | | | | |
7966 // | ShaderVariableManagerD3D12 |---------------->| ShaderVariableD3D12Impl[0] | ShaderVariableD3D12Impl[1] | ... |
8067 // |____________________________| |____________________________|____________________________|_________________|
81
82 //
83 // http://diligentgraphics.com/diligent-engine/architecture/d3d12/shader-resource-layout#Figure2
68 //
69 //
70 //
71 //
72 //
73 // One ShaderResourceLayoutD3D12 instance can be referenced by multiple objects
74 //
75 //
76 // ________________________ _<m_pShaderResourceLayouts>_ _____<m_pShaderVarMgrs>_____ ________________________________
77 // | | | | | | | |
78 // | PipelineStateD3D12Impl |========>| ShaderResourceLayoutD3D12 |<-------| ShaderVariableManagerD3D12 |<====| ShaderResourceBindingD3D12Impl |
79 // |________________________| |____________________________| |____________________________| |________________________________|
80 // A
81 // \
82 // \ _____<m_pShaderVarMgrs>_____ ________________________________
83 // \ | | | |
84 // '-------| ShaderVariableManagerD3D12 |<====| ShaderResourceBindingD3D12Impl |
85 // |____________________________| |________________________________|
86 //
87 //
88 //
8489 // Resources in the resource cache are identified by the root index and offset in the descriptor table
8590 //
8691 //
100105 #include <array>
101106
102107 #include "ShaderBase.hpp"
103 #include "ShaderResourcesD3D12.hpp"
104108 #include "ShaderResourceCacheD3D12.hpp"
105109 #include "ShaderD3D12Impl.hpp"
110 #include "StringPool.hpp"
111 #include "D3DCommonTypeConversions.hpp"
106112
107113 namespace Diligent
108114 {
109115
110116 /// Diligent::ShaderResourceLayoutD3D12 class
111 // sizeof(ShaderResourceLayoutD3D12) == 64 (MS compiler, x64)
117 // sizeof(ShaderResourceLayoutD3D12) == 56 (MS compiler, x64)
112118 class ShaderResourceLayoutD3D12 final
113119 {
114120 public:
115121 explicit ShaderResourceLayoutD3D12(IObject& Owner) noexcept :
116122 m_Owner{Owner}
117 {}
123 {
124 #if defined(_MSC_VER) && defined(_WIN64)
125 static_assert(sizeof(*this) == 56, "Unexpected sizeof(ShaderResourceLayoutD3D12)");
126 #endif
127 }
118128
119129 // There are two modes a layout can be initialized:
120130 // - initialize static resource layout and initialize shader resource cache to hold static resources
140150
141151 ~ShaderResourceLayoutD3D12();
142152
143 // sizeof(D3D12Resource) == 24 (x64)
153 // sizeof(D3D12Resource) == 32 (x64)
144154 struct D3D12Resource final
145155 {
146156 // clang-format off
152162
153163 static constexpr const Uint32 ResourceTypeBits = 3;
154164 static constexpr const Uint32 VariableTypeBits = 2;
155 static constexpr const Uint32 RootIndexBits = 16 - ResourceTypeBits - VariableTypeBits;
156
157 static constexpr const Uint32 InvalidRootIndex = (1 << RootIndexBits) - 1;
158 static constexpr const Uint32 MaxRootIndex = InvalidRootIndex - 1;
159
160 static constexpr const Uint32 InvalidSamplerId = 0xFFFF;
161 static constexpr const Uint32 MaxSamplerId = InvalidSamplerId-1;
165 static constexpr const Uint32 RootIndexBits = 32 - ResourceTypeBits - VariableTypeBits;
166
167 static constexpr const Uint32 InvalidRootIndex = (1U << RootIndexBits) - 1U;
168 static constexpr const Uint32 MaxRootIndex = InvalidRootIndex - 1U;
169
162170 static constexpr const Uint32 InvalidOffset = static_cast<Uint32>(-1);
163171
164 static_assert( SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES < (1 << VariableTypeBits), "2 bits is not enough to store SHADER_RESOURCE_VARIABLE_TYPE");
165 static_assert( static_cast<int>(CachedResourceType::NumTypes) < (1 << ResourceTypeBits), "3 bits is not enough to store CachedResourceType");
166
172 static_assert(SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES < (1 << VariableTypeBits), "Not enough bits to represent SHADER_RESOURCE_VARIABLE_TYPE");
173 static_assert(static_cast<int>(CachedResourceType::NumTypes) < (1 << ResourceTypeBits), "Not enough bits to represent CachedResourceType");
174
167175 /* 0 */ const ShaderResourceLayoutD3D12& ParentResLayout;
168 /*16 */ const Uint32 OffsetFromTableStart;
169 /*20.0*/ const Uint16 ResourceType : ResourceTypeBits; // | 0 1 2 |
170 /*20.3*/ const Uint16 VariableType : VariableTypeBits; // | 3 4 |
171 /*20.5*/ const Uint16 RootIndex : RootIndexBits; // | 5 6 7 ... 15 |
172 /*22 */ const Uint16 SamplerId;
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
176 /* 8 */ const D3DShaderResourceAttribs Attribs;
177 /*24 */ const Uint32 OffsetFromTableStart;
178 /*28.0*/ const Uint32 ResourceType : ResourceTypeBits; // | 0 1 2 |
179 /*28.3*/ const Uint32 VariableType : VariableTypeBits; // | 3 4 |
180 /*28.5*/ const Uint32 RootIndex : RootIndexBits; // | 5 6 7 ... 15 |
181 /*32 */ // End of data
179182
180183 // clang-format on
181184
182185 D3D12Resource(const ShaderResourceLayoutD3D12& _ParentLayout,
186 StringPool& _StringPool,
187 const D3DShaderResourceAttribs& _Attribs,
188 Uint32 _SamplerId,
183189 SHADER_RESOURCE_VARIABLE_TYPE _VariableType,
184190 CachedResourceType _ResType,
185191 Uint32 _RootIndex,
186 Uint32 _OffsetFromTableStart,
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 :
192 Uint32 _OffsetFromTableStart) noexcept :
193193 // clang-format off
194 ParentResLayout {_ParentLayout },
195 ResourceType {static_cast<Uint16>(_ResType) },
196 VariableType {static_cast<Uint16>(_VariableType)},
197 RootIndex {static_cast<Uint16>(_RootIndex) },
198 SamplerId {static_cast<Uint16>(_SamplerId) },
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) }
194 ParentResLayout{_ParentLayout},
195 Attribs
196 {
197 _StringPool,
198 _Attribs,
199 _SamplerId
200 },
201 ResourceType {static_cast<Uint32>(_ResType) },
202 VariableType {static_cast<Uint32>(_VariableType)},
203 RootIndex {static_cast<Uint32>(_RootIndex) },
204 OffsetFromTableStart{ _OffsetFromTableStart }
205205 // clang-format on
206206 {
207 #if defined(_MSC_VER) && defined(_WIN64)
208 static_assert(sizeof(*this) == 32, "Unexpected sizeof(D3D12Resource)");
209 #endif
210
207211 VERIFY(IsValidOffset(), "Offset must be valid");
208212 VERIFY(IsValidRootIndex(), "Root index must be valid");
209213 VERIFY(_RootIndex <= MaxRootIndex, "Root index (", _RootIndex, ") exceeds max allowed value (", MaxRootIndex, ")");
214 VERIFY(static_cast<Uint32>(_ResType) < (1 << ResourceTypeBits), "Resource type is out of representable range");
210215 VERIFY(_VariableType < (1 << VariableTypeBits), "Variable type is out of representable range");
211 VERIFY(_SamplerId == InvalidSamplerId || _SamplerId <= MaxSamplerId, "Sampler id (", _SamplerId, ") exceeds max allowed value (", MaxSamplerId, ")");
212 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());
217216 }
218217
219218 bool IsBound(Uint32 ArrayIndex,
224223 ShaderResourceCacheD3D12& ResourceCache) const;
225224
226225 // clang-format off
227 bool ValidSamplerAssigned()const { return SamplerId != InvalidSamplerId; }
228 bool IsValidRootIndex() const { return RootIndex != InvalidRootIndex; }
229 bool IsValidOffset() const { return OffsetFromTableStart != InvalidOffset; }
226 bool IsValidRootIndex() const { return RootIndex != InvalidRootIndex; }
227 bool IsValidOffset() const { return OffsetFromTableStart != InvalidOffset; }
230228 // clang-format on
231229
232230 CachedResourceType GetResType() const { return static_cast<CachedResourceType>(ResourceType); }
233231 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;
263232
264233 private:
265234 void CacheCB(IDeviceObject* pBuffer,
392361 return GetResource(m_SamplersOffsets[0] + s);
393362 }
394363
395 void AllocateMemory(IMemoryAllocator& Allocator,
396 const std::array<Uint32, SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES>& CbvSrvUavCount,
397 const std::array<Uint32, SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES>& SamplerCount);
364 StringPool AllocateMemory(IMemoryAllocator& Allocator,
365 const std::array<Uint32, SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES>& CbvSrvUavCount,
366 const std::array<Uint32, SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES>& SamplerCount,
367 size_t StringPoolSize);
398368 // clang-format off
399369
400370 /* 0 */ std::unique_ptr<void, STDDeleterRawMem<void> > m_ResourceBuffer;
401371 /* 16 */ std::array<Uint16, SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES + 1> m_CbvSrvUavOffsets = {};
402372 /* 24 */ std::array<Uint16, SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES + 1> m_SamplersOffsets = {};
403373
404 /* 24 */ StringPool m_StringPool;
405374 /* 32 */ IObject& m_Owner;
406 /* 48 */ CComPtr<ID3D12Device> m_pd3d12Device;
407 /* */ SHADER_TYPE m_ShaderType = SHADER_TYPE_UNKNOWN;
375 /* 40 */ CComPtr<ID3D12Device> m_pd3d12Device;
376 /* 48 */ SHADER_TYPE m_ShaderType = SHADER_TYPE_UNKNOWN;
408377 /* */ bool m_IsUsingSeparateSamplers = false;
409 /* 64 */ // End of data
378 /* 56 */ // End of data
410379
411380 // clang-format on
412381 };
2929 /// \file
3030 /// Declaration of Diligent::ShaderResourcesD3D12 class
3131
32 // ShaderResourcesD3D12 are created by ShaderD3D12Impl instances. They are then referenced by ShaderResourceLayoutD3D12 objects, which are in turn
32 // ShaderResourcesD3D12 are created by ShaderD3D12Impl instances. They are then used by ShaderResourceLayoutD3D12 objects, which are
3333 // created by instances of PipelineStatesD3D12Impl and ShaderD3D12Impl
3434 //
3535 // _________________
4242 // | | unique_ptr | | | | | | |
4343 // | ShaderResourcesD3D12 |--------------->| CBs | TexSRVs | TexUAVs | BufSRVs | BufUAVs | Samplers |
4444 // |______________________| |________|___________|___________|___________|___________|____________|
45 // A A A A
46 // | \ / \
47 // |shared_ptr Ref Ref Ref
48 // ________|__________________ ________\________________________/_________________________\_________________________________________
45 // A A A
46 // \ / \
47 // Copy Copy Copy
48 // ___________________________ ________\________________________/_________________________\_________________________________________
4949 // | | unique_ptr | | | | | | |
5050 // | ShaderResourceLayoutD3D12 |--------------->| SRV_CBV_UAV[0] | SRV_CBV_UAV[1] | ... | Sampler[0] | Sampler[1] | ... |
5151 // |___________________________| |___________________|_________________|_______________|__________________|_________________|__________|
5656 // | |
5757 // | PipelineStateD3D12Impl |
5858 // |________________________|
59 //
60 //
61 //
62 // One ShaderResourcesD3D12 instance can be referenced by multiple objects
63 //
64 //
65 // ________________________ _<m_pShaderResourceLayouts>_ _____<m_pShaderVarMgrs>_____ ________________________________
66 // | | | | | | | |
67 // | PipelineStateD3D12Impl |========>| ShaderResourceLayoutD3D12 |<-------| ShaderVariableManagerD3D12 |<====| ShaderResourceBindingD3D12Impl |
68 // |________________________| |____________________________| |____________________________| |________________________________|
69 // | A
70 // |shared_ptr \
71 // _________________ ___________V__________ \ _____<m_pShaderVarMgrs>_____ ________________________________
72 // | | shared_ptr | | \ | | | |
73 // | ShaderD3D12Impl |---------------->| ShaderResourcesD3D12 | '-------| ShaderVariableManagerD3D12 |<====| ShaderResourceBindingD3D12Impl |
74 // |_________________| |______________________| |____________________________| |________________________________|
75 // | |___________________ A
76 // | | |
77 // V V |shared_ptr
78 // _______<m_StaticVarsMgr>____ ___<m_StaticResLayout>_|___
79 // | | | |
80 // | ShaderVariableManagerD3D12 |------>| ShaderResourceLayoutD3D12 |
81 // |____________________________| |___________________________|
8259 //
8360
8461 #include "ShaderResources.hpp"
185185
186186 virtual void DILIGENT_CALL_TYPE SetArray(IDeviceObject* const* ppObjects, Uint32 FirstElement, Uint32 NumElements) override final
187187 {
188 VerifyAndCorrectSetArrayArguments(m_Resource.Name, m_Resource.BindCount, FirstElement, NumElements);
188 VerifyAndCorrectSetArrayArguments(m_Resource.Attribs.Name, m_Resource.Attribs.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.GetHLSLResourceDesc();
200 return m_Resource.Attribs.GetHLSLResourceDesc();
201201 }
202202
203203 virtual Uint32 DILIGENT_CALL_TYPE GetIndex() const override final
539539 // clang-format on
540540 }
541541
542 D3D12_SHADER_VISIBILITY ShaderTypeToD3D12ShaderVisibility(SHADER_TYPE ShaderType)
543 {
544 static_assert(SHADER_TYPE_LAST == SHADER_TYPE_CALLABLE, "Please update the switch below to handle the new shader type");
545 switch (ShaderType)
546 {
547 // clang-format off
548 case SHADER_TYPE_VERTEX: return D3D12_SHADER_VISIBILITY_VERTEX;
549 case SHADER_TYPE_PIXEL: return D3D12_SHADER_VISIBILITY_PIXEL;
550 case SHADER_TYPE_GEOMETRY: return D3D12_SHADER_VISIBILITY_GEOMETRY;
551 case SHADER_TYPE_HULL: return D3D12_SHADER_VISIBILITY_HULL;
552 case SHADER_TYPE_DOMAIN: return D3D12_SHADER_VISIBILITY_DOMAIN;
553 case SHADER_TYPE_COMPUTE: return D3D12_SHADER_VISIBILITY_ALL;
554 # ifdef D3D12_H_HAS_MESH_SHADER
555 case SHADER_TYPE_AMPLIFICATION: return D3D12_SHADER_VISIBILITY_AMPLIFICATION;
556 case SHADER_TYPE_MESH: return D3D12_SHADER_VISIBILITY_MESH;
557 # endif
558 case SHADER_TYPE_RAY_GEN:
559 case SHADER_TYPE_RAY_MISS:
560 case SHADER_TYPE_RAY_CLOSEST_HIT:
561 case SHADER_TYPE_RAY_ANY_HIT:
562 case SHADER_TYPE_RAY_INTERSECTION:
563 case SHADER_TYPE_CALLABLE: return D3D12_SHADER_VISIBILITY_ALL;
564 // clang-format on
565 default:
566 LOG_ERROR("Unknown shader type (", ShaderType, ")");
567 return D3D12_SHADER_VISIBILITY_ALL;
568 }
569 }
570
571 SHADER_TYPE D3D12ShaderVisibilityToShaderType(D3D12_SHADER_VISIBILITY ShaderVisibility)
572 {
573 static_assert(SHADER_TYPE_LAST == SHADER_TYPE_CALLABLE, "Please update the switch below to handle the new shader type");
574 switch (ShaderVisibility)
575 {
576 // clang-format off
577 case D3D12_SHADER_VISIBILITY_ALL: return SHADER_TYPE_UNKNOWN;
578 case D3D12_SHADER_VISIBILITY_VERTEX: return SHADER_TYPE_VERTEX;
579 case D3D12_SHADER_VISIBILITY_PIXEL: return SHADER_TYPE_PIXEL;
580 case D3D12_SHADER_VISIBILITY_GEOMETRY: return SHADER_TYPE_GEOMETRY;
581 case D3D12_SHADER_VISIBILITY_HULL: return SHADER_TYPE_HULL;
582 case D3D12_SHADER_VISIBILITY_DOMAIN: return SHADER_TYPE_DOMAIN;
583 # ifdef D3D12_H_HAS_MESH_SHADER
584 case D3D12_SHADER_VISIBILITY_AMPLIFICATION: return SHADER_TYPE_AMPLIFICATION;
585 case D3D12_SHADER_VISIBILITY_MESH: return SHADER_TYPE_MESH;
586 # endif
587 // clang-format on
588 default:
589 LOG_ERROR("Unknown shader visibility (", ShaderVisibility, ")");
590 return SHADER_TYPE_UNKNOWN;
591 }
592 }
593
594
542595 } // namespace Diligent
107107 {
108108 #define LOG_PSO_ERROR_AND_THROW(...) LOG_ERROR_AND_THROW("Description of ray tracing PSO '", CreateInfo.PSODesc.Name, "' is invalid: ", ##__VA_ARGS__)
109109
110 Uint32 ShaderIndex = 0;
111 Uint32 GroupIndex = 0;
110 Uint32 ShaderIndex = 0;
111 Uint32 GroupIndex = 0;
112
112113 std::unordered_map<IShader*, LPCWSTR> UniqueShaders;
113114
114115 const auto ShaderIndexToStr = [&TempPool](Uint32 Index) -> LPCWSTR {
130131 auto Result = UniqueShaders.emplace(pShader, nullptr);
131132 if (Result.second)
132133 {
133 auto& LibDesc = *TempPool.Allocate<D3D12_DXIL_LIBRARY_DESC>();
134 auto& ExportDesc = *TempPool.Allocate<D3D12_EXPORT_DESC>();
134 auto& LibDesc = *TempPool.Construct<D3D12_DXIL_LIBRARY_DESC>();
135 auto& ExportDesc = *TempPool.Construct<D3D12_EXPORT_DESC>();
135136 auto* pShaderD3D12 = ValidatedCast<ShaderD3D12Impl>(pShader);
136137
137138 LibDesc.DXILLibrary.BytecodeLength = pShaderD3D12->GetShaderByteCode()->GetBufferSize();
160161
161162 for (Uint32 i = 0; i < CreateInfo.GeneralShaderCount; ++i)
162163 {
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;
164 const auto& GeneralShader = CreateInfo.pGeneralShaders[i];
165 AddDxilLib(GeneralShader.pShader, GeneralShader.Name);
166
167 bool IsUniqueName = NameToGroupIndex.emplace(HashMapStringKey{MemPool.CopyString(GeneralShader.Name)}, GroupIndex++).second;
166168 if (!IsUniqueName)
167169 LOG_PSO_ERROR_AND_THROW("pGeneralShaders[", i, "].Name must be unique");
168170 }
169171
170172 for (Uint32 i = 0; i < CreateInfo.TriangleHitShaderCount; ++i)
171173 {
172 auto& HitGroupDesc = *TempPool.Allocate<D3D12_HIT_GROUP_DESC>();
173 HitGroupDesc.HitGroupExport = TempPool.CopyWString(CreateInfo.pTriangleHitShaders[i].Name);
174 const auto& TriHitShader = CreateInfo.pTriangleHitShaders[i];
175
176 auto& HitGroupDesc = *TempPool.Construct<D3D12_HIT_GROUP_DESC>();
177 HitGroupDesc.HitGroupExport = TempPool.CopyWString(TriHitShader.Name);
174178 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);
179 HitGroupDesc.ClosestHitShaderImport = AddDxilLib(TriHitShader.pClosestHitShader, nullptr);
180 HitGroupDesc.AnyHitShaderImport = AddDxilLib(TriHitShader.pAnyHitShader, nullptr);
177181 HitGroupDesc.IntersectionShaderImport = nullptr;
178182
179183 Subobjects.push_back({D3D12_STATE_SUBOBJECT_TYPE_HIT_GROUP, &HitGroupDesc});
180184
181 bool IsUniqueName = NameToGroupIndex.emplace(HashMapStringKey{MemPool.CopyString(CreateInfo.pTriangleHitShaders[i].Name)}, GroupIndex++).second;
185 bool IsUniqueName = NameToGroupIndex.emplace(HashMapStringKey{MemPool.CopyString(TriHitShader.Name)}, GroupIndex++).second;
182186 if (!IsUniqueName)
183187 LOG_PSO_ERROR_AND_THROW("pTriangleHitShaders[", i, "].Name must be unique");
184188 }
185189
186190 for (Uint32 i = 0; i < CreateInfo.ProceduralHitShaderCount; ++i)
187191 {
188 auto& HitGroupDesc = *TempPool.Allocate<D3D12_HIT_GROUP_DESC>();
189 HitGroupDesc.HitGroupExport = TempPool.CopyWString(CreateInfo.pProceduralHitShaders[i].Name);
192 const auto& ProcHitShader = CreateInfo.pProceduralHitShaders[i];
193
194 auto& HitGroupDesc = *TempPool.Construct<D3D12_HIT_GROUP_DESC>();
195 HitGroupDesc.HitGroupExport = TempPool.CopyWString(ProcHitShader.Name);
190196 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);
197 HitGroupDesc.ClosestHitShaderImport = AddDxilLib(ProcHitShader.pClosestHitShader, nullptr);
198 HitGroupDesc.AnyHitShaderImport = AddDxilLib(ProcHitShader.pAnyHitShader, nullptr);
199 HitGroupDesc.IntersectionShaderImport = AddDxilLib(ProcHitShader.pIntersectionShader, nullptr);
194200
195201 Subobjects.push_back({D3D12_STATE_SUBOBJECT_TYPE_HIT_GROUP, &HitGroupDesc});
196202
197 bool IsUniqueName = NameToGroupIndex.emplace(HashMapStringKey{MemPool.CopyString(CreateInfo.pProceduralHitShaders[i].Name)}, GroupIndex++).second;
203 bool IsUniqueName = NameToGroupIndex.emplace(HashMapStringKey{MemPool.CopyString(ProcHitShader.Name)}, GroupIndex++).second;
198204 if (!IsUniqueName)
199205 LOG_PSO_ERROR_AND_THROW("pProceduralHitShaders[", i, "].Name must be unique");
200206 }
201207
202 VERIFY_EXPR(Uint32(CreateInfo.GeneralShaderCount + CreateInfo.TriangleHitShaderCount + CreateInfo.ProceduralHitShaderCount) == GroupIndex);
208 VERIFY_EXPR(Uint32{CreateInfo.GeneralShaderCount} + Uint32{CreateInfo.TriangleHitShaderCount} + Uint32{CreateInfo.ProceduralHitShaderCount} == GroupIndex);
203209
204210 if (CreateInfo.RayTracingPipeline.MaxRecursionDepth > D3D12_RAYTRACING_MAX_DECLARABLE_TRACE_RECURSION_DEPTH)
205211 LOG_PSO_ERROR_AND_THROW("MaxRecursionDepth must be less than equal to ", D3D12_RAYTRACING_MAX_DECLARABLE_TRACE_RECURSION_DEPTH);
206212
207 auto& PipelineConfig = *TempPool.Allocate<D3D12_RAYTRACING_PIPELINE_CONFIG>();
213 auto& PipelineConfig = *TempPool.Construct<D3D12_RAYTRACING_PIPELINE_CONFIG>();
208214 // for compatibility with Vulkan set minimal recursion depth to 1
209215 PipelineConfig.MaxTraceRecursionDepth = std::max<Uint32>(1, CreateInfo.RayTracingPipeline.MaxRecursionDepth);
210216 Subobjects.push_back({D3D12_STATE_SUBOBJECT_TYPE_RAYTRACING_PIPELINE_CONFIG, &PipelineConfig});
211217
212 auto& ShaderConfig = *TempPool.Allocate<D3D12_RAYTRACING_SHADER_CONFIG>();
218 auto& ShaderConfig = *TempPool.Construct<D3D12_RAYTRACING_SHADER_CONFIG>();
213219 ShaderConfig.MaxAttributeSizeInBytes = D3D12_RAYTRACING_MAX_ATTRIBUTE_SIZE_IN_BYTES;
214220 ShaderConfig.MaxPayloadSizeInBytes = 32; // AZ TODO
215221 Subobjects.push_back({D3D12_STATE_SUBOBJECT_TYPE_RAYTRACING_SHADER_CONFIG, &ShaderConfig});
224230 {
225231 const Uint32 ShaderIdentifierSize = D3D12_SHADER_IDENTIFIER_SIZE_IN_BYTES;
226232
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
236233 CComPtr<ID3D12StateObjectProperties> pStateObjectProperties;
237 auto hr = pSO->QueryInterface(IID_PPV_ARGS(&pStateObjectProperties));
234
235 auto hr = pSO->QueryInterface(IID_PPV_ARGS(&pStateObjectProperties));
238236 if (FAILED(hr))
239237 LOG_ERROR_AND_THROW("Failed to get state object properties");
240238
241239 for (Uint32 i = 0; i < CreateInfo.GeneralShaderCount; ++i)
242240 {
243 auto iter = NameToGroupIndex.find(CreateInfo.pGeneralShaders[i].Name);
241 const auto& GeneralShader = CreateInfo.pGeneralShaders[i];
242
243 auto iter = NameToGroupIndex.find(GeneralShader.Name);
244244 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);
245 LOG_ERROR_AND_THROW("Failed to get shader group index for general shader group '", GeneralShader.Name, "'");
246
247 const auto* ShaderID = pStateObjectProperties->GetShaderIdentifier(WidenString(GeneralShader.Name).c_str());
249248 if (ShaderID == nullptr)
250 LOG_ERROR_AND_THROW("Failed to get shader identifier");
249 LOG_ERROR_AND_THROW("Failed to get shader identifier for general shader group '", GeneralShader.Name, "'");
251250
252251 std::memcpy(&ShaderData[ShaderIdentifierSize * iter->second], ShaderID, ShaderIdentifierSize);
253252 }
254253 for (Uint32 i = 0; i < CreateInfo.TriangleHitShaderCount; ++i)
255254 {
256 auto iter = NameToGroupIndex.find(CreateInfo.pTriangleHitShaders[i].Name);
255 const auto& TriHitShader = CreateInfo.pTriangleHitShaders[i];
256
257 auto iter = NameToGroupIndex.find(TriHitShader.Name);
257258 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);
259 LOG_ERROR_AND_THROW("Failed to get shader group index for triangle hit group '", TriHitShader.Name, "'");
260
261 const auto* ShaderID = pStateObjectProperties->GetShaderIdentifier(WidenString(TriHitShader.Name).c_str());
262262 if (ShaderID == nullptr)
263 LOG_ERROR_AND_THROW("Failed to get shader identifier");
263 LOG_ERROR_AND_THROW("Failed to get shader identifier for triangle hit group '", TriHitShader.Name, "'");
264264
265265 std::memcpy(&ShaderData[ShaderIdentifierSize * iter->second], ShaderID, ShaderIdentifierSize);
266266 }
267267 for (Uint32 i = 0; i < CreateInfo.ProceduralHitShaderCount; ++i)
268268 {
269 auto iter = NameToGroupIndex.find(CreateInfo.pProceduralHitShaders[i].Name);
269 const auto& ProcHitShader = CreateInfo.pProceduralHitShaders[i];
270
271 auto iter = NameToGroupIndex.find(ProcHitShader.Name);
270272 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);
273 LOG_ERROR_AND_THROW("Failed to get shader group index for procedural hit shader group '", ProcHitShader.Name, "'");
274
275 const auto* ShaderID = pStateObjectProperties->GetShaderIdentifier(WidenString(ProcHitShader.Name).c_str());
275276 if (ShaderID == nullptr)
276 LOG_ERROR_AND_THROW("Failed to get shader identifier");
277 LOG_ERROR_AND_THROW("Failed to get shader identifier for procedural hit shader group '", ProcHitShader.Name, "'");
277278
278279 std::memcpy(&ShaderData[ShaderIdentifierSize * iter->second], ShaderID, ShaderIdentifierSize);
279280 }
283284
284285
285286 PipelineStateD3D12Impl::ShaderStageInfo::ShaderStageInfo(SHADER_TYPE _Type, ShaderD3D12Impl* _pShader) :
286 Type{_Type}
287 {
288 Shaders.push_back(_pShader);
287 Type{_Type},
288 Shaders{{_pShader}}
289 {
289290 }
290291
291292 void PipelineStateD3D12Impl::ShaderStageInfo::Append(ShaderD3D12Impl* pShader)
299300 }
300301
301302
302 template <typename PSOCreateInfoType>
303 template <typename PSOCreateInfoType, typename InitPSODescType>
303304 void PipelineStateD3D12Impl::InitInternalObjects(const PSOCreateInfoType& CreateInfo,
304 TShaderStages& ShaderStages)
305 TShaderStages& ShaderStages,
306 InitPSODescType InitPSODesc)
305307 {
306308 m_ResourceLayoutIndex.fill(-1);
307309
333335 for (Uint32 s = 0; s < NumShaderStages; ++s)
334336 new (m_pStaticVarManagers + s) ShaderVariableManagerD3D12{*this, GetStaticShaderResCache(s)};
335337
336 InitializePipelineDesc(CreateInfo, MemPool);
338 InitPSODesc(CreateInfo, MemPool);
337339
338340 m_RootSig.AllocateImmutableSamplers(CreateInfo.PSODesc.ResourceLayout);
339341
353355 try
354356 {
355357 TShaderStages ShaderStages;
356 InitInternalObjects(CreateInfo, ShaderStages);
358 InitInternalObjects(CreateInfo, ShaderStages,
359 [this](const GraphicsPipelineStateCreateInfo& CreateInfo, LinearAllocator& MemPool) //
360 {
361 InitializePipelineDesc(CreateInfo, MemPool);
362 } //
363 );
357364
358365 auto pd3d12Device = pDeviceD3D12->GetD3D12Device();
359366 if (m_Desc.PipelineType == PIPELINE_TYPE_GRAPHICS)
438445 // The only valid bit is D3D12_PIPELINE_STATE_FLAG_TOOL_DEBUG, which can only be set on WARP devices.
439446 d3d12PSODesc.Flags = D3D12_PIPELINE_STATE_FLAG_NONE;
440447
441 CComPtr<ID3D12PipelineState> pPSO;
442 HRESULT hr = pd3d12Device->CreateGraphicsPipelineState(&d3d12PSODesc, IID_PPV_ARGS(&pPSO));
448 HRESULT hr = pd3d12Device->CreateGraphicsPipelineState(&d3d12PSODesc, IID_PPV_ARGS(&m_pd3d12PSO));
443449 if (FAILED(hr))
444450 LOG_ERROR_AND_THROW("Failed to create pipeline state");
445
446 m_pd3d12PSO = pPSO;
447451 }
448452
449453 #ifdef D3D12_H_HAS_MESH_SHADER
526530 streamDesc.SizeInBytes = sizeof(d3d12PSODesc);
527531 streamDesc.pPipelineStateSubobjectStream = &d3d12PSODesc;
528532
529 auto* device2 = pDeviceD3D12->GetD3D12Device2();
530 CComPtr<ID3D12PipelineState> pPSO;
531 HRESULT hr = device2->CreatePipelineState(&streamDesc, IID_PPV_ARGS(&pPSO));
533 auto* device2 = pDeviceD3D12->GetD3D12Device2();
534 HRESULT hr = device2->CreatePipelineState(&streamDesc, IID_PPV_ARGS(&m_pd3d12PSO));
532535 if (FAILED(hr))
533536 LOG_ERROR_AND_THROW("Failed to create pipeline state");
534
535 m_pd3d12PSO = pPSO;
536537 }
537538 #endif // D3D12_H_HAS_MESH_SHADER
538539 else
565566 try
566567 {
567568 TShaderStages ShaderStages;
568 InitInternalObjects(CreateInfo, ShaderStages);
569 InitInternalObjects(CreateInfo, ShaderStages,
570 [this](const ComputePipelineStateCreateInfo& CreateInfo, LinearAllocator& MemPool) //
571 {
572 InitializePipelineDesc(CreateInfo, MemPool);
573 } //
574 );
569575
570576 auto pd3d12Device = pDeviceD3D12->GetD3D12Device();
571577
590596
591597 d3d12PSODesc.pRootSignature = m_RootSig.GetD3D12RootSignature();
592598
593 CComPtr<ID3D12PipelineState> pPSO;
594 HRESULT hr = pd3d12Device->CreateComputePipelineState(&d3d12PSODesc, IID_PPV_ARGS(&pPSO));
599 HRESULT hr = pd3d12Device->CreateComputePipelineState(&d3d12PSODesc, IID_PPV_ARGS(&m_pd3d12PSO));
595600 if (FAILED(hr))
596601 LOG_ERROR_AND_THROW("Failed to create pipeline state");
597
598 m_pd3d12PSO = pPSO;
599602
600603 if (*m_Desc.Name != 0)
601604 {
621624 {
622625 try
623626 {
624 m_ResourceLayoutIndex.fill(-1);
625
626 TShaderStages ShaderStages;
627 ExtractShaders<ShaderD3D12Impl>(CreateInfo, ShaderStages);
628
629 TNameToGroupIndexMap NameToGroupIndex;
627 TShaderStages ShaderStages;
630628 std::vector<D3D12_STATE_SUBOBJECT> Subobjects;
631 const Uint32 ShaderIdentifierSize = D3D12_SHADER_IDENTIFIER_SIZE_IN_BYTES;
632629 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();
630 InitInternalObjects(CreateInfo, ShaderStages,
631 [&](const RayTracingPipelineStateCreateInfo& CreateInfo, LinearAllocator& MemPool) //
632 {
633 TNameToGroupIndexMap NameToGroupIndex;
634 BuildRTPipelineDescription(CreateInfo, NameToGroupIndex, Subobjects, TempPool, MemPool);
635 InitializePipelineDesc(CreateInfo, std::move(NameToGroupIndex), MemPool);
636 } //
637 );
638
639 D3D12_GLOBAL_ROOT_SIGNATURE GlobalRoot = {m_RootSig.GetD3D12RootSignature()};
671640 Subobjects.push_back({D3D12_STATE_SUBOBJECT_TYPE_GLOBAL_ROOT_SIGNATURE, &GlobalRoot});
672641
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();
642 D3D12_STATE_OBJECT_DESC RTPipelineDesc = {};
643 RTPipelineDesc.Type = D3D12_STATE_OBJECT_TYPE_RAYTRACING_PIPELINE;
644 RTPipelineDesc.NumSubobjects = static_cast<UINT>(Subobjects.size());
645 RTPipelineDesc.pSubobjects = Subobjects.data();
646
679647 CComPtr<ID3D12StateObject> pSO;
680 HRESULT hr = pd3d12Device->CreateStateObject(&RTPipelineDesc, IID_PPV_ARGS(&pSO));
648
649 auto pd3d12Device = pDeviceD3D12->GetD3D12Device5();
650 HRESULT hr = pd3d12Device->CreateStateObject(&RTPipelineDesc, IID_PPV_ARGS(&pSO));
681651 if (FAILED(hr))
682652 LOG_ERROR_AND_THROW("Failed to create ray tracing state object");
683653
135135 sizeof(FenceD3D12Impl),
136136 sizeof(QueryD3D12Impl),
137137 sizeof(RenderPassD3D12Impl),
138 sizeof(FramebufferD3D12Impl)
138 sizeof(FramebufferD3D12Impl),
139 0,
140 0,
141 0
139142 }
140143 },
141144 m_pd3d12Device {pd3d12Device},
311314 CHECK_REQUIRED_FEATURE(ShaderInt8, "8-bit shader operations are");
312315 CHECK_REQUIRED_FEATURE(ResourceBuffer8BitAccess, "8-bit resoure buffer access is");
313316 CHECK_REQUIRED_FEATURE(UniformBuffer8BitAccess, "8-bit uniform buffer access is");
314
315 CHECK_REQUIRED_FEATURE(RayTracing, "ray tracing is");
317
318 CHECK_REQUIRED_FEATURE(RayTracing, "ray tracing is");
316319 // clang-format on
317320 #undef CHECK_REQUIRED_FEATURE
318321
172172 }
173173
174174 // clang-format off
175 static constexpr D3D12_SHADER_VISIBILITY ShaderTypeInd2ShaderVisibilityMap[]
176 {
177 D3D12_SHADER_VISIBILITY_VERTEX, // 0
178 D3D12_SHADER_VISIBILITY_PIXEL, // 1
179 D3D12_SHADER_VISIBILITY_GEOMETRY, // 2
180 D3D12_SHADER_VISIBILITY_HULL, // 3
181 D3D12_SHADER_VISIBILITY_DOMAIN, // 4
182 D3D12_SHADER_VISIBILITY_ALL, // 5
183 #ifdef D3D12_H_HAS_MESH_SHADER
184 D3D12_SHADER_VISIBILITY_AMPLIFICATION, // 6
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
196 };
197 // clang-format on
198 D3D12_SHADER_VISIBILITY GetShaderVisibility(SHADER_TYPE ShaderType)
199 {
200 auto ShaderInd = GetShaderTypeIndex(ShaderType);
201 auto ShaderVisibility = ShaderTypeInd2ShaderVisibilityMap[ShaderInd];
202 #ifdef DILIGENT_DEBUG
203 static_assert(SHADER_TYPE_LAST == SHADER_TYPE_CALLABLE, "Please update the switch below to handle the new shader type");
204 switch (ShaderType)
205 {
206 // clang-format off
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;
213 # ifdef D3D12_H_HAS_MESH_SHADER
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;
216 # 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;
223 // clang-format on
224 default: LOG_ERROR("Unknown shader type (", ShaderType, ")"); break;
225 }
226 #endif
227 return ShaderVisibility;
228 }
229
230 // clang-format off
231175 static D3D12_DESCRIPTOR_HEAP_TYPE RangeType2HeapTypeMap[]
232176 {
233177 D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, //D3D12_DESCRIPTOR_RANGE_TYPE_SRV = 0
262206 const char* SamplerSuffix,
263207 const D3DShaderResourceAttribs& SamplerAttribs)
264208 {
265 #ifdef DILIGENT_DEBUG
266 m_DbgShaderStages |= ShaderType;
267 #endif
268
269 auto ShaderVisibility = GetShaderVisibility(ShaderType);
209 auto ShaderVisibility = ShaderTypeToD3D12ShaderVisibility(ShaderType);
270210 auto SamplerFound = false;
271211 for (auto& ImtblSmplr : m_ImmutableSamplers)
272212 {
298238 Uint32& OffsetFromTableStart // Output parameter
299239 )
300240 {
301 #ifdef DILIGENT_DEBUG
302 m_DbgShaderStages |= ShaderType;
303 #endif
304
305 const auto ShaderVisibility = GetShaderVisibility(ShaderType);
241 const auto ShaderVisibility = ShaderTypeToD3D12ShaderVisibility(ShaderType);
306242 if (RangeType == D3D12_DESCRIPTOR_RANGE_TYPE_CBV && ShaderResAttribs.BindCount == 1)
307243 {
308244 // Allocate single CBV directly in the root signature
442378 while (ShaderStages != 0)
443379 {
444380 auto Stage = ShaderStages & ~(ShaderStages - 1);
445 m_ImmutableSamplers.emplace_back(ImtblSamDesc, GetShaderVisibility(static_cast<SHADER_TYPE>(Stage)));
381 m_ImmutableSamplers.emplace_back(ImtblSamDesc, ShaderTypeToD3D12ShaderVisibility(static_cast<SHADER_TYPE>(Stage)));
446382 ShaderStages &= ~Stage;
447383 }
448384 }
651587 auto HeapType = HeapTypeFromRangeType(D3D12RootParam.DescriptorTable.pDescriptorRanges[0].RangeType);
652588
653589 #ifdef DILIGENT_DEBUG
654 RootTableCache.SetDebugAttribs(TableSize, HeapType, m_DbgShaderStages);
590 RootTableCache.SetDebugAttribs(TableSize, HeapType, D3D12ShaderVisibilityToShaderType(D3D12RootParam.ShaderVisibility));
655591 #endif
656592
657593 // Space for dynamic variables is allocated at every draw call
684620 VERIFY_EXPR(RootTableCache.m_TableStartOffset == ShaderResourceCacheD3D12::InvalidDescriptorOffset);
685621
686622 VERIFY_EXPR(D3D12RootParam.ParameterType == D3D12_ROOT_PARAMETER_TYPE_CBV);
687 RootTableCache.SetDebugAttribs(1, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, m_DbgShaderStages);
623 RootTableCache.SetDebugAttribs(1, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, D3D12ShaderVisibilityToShaderType(D3D12RootParam.ShaderVisibility));
688624 }
689625 #endif
690626
914850 const auto& range = D3D12Param.DescriptorTable.pDescriptorRanges[r];
915851 for (UINT d = 0; d < range.NumDescriptors; ++d)
916852 {
853 SHADER_TYPE dbgShaderType = SHADER_TYPE_UNKNOWN;
917854 #ifdef DILIGENT_DEBUG
855 dbgShaderType = D3D12ShaderVisibilityToShaderType(D3D12Param.ShaderVisibility);
856 #endif
918857 VERIFY(dbgHeapType == HeapTypeFromRangeType(range.RangeType), "Mistmatch between descriptor heap type and descriptor range type");
919 #endif
858
920859 auto OffsetFromTableStart = range.OffsetInDescriptorsFromTableStart + d;
921 auto& Res = ResourceCache.GetRootTable(RootInd).GetResource(OffsetFromTableStart, dbgHeapType, SHADER_TYPE_UNKNOWN);
860 auto& Res = ResourceCache.GetRootTable(RootInd).GetResource(OffsetFromTableStart, dbgHeapType, dbgShaderType);
922861
923862 Operation(OffsetFromTableStart, range, Res);
924863 }
3838 #include "PipelineStateD3D12Impl.hpp"
3939 #include "ShaderResourceVariableBase.hpp"
4040 #include "ShaderVariableD3DBase.hpp"
41 #include "LinearAllocator.hpp"
4142
4243 namespace Diligent
4344 {
8283 }
8384
8485
85 void ShaderResourceLayoutD3D12::AllocateMemory(IMemoryAllocator& Allocator,
86 const std::array<Uint32, SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES>& CbvSrvUavCount,
87 const std::array<Uint32, SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES>& SamplerCount)
86 StringPool ShaderResourceLayoutD3D12::AllocateMemory(IMemoryAllocator& Allocator,
87 const std::array<Uint32, SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES>& CbvSrvUavCount,
88 const std::array<Uint32, SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES>& SamplerCount,
89 size_t StringPoolSize)
8890 {
8991 m_CbvSrvUavOffsets[0] = 0;
9092 for (SHADER_RESOURCE_VARIABLE_TYPE VarType = SHADER_RESOURCE_VARIABLE_TYPE_STATIC; VarType < SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES; VarType = static_cast<SHADER_RESOURCE_VARIABLE_TYPE>(VarType + 1))
102104 VERIFY_EXPR(GetSamplerCount(VarType) == SamplerCount[VarType]);
103105 }
104106
105 size_t MemSize = GetTotalResourceCount() * sizeof(D3D12Resource);
106 if (MemSize == 0)
107 return;
108
109 auto* pRawMem = ALLOCATE_RAW(Allocator, "Raw memory buffer for shader resource layout resources", MemSize);
110 m_ResourceBuffer = std::unique_ptr<void, STDDeleterRawMem<void>>(pRawMem, Allocator);
107 LinearAllocator MemPool{Allocator};
108 MemPool.AddSpace<D3D12Resource>(GetTotalResourceCount());
109 MemPool.AddSpace<char>(StringPoolSize);
110
111 MemPool.Reserve();
112
113 auto* pResources = MemPool.Allocate<D3D12Resource>(GetTotalResourceCount());
114 auto* pStringPoolData = MemPool.ConstructArray<char>(StringPoolSize);
115
116 m_ResourceBuffer = std::unique_ptr<void, STDDeleterRawMem<void>>(MemPool.Release(), Allocator);
117 VERIFY_EXPR(m_ResourceBuffer.get() == pResources);
118
119 StringPool stringPool;
120 stringPool.AssignMemory(pStringPoolData, StringPoolSize);
121 return stringPool;
111122 }
112123
113124
135146
136147 std::unordered_map<HashMapStringKey, Uint32, HashMapStringKey::Hasher> ResourceNameToIndex;
137148
138 // Count number of resources to allocate all needed memory
149 // Count the number of resources to allocate all needed memory
139150 m_IsUsingSeparateSamplers = !Shaders[0]->GetShaderResources()->IsUsingCombinedTextureSamplers();
140151 m_ShaderType = Shaders[0]->GetDesc().ShaderType;
141152 size_t StringPoolSize = 0;
142153
154 static constexpr Uint32 InvalidResourceIndex = ~0u;
155
143156 for (auto* pShader : Shaders)
144157 {
145158 auto pResources = pShader->GetShaderResources();
146159 VERIFY_EXPR(pResources->GetShaderType() == m_ShaderType);
147 const auto HandleResType = [&](const auto& Res, Uint32) //
160 const auto HandleCbvSrvUav = [&](const auto& Res, Uint32) //
148161 {
149162 auto VarType = pResources->FindVariableType(Res, ResourceLayout);
150163 if (IsAllowedType(VarType, AllowedTypeBits))
151164 {
152 bool IsUniqueName = ResourceNameToIndex.emplace(HashMapStringKey{Res.Name}, ~0u).second;
165 bool IsUniqueName = ResourceNameToIndex.emplace(HashMapStringKey{Res.Name}, InvalidResourceIndex).second;
153166 if (IsUniqueName)
154167 {
155168 StringPoolSize += strlen(Res.Name) + 1;
157170 }
158171 }
159172 };
173
160174 pResources->ProcessResources(
161 HandleResType,
175 HandleCbvSrvUav,
162176 [&](const D3DShaderResourceAttribs& Sam, Uint32) //
163177 {
164178 auto VarType = pResources->FindVariableType(Sam, ResourceLayout);
170184 // Skip immutable samplers
171185 if (ImtblSamplerInd < 0)
172186 {
173 bool IsUniqueName = ResourceNameToIndex.emplace(HashMapStringKey{Sam.Name}, ~0u).second;
187 bool IsUniqueName = ResourceNameToIndex.emplace(HashMapStringKey{Sam.Name}, InvalidResourceIndex).second;
174188 if (IsUniqueName)
175189 {
176190 StringPoolSize += strlen(Sam.Name) + 1;
184198 auto VarType = pResources->FindVariableType(TexSRV, ResourceLayout);
185199 if (IsAllowedType(VarType, AllowedTypeBits))
186200 {
187 bool IsUniqueName = ResourceNameToIndex.emplace(HashMapStringKey{TexSRV.Name}, ~0u).second;
201 bool IsUniqueName = ResourceNameToIndex.emplace(HashMapStringKey{TexSRV.Name}, InvalidResourceIndex).second;
188202 if (IsUniqueName)
189203 {
190204 StringPoolSize += strlen(TexSRV.Name) + 1;
202216 }
203217 }
204218 },
205 HandleResType,
206 HandleResType,
207 HandleResType,
208 HandleResType);
209 }
210
211 AllocateMemory(LayoutDataAllocator, CbvSrvUavCount, SamplerCount);
212
213 m_StringPool.Reserve(StringPoolSize, GetRawAllocator());
219 HandleCbvSrvUav,
220 HandleCbvSrvUav,
221 HandleCbvSrvUav,
222 HandleCbvSrvUav);
223 }
224
225 auto stringPool = AllocateMemory(LayoutDataAllocator, CbvSrvUavCount, SamplerCount, StringPoolSize);
214226
215227 std::array<Uint32, SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES> CurrCbvSrvUav = {};
216228 std::array<Uint32, SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES> CurrSampler = {};
219231 auto AddResource = [&](const D3DShaderResourceAttribs& Attribs,
220232 CachedResourceType ResType,
221233 SHADER_RESOURCE_VARIABLE_TYPE VarType,
222 Uint32 SamplerId = D3D12Resource::InvalidSamplerId) //
234 Uint32 SamplerId = D3DShaderResourceAttribs::InvalidSamplerId) //
223235 {
224236 auto ResIter = ResourceNameToIndex.find(HashMapStringKey{Attribs.Name});
225237 VERIFY_EXPR(ResIter != ResourceNameToIndex.end());
226238
227 if (ResIter->second == ~0u)
239 if (ResIter->second == InvalidResourceIndex)
228240 {
229241 Uint32 RootIndex = D3D12Resource::InvalidRootIndex;
230242 Uint32 Offset = D3D12Resource::InvalidOffset;
257269 VERIFY(RootIndex != D3D12Resource::InvalidRootIndex, "Root index must be valid");
258270 VERIFY(Offset != D3D12Resource::InvalidOffset, "Offset must be valid");
259271
260 // Static samplers are never copied, and SamplerId == InvalidSamplerId
272 // Immutable samplers are never copied, and SamplerId == InvalidSamplerId
261273 Uint32 ResOffset = (ResType == CachedResourceType::Sampler) ?
262274 GetSamplerOffset(VarType, CurrSampler[VarType]++) :
263275 GetSrvCbvUavOffset(VarType, CurrCbvSrvUav[VarType]++);
264276 ResIter->second = ResOffset;
265277 auto& NewResource = GetResource(ResOffset);
266 ::new (&NewResource) D3D12Resource{*this, VarType, ResType, RootIndex, Offset, SamplerId, m_StringPool.CopyString(Attribs.Name), Attribs.BindCount, Attribs.BindPoint,
267 Attribs.GetInputType(), Attribs.GetSRVDimension()};
278 ::new (&NewResource) D3D12Resource //
279 {
280 *this,
281 stringPool,
282 Attribs,
283 SamplerId,
284 VarType,
285 ResType,
286 RootIndex,
287 Offset //
288 };
268289 }
269290 else
270291 {
271292 // merge with existing
272293 auto& ExistingRes = GetResource(ResIter->second);
273294 VERIFY_EXPR(ExistingRes.VariableType == VarType);
274 VERIFY_EXPR(ExistingRes.GetInputType() == Attribs.GetInputType());
275 VERIFY_EXPR(ExistingRes.BindCount == Attribs.BindCount);
295 VERIFY_EXPR(ExistingRes.Attribs.GetInputType() == Attribs.GetInputType());
296 VERIFY_EXPR(ExistingRes.Attribs.BindCount == Attribs.BindCount);
276297 }
277298 };
278299
292313 if (IsAllowedType(VarType, AllowedTypeBits))
293314 {
294315 // The error (if any) have already been logged when counting the resources
295 constexpr bool LogStaticSamplerArrayError = false;
296 auto StaticSamplerInd = pResources->FindImmutableSampler(Sam, ResourceLayout, LogStaticSamplerArrayError);
297 if (StaticSamplerInd >= 0)
316 constexpr bool LogImtblSamplerArrayError = false;
317 const auto ImtblSamplerInd = pResources->FindImmutableSampler(Sam, ResourceLayout, LogImtblSamplerArrayError);
318 if (ImtblSamplerInd >= 0)
298319 {
299320 if (pRootSig != nullptr)
300321 pRootSig->InitImmutableSampler(pResources->GetShaderType(), Sam.Name, pResources->GetCombinedSamplerSuffix(), Sam);
313334 static_assert(SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES == 3, "Unexpected number of shader variable types");
314335 VERIFY(CurrSampler[SHADER_RESOURCE_VARIABLE_TYPE_STATIC] + CurrSampler[SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE] + CurrSampler[SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC] == GetTotalSamplerCount(), "All samplers must be initialized before texture SRVs");
315336
316 Uint32 SamplerId = D3D12Resource::InvalidSamplerId;
337 Uint32 SamplerId = D3DShaderResourceAttribs::InvalidSamplerId;
317338 if (TexSRV.IsCombinedWithSampler())
318339 {
319340 const auto& SamplerAttribs = pResources->GetCombinedSampler(TexSRV);
324345 ") of the sampler '", SamplerAttribs.Name, "' that is assigned to it");
325346
326347 // The error (if any) have already been logged when counting the resources
327 constexpr bool LogStaticSamplerArrayError = false;
328 auto StaticSamplerInd = pResources->FindImmutableSampler(SamplerAttribs, ResourceLayout, LogStaticSamplerArrayError);
329 if (StaticSamplerInd >= 0)
348 constexpr bool LogImtblSamplerArrayError = false;
349 const auto ImtblSamplerInd = pResources->FindImmutableSampler(SamplerAttribs, ResourceLayout, LogImtblSamplerArrayError);
350 if (ImtblSamplerInd >= 0)
330351 {
331 // Static samplers are never copied, and SamplerId == InvalidSamplerId
352 // Immutable samplers are never copied, and SamplerId == InvalidSamplerId
332353 #ifdef DILIGENT_DEBUG
333354 auto SamplerCount = GetTotalSamplerCount();
334355 for (Uint32 s = 0; s < SamplerCount; ++s)
335356 {
336357 const auto& Sampler = GetSampler(s);
337 if (strcmp(Sampler.Name, SamplerAttribs.Name) == 0)
338 LOG_ERROR("Static sampler '", Sampler.Name, "' was found among resources. This seems to be a bug");
358 if (strcmp(Sampler.Attribs.Name, SamplerAttribs.Name) == 0)
359 LOG_ERROR("Immutable sampler '", Sampler.Attribs.Name, "' was found among resources. This seems to be a bug");
339360 }
340361 #endif
341362 }
346367 for (SamplerId = 0; SamplerId < SamplerCount; ++SamplerId)
347368 {
348369 const auto& Sampler = GetSampler(SamplerId);
349 SamplerFound = strcmp(Sampler.Name, SamplerAttribs.Name) == 0;
370 SamplerFound = strcmp(Sampler.Attribs.Name, SamplerAttribs.Name) == 0;
350371 if (SamplerFound)
351372 break;
352373 }
354375 if (!SamplerFound)
355376 {
356377 LOG_ERROR("Unable to find sampler '", SamplerAttribs.Name, "' assigned to texture SRV '", TexSRV.Name, "' in the list of already created resources. This seems to be a bug.");
357 SamplerId = D3D12Resource::InvalidSamplerId;
378 SamplerId = D3DShaderResourceAttribs::InvalidSamplerId;
358379 }
359 VERIFY(SamplerId <= D3D12Resource::MaxSamplerId, "Sampler index excceeds allowed limit");
380 VERIFY(SamplerId <= D3DShaderResourceAttribs::MaxSamplerId, "Sampler index excceeds allowed limit");
360381 }
361382 }
362383 AddResource(TexSRV, CachedResourceType::TexSRV, VarType, SamplerId);
390411 }
391412
392413 #ifdef DILIGENT_DEBUG
414 VERIFY_EXPR(stringPool.GetRemainingSize() == 0);
393415 for (SHADER_RESOURCE_VARIABLE_TYPE VarType = SHADER_RESOURCE_VARIABLE_TYPE_STATIC; VarType < SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES; VarType = static_cast<SHADER_RESOURCE_VARIABLE_TYPE>(VarType + 1))
394416 {
395417 VERIFY(CurrCbvSrvUav[VarType] == CbvSrvUavCount[VarType], "Not all Srv/Cbv/Uavs are initialized, which result in a crash when dtor is called");
426448 // resource mapping can be of wrong type
427449 RefCntAutoPtr<BufferD3D12Impl> pBuffD3D12(pBuffer, IID_BufferD3D12);
428450 #ifdef DILIGENT_DEVELOPMENT
429 VerifyConstantBufferBinding(*this, GetVariableType(), ArrayInd, pBuffer, pBuffD3D12.RawPtr(), DstRes.pObject.RawPtr(), ParentResLayout.GetShaderName());
451 VerifyConstantBufferBinding(Attribs, GetVariableType(), ArrayInd, pBuffer, pBuffD3D12.RawPtr(), DstRes.pObject.RawPtr(), ParentResLayout.GetShaderName());
430452 #endif
431453 if (pBuffD3D12)
432454 {
462484 }
463485 }
464486
465 RESOURCE_DIMENSION ShaderResourceLayoutD3D12::D3D12Resource::GetResourceDimension() const
466 {
467 switch (GetSRVDimension())
468 {
469 // clang-format off
470 case D3D_SRV_DIMENSION_BUFFER: return RESOURCE_DIM_BUFFER;
471 case D3D_SRV_DIMENSION_TEXTURE1D: return RESOURCE_DIM_TEX_1D;
472 case D3D_SRV_DIMENSION_TEXTURE1DARRAY: return RESOURCE_DIM_TEX_1D_ARRAY;
473 case D3D_SRV_DIMENSION_TEXTURE2D: return RESOURCE_DIM_TEX_2D;
474 case D3D_SRV_DIMENSION_TEXTURE2DARRAY: return RESOURCE_DIM_TEX_2D_ARRAY;
475 case D3D_SRV_DIMENSION_TEXTURE2DMS: return RESOURCE_DIM_TEX_2D;
476 case D3D_SRV_DIMENSION_TEXTURE2DMSARRAY: return RESOURCE_DIM_TEX_2D_ARRAY;
477 case D3D_SRV_DIMENSION_TEXTURE3D: return RESOURCE_DIM_TEX_3D;
478 case D3D_SRV_DIMENSION_TEXTURECUBE: return RESOURCE_DIM_TEX_CUBE;
479 case D3D_SRV_DIMENSION_TEXTURECUBEARRAY: return RESOURCE_DIM_TEX_CUBE_ARRAY;
480 // clang-format on
481 default:
482 return RESOURCE_DIM_BUFFER;
483 }
484 }
485
486 bool ShaderResourceLayoutD3D12::D3D12Resource::IsMultisample() const
487 {
488 switch (GetSRVDimension())
489 {
490 case D3D_SRV_DIMENSION_TEXTURE2DMS:
491 case D3D_SRV_DIMENSION_TEXTURE2DMSARRAY:
492 return true;
493 default:
494 return false;
495 }
496 }
497
498
499487 template <typename TResourceViewType>
500488 struct ResourceViewTraits
501489 {};
505493 {
506494 static const INTERFACE_ID& IID;
507495
508 static bool VerifyView(ITextureViewD3D12* pViewD3D12, const ShaderResourceLayoutD3D12::D3D12Resource& Attribs, const char* ShaderName)
496 static bool VerifyView(ITextureViewD3D12* pViewD3D12, const D3DShaderResourceAttribs& Attribs, const char* ShaderName)
509497 {
510498 return true;
511499 }
517505 {
518506 static const INTERFACE_ID& IID;
519507
520 static bool VerifyView(IBufferViewD3D12* pViewD3D12, const ShaderResourceLayoutD3D12::D3D12Resource& Attribs, const char* ShaderName)
508 static bool VerifyView(IBufferViewD3D12* pViewD3D12, const D3DShaderResourceAttribs& Attribs, const char* ShaderName)
521509 {
522510 return VerifyBufferViewModeD3D(pViewD3D12, Attribs, ShaderName);
523511 }
538526 // resource mapping can be of wrong type
539527 RefCntAutoPtr<TResourceViewType> pViewD3D12{pView, ResourceViewTraits<TResourceViewType>::IID};
540528 #ifdef DILIGENT_DEVELOPMENT
541 VerifyResourceViewBinding(*this, GetVariableType(), ArrayIndex, pView, pViewD3D12.RawPtr(), {dbgExpectedViewType}, DstRes.pObject.RawPtr(), ParentResLayout.GetShaderName());
542 ResourceViewTraits<TResourceViewType>::VerifyView(pViewD3D12, *this, ParentResLayout.GetShaderName());
529 VerifyResourceViewBinding(Attribs, GetVariableType(), ArrayIndex, pView, pViewD3D12.RawPtr(), {dbgExpectedViewType}, DstRes.pObject.RawPtr(), ParentResLayout.GetShaderName());
530 ResourceViewTraits<TResourceViewType>::VerifyView(pViewD3D12, Attribs, ParentResLayout.GetShaderName());
543531 #endif
544532 if (pViewD3D12)
545533 {
575563 Uint32 ArrayIndex,
576564 D3D12_CPU_DESCRIPTOR_HANDLE ShdrVisibleHeapCPUDescriptorHandle) const
577565 {
578 VERIFY(IsValidBindPoint(), "Invalid bind point");
579 VERIFY_EXPR(ArrayIndex < BindCount);
566 VERIFY(Attribs.IsValidBindPoint(), "Invalid bind point");
567 VERIFY_EXPR(ArrayIndex < Attribs.BindCount);
580568
581569 RefCntAutoPtr<ISamplerD3D12> pSamplerD3D12(pSampler, IID_SamplerD3D12);
582570 if (pSamplerD3D12)
586574 if (DstSam.pObject != pSampler)
587575 {
588576 auto VarTypeStr = GetShaderVariableTypeLiteralName(GetVariableType());
589 LOG_ERROR_MESSAGE("Non-null sampler is already bound to ", VarTypeStr, " shader variable '", GetPrintName(ArrayIndex),
577 LOG_ERROR_MESSAGE("Non-null sampler is already bound to ", VarTypeStr, " shader variable '", Attribs.GetPrintName(ArrayIndex),
590578 "' in shader '", ParentResLayout.GetShaderName(), "'. Attempting to bind another sampler is an error and will "
591579 "be ignored. Use another shader resource binding instance or label the variable as dynamic.");
592580 }
615603 }
616604 else
617605 {
618 LOG_ERROR_MESSAGE("Failed to bind object '", pSampler->GetDesc().Name, "' to variable '", GetPrintName(ArrayIndex),
606 LOG_ERROR_MESSAGE("Failed to bind object '", pSampler->GetDesc().Name, "' to variable '", Attribs.GetPrintName(ArrayIndex),
619607 "' in shader '", ParentResLayout.GetShaderName(), "'. Incorect object type: sampler is expected.");
620608 }
621609 }
630618 const ShaderResourceLayoutD3D12::D3D12Resource& ShaderResourceLayoutD3D12::GetAssignedSampler(const D3D12Resource& TexSrv) const
631619 {
632620 VERIFY(TexSrv.GetResType() == CachedResourceType::TexSRV, "Unexpected resource type: texture SRV is expected");
633 VERIFY(TexSrv.ValidSamplerAssigned(), "Texture SRV has no associated sampler");
634 const auto& SamInfo = GetSampler(TexSrv.SamplerId);
621 VERIFY(TexSrv.Attribs.IsCombinedWithSampler(), "Texture SRV has no associated sampler");
622 const auto& SamInfo = GetSampler(TexSrv.Attribs.GetCombinedSamplerId());
635623 VERIFY(SamInfo.GetVariableType() == TexSrv.GetVariableType(), "Inconsistent texture and sampler variable types");
636624 //VERIFY(StreqSuff(SamInfo.Name, TexSrv.Name, GetCombinedSamplerSuffix()), "Sampler name '", SamInfo.Name, "' does not match texture name '", TexSrv.Name, '\'');
637625 return SamInfo;
647635 Uint32 ArrayIndex,
648636 ShaderResourceCacheD3D12& ResourceCache) const
649637 {
650 VERIFY_EXPR(ArrayIndex < BindCount);
638 VERIFY_EXPR(ArrayIndex < Attribs.BindCount);
651639
652640 const bool IsSampler = GetResType() == CachedResourceType::Sampler;
653641 auto DescriptorHeapType = IsSampler ? D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER : D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV;
665653 }
666654 else if (ResourceCache.DbgGetContentType() == ShaderResourceCacheD3D12::DbgCacheContentType::SRBResources)
667655 {
668 if (GetResType() == CachedResourceType::CBV && BindCount == 1)
656 if (GetResType() == CachedResourceType::CBV && Attribs.BindCount == 1)
669657 {
670658 VERIFY(ShdrVisibleHeapCPUDescriptorHandle.ptr == 0, "Non-array constant buffers are bound as root views and should not be assigned shader visible descriptor space");
671659 }
698686 pObj, DstRes, ArrayIndex, ShdrVisibleHeapCPUDescriptorHandle, TEXTURE_VIEW_SHADER_RESOURCE,
699687 [&](ITextureViewD3D12* pTexView) //
700688 {
701 if (ValidSamplerAssigned())
689 if (Attribs.IsCombinedWithSampler())
702690 {
703691 auto& Sam = ParentResLayout.GetAssignedSampler(*this);
704692 //VERIFY( !Sam.IsImmutableSampler(), "Immutable samplers should never be assigned space in the cache" );
705 VERIFY_EXPR(BindCount == Sam.BindCount || Sam.BindCount == 1);
706 auto SamplerArrInd = Sam.BindCount > 1 ? ArrayIndex : 0;
693 VERIFY_EXPR(Attribs.BindCount == Sam.Attribs.BindCount || Sam.Attribs.BindCount == 1);
694 auto SamplerArrInd = Sam.Attribs.BindCount > 1 ? ArrayIndex : 0;
707695
708696 auto ShdrVisibleSamplerHeapCPUDescriptorHandle = ResourceCache.GetShaderVisibleTableCPUDescriptorHandle<D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER>(Sam.RootIndex, Sam.OffsetFromTableStart + SamplerArrInd);
709697
734722 }
735723 else
736724 {
737 LOG_ERROR_MESSAGE("Failed to bind sampler to variable '", Sam.Name, ". Sampler is not set in the texture view '", pTexView->GetDesc().Name, '\'');
725 LOG_ERROR_MESSAGE("Failed to bind sampler to variable '", Sam.Attribs.Name, ". Sampler is not set in the texture view '", pTexView->GetDesc().Name, '\'');
738726 }
739727 }
740728 });
767755 else
768756 {
769757 if (DstRes.pObject != nullptr && GetVariableType() != SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC)
770 LOG_ERROR_MESSAGE("Shader variable '", Name, "' in shader '", ParentResLayout.GetShaderName(), "' is not dynamic but is being reset to null. This is an error and may cause unpredicted behavior. Use another shader resource binding instance or label the variable as dynamic if you need to bind another resource.");
758 LOG_ERROR_MESSAGE("Shader variable '", Attribs.Name, "' in shader '", ParentResLayout.GetShaderName(), "' is not dynamic but is being reset to null. This is an error and may cause unpredicted behavior. Use another shader resource binding instance or label the variable as dynamic if you need to bind another resource.");
771759
772760 DstRes = ShaderResourceCacheD3D12::Resource{};
773 if (ValidSamplerAssigned())
761 if (Attribs.IsCombinedWithSampler())
774762 {
775763 auto& Sam = ParentResLayout.GetAssignedSampler(*this);
776764 D3D12_CPU_DESCRIPTOR_HANDLE NullHandle = {0};
777 auto SamplerArrInd = Sam.BindCount > 1 ? ArrayIndex : 0;
765 auto SamplerArrInd = Sam.Attribs.BindCount > 1 ? ArrayIndex : 0;
778766 auto& DstSam = ResourceCache.GetRootTable(Sam.RootIndex).GetResource(Sam.OffsetFromTableStart + SamplerArrInd, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, ParentResLayout.GetShaderType());
779767 if (DstSam.pObject != nullptr && Sam.GetVariableType() != SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC)
780 LOG_ERROR_MESSAGE("Sampler variable '", Sam.Name, "' in shader '", ParentResLayout.GetShaderName(), "' is not dynamic but is being reset to null. This is an error and may cause unpredicted behavior. Use another shader resource binding instance or label the variable as dynamic if you need to bind another sampler.");
768 LOG_ERROR_MESSAGE("Sampler variable '", Sam.Attribs.Name, "' in shader '", ParentResLayout.GetShaderName(), "' is not dynamic but is being reset to null. This is an error and may cause unpredicted behavior. Use another shader resource binding instance or label the variable as dynamic if you need to bind another sampler.");
781769 DstSam = ShaderResourceCacheD3D12::Resource{};
782770 }
783771 }
785773
786774 bool ShaderResourceLayoutD3D12::D3D12Resource::IsBound(Uint32 ArrayIndex, const ShaderResourceCacheD3D12& ResourceCache) const
787775 {
788 VERIFY_EXPR(ArrayIndex < BindCount);
776 VERIFY_EXPR(ArrayIndex < Attribs.BindCount);
789777
790778 if (RootIndex < ResourceCache.GetNumRootTables())
791779 {
806794
807795 return false;
808796 }
809
810 HLSLShaderResourceDesc ShaderResourceLayoutD3D12::D3D12Resource::GetHLSLResourceDesc() const
811 {
812 HLSLShaderResourceDesc ResourceDesc;
813 ResourceDesc.Name = Name;
814 ResourceDesc.ArraySize = BindCount;
815 ResourceDesc.ShaderRegister = BindPoint;
816 switch (GetInputType())
817 {
818 case D3D_SIT_CBUFFER:
819 ResourceDesc.Type = SHADER_RESOURCE_TYPE_CONSTANT_BUFFER;
820 break;
821
822 case D3D_SIT_TBUFFER:
823 UNSUPPORTED("TBuffers are not supported");
824 ResourceDesc.Type = SHADER_RESOURCE_TYPE_UNKNOWN;
825 break;
826
827 case D3D_SIT_TEXTURE:
828 ResourceDesc.Type = (GetSRVDimension() == D3D_SRV_DIMENSION_BUFFER ? SHADER_RESOURCE_TYPE_BUFFER_SRV : SHADER_RESOURCE_TYPE_TEXTURE_SRV);
829 break;
830
831 case D3D_SIT_SAMPLER:
832 ResourceDesc.Type = SHADER_RESOURCE_TYPE_SAMPLER;
833 break;
834
835 case D3D_SIT_UAV_RWTYPED:
836 ResourceDesc.Type = (GetSRVDimension() == D3D_SRV_DIMENSION_BUFFER ? SHADER_RESOURCE_TYPE_BUFFER_UAV : SHADER_RESOURCE_TYPE_TEXTURE_UAV);
837 break;
838
839 case D3D_SIT_STRUCTURED:
840 case D3D_SIT_BYTEADDRESS:
841 ResourceDesc.Type = SHADER_RESOURCE_TYPE_BUFFER_SRV;
842 break;
843
844 case D3D_SIT_UAV_RWSTRUCTURED:
845 case D3D_SIT_UAV_RWBYTEADDRESS:
846 case D3D_SIT_UAV_APPEND_STRUCTURED:
847 case D3D_SIT_UAV_CONSUME_STRUCTURED:
848 case D3D_SIT_UAV_RWSTRUCTURED_WITH_COUNTER:
849 ResourceDesc.Type = SHADER_RESOURCE_TYPE_BUFFER_UAV;
850 break;
851
852 default:
853 UNEXPECTED("Unknown input type");
854 }
855
856 return ResourceDesc;
857 }
858
859797
860798 void ShaderResourceLayoutD3D12::CopyStaticResourceDesriptorHandles(const ShaderResourceCacheD3D12& SrcCache, const ShaderResourceLayoutD3D12& DstLayout, ShaderResourceCacheD3D12& DstCache) const
861799 {
874812 // Get resource attributes
875813 const auto& res = DstLayout.GetSrvCbvUav(SHADER_RESOURCE_VARIABLE_TYPE_STATIC, r);
876814 auto RangeType = GetDescriptorRangeType(res.GetResType());
877 for (Uint32 ArrInd = 0; ArrInd < res.BindCount; ++ArrInd)
878 {
879 auto BindPoint = res.BindPoint + ArrInd;
815 for (Uint32 ArrInd = 0; ArrInd < res.Attribs.BindCount; ++ArrInd)
816 {
817 auto BindPoint = res.Attribs.BindPoint + ArrInd;
880818 // Source resource in the static resource cache is in the root table at index RangeType, at offset BindPoint
881819 // D3D12_DESCRIPTOR_RANGE_TYPE_SRV = 0,
882820 // D3D12_DESCRIPTOR_RANGE_TYPE_UAV = 1
883821 // D3D12_DESCRIPTOR_RANGE_TYPE_CBV = 2
884822 const auto& SrcRes = SrcCache.GetRootTable(RangeType).GetResource(BindPoint, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, GetShaderType());
885823 if (!SrcRes.pObject)
886 LOG_ERROR_MESSAGE("No resource is assigned to static shader variable '", res.GetPrintName(ArrInd), "' in shader '", GetShaderName(), "'.");
824 LOG_ERROR_MESSAGE("No resource is assigned to static shader variable '", res.Attribs.GetPrintName(ArrInd), "' in shader '", GetShaderName(), "'.");
887825 // Destination resource is at the root index and offset defined by the resource layout
888826 auto& DstRes = DstCache.GetRootTable(res.RootIndex).GetResource(res.OffsetFromTableStart + ArrInd, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, GetShaderType());
889827
924862 }
925863 }
926864
927 if (res.ValidSamplerAssigned())
865 if (res.Attribs.IsCombinedWithSampler())
928866 {
929867 const auto& SamInfo = DstLayout.GetAssignedSampler(res);
930868
931869 //VERIFY(!SamInfo.IsImmutableSampler(), "Immutable samplers should never be assigned space in the cache");
932870
933 VERIFY(SamInfo.IsValidBindPoint(), "Sampler bind point must be valid");
934 VERIFY_EXPR(SamInfo.BindCount == res.BindCount || SamInfo.BindCount == 1);
871 VERIFY(SamInfo.Attribs.IsValidBindPoint(), "Sampler bind point must be valid");
872 VERIFY_EXPR(SamInfo.Attribs.BindCount == res.Attribs.BindCount || SamInfo.Attribs.BindCount == 1);
935873 }
936874 }
937875
940878 for (Uint32 s = 0; s < SamplerCount; ++s)
941879 {
942880 const auto& SamInfo = DstLayout.GetSampler(SHADER_RESOURCE_VARIABLE_TYPE_STATIC, s);
943 for (Uint32 ArrInd = 0; ArrInd < SamInfo.BindCount; ++ArrInd)
944 {
945 auto BindPoint = SamInfo.BindPoint + ArrInd;
881 for (Uint32 ArrInd = 0; ArrInd < SamInfo.Attribs.BindCount; ++ArrInd)
882 {
883 auto BindPoint = SamInfo.Attribs.BindPoint + ArrInd;
946884 // Source sampler in the static resource cache is in the root table at index 3
947885 // (D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER = 3), at offset BindPoint
948886 const auto& SrcSampler = SrcCache.GetRootTable(D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER).GetResource(BindPoint, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, GetShaderType());
949887 if (!SrcSampler.pObject)
950 LOG_ERROR_MESSAGE("No sampler assigned to static shader variable '", SamInfo.GetPrintName(ArrInd), "' in shader '", GetShaderName(), "'.");
888 LOG_ERROR_MESSAGE("No sampler assigned to static shader variable '", SamInfo.Attribs.GetPrintName(ArrInd), "' in shader '", GetShaderName(), "'.");
951889 auto& DstSampler = DstCache.GetRootTable(SamInfo.RootIndex).GetResource(SamInfo.OffsetFromTableStart + ArrInd, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, GetShaderType());
952890
953891 if (DstSampler.pObject != SrcSampler.pObject)
987925 const auto& res = GetSrvCbvUav(VarType, r);
988926 VERIFY(res.GetVariableType() == VarType, "Unexpected variable type");
989927
990 for (Uint32 ArrInd = 0; ArrInd < res.BindCount; ++ArrInd)
928 for (Uint32 ArrInd = 0; ArrInd < res.Attribs.BindCount; ++ArrInd)
991929 {
992930 const auto& CachedRes = ResourceCache.GetRootTable(res.RootIndex).GetResource(res.OffsetFromTableStart + ArrInd, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, GetShaderType());
993931 if (CachedRes.pObject)
999937 // Dynamic buffers do not have CPU descriptor handle as they do not keep D3D12 buffer, and space is allocated from the GPU ring buffer
1000938 CachedRes.CPUDescriptorHandle.ptr == 0 && !(CachedRes.Type == CachedResourceType::CBV && CachedRes.pObject.RawPtr<const BufferD3D12Impl>()->GetDesc().Usage == USAGE_DYNAMIC))
1001939 {
1002 LOG_ERROR_MESSAGE("No resource is bound to ", GetShaderVariableTypeLiteralName(res.GetVariableType()), " variable '", res.GetPrintName(ArrInd), "' in shader '", GetShaderName(), "'");
940 LOG_ERROR_MESSAGE("No resource is bound to ", GetShaderVariableTypeLiteralName(res.GetVariableType()), " variable '", res.Attribs.GetPrintName(ArrInd), "' in shader '", GetShaderName(), "'");
1003941 BindingsOK = false;
1004942 }
1005943
1006 if (res.BindCount > 1 && res.ValidSamplerAssigned())
944 if (res.Attribs.BindCount > 1 && res.Attribs.IsCombinedWithSampler())
1007945 {
1008946 // Verify that if single sampler is used for all texture array elements, all samplers set in the resource views are consistent
1009947 const auto& SamInfo = GetAssignedSampler(res);
1010 if (SamInfo.BindCount == 1)
948 if (SamInfo.Attribs.BindCount == 1)
1011949 {
1012950 const auto& CachedSampler = ResourceCache.GetRootTable(SamInfo.RootIndex).GetResource(SamInfo.OffsetFromTableStart, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, GetShaderType());
1013951 // Conversion must always succeed as the type is verified when resource is bound to the variable
1016954 const auto* pSampler = pTexView->GetSampler();
1017955 if (pSampler != nullptr && CachedSampler.pObject != nullptr && CachedSampler.pObject != pSampler)
1018956 {
1019 LOG_ERROR_MESSAGE("All elements of texture array '", res.Name, "' in shader '", GetShaderName(), "' share the same sampler. However, the sampler set in view for element ", ArrInd, " does not match bound sampler. This may cause incorrect behavior on GL platform.");
957 LOG_ERROR_MESSAGE("All elements of texture array '", res.Attribs.Name, "' in shader '", GetShaderName(), "' share the same sampler. However, the sampler set in view for element ", ArrInd, " does not match bound sampler. This may cause incorrect behavior on GL platform.");
1020958 }
1021959 }
1022960 }
1031969 }
1032970 else if (ResourceCache.DbgGetContentType() == ShaderResourceCacheD3D12::DbgCacheContentType::SRBResources)
1033971 {
1034 if (res.GetResType() == CachedResourceType::CBV && res.BindCount == 1)
972 if (res.GetResType() == CachedResourceType::CBV && res.Attribs.BindCount == 1)
1035973 {
1036974 VERIFY(ShdrVisibleHeapCPUDescriptorHandle.ptr == 0, "Non-array constant buffers are bound as root views and should not be assigned shader visible descriptor space");
1037975 }
1051989 # endif
1052990 }
1053991
1054 if (res.ValidSamplerAssigned())
992 if (res.Attribs.IsCombinedWithSampler())
1055993 {
1056994 VERIFY(res.GetResType() == CachedResourceType::TexSRV, "Sampler can only be assigned to a texture SRV");
1057995 const auto& SamInfo = GetAssignedSampler(res);
1058996 //VERIFY(!SamInfo.IsImmutableSampler(), "Immutable samplers should never be assigned space in the cache" );
1059 VERIFY(SamInfo.IsValidBindPoint(), "Sampler bind point must be valid");
1060
1061 for (Uint32 ArrInd = 0; ArrInd < SamInfo.BindCount; ++ArrInd)
997 VERIFY(SamInfo.Attribs.IsValidBindPoint(), "Sampler bind point must be valid");
998
999 for (Uint32 ArrInd = 0; ArrInd < SamInfo.Attribs.BindCount; ++ArrInd)
10621000 {
10631001 const auto& CachedSampler = ResourceCache.GetRootTable(SamInfo.RootIndex).GetResource(SamInfo.OffsetFromTableStart + ArrInd, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, GetShaderType());
10641002 if (CachedSampler.pObject)
10671005 VERIFY(CachedSampler.Type == CachedResourceType::Unknown, "Unexpected cached sampler type");
10681006 if (!CachedSampler.pObject || CachedSampler.CPUDescriptorHandle.ptr == 0)
10691007 {
1070 LOG_ERROR_MESSAGE("No sampler is assigned to texture variable '", res.GetPrintName(ArrInd), "' in shader '", GetShaderName(), "'");
1008 LOG_ERROR_MESSAGE("No sampler is assigned to texture variable '", res.Attribs.GetPrintName(ArrInd), "' in shader '", GetShaderName(), "'");
10711009 BindingsOK = false;
10721010 }
10731011
11001038 const auto& sam = GetSampler(VarType, s);
11011039 VERIFY(sam.GetVariableType() == VarType, "Unexpected sampler variable type");
11021040
1103 for (Uint32 ArrInd = 0; ArrInd < sam.BindCount; ++ArrInd)
1041 for (Uint32 ArrInd = 0; ArrInd < sam.Attribs.BindCount; ++ArrInd)
11041042 {
11051043 const auto& CachedSampler = ResourceCache.GetRootTable(sam.RootIndex).GetResource(sam.OffsetFromTableStart + ArrInd, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, GetShaderType());
11061044 if (CachedSampler.pObject)
11091047 VERIFY(CachedSampler.Type == CachedResourceType::Unknown, "Unexpected cached sampler type");
11101048 if (!CachedSampler.pObject || CachedSampler.CPUDescriptorHandle.ptr == 0)
11111049 {
1112 LOG_ERROR_MESSAGE("No sampler is bound to sampler variable '", sam.GetPrintName(ArrInd), "' in shader '", GetShaderName(), "'");
1050 LOG_ERROR_MESSAGE("No sampler is bound to sampler variable '", sam.Attribs.GetPrintName(ArrInd), "' in shader '", GetShaderName(), "'");
11131051 BindingsOK = false;
11141052 }
11151053 }
124124 for (Uint32 v = 0; v < m_NumVariables; ++v)
125125 {
126126 auto& Var = m_pVariables[v];
127 if (strcmp(Var.m_Resource.Name, Name) == 0)
127 if (strcmp(Var.m_Resource.Attribs.Name, Name) == 0)
128128 {
129129 pVar = &Var;
130130 break;
180180 if ((Flags & (1 << Res.GetVariableType())) == 0)
181181 continue;
182182
183 for (Uint32 ArrInd = 0; ArrInd < Res.BindCount; ++ArrInd)
183 for (Uint32 ArrInd = 0; ArrInd < Res.Attribs.BindCount; ++ArrInd)
184184 {
185185 if ((Flags & BIND_SHADER_RESOURCES_KEEP_EXISTING) && Res.IsBound(ArrInd, m_ResourceCache))
186186 continue;
187187
188188 RefCntAutoPtr<IDeviceObject> pObj;
189189 VERIFY_EXPR(pResourceMapping != nullptr);
190 pResourceMapping->GetResource(Res.Name, &pObj, ArrInd);
190 pResourceMapping->GetResource(Res.Attribs.Name, &pObj, ArrInd);
191191 if (pObj)
192192 {
193193 // Call non-virtual function
196196 else
197197 {
198198 if ((Flags & BIND_SHADER_RESOURCES_VERIFY_ALL_RESOLVED) && !Res.IsBound(ArrInd, m_ResourceCache))
199 LOG_ERROR_MESSAGE("Unable to bind resource to shader variable '", Res.GetPrintName(ArrInd), "': resource is not found in the resource mapping");
199 LOG_ERROR_MESSAGE("Unable to bind resource to shader variable '", Res.Attribs.GetPrintName(ArrInd), "': resource is not found in the resource mapping");
200200 }
201201 }
202202 }
22 project(Diligent-GraphicsEngineD3DBase CXX)
33
44 set(INCLUDE
5 include/D3DCommonTypeConversions.hpp
56 include/D3DErrors.hpp
67 include/D3DShaderResourceLoader.hpp
78 include/D3DTypeConversionImpl.hpp
2122 )
2223
2324 set(SOURCE
25 src/D3DCommonTypeConversions.cpp
2426 src/DXGITypeConversions.cpp
2527 src/ShaderD3DBase.cpp
2628 src/ShaderResources.cpp
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 /// Common D3D type conversions
31
32 #include "GraphicsTypes.h"
33
34 namespace Diligent
35 {
36
37 RESOURCE_DIMENSION D3DSrvDimensionToResourceDimension(D3D_SRV_DIMENSION SrvDim);
38
39 } // namespace Diligent
6666 #include "StringPool.hpp"
6767 #include "D3DShaderResourceLoader.hpp"
6868 #include "PipelineState.h"
69 #include "D3DCommonTypeConversions.hpp"
6970
7071 namespace Diligent
7172 {
8081 /* 8 */ const Uint16 BindPoint;
8182 /*10 */ const Uint16 BindCount;
8283
83 private:
8484 // 4 4 24
8585 // bit | 0 1 2 3 | 4 5 6 7 | 8 9 10 ... 31 |
8686 // | | | |
9393 static_assert(D3D_SIT_UAV_RWSTRUCTURED_WITH_COUNTER < (1 << ShaderInputTypeBits), "Not enough bits to represent D3D_SHADER_INPUT_TYPE");
9494 static_assert(D3D_SRV_DIMENSION_BUFFEREX < (1 << SRVDimBits), "Not enough bits to represent D3D_SRV_DIMENSION");
9595
96 private:
9697 // We need to use Uint32 instead of the actual type for reliability and correctness.
9798 // There originally was a problem when the type of InputType was D3D_SHADER_INPUT_TYPE:
9899 // the value of D3D_SIT_UAV_RWBYTEADDRESS (8) was interpreted as -8 (as the underlying enum type
105106 // clang-format on
106107
107108 public:
108 static constexpr const Uint32 InvalidSamplerId = (1 << SamplerOrTexSRVIdBits) - 1;
109 static constexpr const Uint32 InvalidTexSRVId = (1 << SamplerOrTexSRVIdBits) - 1;
109 static constexpr const Uint32 InvalidSamplerId = (1U << SamplerOrTexSRVIdBits) - 1U;
110 static constexpr const Uint32 MaxSamplerId = InvalidSamplerId - 1;
111 static constexpr const Uint32 InvalidTexSRVId = (1U << SamplerOrTexSRVIdBits) - 1U;
110112 static constexpr const Uint16 InvalidBindPoint = std::numeric_limits<Uint16>::max();
111113 static constexpr const Uint16 MaxBindPoint = InvalidBindPoint - 1;
112114 static constexpr const Uint16 MaxBindCount = std::numeric_limits<Uint16>::max();
156158 }
157159 // clang-format on
158160 {
159 VERIFY(GetInputType() == D3D_SIT_TEXTURE && GetSRVDimension() != D3D_SRV_DIMENSION_BUFFER, "Only texture SRV can be assigned a texture sampler");
161 VERIFY(SamplerId == InvalidSamplerId || (GetInputType() == D3D_SIT_TEXTURE && GetSRVDimension() != D3D_SRV_DIMENSION_BUFFER),
162 "Only texture SRV can be assigned a valid texture sampler");
160163 }
161164
162165 D3DShaderResourceAttribs(StringPool& NamesPool, const D3DShaderResourceAttribs& rhs) noexcept :
191194 return static_cast<D3D_SRV_DIMENSION>(SRVDimension);
192195 }
193196
194 RESOURCE_DIMENSION GetResourceDimension() const;
197 RESOURCE_DIMENSION GetResourceDimension() const
198 {
199 return D3DSrvDimensionToResourceDimension(GetSRVDimension());
200 }
195201
196202 bool IsMultisample() const;
197203
198204 bool IsCombinedWithSampler() const
199205 {
200 return GetCombinedSamplerId() != InvalidSamplerId;
206 return GetInputType() == D3D_SIT_TEXTURE && SamplerOrTexSRVId != InvalidSamplerId;
201207 }
202208
203209 bool IsCombinedWithTexSRV() const
235241
236242 HLSLShaderResourceDesc GetHLSLResourceDesc() const;
237243
244 Uint32 GetCombinedSamplerId() const
245 {
246 VERIFY(GetInputType() == D3D_SIT_TEXTURE && GetSRVDimension() != D3D_SRV_DIMENSION_BUFFER, "Invalid input type: D3D_SIT_TEXTURE is expected");
247 return SamplerOrTexSRVId;
248 }
249
238250 private:
239251 friend class ShaderResources;
240
241 Uint32 GetCombinedSamplerId() const
242 {
243 VERIFY(GetInputType() == D3D_SIT_TEXTURE && GetSRVDimension() != D3D_SRV_DIMENSION_BUFFER, "Invalid input type: D3D_SIT_TEXTURE is expected");
244 return SamplerOrTexSRVId;
245 }
246252
247253 void SetTexSRVId(Uint32 TexSRVId)
248254 {
8686 };
8787
8888
89 template <typename BufferViewImplType, typename AttribsType>
90 bool VerifyBufferViewModeD3D(BufferViewImplType* pViewD3D11, const AttribsType& Attribs, const char* ShaderName)
89 template <typename BufferViewImplType>
90 bool VerifyBufferViewModeD3D(BufferViewImplType* pViewD3D11, const D3DShaderResourceAttribs& Attribs, const char* ShaderName)
9191 {
9292 if (pViewD3D11 == nullptr)
9393 return true;
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 #include <d3dcommon.h>
28 #include "D3DCommonTypeConversions.hpp"
29
30 namespace Diligent
31 {
32
33 RESOURCE_DIMENSION D3DSrvDimensionToResourceDimension(D3D_SRV_DIMENSION SrvDim)
34 {
35 switch (SrvDim)
36 {
37 // clang-format off
38 case D3D_SRV_DIMENSION_BUFFER: return RESOURCE_DIM_BUFFER;
39 case D3D_SRV_DIMENSION_TEXTURE1D: return RESOURCE_DIM_TEX_1D;
40 case D3D_SRV_DIMENSION_TEXTURE1DARRAY: return RESOURCE_DIM_TEX_1D_ARRAY;
41 case D3D_SRV_DIMENSION_TEXTURE2D: return RESOURCE_DIM_TEX_2D;
42 case D3D_SRV_DIMENSION_TEXTURE2DARRAY: return RESOURCE_DIM_TEX_2D_ARRAY;
43 case D3D_SRV_DIMENSION_TEXTURE2DMS: return RESOURCE_DIM_TEX_2D;
44 case D3D_SRV_DIMENSION_TEXTURE2DMSARRAY: return RESOURCE_DIM_TEX_2D_ARRAY;
45 case D3D_SRV_DIMENSION_TEXTURE3D: return RESOURCE_DIM_TEX_3D;
46 case D3D_SRV_DIMENSION_TEXTURECUBE: return RESOURCE_DIM_TEX_CUBE;
47 case D3D_SRV_DIMENSION_TEXTURECUBEARRAY: return RESOURCE_DIM_TEX_CUBE_ARRAY;
48 // clang-format on
49 default:
50 return RESOURCE_DIM_BUFFER;
51 }
52 }
53
54 } // namespace Diligent
5454
5555 for (Uint32 n = 0; n < GetNumSamplers(); ++n)
5656 GetSampler(n).~D3DShaderResourceAttribs();
57
58 for (Uint32 n = 0; n < GetNumAccelStructs(); ++n)
59 GetAccelStruct(n).~D3DShaderResourceAttribs();
5760 }
5861
5962 void ShaderResources::AllocateMemory(IMemoryAllocator& Allocator,
466469 return ResourceDesc;
467470 }
468471
469 RESOURCE_DIMENSION D3DShaderResourceAttribs::GetResourceDimension() const
470 {
471 switch (GetSRVDimension())
472 {
473 // clang-format off
474 case D3D_SRV_DIMENSION_BUFFER: return RESOURCE_DIM_BUFFER;
475 case D3D_SRV_DIMENSION_TEXTURE1D: return RESOURCE_DIM_TEX_1D;
476 case D3D_SRV_DIMENSION_TEXTURE1DARRAY: return RESOURCE_DIM_TEX_1D_ARRAY;
477 case D3D_SRV_DIMENSION_TEXTURE2D: return RESOURCE_DIM_TEX_2D;
478 case D3D_SRV_DIMENSION_TEXTURE2DARRAY: return RESOURCE_DIM_TEX_2D_ARRAY;
479 case D3D_SRV_DIMENSION_TEXTURE2DMS: return RESOURCE_DIM_TEX_2D;
480 case D3D_SRV_DIMENSION_TEXTURE2DMSARRAY: return RESOURCE_DIM_TEX_2D_ARRAY;
481 case D3D_SRV_DIMENSION_TEXTURE3D: return RESOURCE_DIM_TEX_3D;
482 case D3D_SRV_DIMENSION_TEXTURECUBE: return RESOURCE_DIM_TEX_CUBE;
483 case D3D_SRV_DIMENSION_TEXTURECUBEARRAY: return RESOURCE_DIM_TEX_CUBE_ARRAY;
484 // clang-format on
485 default:
486 return RESOURCE_DIM_BUFFER;
487 }
488 }
489
490472 bool D3DShaderResourceAttribs::IsMultisample() const
491473 {
492474 switch (GetSRVDimension())
148148 sizeof(FenceGLImpl),
149149 sizeof(QueryGLImpl),
150150 sizeof(RenderPassGLImpl),
151 sizeof(FramebufferGLImpl)
151 sizeof(FramebufferGLImpl),
152 0,
153 0,
154 0
152155 }
153156 },
154157 // Device caps must be filled in before the constructor of Pipeline Cache is called!
155158 m_GLContext{InitAttribs, m_DeviceCaps, pSCDesc}
156159 // clang-format on
157160 {
161 static_assert(sizeof(DeviceObjectSizes) == sizeof(size_t) * 15, "Please add new objects to DeviceObjectSizes constructor");
162
158163 GLint NumExtensions = 0;
159164 glGetIntegerv(GL_NUM_EXTENSIONS, &NumExtensions);
160165 CHECK_GL_ERROR("Failed to get the number of extensions");
737742
738743 void RenderDeviceGLImpl::CreateRayTracingPipelineState(const RayTracingPipelineStateCreateInfo& PSOCreateInfo, IPipelineState** ppPipelineState)
739744 {
740 UNSUPPORTED("CreateRayTracingPipelineState is not supported in OpenGL");
745 UNSUPPORTED("Ray tracing is not supported in OpenGL");
741746 *ppPipelineState = nullptr;
742747 }
743748
135135 // set by the same Vulkan command. If there are no dynamic descriptors, this
136136 // function also binds descriptor sets rightaway.
137137 void PrepareDescriptorSets(DeviceContextVkImpl* pCtxVkImpl,
138 VkPipelineBindPoint BindPoint,
138139 const ShaderResourceCacheVk& ResourceCache,
139140 DescriptorSetBindInfo& BindInfo,
140141 VkDescriptorSet VkDynamicDescrSet) const;
128128 private:
129129 using TShaderStages = ShaderResourceLayoutVk::TShaderStages;
130130
131 template <typename PSOCreateInfoType>
131 template <typename PSOCreateInfoType, typename InitPSODescType>
132132 void InitInternalObjects(const PSOCreateInfoType& CreateInfo,
133133 std::vector<VkPipelineShaderStageCreateInfo>& vkShaderStages,
134 std::vector<VulkanUtilities::ShaderModuleWrapper>& ShaderModules);
134 std::vector<VulkanUtilities::ShaderModuleWrapper>& ShaderModules,
135 InitPSODescType InitPSODesc);
135136
136137 void InitResourceLayouts(const PipelineStateCreateInfo& CreateInfo,
137138 TShaderStages& ShaderStages);
169170 // Resource layout index in m_ShaderResourceLayouts array for every shader stage,
170171 // indexed by the shader type pipeline index (returned by GetShaderTypePipelineIndex)
171172 std::array<Int8, MAX_SHADERS_IN_PIPELINE> m_ResourceLayoutIndex = {-1, -1, -1, -1, -1, -1};
173 static_assert(MAX_SHADERS_IN_PIPELINE == 6, "Please update the initializer list above");
172174
173175 bool m_HasStaticResources = false;
174176 bool m_HasNonStaticResources = false;
196196
197197 IDXCompiler* GetDxCompiler() const { return m_pDxCompiler.get(); }
198198
199 Uint32 GetShaderGroupHandleSize() const
200 {
201 return GetPhysicalDevice().GetExtProperties().RayTracing.shaderGroupHandleSize;
202 }
203
199204 private:
200205 template <typename PSOCreateInfoType>
201206 void CreatePipelineState(const PSOCreateInfoType& PSOCreateInfo, IPipelineState** ppPipelineState);
8383 // Resource layout index in m_ShaderResourceCache array for every shader stage,
8484 // indexed by the shader type pipeline index (returned by GetShaderTypePipelineIndex)
8585 std::array<Int8, MAX_SHADERS_IN_PIPELINE> m_ResourceLayoutIndex = {-1, -1, -1, -1, -1, -1};
86 static_assert(MAX_SHADERS_IN_PIPELINE == 6, "Please update the initializer list above");
8687
8788 bool m_bStaticResourcesInitialized = false;
8889 Uint8 m_NumShaders = 0;
4343 // d == m_NumResources[SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC]
4444 //
4545 //
46 //
47 // * Every VkResource structure holds a reference to SPIRVShaderResourceAttribs structure from SPIRVShaderResources.
48 // * ShaderResourceLayoutVk keeps a shared pointer to SPIRVShaderResources instance.
49 // * Every ShaderVariableVkImpl variable managed by ShaderVariableManagerVk keeps a reference to corresponding VkResource.
50 //
51 //
52 // ______________________ ________________________________________________________________________
53 // | | unique_ptr | | | | | | | |
54 // | SPIRVShaderResources |--------------->| UBs | SBs | StrgImgs | SmplImgs | ACs | SepSamplers | SepImgs |
55 // |______________________| |________|_________|__________|__________|_______|_____________|_________|
56 // A A A
57 // | | |
58 // |shared_ptr Ref Ref
59 // ________|__________________ ________\____________________|_____________________________________________
46 // Every ShaderVariableVkImpl variable managed by ShaderVariableManagerVk keeps a reference to corresponding VkResource.
47 //
48 // ___________________________ ___________________________________________________________________________
6049 // | | unique_ptr | | | | |
6150 // | ShaderResourceLayoutVk |--------------->| VkResource[0] | VkResource[1] | ... | VkResource[s+m+d-1] |
6251 // |___________________________| |___________________|_________________|_______________|_____________________|
9887
9988 #include <array>
10089 #include <memory>
90 #include <unordered_map>
10191
10292 #include "PipelineState.h"
10393 #include "ShaderBase.hpp"
10494 #include "HashUtils.hpp"
10595 #include "ShaderResourceCacheVk.hpp"
106 #include "SPIRVShaderResources.hpp"
10796 #include "VulkanUtilities/VulkanLogicalDevice.hpp"
97 #include "StringPool.hpp"
10898
10999 namespace Diligent
110100 {
112102 class ShaderVkImpl;
113103
114104 /// Diligent::ShaderResourceLayoutVk class
115 // sizeof(ShaderResourceLayoutVk)==72 (MS compiler, x64)
105 // sizeof(ShaderResourceLayoutVk)==40 (MS compiler, x64)
116106 class ShaderResourceLayoutVk
117107 {
118108 public:
133123 ShaderResourceLayoutVk(const VulkanUtilities::VulkanLogicalDevice& LogicalDevice) noexcept :
134124 m_LogicalDevice{LogicalDevice}
135125 {
126 #if defined(_MSC_VER) && defined(_WIN64)
127 static_assert(sizeof(*this) == 40, "Unexpected sizeof(ShaderResourceLayoutVk).");
128 #endif
136129 }
137130
138131 // clang-format off
180173
181174 static constexpr const Uint32 InvalidSamplerInd = (1 << SamplerIndBits)-1;
182175
176 static constexpr const Uint32 ResourceDimBits = 7;
177 static constexpr const Uint32 IsMSFlagBits = 8 - ResourceDimBits;
178 static_assert(RESOURCE_DIM_NUM_DIMENSIONS <= (1 << ResourceDimBits), "Not enough bits to represent RESOURCE_DIMENSION");
179
183180 using ResourceType = SPIRVShaderResourceAttribs::ResourceType;
184181
185182 /* 0 */ const Uint16 Binding;
186 /* 2 */ const Uint16 ArraySize;
183 /* 2 */ const Uint16 DescriptorSet;
184
187185 /* 4.0 */ const Uint32 CacheOffset : CacheOffsetBits; // Offset from the beginning of the cached descriptor set
188186 /* 6.5 */ const Uint32 SamplerInd : SamplerIndBits; // When using combined texture samplers, index of the separate sampler
189187 // assigned to separate image
190188 /* 7.5 */ const Uint32 VariableType : VariableTypeBits;
191189 /* 7.7 */ const Uint32 ImmutableSamplerAssigned : ImmutableSamplerFlagBits;
192 /* 8 */ const Uint8 DescriptorSet;
193
194 /* 9 */ const ResourceType Type;
195 /* 10.0*/ const Uint8 ResourceDim : 7;
196 /* 10.7*/ const Uint8 IsMS : 1;
190
191 /* 8 */ const Uint16 ArraySize;
192
193 /* 10 */ const ResourceType Type;
194 /* 11.0*/ const Uint8 ResourceDim : ResourceDimBits;
195 /* 11.7*/ const Uint8 IsMS : IsMSFlagBits;
196
197197 /* 16 */ const char* const Name;
198198 /* 24 */ const ShaderResourceLayoutVk& ParentResLayout;
199199 // clang-format on
202202 const char* _Name,
203203 Uint16 _ArraySize,
204204 ResourceType _Type,
205 Uint8 _ResourceDim,
206 Uint8 _IsMS,
205 RESOURCE_DIMENSION _ResourceDim,
206 bool _IsMS,
207207 SHADER_RESOURCE_VARIABLE_TYPE _VariableType,
208208 uint32_t _Binding,
209209 uint32_t _DescriptorSet,
217217 SamplerInd {_SamplerInd },
218218 VariableType {_VariableType },
219219 ImmutableSamplerAssigned {_ImmutableSamplerAssigned ? 1U : 0U},
220 Name {_Name },
221 ArraySize {_ArraySize },
222 Type {_Type },
223 ResourceDim {_ResourceDim },
224 IsMS {_IsMS },
225 ParentResLayout {_ParentLayout }
220 ArraySize {_ArraySize },
221 Type {_Type },
222 ResourceDim {_ResourceDim },
223 IsMS {_IsMS ? 1U : 0U},
224 Name {_Name },
225 ParentResLayout {_ParentLayout }
226226 // clang-format on
227227 {
228 VERIFY(_CacheOffset < (1 << CacheOffsetBits), "Cache offset (", _CacheOffset, ") exceeds max representable value ", (1 << CacheOffsetBits));
229 VERIFY(_SamplerInd < (1 << SamplerIndBits), "Sampler index (", _SamplerInd, ") exceeds max representable value ", (1 << SamplerIndBits));
230 VERIFY(_Binding <= std::numeric_limits<decltype(Binding)>::max(), "Binding (", _Binding, ") exceeds max representable value ", std::numeric_limits<decltype(Binding)>::max());
228 #if defined(_MSC_VER) && defined(_WIN64)
229 static_assert(sizeof(*this) == 32, "Unexpected sizeof(VkResource)");
230 #endif
231 // clang-format off
232 VERIFY(_CacheOffset < (1 << CacheOffsetBits), "Cache offset (", _CacheOffset, ") exceeds max representable value ", (1 << CacheOffsetBits) );
233 VERIFY(_SamplerInd < (1 << SamplerIndBits), "Sampler index (", _SamplerInd, ") exceeds max representable value ", (1 << SamplerIndBits) );
234 VERIFY(_Binding <= std::numeric_limits<decltype(Binding)>::max(), "Binding (", _Binding, ") exceeds max representable value ", std::numeric_limits<decltype(Binding)>::max() );
231235 VERIFY(_DescriptorSet <= std::numeric_limits<decltype(DescriptorSet)>::max(), "Descriptor set (", _DescriptorSet, ") exceeds max representable value ", std::numeric_limits<decltype(DescriptorSet)>::max());
232 }
236 VERIFY(_VariableType < (1 << VariableTypeBits), "Variable type (", Uint32{_VariableType}, ") exceeds max representable value ", (1 << VariableTypeBits) );
237 VERIFY(_ResourceDim < (1 << ResourceDimBits), "Resource dimension (", Uint32{_ResourceDim}, ") exceeds max representable value ", (1 << ResourceDimBits) );
238 // clang-format on
239 }
240
233241
234242 // Checks if a resource is bound in ResourceCache at the given ArrayIndex
235243 bool IsBound(Uint32 ArrayIndex, const ShaderResourceCacheVk& ResourceCache) const;
272280 return Name;
273281 }
274282
275 ShaderResourceDesc GetResourceDesc() const;
283 ShaderResourceDesc GetResourceDesc() const
284 {
285 return ShaderResourceDesc{Name, SPIRVShaderResourceAttribs::GetShaderResourceType(Type), ArraySize};
286 }
276287
277288 RESOURCE_DIMENSION GetResourceDimension() const
278289 {
402413 return m_NumResources[SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES];
403414 }
404415
416 static constexpr Uint32 InvalidResourceIndex = ~0u;
417
405418 using ResourceNameToIndex_t = std::unordered_map<HashMapStringKey, Uint32, HashMapStringKey::Hasher>;
406 void AllocateMemory(const std::vector<const ShaderVkImpl*>& Shaders,
407 IMemoryAllocator& Allocator,
408 const PipelineResourceLayoutDesc& ResourceLayoutDesc,
409 const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes,
410 Uint32 NumAllowedTypes,
411 ResourceNameToIndex_t& UniqueNames,
412 bool AllocateImmutableSamplers);
419 StringPool AllocateMemory(const std::vector<const ShaderVkImpl*>& Shaders,
420 IMemoryAllocator& Allocator,
421 const PipelineResourceLayoutDesc& ResourceLayoutDesc,
422 const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes,
423 Uint32 NumAllowedTypes,
424 ResourceNameToIndex_t& UniqueNames,
425 bool AllocateImmutableSamplers);
413426
414427 using ImmutableSamplerPtrType = RefCntAutoPtr<ISampler>;
415428 ImmutableSamplerPtrType& GetImmutableSampler(Uint32 n) noexcept
421434
422435 // clang-format off
423436 /* 0 */ const VulkanUtilities::VulkanLogicalDevice& m_LogicalDevice;
424 /* 8 */ std::unique_ptr<void, STDDeleterRawMem<void> > m_ResourceBuffer; // AZ TODO: use linear allocator
425 /*24 */ StringPool m_StringPool;
426
427 /*48 */ std::array<Uint16, SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES+1> m_NumResources = {};
428
429 /*56 */ Uint32 m_NumImmutableSamplers = 0;
430 /*60 */ SHADER_TYPE m_ShaderType = SHADER_TYPE_UNKNOWN;
431 /*64 */ bool m_IsUsingSeparateSamplers = false;
432
433 /*72 */ // End of class
437 /* 8 */ std::unique_ptr<void, STDDeleterRawMem<void> > m_ResourceBuffer;
438
439 /*24 */ std::array<Uint16, SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES+1> m_NumResources = {};
440
441 /*32 */ Uint16 m_NumImmutableSamplers = 0;
442 /*34 */ bool m_IsUsingSeparateSamplers = false;
443 /*36 */ SHADER_TYPE m_ShaderType = SHADER_TYPE_UNKNOWN;
444
445 /*40 */ // End of class
434446 // clang-format on
435447 };
436448
251251 GetFeatureState(EngineCI.Features.Feature, IsFeatureSupported, FeatureName); \
252252 } while (false)
253253
254 ENABLE_FEATURE(DeviceExtFeatures.MeshShader.taskShader != VK_FALSE && DeviceExtFeatures.MeshShader.meshShader != VK_FALSE, MeshShaders, "Mesh shaders are");
255
254 const auto& MeshShaderFeats = DeviceExtFeatures.MeshShader;
255 ENABLE_FEATURE(MeshShaderFeats.taskShader != VK_FALSE && MeshShaderFeats.meshShader != VK_FALSE, MeshShaders, "Mesh shaders are");
256
257 const auto& ShaderFloat16Int8Feats = DeviceExtFeatures.ShaderFloat16Int8;
256258 // clang-format off
257 ENABLE_FEATURE(DeviceExtFeatures.ShaderFloat16Int8.shaderFloat16 != VK_FALSE, ShaderFloat16, "16-bit float shader operations are");
258 ENABLE_FEATURE(DeviceExtFeatures.ShaderFloat16Int8.shaderInt8 != VK_FALSE, ShaderInt8, "8-bit int shader operations are");
259 ENABLE_FEATURE(ShaderFloat16Int8Feats.shaderFloat16 != VK_FALSE, ShaderFloat16, "16-bit float shader operations are");
260 ENABLE_FEATURE(ShaderFloat16Int8Feats.shaderInt8 != VK_FALSE, ShaderInt8, "8-bit int shader operations are");
259261 // clang-format on
260262
263 const auto& Storage16BitFeats = DeviceExtFeatures.Storage16Bit;
261264 // clang-format off
262 ENABLE_FEATURE(DeviceExtFeatures.Storage16Bit.storageBuffer16BitAccess != VK_FALSE, ResourceBuffer16BitAccess, "16-bit resoure buffer access is");
263 ENABLE_FEATURE(DeviceExtFeatures.Storage16Bit.uniformAndStorageBuffer16BitAccess != VK_FALSE, UniformBuffer16BitAccess, "16-bit uniform buffer access is");
264 ENABLE_FEATURE(DeviceExtFeatures.Storage16Bit.storageInputOutput16 != VK_FALSE, ShaderInputOutput16, "16-bit shader inputs/outputs are");
265 ENABLE_FEATURE(Storage16BitFeats.storageBuffer16BitAccess != VK_FALSE, ResourceBuffer16BitAccess, "16-bit resoure buffer access is");
266 ENABLE_FEATURE(Storage16BitFeats.uniformAndStorageBuffer16BitAccess != VK_FALSE, UniformBuffer16BitAccess, "16-bit uniform buffer access is");
267 ENABLE_FEATURE(Storage16BitFeats.storageInputOutput16 != VK_FALSE, ShaderInputOutput16, "16-bit shader inputs/outputs are");
265268 // clang-format on
266269
270 const auto& Storage8BitFeats = DeviceExtFeatures.Storage8Bit;
267271 // clang-format off
268 ENABLE_FEATURE(DeviceExtFeatures.Storage8Bit.storageBuffer8BitAccess != VK_FALSE, ResourceBuffer8BitAccess, "8-bit resoure buffer access is");
269 ENABLE_FEATURE(DeviceExtFeatures.Storage8Bit.uniformAndStorageBuffer8BitAccess != VK_FALSE, UniformBuffer8BitAccess, "8-bit uniform buffer access is");
272 ENABLE_FEATURE(Storage8BitFeats.storageBuffer8BitAccess != VK_FALSE, ResourceBuffer8BitAccess, "8-bit resoure buffer access is");
273 ENABLE_FEATURE(Storage8BitFeats.uniformAndStorageBuffer8BitAccess != VK_FALSE, UniformBuffer8BitAccess, "8-bit uniform buffer access is");
270274 // clang-format on
271275
272276 ENABLE_FEATURE((DeviceExtFeatures.RayTracing.rayTracing != VK_FALSE && DeviceExtFeatures.Spirv14) || DeviceExtFeatures.RayTracingNV, RayTracing, "Ray tracing is");
285289 // Mesh shader
286290 if (EngineCI.Features.MeshShaders != DEVICE_FEATURE_STATE_DISABLED)
287291 {
288 EnabledExtFeats.MeshShader = DeviceExtFeatures.MeshShader;
292 EnabledExtFeats.MeshShader = MeshShaderFeats;
289293 VERIFY_EXPR(EnabledExtFeats.MeshShader.taskShader != VK_FALSE && EnabledExtFeats.MeshShader.meshShader != VK_FALSE);
290294 VERIFY(PhysicalDevice->IsExtensionSupported(VK_NV_MESH_SHADER_EXTENSION_NAME),
291295 "VK_NV_mesh_shader extension must be supported as it has already been checked by VulkanPhysicalDevice and "
298302 if (EngineCI.Features.ShaderFloat16 != DEVICE_FEATURE_STATE_DISABLED ||
299303 EngineCI.Features.ShaderInt8 != DEVICE_FEATURE_STATE_DISABLED)
300304 {
301 EnabledExtFeats.ShaderFloat16Int8 = DeviceExtFeatures.ShaderFloat16Int8;
305 EnabledExtFeats.ShaderFloat16Int8 = ShaderFloat16Int8Feats;
302306 VERIFY_EXPR(EnabledExtFeats.ShaderFloat16Int8.shaderFloat16 != VK_FALSE || EnabledExtFeats.ShaderFloat16Int8.shaderInt8 != VK_FALSE);
303307 VERIFY(PhysicalDevice->IsExtensionSupported(VK_KHR_SHADER_FLOAT16_INT8_EXTENSION_NAME),
304308 "VK_KHR_shader_float16_int8 extension must be supported as it has already been checked by VulkanPhysicalDevice "
323327 // clang-format on
324328 {
325329 // clang-format off
326 EnabledExtFeats.Storage16Bit = DeviceExtFeatures.Storage16Bit;
330 EnabledExtFeats.Storage16Bit = Storage16BitFeats;
327331 VERIFY_EXPR(EngineCI.Features.ResourceBuffer16BitAccess == DEVICE_FEATURE_STATE_DISABLED || EnabledExtFeats.Storage16Bit.storageBuffer16BitAccess != VK_FALSE);
328332 VERIFY_EXPR(EngineCI.Features.UniformBuffer16BitAccess == DEVICE_FEATURE_STATE_DISABLED || EnabledExtFeats.Storage16Bit.uniformAndStorageBuffer16BitAccess != VK_FALSE);
329333 VERIFY_EXPR(EngineCI.Features.ShaderInputOutput16 == DEVICE_FEATURE_STATE_DISABLED || EnabledExtFeats.Storage16Bit.storageInputOutput16 != VK_FALSE);
359363 // clang-format on
360364 {
361365 // clang-format off
362 EnabledExtFeats.Storage8Bit = DeviceExtFeatures.Storage8Bit;
366 EnabledExtFeats.Storage8Bit = Storage8BitFeats;
363367 VERIFY_EXPR(EngineCI.Features.ResourceBuffer8BitAccess == DEVICE_FEATURE_STATE_DISABLED || EnabledExtFeats.Storage8Bit.storageBuffer8BitAccess != VK_FALSE);
364368 VERIFY_EXPR(EngineCI.Features.UniformBuffer8BitAccess == DEVICE_FEATURE_STATE_DISABLED || EnabledExtFeats.Storage8Bit.uniformAndStorageBuffer8BitAccess != VK_FALSE);
365369 // clang-format on
432432 }
433433
434434 void PipelineLayout::PrepareDescriptorSets(DeviceContextVkImpl* pCtxVkImpl,
435 VkPipelineBindPoint BindPoint,
435436 const ShaderResourceCacheVk& ResourceCache,
436437 DescriptorSetBindInfo& BindInfo,
437438 VkDescriptorSet VkDynamicDescrSet) const
477478 BindInfo.DynamicOffsetCount = TotalDynamicDescriptors;
478479 if (TotalDynamicDescriptors > BindInfo.DynamicOffsets.size())
479480 BindInfo.DynamicOffsets.resize(TotalDynamicDescriptors);
481 BindInfo.BindPoint = BindPoint;
480482 BindInfo.pResourceCache = &ResourceCache;
481483 #ifdef DILIGENT_DEBUG
482484 BindInfo.pDbgPipelineLayout = this;
128128 }
129129
130130
131 void CreateComputePipeline(RenderDeviceVkImpl* pDeviceVk,
132 std::vector<VkPipelineShaderStageCreateInfo>& Stages,
133 const PipelineLayout& Layout,
134 const PipelineStateDesc& PSODesc,
135 VulkanUtilities::PipelineWrapper& Pipeline)
131 static void CreateComputePipeline(RenderDeviceVkImpl* pDeviceVk,
132 std::vector<VkPipelineShaderStageCreateInfo>& Stages,
133 const PipelineLayout& Layout,
134 const PipelineStateDesc& PSODesc,
135 VulkanUtilities::PipelineWrapper& Pipeline)
136136 {
137137 const auto& LogicalDevice = pDeviceVk->GetLogicalDevice();
138138
153153 }
154154
155155
156 void CreateGraphicsPipeline(RenderDeviceVkImpl* pDeviceVk,
157 std::vector<VkPipelineShaderStageCreateInfo>& Stages,
158 const PipelineLayout& Layout,
159 const PipelineStateDesc& PSODesc,
160 const GraphicsPipelineDesc& GraphicsPipeline,
161 VulkanUtilities::PipelineWrapper& Pipeline,
162 RefCntAutoPtr<IRenderPass>& pRenderPass)
156 static void CreateGraphicsPipeline(RenderDeviceVkImpl* pDeviceVk,
157 std::vector<VkPipelineShaderStageCreateInfo>& Stages,
158 const PipelineLayout& Layout,
159 const PipelineStateDesc& PSODesc,
160 const GraphicsPipelineDesc& GraphicsPipeline,
161 VulkanUtilities::PipelineWrapper& Pipeline,
162 RefCntAutoPtr<IRenderPass>& pRenderPass)
163163 {
164164 const auto& LogicalDevice = pDeviceVk->GetLogicalDevice();
165165 const auto& PhysicalDevice = pDeviceVk->GetPhysicalDevice();
337337 }
338338
339339
340 void CreateRayTracingPipeline(RenderDeviceVkImpl* pDeviceVk,
341 std::vector<VkPipelineShaderStageCreateInfo>& Stages,
342 const std::vector<VkRayTracingShaderGroupCreateInfoKHR>& ShaderGroups,
343 const PipelineLayout& Layout,
344 const PipelineStateDesc& PSODesc,
345 const RayTracingPipelineDesc& RayTracingPipeline,
346 VulkanUtilities::PipelineWrapper& Pipeline)
340 static void CreateRayTracingPipeline(RenderDeviceVkImpl* pDeviceVk,
341 std::vector<VkPipelineShaderStageCreateInfo>& Stages,
342 const std::vector<VkRayTracingShaderGroupCreateInfoKHR>& ShaderGroups,
343 const PipelineLayout& Layout,
344 const PipelineStateDesc& PSODesc,
345 const RayTracingPipelineDesc& RayTracingPipeline,
346 VulkanUtilities::PipelineWrapper& Pipeline)
347347 {
348348 const auto& LogicalDevice = pDeviceVk->GetLogicalDevice();
349349 const auto& PhysicalDevice = pDeviceVk->GetPhysicalDevice();
409409
410410 for (Uint32 i = 0; i < CreateInfo.GeneralShaderCount; ++i)
411411 {
412 const auto& GeneralShader = CreateInfo.pGeneralShaders[i];
413
412414 VkRayTracingShaderGroupCreateInfoKHR Group = {};
413415
414416 Group.sType = VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_KHR;
415417 Group.type = VK_RAY_TRACING_SHADER_GROUP_TYPE_GENERAL_KHR;
416 Group.generalShader = ShaderToIndex(CreateInfo.pGeneralShaders[i].pShader);
418 Group.generalShader = ShaderToIndex(GeneralShader.pShader);
417419 Group.closestHitShader = VK_SHADER_UNUSED_KHR;
418420 Group.anyHitShader = VK_SHADER_UNUSED_KHR;
419421 Group.intersectionShader = VK_SHADER_UNUSED_KHR;
420422
421 bool IsUniqueName = NameToGroupIndex.emplace(HashMapStringKey{MemPool.CopyString(CreateInfo.pGeneralShaders[i].Name)}, GroupIndex++).second;
423 bool IsUniqueName = NameToGroupIndex.emplace(HashMapStringKey{MemPool.CopyString(GeneralShader.Name)}, GroupIndex++).second;
422424