Diligent Engine  v.2.4.g
ShaderResources.hpp
Go to the documentation of this file.
1 /*
2  * Copyright 2019-2021 Diligent Graphics LLC
3  * Copyright 2015-2019 Egor Yusov
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  * In no event and under no legal theory, whether in tort (including negligence),
18  * contract, or otherwise, unless required by applicable law (such as deliberate
19  * and grossly negligent acts) or agreed to in writing, shall any Contributor be
20  * liable for any damages, including any direct, indirect, special, incidental,
21  * or consequential damages of any character arising as a result of this License or
22  * out of the use or inability to use the software (including but not limited to damages
23  * for loss of goodwill, work stoppage, computer failure or malfunction, or any and
24  * all other commercial damages or losses), even if such Contributor has been advised
25  * of the possibility of such damages.
26  */
27 
28 #pragma once
29 
33 
34 // ShaderResources class uses continuous chunk of memory to store all resources, as follows:
35 //
36 //
37 // m_MemoryBuffer m_TexSRVOffset m_TexUAVOffset m_BufSRVOffset m_BufUAVOffset m_SamplersOffset m_MemorySize
38 // | | | | | | | |
39 // | CB[0] ... CB[Ncb-1] | TexSRV[0] ... TexSRV[Ntsrv-1] | TexUAV[0] ... TexUAV[Ntuav-1] | BufSRV[0] ... BufSRV[Nbsrv-1] | BufUAV[0] ... BufUAV[Nbuav-1] | Sam[0] ... Sam[Nsam-1] | Resource Names |
40 //
41 // Ncb - number of constant buffers
42 // Ntsrv - number of texture SRVs
43 // Ntuav - number of texture UAVs
44 // Nbsrv - number of buffer SRVs
45 // Nbuav - number of buffer UAVs
46 // Nsam - number of samplers
47 //
48 //
49 // If texture SRV is assigned a sampler, it is cross-referenced through SamplerOrTexSRVId:
50 //
51 // _____________________SamplerOrTexSRVId___________________
52 // | |
53 // | V
54 // | CBs | ... TexSRV[n] ... | TexUAVs | BufSRVs | BufUAVs | Sam[0] ... Sam[SamplerId] ... |
55 // A |
56 // '---------------------SamplerOrTexSRVId-------------------'
57 //
58 
59 #include <memory>
60 
61 #define NOMINMAX
62 #include <d3dcommon.h>
63 
64 #ifndef NTDDI_WIN10_VB // First defined in Win SDK 10.0.19041.0
65 # define D3D_SIT_RTACCELERATIONSTRUCTURE (D3D_SIT_UAV_RWSTRUCTURED_WITH_COUNTER + 1)
66 #endif
67 
68 #include "ShaderD3D.h"
69 #include "STDAllocator.hpp"
70 #include "HashUtils.hpp"
71 #include "StringPool.hpp"
73 #include "PipelineState.h"
75 
76 namespace Diligent
77 {
78 
79 // sizeof(D3DShaderResourceAttribs) == 16 (x64)
81 {
82  // clang-format off
83 
84 /* 0 */ const char* const Name;
85 
86 /* 8 */ const Uint16 BindPoint;
87 /*10 */ const Uint16 BindCount;
88 
89  // 4 4 24
90  // bit | 0 1 2 3 | 4 5 6 7 | 8 9 10 ... 31 |
91  // | | | |
92  // | InputType | SRV Dim | SamplerOrTexSRVIdBits |
93  static constexpr const Uint32 ShaderInputTypeBits = 4;
94  static constexpr const Uint32 SRVDimBits = 4;
95  static constexpr const Uint32 SamplerOrTexSRVIdBits = 24;
96  static_assert(ShaderInputTypeBits + SRVDimBits + SamplerOrTexSRVIdBits == 32, "Attributes are better be packed into 32 bits");
97 
98  static_assert(D3D_SIT_UAV_RWSTRUCTURED_WITH_COUNTER < (1 << ShaderInputTypeBits), "Not enough bits to represent D3D_SHADER_INPUT_TYPE");
99  static_assert(D3D_SRV_DIMENSION_BUFFEREX < (1 << SRVDimBits), "Not enough bits to represent D3D_SRV_DIMENSION");
100 
101 private:
102  // We need to use Uint32 instead of the actual type for reliability and correctness.
103  // There originally was a problem when the type of InputType was D3D_SHADER_INPUT_TYPE:
104  // the value of D3D_SIT_UAV_RWBYTEADDRESS (8) was interpreted as -8 (as the underlying enum type
105  // is signed) causing errors
106 /*12.0*/ const Uint32 InputType : ShaderInputTypeBits; // Max value: D3D_SIT_UAV_RWSTRUCTURED_WITH_COUNTER == 11
107 /*12.4*/ const Uint32 SRVDimension : SRVDimBits; // Max value: D3D_SRV_DIMENSION_BUFFEREX == 11
108 /*13.0*/ Uint32 SamplerOrTexSRVId : SamplerOrTexSRVIdBits; // Max value: 2^24-1
109 /*16 */ // End of structure
110 
111  // clang-format on
112 
113 public:
114  static constexpr const Uint32 InvalidSamplerId = (1U << SamplerOrTexSRVIdBits) - 1U;
115  static constexpr const Uint32 MaxSamplerId = InvalidSamplerId - 1;
116  static constexpr const Uint32 InvalidTexSRVId = (1U << SamplerOrTexSRVIdBits) - 1U;
118  static constexpr const Uint16 MaxBindPoint = InvalidBindPoint - 1;
120 
121 
122  D3DShaderResourceAttribs(const char* _Name,
123  UINT _BindPoint,
124  UINT _BindCount,
125  D3D_SHADER_INPUT_TYPE _InputType,
126  D3D_SRV_DIMENSION _SRVDimension,
127  Uint32 _SamplerId) noexcept :
128  // clang-format off
129  Name {_Name},
130  BindPoint {static_cast<decltype(BindPoint)> (_BindPoint) },
131  BindCount {static_cast<decltype(BindCount)> (_BindCount) },
132  InputType {static_cast<decltype(InputType)> (_InputType) },
133  SRVDimension {static_cast<decltype(SRVDimension)>(_SRVDimension)},
134  SamplerOrTexSRVId {_SamplerId}
135  // clang-format on
136  {
137 #ifdef DILIGENT_DEBUG
138  // clang-format off
139  VERIFY(_BindPoint <= MaxBindPoint || _BindPoint == InvalidBindPoint, "Bind Point is out of allowed range");
140  VERIFY(_BindCount <= MaxBindCount, "Bind Count is out of allowed range");
141  VERIFY(_InputType < (1 << ShaderInputTypeBits), "Shader input type is out of expected range");
142  VERIFY(_SRVDimension < (1 << SRVDimBits), "SRV dimensions is out of expected range");
143  VERIFY(_SamplerId < (1 << SamplerOrTexSRVIdBits), "SamplerOrTexSRVId is out of representable range");
144  // clang-format on
145 
146  if (_InputType == D3D_SIT_TEXTURE && _SRVDimension != D3D_SRV_DIMENSION_BUFFER)
147  VERIFY_EXPR(GetCombinedSamplerId() == _SamplerId);
148  else
149  VERIFY(_SamplerId == InvalidSamplerId, "Only texture SRV can be assigned a valid texture sampler");
150 #endif
151  }
152 
153  D3DShaderResourceAttribs(StringPool& NamesPool, const D3DShaderResourceAttribs& rhs, Uint32 _SamplerId, Uint32 _BindPoint) noexcept :
154  // clang-format off
156  {
157  NamesPool.CopyString(rhs.Name),
158  _BindPoint,
159  rhs.BindCount,
160  rhs.GetInputType(),
161  rhs.GetSRVDimension(),
162  _SamplerId
163  }
164  // clang-format on
165  {
166  VERIFY(_SamplerId == InvalidSamplerId || (GetInputType() == D3D_SIT_TEXTURE && GetSRVDimension() != D3D_SRV_DIMENSION_BUFFER),
167  "Only texture SRV can be assigned a valid texture sampler");
168  }
169 
171  // clang-format off
173  {
174  NamesPool.CopyString(rhs.Name),
175  rhs.BindPoint,
176  rhs.BindCount,
177  rhs.GetInputType(),
178  rhs.GetSRVDimension(),
179  rhs.SamplerOrTexSRVId
180  }
181  // clang-format on
182  {
183  }
184 
185  // clang-format off
187  D3DShaderResourceAttribs ( D3DShaderResourceAttribs&& rhs) = default; // Required for vector<D3DShaderResourceAttribs>
190  // clang-format on
191 
192  D3D_SHADER_INPUT_TYPE GetInputType() const
193  {
194  return static_cast<D3D_SHADER_INPUT_TYPE>(InputType);
195  }
196 
197  D3D_SRV_DIMENSION GetSRVDimension() const
198  {
199  return static_cast<D3D_SRV_DIMENSION>(SRVDimension);
200  }
201 
203  {
205  }
206 
207  bool IsMultisample() const;
208 
210  {
211  return GetInputType() == D3D_SIT_TEXTURE && SamplerOrTexSRVId != InvalidSamplerId;
212  }
213 
214  bool IsCombinedWithTexSRV() const
215  {
216  return GetCombinedTexSRVId() != InvalidTexSRVId;
217  }
218 
219  bool IsValidBindPoint() const
220  {
221  return BindPoint != InvalidBindPoint;
222  }
223 
224  bool IsCompatibleWith(const D3DShaderResourceAttribs& Attribs) const
225  {
226  return BindPoint == Attribs.BindPoint &&
227  BindCount == Attribs.BindCount &&
228  InputType == Attribs.InputType &&
229  SRVDimension == Attribs.SRVDimension &&
230  SamplerOrTexSRVId == Attribs.SamplerOrTexSRVId;
231  }
232 
233  size_t GetHash() const
234  {
235  return ComputeHash(BindPoint, BindCount, InputType, SRVDimension, SamplerOrTexSRVId);
236  }
237 
239 
241  {
242  VERIFY(GetInputType() == D3D_SIT_TEXTURE && GetSRVDimension() != D3D_SRV_DIMENSION_BUFFER, "Invalid input type: D3D_SIT_TEXTURE is expected");
243  return SamplerOrTexSRVId;
244  }
245 
246 private:
247  friend class ShaderResources;
248 
249  void SetTexSRVId(Uint32 TexSRVId)
250  {
251  VERIFY(GetInputType() == D3D_SIT_SAMPLER, "Invalid input type: D3D_SIT_SAMPLER is expected");
252  VERIFY(TexSRVId < (1 << SamplerOrTexSRVIdBits), "TexSRVId (", TexSRVId, ") is out of representable range");
253  SamplerOrTexSRVId = TexSRVId;
254  }
255 
256  Uint32 GetCombinedTexSRVId() const
257  {
258  VERIFY(GetInputType() == D3D_SIT_SAMPLER, "Invalid input type: D3D_SIT_SAMPLER is expected");
259  return SamplerOrTexSRVId;
260  }
261 };
262 static_assert(sizeof(D3DShaderResourceAttribs) == sizeof(void*) + sizeof(Uint32) * 2, "Unexpected sizeof(D3DShaderResourceAttribs)");
263 
264 
267 {
268 public:
270  m_ShaderType{ShaderType}
271  {
272  }
273 
274  // clang-format off
275  ShaderResources (const ShaderResources&) = delete;
276  ShaderResources ( ShaderResources&&) = delete;
277  ShaderResources& operator = (const ShaderResources&) = delete;
279  // clang-format on
280 
282 
283  // clang-format off
284  Uint32 GetNumCBs() const noexcept { return (m_TexSRVOffset - 0); }
285  Uint32 GetNumTexSRV() const noexcept { return (m_TexUAVOffset - m_TexSRVOffset); }
286  Uint32 GetNumTexUAV() const noexcept { return (m_BufSRVOffset - m_TexUAVOffset); }
287  Uint32 GetNumBufSRV() const noexcept { return (m_BufUAVOffset - m_BufSRVOffset); }
288  Uint32 GetNumBufUAV() const noexcept { return (m_SamplersOffset - m_BufUAVOffset); }
289  Uint32 GetNumSamplers() const noexcept { return (m_AccelStructsOffset - m_SamplersOffset); }
290  Uint32 GetNumAccelStructs()const noexcept { return (m_TotalResources - m_AccelStructsOffset); }
291  Uint32 GetTotalResources() const noexcept { return m_TotalResources; }
292 
293  const D3DShaderResourceAttribs& GetCB (Uint32 n)const noexcept { return GetResAttribs(n, GetNumCBs(), 0); }
294  const D3DShaderResourceAttribs& GetTexSRV (Uint32 n)const noexcept { return GetResAttribs(n, GetNumTexSRV(), m_TexSRVOffset); }
295  const D3DShaderResourceAttribs& GetTexUAV (Uint32 n)const noexcept { return GetResAttribs(n, GetNumTexUAV(), m_TexUAVOffset); }
296  const D3DShaderResourceAttribs& GetBufSRV (Uint32 n)const noexcept { return GetResAttribs(n, GetNumBufSRV(), m_BufSRVOffset); }
297  const D3DShaderResourceAttribs& GetBufUAV (Uint32 n)const noexcept { return GetResAttribs(n, GetNumBufUAV(), m_BufUAVOffset); }
298  const D3DShaderResourceAttribs& GetSampler (Uint32 n)const noexcept { return GetResAttribs(n, GetNumSamplers(), m_SamplersOffset); }
299  const D3DShaderResourceAttribs& GetAccelStruct(Uint32 n)const noexcept { return GetResAttribs(n, GetNumAccelStructs(), m_AccelStructsOffset); }
300  // clang-format on
301 
303  {
304  VERIFY(TexSRV.IsCombinedWithSampler(), "This texture SRV is not combined with any sampler");
305  return GetSampler(TexSRV.GetCombinedSamplerId());
306  }
307 
309  {
310  VERIFY(Sampler.IsCombinedWithTexSRV(), "This sampler is not combined with any texture SRV");
311  return GetTexSRV(Sampler.GetCombinedTexSRVId());
312  }
313 
314  SHADER_TYPE GetShaderType() const noexcept { return m_ShaderType; }
315 
317 
318  template <typename THandleCB,
319  typename THandleSampler,
320  typename THandleTexSRV,
321  typename THandleTexUAV,
322  typename THandleBufSRV,
323  typename THandleBufUAV,
324  typename THandleAccelStruct>
325  void ProcessResources(THandleCB HandleCB,
326  THandleSampler HandleSampler,
327  THandleTexSRV HandleTexSRV,
328  THandleTexUAV HandleTexUAV,
329  THandleBufSRV HandleBufSRV,
330  THandleBufUAV HandleBufUAV,
331  THandleAccelStruct HandleAccelStruct) const
332  {
333  for (Uint32 n = 0; n < GetNumCBs(); ++n)
334  {
335  const auto& CB = GetCB(n);
336  HandleCB(CB, n);
337  }
338 
339  for (Uint32 n = 0; n < GetNumSamplers(); ++n)
340  {
341  const auto& Sampler = GetSampler(n);
342  HandleSampler(Sampler, n);
343  }
344 
345  for (Uint32 n = 0; n < GetNumTexSRV(); ++n)
346  {
347  const auto& TexSRV = GetTexSRV(n);
348  HandleTexSRV(TexSRV, n);
349  }
350 
351  for (Uint32 n = 0; n < GetNumTexUAV(); ++n)
352  {
353  const auto& TexUAV = GetTexUAV(n);
354  HandleTexUAV(TexUAV, n);
355  }
356 
357  for (Uint32 n = 0; n < GetNumBufSRV(); ++n)
358  {
359  const auto& BufSRV = GetBufSRV(n);
360  HandleBufSRV(BufSRV, n);
361  }
362 
363  for (Uint32 n = 0; n < GetNumBufUAV(); ++n)
364  {
365  const auto& BufUAV = GetBufUAV(n);
366  HandleBufUAV(BufUAV, n);
367  }
368 
369  for (Uint32 n = 0; n < GetNumAccelStructs(); ++n)
370  {
371  const auto& AS = GetAccelStruct(n);
372  HandleAccelStruct(AS, n);
373  }
374  }
375  template <typename THandler>
376  void ProcessResources(THandler Handler) const
377  {
378  ProcessResources(Handler, Handler, Handler, Handler, Handler, Handler, Handler);
379  }
380 
381  bool IsCompatibleWith(const ShaderResources& Resources) const;
382  bool IsUsingCombinedTextureSamplers() const { return m_SamplerSuffix != nullptr; }
383  const char* GetCombinedSamplerSuffix() const { return m_SamplerSuffix; }
384  const Char* GetShaderName() const { return m_ShaderName; }
385 
386  size_t GetHash() const;
387 
388 #ifdef DILIGENT_DEVELOPMENT
389  static void DvpVerifyResourceLayout(const PipelineResourceLayoutDesc& ResourceLayout,
390  const ShaderResources* const pShaderResources[],
391  Uint32 NumShaders,
392  bool VerifyVariables,
393  bool VerifyImmutableSamplers) noexcept;
394 #endif
395 
396  void GetShaderModel(Uint32& Major, Uint32& Minor) const
397  {
398  Major = (m_ShaderVersion & 0x000000F0) >> 4;
399  Minor = (m_ShaderVersion & 0x0000000F);
400  }
401 
402 protected:
403  template <typename D3D_SHADER_DESC,
404  typename D3D_SHADER_INPUT_BIND_DESC,
405  typename TShaderReflection,
406  typename TNewResourceHandler>
407  void Initialize(TShaderReflection* pShaderReflection,
408  TNewResourceHandler NewResHandler,
409  const Char* ShaderName,
410  const Char* SamplerSuffix);
411 
412 
413  __forceinline D3DShaderResourceAttribs& GetResAttribs(Uint32 n, Uint32 NumResources, Uint32 Offset) noexcept
414  {
415  VERIFY(n < NumResources, "Resource index (", n, ") is out of range. Resource array size: ", NumResources);
416  VERIFY_EXPR(Offset + n < m_TotalResources);
417  return reinterpret_cast<D3DShaderResourceAttribs*>(m_MemoryBuffer.get())[Offset + n];
418  }
419 
420  __forceinline const D3DShaderResourceAttribs& GetResAttribs(Uint32 n, Uint32 NumResources, Uint32 Offset) const noexcept
421  {
422  VERIFY(n < NumResources, "Resource index (", n, ") is out of range. Resource array size: ", NumResources);
423  VERIFY_EXPR(Offset + n < m_TotalResources);
424  return reinterpret_cast<const D3DShaderResourceAttribs*>(m_MemoryBuffer.get())[Offset + n];
425  }
426 
427  // clang-format off
428  D3DShaderResourceAttribs& GetCB(Uint32 n) noexcept { return GetResAttribs(n, GetNumCBs(), 0); }
429  D3DShaderResourceAttribs& GetTexSRV(Uint32 n) noexcept { return GetResAttribs(n, GetNumTexSRV(), m_TexSRVOffset); }
430  D3DShaderResourceAttribs& GetTexUAV(Uint32 n) noexcept { return GetResAttribs(n, GetNumTexUAV(), m_TexUAVOffset); }
431  D3DShaderResourceAttribs& GetBufSRV(Uint32 n) noexcept { return GetResAttribs(n, GetNumBufSRV(), m_BufSRVOffset); }
432  D3DShaderResourceAttribs& GetBufUAV(Uint32 n) noexcept { return GetResAttribs(n, GetNumBufUAV(), m_BufUAVOffset); }
433  D3DShaderResourceAttribs& GetSampler(Uint32 n) noexcept { return GetResAttribs(n, GetNumSamplers(), m_SamplersOffset); }
434  D3DShaderResourceAttribs& GetAccelStruct(Uint32 n)noexcept { return GetResAttribs(n, GetNumAccelStructs(), m_AccelStructsOffset); }
435  // clang-format on
436 
437 private:
438  void AllocateMemory(IMemoryAllocator& Allocator,
439  const D3DShaderResourceCounters& ResCounters,
440  size_t ResourceNamesPoolSize,
441  StringPool& ResourceNamesPool);
442 
443  Uint32 FindAssignedSamplerId(const D3DShaderResourceAttribs& TexSRV, const char* SamplerSuffix) const;
444 
445  // Memory buffer that holds all resources as continuous chunk of memory:
446  // | CBs | TexSRVs | TexUAVs | BufSRVs | BufUAVs | Samplers | Resource Names |
447  //
448 
449  std::unique_ptr<void, STDDeleterRawMem<void>> m_MemoryBuffer;
450 
451  const char* m_SamplerSuffix = nullptr; // The suffix and the shader name
452  const char* m_ShaderName = nullptr; // are put into the Resource Names section
453 
454  // Offsets in elements of D3DShaderResourceAttribs
455  typedef Uint16 OffsetType;
456  OffsetType m_TexSRVOffset = 0;
457  OffsetType m_TexUAVOffset = 0;
458  OffsetType m_BufSRVOffset = 0;
459  OffsetType m_BufUAVOffset = 0;
460  OffsetType m_SamplersOffset = 0;
461  OffsetType m_AccelStructsOffset = 0;
462  OffsetType m_TotalResources = 0;
463 
464  const SHADER_TYPE m_ShaderType;
465 
466  Uint32 m_ShaderVersion = 0;
467 };
468 
469 
470 template <typename D3D_SHADER_DESC,
471  typename D3D_SHADER_INPUT_BIND_DESC,
472  typename TShaderReflection,
473  typename TNewResourceHandler>
474 void ShaderResources::Initialize(TShaderReflection* pShaderReflection,
475  TNewResourceHandler NewResHandler,
476  const Char* ShaderName,
477  const Char* CombinedSamplerSuffix)
478 {
479  Uint32 CurrCB = 0, CurrTexSRV = 0, CurrTexUAV = 0, CurrBufSRV = 0, CurrBufUAV = 0, CurrSampler = 0, CurrAS = 0;
480 
481  // Resource names pool is only needed to facilitate string allocation.
482  StringPool ResourceNamesPool;
483 
484  LoadD3DShaderResources<D3D_SHADER_DESC, D3D_SHADER_INPUT_BIND_DESC>(
485  pShaderReflection,
486 
487  [&](const D3D_SHADER_DESC& d3dShaderDesc) //
488  {
489  m_ShaderVersion = d3dShaderDesc.Version;
490  },
491 
492  [&](const D3DShaderResourceCounters& ResCounters, size_t ResourceNamesPoolSize) //
493  {
494  VERIFY_EXPR(ShaderName != nullptr);
495  ResourceNamesPoolSize += strlen(ShaderName) + 1;
496 
497  if (CombinedSamplerSuffix != nullptr)
498  ResourceNamesPoolSize += strlen(CombinedSamplerSuffix) + 1;
499 
500  AllocateMemory(GetRawAllocator(), ResCounters, ResourceNamesPoolSize, ResourceNamesPool);
501  },
502 
503  [&](const D3DShaderResourceAttribs& CBAttribs) //
504  {
505  VERIFY_EXPR(CBAttribs.GetInputType() == D3D_SIT_CBUFFER);
506  auto* pNewCB = new (&GetCB(CurrCB++)) D3DShaderResourceAttribs{ResourceNamesPool, CBAttribs};
507  NewResHandler.OnNewCB(*pNewCB);
508  },
509 
510  [&](const D3DShaderResourceAttribs& TexUAV) //
511  {
512  VERIFY_EXPR(TexUAV.GetInputType() == D3D_SIT_UAV_RWTYPED && TexUAV.GetSRVDimension() != D3D_SRV_DIMENSION_BUFFER);
513  auto* pNewTexUAV = new (&GetTexUAV(CurrTexUAV++)) D3DShaderResourceAttribs{ResourceNamesPool, TexUAV};
514  NewResHandler.OnNewTexUAV(*pNewTexUAV);
515  },
516 
517  [&](const D3DShaderResourceAttribs& BuffUAV) //
518  {
519  VERIFY_EXPR(BuffUAV.GetInputType() == D3D_SIT_UAV_RWTYPED && BuffUAV.GetSRVDimension() == D3D_SRV_DIMENSION_BUFFER || BuffUAV.GetInputType() == D3D_SIT_UAV_RWSTRUCTURED || BuffUAV.GetInputType() == D3D_SIT_UAV_RWBYTEADDRESS);
520  auto* pNewBufUAV = new (&GetBufUAV(CurrBufUAV++)) D3DShaderResourceAttribs{ResourceNamesPool, BuffUAV};
521  NewResHandler.OnNewBuffUAV(*pNewBufUAV);
522  },
523 
524  [&](const D3DShaderResourceAttribs& BuffSRV) //
525  {
526  VERIFY_EXPR(BuffSRV.GetInputType() == D3D_SIT_TEXTURE && BuffSRV.GetSRVDimension() == D3D_SRV_DIMENSION_BUFFER || BuffSRV.GetInputType() == D3D_SIT_STRUCTURED || BuffSRV.GetInputType() == D3D_SIT_BYTEADDRESS);
527  auto* pNewBuffSRV = new (&GetBufSRV(CurrBufSRV++)) D3DShaderResourceAttribs{ResourceNamesPool, BuffSRV};
528  NewResHandler.OnNewBuffSRV(*pNewBuffSRV);
529  },
530 
531  [&](const D3DShaderResourceAttribs& SamplerAttribs) //
532  {
533  VERIFY_EXPR(SamplerAttribs.GetInputType() == D3D_SIT_SAMPLER);
534  auto* pNewSampler = new (&GetSampler(CurrSampler++)) D3DShaderResourceAttribs{ResourceNamesPool, SamplerAttribs};
535  NewResHandler.OnNewSampler(*pNewSampler);
536  },
537 
538  [&](const D3DShaderResourceAttribs& TexAttribs) //
539  {
540  VERIFY_EXPR(TexAttribs.GetInputType() == D3D_SIT_TEXTURE && TexAttribs.GetSRVDimension() != D3D_SRV_DIMENSION_BUFFER);
541  VERIFY(CurrSampler == GetNumSamplers(), "All samplers must be initialized before texture SRVs");
542 
543  auto SamplerId = CombinedSamplerSuffix != nullptr ? FindAssignedSamplerId(TexAttribs, CombinedSamplerSuffix) : D3DShaderResourceAttribs::InvalidSamplerId;
544  auto* pNewTexSRV = new (&GetTexSRV(CurrTexSRV)) D3DShaderResourceAttribs{ResourceNamesPool, TexAttribs, SamplerId, TexAttribs.BindPoint};
546  {
547  GetSampler(SamplerId).SetTexSRVId(CurrTexSRV);
548  }
549  ++CurrTexSRV;
550  NewResHandler.OnNewTexSRV(*pNewTexSRV);
551  },
552 
553  [&](const D3DShaderResourceAttribs& AccelStructAttribs) //
554  {
555  VERIFY_EXPR(AccelStructAttribs.GetInputType() == D3D_SIT_RTACCELERATIONSTRUCTURE);
556  auto* pNewAccelStruct = new (&GetAccelStruct(CurrAS++)) D3DShaderResourceAttribs{ResourceNamesPool, AccelStructAttribs};
557  NewResHandler.OnNewAccelStruct(*pNewAccelStruct);
558  } //
559  );
560 
561  m_ShaderName = ResourceNamesPool.CopyString(ShaderName);
562 
563  if (CombinedSamplerSuffix != nullptr)
564  {
565  m_SamplerSuffix = ResourceNamesPool.CopyString(CombinedSamplerSuffix);
566 
567 #ifdef DILIGENT_DEVELOPMENT
568  for (Uint32 n = 0; n < GetNumSamplers(); ++n)
569  {
570  const auto& Sampler = GetSampler(n);
571  if (!Sampler.IsCombinedWithTexSRV())
572  LOG_ERROR_MESSAGE("Shader '", ShaderName, "' uses combined texture samplers, but sampler '", Sampler.Name, "' is not assigned to any texture");
573  }
574 #endif
575  }
576 
577  VERIFY_EXPR(ResourceNamesPool.GetRemainingSize() == 0);
578  // clang-format off
579  VERIFY(CurrCB == GetNumCBs(), "Not all CBs are initialized which will cause a crash when ~D3DShaderResourceAttribs() is called");
580  VERIFY(CurrTexSRV == GetNumTexSRV(), "Not all Tex SRVs are initialized which will cause a crash when ~D3DShaderResourceAttribs() is called" );
581  VERIFY(CurrTexUAV == GetNumTexUAV(), "Not all Tex UAVs are initialized which will cause a crash when ~D3DShaderResourceAttribs() is called" );
582  VERIFY(CurrBufSRV == GetNumBufSRV(), "Not all Buf SRVs are initialized which will cause a crash when ~D3DShaderResourceAttribs() is called" );
583  VERIFY(CurrBufUAV == GetNumBufUAV(), "Not all Buf UAVs are initialized which will cause a crash when ~D3DShaderResourceAttribs() is called" );
584  VERIFY(CurrSampler == GetNumSamplers(), "Not all Samplers are initialized which will cause a crash when ~D3DShaderResourceAttribs() is called" );
585  VERIFY(CurrAS == GetNumAccelStructs(), "Not all Accel Structs are initialized which will cause a crash when ~D3DShaderResourceAttribs() is called" );
586  // clang-format on
587 }
588 
589 } // namespace Diligent
590 
591 namespace std
592 {
593 
594 template <>
595 struct hash<Diligent::D3DShaderResourceAttribs>
596 {
597  size_t operator()(const Diligent::D3DShaderResourceAttribs& Attribs) const
598  {
599  return Attribs.GetHash();
600  }
601 };
602 
603 template <>
604 struct hash<Diligent::ShaderResources>
605 {
606  size_t operator()(const Diligent::ShaderResources& Res) const
607  {
608  return Res.GetHash();
609  }
610 };
611 
612 } // namespace std
Diligent::D3DShaderResourceAttribs::BindPoint
const Uint16 BindPoint
Definition: ShaderResources.hpp:86
Diligent::D3DShaderResourceCounters
Definition: D3DShaderResourceLoader.hpp:43
LOG_ERROR_MESSAGE
#define LOG_ERROR_MESSAGE(...)
Definition: Errors.hpp:122
Diligent::Char
char Char
Definition: BasicTypes.h:64
Diligent::ShaderResources::operator=
ShaderResources & operator=(const ShaderResources &)=delete
Diligent::ShaderResources::GetCB
D3DShaderResourceAttribs & GetCB(Uint32 n) noexcept
Definition: ShaderResources.hpp:428
Diligent::SHADER_TYPE
SHADER_TYPE
Describes the shader type.
Definition: GraphicsTypes.h:65
Diligent::ShaderResources::GetTotalResources
Uint32 GetTotalResources() const noexcept
Definition: ShaderResources.hpp:291
Diligent::D3DShaderResourceAttribs::D3DShaderResourceAttribs
D3DShaderResourceAttribs(StringPool &NamesPool, const D3DShaderResourceAttribs &rhs, Uint32 _SamplerId, Uint32 _BindPoint) noexcept
Definition: ShaderResources.hpp:153
Diligent::StringPool::GetRemainingSize
size_t GetRemainingSize() const
Definition: StringPool.hpp:154
STDAllocator.hpp
Diligent::ShaderResources::GetNumCBs
Uint32 GetNumCBs() const noexcept
Definition: ShaderResources.hpp:284
Diligent::ShaderResources::GetNumBufSRV
Uint32 GetNumBufSRV() const noexcept
Definition: ShaderResources.hpp:287
Diligent::HLSLShaderResourceDesc
HLSL resource description.
Definition: ShaderD3D.h:46
Diligent::D3DShaderResourceAttribs::SamplerOrTexSRVIdBits
static constexpr const Uint32 SamplerOrTexSRVIdBits
Definition: ShaderResources.hpp:95
Diligent::D3DShaderResourceAttribs::GetCombinedSamplerId
Uint32 GetCombinedSamplerId() const
Definition: ShaderResources.hpp:240
Diligent::D3DShaderResourceAttribs::MaxBindCount
static constexpr const Uint16 MaxBindCount
Definition: ShaderResources.hpp:119
Diligent::ShaderResources::GetResAttribs
__forceinline D3DShaderResourceAttribs & GetResAttribs(Uint32 n, Uint32 NumResources, Uint32 Offset) noexcept
Definition: ShaderResources.hpp:413
Diligent::D3DShaderResourceAttribs::D3DShaderResourceAttribs
D3DShaderResourceAttribs(StringPool &NamesPool, const D3DShaderResourceAttribs &rhs) noexcept
Definition: ShaderResources.hpp:170
Diligent::StringPool::CopyString
Char * CopyString(const String &Str)
Definition: StringPool.hpp:124
Diligent::ShaderResources::GetShaderName
const Char * GetShaderName() const
Definition: ShaderResources.hpp:384
Diligent::D3DShaderResourceAttribs::InvalidBindPoint
static constexpr const Uint16 InvalidBindPoint
Definition: ShaderResources.hpp:117
Diligent::ShaderResources::GetAccelStruct
const D3DShaderResourceAttribs & GetAccelStruct(Uint32 n) const noexcept
Definition: ShaderResources.hpp:299
Diligent::ShaderResources::GetResAttribs
const __forceinline D3DShaderResourceAttribs & GetResAttribs(Uint32 n, Uint32 NumResources, Uint32 Offset) const noexcept
Definition: ShaderResources.hpp:420
Diligent::D3DShaderResourceAttribs::MaxSamplerId
static constexpr const Uint32 MaxSamplerId
Definition: ShaderResources.hpp:115
Diligent::D3DShaderResourceAttribs::InvalidTexSRVId
static constexpr const Uint32 InvalidTexSRVId
Definition: ShaderResources.hpp:116
Diligent::D3DShaderResourceAttribs::IsMultisample
bool IsMultisample() const
Definition: ShaderResources.cpp:360
Diligent::max
Vector3< T > max(const Vector3< T > &a, const Vector3< T > &b)
Definition: BasicMath.hpp:1660
std::hash< Diligent::D3DShaderResourceAttribs >::operator()
size_t operator()(const Diligent::D3DShaderResourceAttribs &Attribs) const
Definition: ShaderResources.hpp:597
Diligent::ShaderResources::ShaderResources
ShaderResources(SHADER_TYPE ShaderType) noexcept
Definition: ShaderResources.hpp:269
Diligent::D3DShaderResourceAttribs::D3DShaderResourceAttribs
D3DShaderResourceAttribs(const char *_Name, UINT _BindPoint, UINT _BindCount, D3D_SHADER_INPUT_TYPE _InputType, D3D_SRV_DIMENSION _SRVDimension, Uint32 _SamplerId) noexcept
Definition: ShaderResources.hpp:122
Diligent::D3DShaderResourceAttribs::IsValidBindPoint
bool IsValidBindPoint() const
Definition: ShaderResources.hpp:219
D3DCommonTypeConversions.hpp
Diligent::ShaderResources::GetCombinedTextureSRV
const D3DShaderResourceAttribs & GetCombinedTextureSRV(const D3DShaderResourceAttribs &Sampler) const noexcept
Definition: ShaderResources.hpp:308
Diligent::ShaderResources::GetSampler
const D3DShaderResourceAttribs & GetSampler(Uint32 n) const noexcept
Definition: ShaderResources.hpp:298
Diligent::ShaderResources::GetTexUAV
const D3DShaderResourceAttribs & GetTexUAV(Uint32 n) const noexcept
Definition: ShaderResources.hpp:295
Diligent::D3DShaderResourceAttribs::GetResourceDimension
RESOURCE_DIMENSION GetResourceDimension() const
Definition: ShaderResources.hpp:202
Diligent::D3DShaderResourceAttribs::IsCompatibleWith
bool IsCompatibleWith(const D3DShaderResourceAttribs &Attribs) const
Definition: ShaderResources.hpp:224
Diligent::ShaderResources::GetCombinedSampler
const D3DShaderResourceAttribs & GetCombinedSampler(const D3DShaderResourceAttribs &TexSRV) const noexcept
Definition: ShaderResources.hpp:302
Diligent::GetRawAllocator
IMemoryAllocator & GetRawAllocator()
Returns raw memory allocator.
Definition: EngineMemory.cpp:51
Diligent::ShaderResources::GetBufSRV
D3DShaderResourceAttribs & GetBufSRV(Uint32 n) noexcept
Definition: ShaderResources.hpp:431
D3D_SRV_DIMENSION_BUFFER
#define D3D_SRV_DIMENSION_BUFFER
Definition: D3D12TypeDefinitions.h:152
Diligent::ShaderResources::GetCombinedSamplerSuffix
const char * GetCombinedSamplerSuffix() const
Definition: ShaderResources.hpp:383
Diligent::ShaderResources::GetBufSRV
const D3DShaderResourceAttribs & GetBufSRV(Uint32 n) const noexcept
Definition: ShaderResources.hpp:296
Diligent::D3DShaderResourceAttribs::InvalidSamplerId
static constexpr const Uint32 InvalidSamplerId
Definition: ShaderResources.hpp:114
Diligent::D3DSrvDimensionToResourceDimension
RESOURCE_DIMENSION D3DSrvDimensionToResourceDimension(D3D_SRV_DIMENSION SrvDim)
Definition: D3DCommonTypeConversions.cpp:35
Diligent::ShaderResources::GetNumAccelStructs
Uint32 GetNumAccelStructs() const noexcept
Definition: ShaderResources.hpp:290
Diligent::ShaderResources::GetTexUAV
D3DShaderResourceAttribs & GetTexUAV(Uint32 n) noexcept
Definition: ShaderResources.hpp:430
Diligent::ShaderResources::GetNumTexUAV
Uint32 GetNumTexUAV() const noexcept
Definition: ShaderResources.hpp:286
Diligent::ShaderResources::GetTexSRV
D3DShaderResourceAttribs & GetTexSRV(Uint32 n) noexcept
Definition: ShaderResources.hpp:429
Diligent::D3DShaderResourceAttribs::Name
const char *const Name
Definition: ShaderResources.hpp:84
Diligent::ShaderResources::ProcessResources
void ProcessResources(THandler Handler) const
Definition: ShaderResources.hpp:376
Diligent::ShaderResources::GetSampler
D3DShaderResourceAttribs & GetSampler(Uint32 n) noexcept
Definition: ShaderResources.hpp:433
Diligent::ShaderResources::GetHLSLShaderResourceDesc
HLSLShaderResourceDesc GetHLSLShaderResourceDesc(Uint32 Index) const
Definition: ShaderResources.cpp:372
Diligent::D3DShaderResourceAttribs::GetHash
size_t GetHash() const
Definition: ShaderResources.hpp:233
Diligent::ShaderResources::Initialize
void Initialize(TShaderReflection *pShaderReflection, TNewResourceHandler NewResHandler, const Char *ShaderName, const Char *SamplerSuffix)
Definition: ShaderResources.hpp:474
Diligent::D3DShaderResourceAttribs::ShaderInputTypeBits
static constexpr const Uint32 ShaderInputTypeBits
Definition: ShaderResources.hpp:93
Diligent::Uint32
uint32_t Uint32
32-bit unsigned integer
Definition: BasicTypes.h:51
Diligent::ComputeHash
std::size_t ComputeHash(const ArgsType &... Args)
Definition: HashUtils.hpp:57
Diligent::D3DShaderResourceAttribs::GetInputType
D3D_SHADER_INPUT_TYPE GetInputType() const
Definition: ShaderResources.hpp:192
Diligent::ShaderResources::GetNumSamplers
Uint32 GetNumSamplers() const noexcept
Definition: ShaderResources.hpp:289
Diligent::ShaderResources::GetTexSRV
const D3DShaderResourceAttribs & GetTexSRV(Uint32 n) const noexcept
Definition: ShaderResources.hpp:294
PipelineState.h
Diligent::ShaderResources::GetShaderType
SHADER_TYPE GetShaderType() const noexcept
Definition: ShaderResources.hpp:314
Diligent::D3DShaderResourceAttribs::IsCombinedWithTexSRV
bool IsCombinedWithTexSRV() const
Definition: ShaderResources.hpp:214
Diligent::ShaderResources::IsCompatibleWith
bool IsCompatibleWith(const ShaderResources &Resources) const
Definition: ShaderResources.cpp:255
Diligent::D3DShaderResourceAttribs::GetSRVDimension
D3D_SRV_DIMENSION GetSRVDimension() const
Definition: ShaderResources.hpp:197
Diligent::ShaderResources::GetHash
size_t GetHash() const
Definition: ShaderResources.cpp:384
Diligent::D3DShaderResourceAttribs::operator=
D3DShaderResourceAttribs & operator=(const D3DShaderResourceAttribs &rhs)=delete
Diligent::D3DShaderResourceAttribs
Definition: ShaderResources.hpp:80
Diligent::DescriptorType::Sampler
@ Sampler
Diligent::D3DShaderResourceAttribs::BindCount
const Uint16 BindCount
Definition: ShaderResources.hpp:87
Diligent::IMemoryAllocator
Base interface for a raw memory allocator.
Definition: MemoryAllocator.h:41
Diligent::ShaderResources::GetBufUAV
const D3DShaderResourceAttribs & GetBufUAV(Uint32 n) const noexcept
Definition: ShaderResources.hpp:297
Diligent::D3DShaderResourceAttribs::MaxBindPoint
static constexpr const Uint16 MaxBindPoint
Definition: ShaderResources.hpp:118
Diligent::ShaderResources::GetNumTexSRV
Uint32 GetNumTexSRV() const noexcept
Definition: ShaderResources.hpp:285
HashUtils.hpp
Diligent::ShaderResources
Diligent::ShaderResources class.
Definition: ShaderResources.hpp:266
std
Definition: AdvancedMath.hpp:979
Diligent::Uint16
uint16_t Uint16
16-bit unsigned integer
Definition: BasicTypes.h:52
Diligent::ShaderResources::GetCB
const D3DShaderResourceAttribs & GetCB(Uint32 n) const noexcept
Definition: ShaderResources.hpp:293
VERIFY_EXPR
#define VERIFY_EXPR(...)
Definition: DebugUtilities.hpp:79
StringPool.hpp
Diligent::ShaderResources::GetBufUAV
D3DShaderResourceAttribs & GetBufUAV(Uint32 n) noexcept
Definition: ShaderResources.hpp:432
VERIFY
#define VERIFY(...)
Definition: DebugUtilities.hpp:76
Diligent::StringPool
Implementation of a simple fixed-size string pool.
Definition: StringPool.hpp:42
ShaderD3D.h
Diligent::D3DShaderResourceAttribs::SRVDimBits
static constexpr const Uint32 SRVDimBits
Definition: ShaderResources.hpp:94
std::hash< Diligent::ShaderResources >::operator()
size_t operator()(const Diligent::ShaderResources &Res) const
Definition: ShaderResources.hpp:606
Diligent::ShaderResources::GetShaderModel
void GetShaderModel(Uint32 &Major, Uint32 &Minor) const
Definition: ShaderResources.hpp:396
Diligent::RESOURCE_DIMENSION
RESOURCE_DIMENSION
Describes resource dimension.
Definition: GraphicsTypes.h:256
Diligent::ShaderResources::GetAccelStruct
D3DShaderResourceAttribs & GetAccelStruct(Uint32 n) noexcept
Definition: ShaderResources.hpp:434
Diligent::ShaderResources::IsUsingCombinedTextureSamplers
bool IsUsingCombinedTextureSamplers() const
Definition: ShaderResources.hpp:382
Diligent::ShaderResources::~ShaderResources
~ShaderResources()
Definition: ShaderResources.cpp:38
Diligent::D3DShaderResourceAttribs::GetHLSLResourceDesc
HLSLShaderResourceDesc GetHLSLResourceDesc() const
Definition: ShaderResources.cpp:306
ShaderType
Uint16 ShaderType
Definition: DXBCUtils.cpp:70
Diligent::ShaderResources::ProcessResources
void ProcessResources(THandleCB HandleCB, THandleSampler HandleSampler, THandleTexSRV HandleTexSRV, THandleTexUAV HandleTexUAV, THandleBufSRV HandleBufSRV, THandleBufUAV HandleBufUAV, THandleAccelStruct HandleAccelStruct) const
Definition: ShaderResources.hpp:325
Diligent::PipelineResourceLayoutDesc
Pipeline layout description.
Definition: PipelineState.h:103
D3DShaderResourceLoader.hpp
Diligent
The library uses Direct3D-style math:
Definition: AdvancedMath.hpp:37
D3D_SIT_RTACCELERATIONSTRUCTURE
#define D3D_SIT_RTACCELERATIONSTRUCTURE
Definition: ShaderResources.hpp:65
Diligent::ShaderResources::GetNumBufUAV
Uint32 GetNumBufUAV() const noexcept
Definition: ShaderResources.hpp:288
Diligent::D3DShaderResourceAttribs::IsCombinedWithSampler
bool IsCombinedWithSampler() const
Definition: ShaderResources.hpp:209