3232
3333// SPIRVShaderResources class uses continuous chunk of memory to store all resources, as follows:
3434//
35- // m_MemoryBuffer m_TotalResources
36- // | | |
37- // | Uniform Buffers | Storage Buffers | Storage Images | Sampled Images | Atomic Counters | Separate Samplers | Separate Images | Stage Inputs | Resource Names |
35+ // m_MemoryBuffer m_TotalResources
36+ // | | |
37+ // | Uniform Buffers | Storage Buffers | Storage Images | Sampled Images | Atomic Counters | Separate Samplers | Separate Images | Input Attachments | Accel Structs | Push Constants | Stage Inputs | Resource Names |
3838
3939#include < memory>
4040#include < vector>
@@ -79,6 +79,7 @@ struct SPIRVShaderResourceAttribs
7979 SeparateSampler,
8080 InputAttachment,
8181 AccelerationStructure,
82+ PushConstant, // Vulkan push constant buffer - special inline constant that uses vkCmdPushConstants
8283 NumResourceTypes
8384 };
8485
@@ -111,6 +112,11 @@ struct SPIRVShaderResourceAttribs
111112 Uint32 _BufferStaticSize = 0 ,
112113 Uint32 _BufferStride = 0 ) noexcept ;
113114
115+ // Constructor for push constants (no binding or descriptor set decoration)
116+ SPIRVShaderResourceAttribs (const char * _Name,
117+ ResourceType _Type,
118+ Uint32 _BufferStaticSize) noexcept ;
119+
114120 ShaderResourceDesc GetResourceDesc () const
115121 {
116122 return ShaderResourceDesc{Name, GetShaderResourceType (Type), ArraySize};
@@ -125,6 +131,39 @@ struct SPIRVShaderResourceAttribs
125131 {
126132 return IsMS != 0 ;
127133 }
134+
135+ Uint32 GetConstantBufferSize () const
136+ {
137+ VERIFY ((Type == PushConstant || Type == UniformBuffer), " Invalid resource type: PushConstant or UniformBuffer expected" );
138+ return BufferStaticSize;
139+ }
140+
141+ Uint32 GetInlineConstantCountOrThrow (const char * ShaderName) const
142+ {
143+ VERIFY_EXPR (Type == PushConstant || Type == UniformBuffer);
144+
145+ if (ArraySize != 1 )
146+ {
147+ LOG_ERROR_AND_THROW (" Inline constants resource '" , Name, " ' in shader '" , ShaderName, " ' can not be an array." );
148+ }
149+ const Uint32 NumConstants = GetConstantBufferSize () / sizeof (Uint32);
150+
151+ constexpr Uint32 kMaxInlineConstants = 64 ;
152+ if (NumConstants > kMaxInlineConstants )
153+ {
154+ LOG_ERROR_AND_THROW (" Inline constants resource '" , Name, " ' in shader '" , ShaderName, " ' has " ,
155+ NumConstants, " constants. The maximum supported number of inline constants is " ,
156+ kMaxInlineConstants , ' .' );
157+ }
158+
159+ if (NumConstants == 0 )
160+ {
161+ LOG_ERROR_AND_THROW (" Resource '" , Name, " ' in shader '" , ShaderName,
162+ " ' is marked as inline constants, but has zero buffer size. " );
163+ }
164+
165+ return NumConstants;
166+ }
128167};
129168static_assert (sizeof (SPIRVShaderResourceAttribs) % sizeof (void *) == 0 , " Size of SPIRVShaderResourceAttribs struct must be multiple of sizeof(void*)" );
130169
@@ -166,28 +205,30 @@ class SPIRVShaderResources
166205
167206 // clang-format off
168207
169- Uint32 GetNumUBs ()const noexcept { return (m_StorageBufferOffset - 0 ); }
170- Uint32 GetNumSBs ()const noexcept { return (m_StorageImageOffset - m_StorageBufferOffset); }
171- Uint32 GetNumImgs ()const noexcept { return (m_SampledImageOffset - m_StorageImageOffset); }
172- Uint32 GetNumSmpldImgs ()const noexcept { return (m_AtomicCounterOffset - m_SampledImageOffset); }
173- Uint32 GetNumACs ()const noexcept { return (m_SeparateSamplerOffset - m_AtomicCounterOffset); }
174- Uint32 GetNumSepSmplrs ()const noexcept { return (m_SeparateImageOffset - m_SeparateSamplerOffset);}
175- Uint32 GetNumSepImgs ()const noexcept { return (m_InputAttachmentOffset - m_SeparateImageOffset); }
176- Uint32 GetNumInptAtts ()const noexcept { return (m_AccelStructOffset - m_InputAttachmentOffset);}
177- Uint32 GetNumAccelStructs ()const noexcept { return (m_TotalResources - m_AccelStructOffset); }
208+ Uint32 GetNumUBs ()const noexcept { return (m_StorageBufferOffset - 0 ); }
209+ Uint32 GetNumSBs ()const noexcept { return (m_StorageImageOffset - m_StorageBufferOffset); }
210+ Uint32 GetNumImgs ()const noexcept { return (m_SampledImageOffset - m_StorageImageOffset); }
211+ Uint32 GetNumSmpldImgs ()const noexcept { return (m_AtomicCounterOffset - m_SampledImageOffset); }
212+ Uint32 GetNumACs ()const noexcept { return (m_SeparateSamplerOffset - m_AtomicCounterOffset); }
213+ Uint32 GetNumSepSmplrs ()const noexcept { return (m_SeparateImageOffset - m_SeparateSamplerOffset); }
214+ Uint32 GetNumSepImgs ()const noexcept { return (m_InputAttachmentOffset - m_SeparateImageOffset); }
215+ Uint32 GetNumInptAtts ()const noexcept { return (m_AccelStructOffset - m_InputAttachmentOffset); }
216+ Uint32 GetNumAccelStructs ()const noexcept { return (m_PushConstantOffset - m_AccelStructOffset); }
217+ Uint32 GetNumPushConstants ()const noexcept { return (m_TotalResources - m_PushConstantOffset); }
178218 Uint32 GetTotalResources () const noexcept { return m_TotalResources; }
179219 Uint32 GetNumShaderStageInputs ()const noexcept { return m_NumShaderStageInputs; }
180220
181- const SPIRVShaderResourceAttribs& GetUB (Uint32 n)const noexcept { return GetResAttribs (n, GetNumUBs (), 0 ); }
182- const SPIRVShaderResourceAttribs& GetSB (Uint32 n)const noexcept { return GetResAttribs (n, GetNumSBs (), m_StorageBufferOffset ); }
183- const SPIRVShaderResourceAttribs& GetImg (Uint32 n)const noexcept { return GetResAttribs (n, GetNumImgs (), m_StorageImageOffset ); }
184- const SPIRVShaderResourceAttribs& GetSmpldImg (Uint32 n)const noexcept { return GetResAttribs (n, GetNumSmpldImgs (), m_SampledImageOffset ); }
185- const SPIRVShaderResourceAttribs& GetAC (Uint32 n)const noexcept { return GetResAttribs (n, GetNumACs (), m_AtomicCounterOffset ); }
186- const SPIRVShaderResourceAttribs& GetSepSmplr (Uint32 n)const noexcept { return GetResAttribs (n, GetNumSepSmplrs (), m_SeparateSamplerOffset); }
187- const SPIRVShaderResourceAttribs& GetSepImg (Uint32 n)const noexcept { return GetResAttribs (n, GetNumSepImgs (), m_SeparateImageOffset ); }
188- const SPIRVShaderResourceAttribs& GetInptAtt (Uint32 n)const noexcept { return GetResAttribs (n, GetNumInptAtts (), m_InputAttachmentOffset); }
189- const SPIRVShaderResourceAttribs& GetAccelStruct (Uint32 n)const noexcept { return GetResAttribs (n, GetNumAccelStructs (), m_AccelStructOffset ); }
190- const SPIRVShaderResourceAttribs& GetResource (Uint32 n)const noexcept { return GetResAttribs (n, GetTotalResources (), 0 ); }
221+ const SPIRVShaderResourceAttribs& GetUB (Uint32 n)const noexcept { return GetResAttribs (n, GetNumUBs (), 0 ); }
222+ const SPIRVShaderResourceAttribs& GetSB (Uint32 n)const noexcept { return GetResAttribs (n, GetNumSBs (), m_StorageBufferOffset ); }
223+ const SPIRVShaderResourceAttribs& GetImg (Uint32 n)const noexcept { return GetResAttribs (n, GetNumImgs (), m_StorageImageOffset ); }
224+ const SPIRVShaderResourceAttribs& GetSmpldImg (Uint32 n)const noexcept { return GetResAttribs (n, GetNumSmpldImgs (), m_SampledImageOffset ); }
225+ const SPIRVShaderResourceAttribs& GetAC (Uint32 n)const noexcept { return GetResAttribs (n, GetNumACs (), m_AtomicCounterOffset ); }
226+ const SPIRVShaderResourceAttribs& GetSepSmplr (Uint32 n)const noexcept { return GetResAttribs (n, GetNumSepSmplrs (), m_SeparateSamplerOffset ); }
227+ const SPIRVShaderResourceAttribs& GetSepImg (Uint32 n)const noexcept { return GetResAttribs (n, GetNumSepImgs (), m_SeparateImageOffset ); }
228+ const SPIRVShaderResourceAttribs& GetInptAtt (Uint32 n)const noexcept { return GetResAttribs (n, GetNumInptAtts (), m_InputAttachmentOffset ); }
229+ const SPIRVShaderResourceAttribs& GetAccelStruct (Uint32 n)const noexcept { return GetResAttribs (n, GetNumAccelStructs (), m_AccelStructOffset ); }
230+ const SPIRVShaderResourceAttribs& GetPushConstant (Uint32 n)const noexcept { return GetResAttribs (n, GetNumPushConstants (), m_PushConstantOffset ); }
231+ const SPIRVShaderResourceAttribs& GetResource (Uint32 n)const noexcept { return GetResAttribs (n, GetTotalResources (), 0 ); }
191232
192233 // clang-format on
193234
@@ -217,15 +258,16 @@ class SPIRVShaderResources
217258
218259 struct ResourceCounters
219260 {
220- Uint32 NumUBs = 0 ;
221- Uint32 NumSBs = 0 ;
222- Uint32 NumImgs = 0 ;
223- Uint32 NumSmpldImgs = 0 ;
224- Uint32 NumACs = 0 ;
225- Uint32 NumSepSmplrs = 0 ;
226- Uint32 NumSepImgs = 0 ;
227- Uint32 NumInptAtts = 0 ;
228- Uint32 NumAccelStructs = 0 ;
261+ Uint32 NumUBs = 0 ;
262+ Uint32 NumSBs = 0 ;
263+ Uint32 NumImgs = 0 ;
264+ Uint32 NumSmpldImgs = 0 ;
265+ Uint32 NumACs = 0 ;
266+ Uint32 NumSepSmplrs = 0 ;
267+ Uint32 NumSepImgs = 0 ;
268+ Uint32 NumInptAtts = 0 ;
269+ Uint32 NumAccelStructs = 0 ;
270+ Uint32 NumPushConstants = 0 ; // Vulkan push constant buffers (max 1 per Vulkan spec)
229271 };
230272
231273 SHADER_TYPE GetShaderType () const noexcept { return m_ShaderType; }
@@ -243,16 +285,18 @@ class SPIRVShaderResources
243285 typename THandleSepSmpl,
244286 typename THandleSepImg,
245287 typename THandleInptAtt,
246- typename THandleAccelStruct>
247- void ProcessResources (THandleUB HandleUB,
248- THandleSB HandleSB,
249- THandleImg HandleImg,
250- THandleSmplImg HandleSmplImg,
251- THandleAC HandleAC,
252- THandleSepSmpl HandleSepSmpl,
253- THandleSepImg HandleSepImg,
254- THandleInptAtt HandleInptAtt,
255- THandleAccelStruct HandleAccelStruct) const
288+ typename THandleAccelStruct,
289+ typename THandlePushConstant>
290+ void ProcessResources (THandleUB HandleUB,
291+ THandleSB HandleSB,
292+ THandleImg HandleImg,
293+ THandleSmplImg HandleSmplImg,
294+ THandleAC HandleAC,
295+ THandleSepSmpl HandleSepSmpl,
296+ THandleSepImg HandleSepImg,
297+ THandleInptAtt HandleInptAtt,
298+ THandleAccelStruct HandleAccelStruct,
299+ THandlePushConstant HandlePushConstant) const
256300 {
257301 for (Uint32 n = 0 ; n < GetNumUBs (); ++n)
258302 {
@@ -308,7 +352,13 @@ class SPIRVShaderResources
308352 HandleAccelStruct (AccelStruct, n);
309353 }
310354
311- static_assert (Uint32{SPIRVShaderResourceAttribs::ResourceType::NumResourceTypes} == 12 , " Please handle the new resource type here, if needed" );
355+ for (Uint32 n = 0 ; n < GetNumPushConstants (); ++n)
356+ {
357+ const SPIRVShaderResourceAttribs& PushConstant = GetPushConstant (n);
358+ HandlePushConstant (PushConstant, n);
359+ }
360+
361+ static_assert (Uint32{SPIRVShaderResourceAttribs::ResourceType::NumResourceTypes} == 13 , " Please handle the new resource type here, if needed" );
312362 }
313363
314364 template <typename THandler>
@@ -359,16 +409,17 @@ class SPIRVShaderResources
359409
360410 // clang-format off
361411
362- SPIRVShaderResourceAttribs& GetUB (Uint32 n)noexcept { return GetResAttribs (n, GetNumUBs (), 0 ); }
363- SPIRVShaderResourceAttribs& GetSB (Uint32 n)noexcept { return GetResAttribs (n, GetNumSBs (), m_StorageBufferOffset ); }
364- SPIRVShaderResourceAttribs& GetImg (Uint32 n)noexcept { return GetResAttribs (n, GetNumImgs (), m_StorageImageOffset ); }
365- SPIRVShaderResourceAttribs& GetSmpldImg (Uint32 n)noexcept { return GetResAttribs (n, GetNumSmpldImgs (), m_SampledImageOffset ); }
366- SPIRVShaderResourceAttribs& GetAC (Uint32 n)noexcept { return GetResAttribs (n, GetNumACs (), m_AtomicCounterOffset ); }
367- SPIRVShaderResourceAttribs& GetSepSmplr (Uint32 n)noexcept { return GetResAttribs (n, GetNumSepSmplrs (), m_SeparateSamplerOffset); }
368- SPIRVShaderResourceAttribs& GetSepImg (Uint32 n)noexcept { return GetResAttribs (n, GetNumSepImgs (), m_SeparateImageOffset ); }
369- SPIRVShaderResourceAttribs& GetInptAtt (Uint32 n)noexcept { return GetResAttribs (n, GetNumInptAtts (), m_InputAttachmentOffset); }
370- SPIRVShaderResourceAttribs& GetAccelStruct (Uint32 n)noexcept { return GetResAttribs (n, GetNumAccelStructs (), m_AccelStructOffset ); }
371- SPIRVShaderResourceAttribs& GetResource (Uint32 n)noexcept { return GetResAttribs (n, GetTotalResources (), 0 ); }
412+ SPIRVShaderResourceAttribs& GetUB (Uint32 n)noexcept { return GetResAttribs (n, GetNumUBs (), 0 ); }
413+ SPIRVShaderResourceAttribs& GetSB (Uint32 n)noexcept { return GetResAttribs (n, GetNumSBs (), m_StorageBufferOffset ); }
414+ SPIRVShaderResourceAttribs& GetImg (Uint32 n)noexcept { return GetResAttribs (n, GetNumImgs (), m_StorageImageOffset ); }
415+ SPIRVShaderResourceAttribs& GetSmpldImg (Uint32 n)noexcept { return GetResAttribs (n, GetNumSmpldImgs (), m_SampledImageOffset ); }
416+ SPIRVShaderResourceAttribs& GetAC (Uint32 n)noexcept { return GetResAttribs (n, GetNumACs (), m_AtomicCounterOffset ); }
417+ SPIRVShaderResourceAttribs& GetSepSmplr (Uint32 n)noexcept { return GetResAttribs (n, GetNumSepSmplrs (), m_SeparateSamplerOffset ); }
418+ SPIRVShaderResourceAttribs& GetSepImg (Uint32 n)noexcept { return GetResAttribs (n, GetNumSepImgs (), m_SeparateImageOffset ); }
419+ SPIRVShaderResourceAttribs& GetInptAtt (Uint32 n)noexcept { return GetResAttribs (n, GetNumInptAtts (), m_InputAttachmentOffset ); }
420+ SPIRVShaderResourceAttribs& GetAccelStruct (Uint32 n)noexcept { return GetResAttribs (n, GetNumAccelStructs (), m_AccelStructOffset ); }
421+ SPIRVShaderResourceAttribs& GetPushConstant (Uint32 n)noexcept { return GetResAttribs (n, GetNumPushConstants (), m_PushConstantOffset ); }
422+ SPIRVShaderResourceAttribs& GetResource (Uint32 n)noexcept { return GetResAttribs (n, GetTotalResources (), 0 ); }
372423
373424 // clang-format on
374425
@@ -394,6 +445,7 @@ class SPIRVShaderResources
394445 OffsetType m_SeparateImageOffset = 0 ;
395446 OffsetType m_InputAttachmentOffset = 0 ;
396447 OffsetType m_AccelStructOffset = 0 ;
448+ OffsetType m_PushConstantOffset = 0 ;
397449 OffsetType m_TotalResources = 0 ;
398450 OffsetType m_NumShaderStageInputs = 0 ;
399451
0 commit comments