HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
RV_ShaderVariableSet.h
Go to the documentation of this file.
1 
2 /*
3  * PROPRIETARY INFORMATION. This software is proprietary to
4  * Side Effects Software Inc., and is not to be reproduced,
5  * transmitted, or disclosed in any way without written permission.
6  *
7  * NAME: RV_ShaderVariableSet.h ( RV Library, C++)
8  *
9  * COMMENTS:
10  * Class to handle creating a set of Variables to be bound alongisde a
11  * shader, i.e. a Descriptor Set
12  */
13 
14 #ifndef RV_ShaderVariableSet_h
15 #define RV_ShaderVariableSet_h
16 
17 #include "RV_API.h"
18 
19 #include "RV_Type.h"
20 
21 #include <VE/VE_VK.h>
22 
23 #include <UT/UT_Array.h>
24 #include <UT/UT_ArrayStringMap.h>
25 #include <UT/UT_UniquePtr.h>
26 #include <UT/UT_StringHolder.h>
27 #include <UT/UT_StringMap.h>
28 
29 #include <utility>
30 
31 class RV_Instance;
32 class RV_Render;
33 class RV_ShaderBlock;
35 class RV_VKBuffer;
36 class RV_VKImage;
37 class RV_VKSampler;
39 class RV_VKCommandBuffer;
40 class RV_VKDescriptorSet;
45 
46 // ~~~~~~~~~~
47 // RV_ShaderVariableSet
48 //
49 // High level class for variable bindings used in shaders (i.e. desciptor sets)
50 // Stores the layout, the values.
51 //
52 // Mutable and not thread safe
53 
54 /// A collection of Vulkan UBO, SSBO, and Image shader bindings (descriptor set)
56 {
57 public:
59  RV_Instance* inst,
60  const RV_VKDescriptorSetInfo* layout,
63 
65  RV_Instance* inst,
66  const RV_VKDescriptorSetInfo* layout,
67  const RV_ShaderVariableSet* opt_base = nullptr,
69 
70  /// Returns true if binding named 'name' exists
71  bool hasBinding(const UT_StringRef& name) const;
72 
73  /// Returns true if binding exists
74  bool hasBinding(uint32_t binding_num) const
75  {
76  return myBindingResourceIdx.isValidIndex(binding_num) &&
77  myBindingResourceIdx[binding_num] != -1;
78  }
79 
80  /// The list of bindings
81  const UT_Array<RV_VKDescriptorBinding>& getBindings() const;
82  /// Return a single binding by index
83  const RV_VKDescriptorBinding& getBinding(uint32_t binding_num) const;
84  /// Return a single binding by name
85  RV_VKDescriptorBinding getBinding(const UT_StringRef& name) const;
86 
87  /// The raw Vulkan descriptor set which this set represents.
88  VkDescriptorSet getVkDescriptorSet();
89 
91  { return myDescriptorSet.get(); }
92 
93  const RV_ResourceID &getDescriptorSetId() const;
94 
95  /// The raw Vulkan descritor set create info
97  { return *myLayout; }
98 
99  /// Label for debugging
100  const UT_StringHolder &getName() const { return myName; }
101  /// Return unique ID for descriptorSet object
102  const RV_ResourceID &getID() const { return myId; }
103  // --------------------------------
104  // Bound Resources
105  // TODO: make return value ptr, instead of output var?
106 
107  /// Fetch a bound UBO or SSBO with the given name (may be null)
108  /// Return false if the binding doesn't exist or isn't a buffer object.
109  bool getBufferBlock(const UT_StringRef& name, RV_ShaderBlock*& out_block);
110  /// Fetch a bound UBO or SSBO with the given name (may be null)
111  /// Return false if the binding doesn't exist or isn't a buffer object.
112  bool getBufferBlock(const UT_StringRef& name, const RV_ShaderBlock*&) const;
113  /// Fetch a bound UBO or SSBO by index (may be null).
114  /// Return false if the binding doesn't exist or isn't a buffer object.
115  bool getBufferBlock(int binding_num, RV_ShaderBlock*& out_block);
116  /// Fetch a bound UBO or SSBO by index (may be null).
117  /// Return false if the binding doesn't exist or isn't a buffer object.
118  bool getBufferBlock(int binding_num, const RV_ShaderBlock*& out_block)
119  const;
120 
121  /// Fetch a bound texture with the given name (may be null)
122  /// Return false if the binding doesn't exist or isn't a texture.
123  bool getTexture(const UT_StringRef& name, RV_VKImage*& out_image);
124  /// Fetch a bound texture with the given name (may be null)
125  /// Return false if the binding doesn't exist or isn't a texture.
126  bool getTexture(const UT_StringRef& name, const RV_VKImage*&) const;
127  /// Fetch a bound texture by index (may be null)
128  /// Return false if the binding doesn't exist or isn't a texture.
129  bool getTexture(int binding_num, RV_VKImage*& out_image);
130  /// Fetch a bound texture by index (may be null)
131  /// Return false if the binding doesn't exist or isn't a texture.
132  bool getTexture(int binding_num, const RV_VKImage*& out_image) const;
133 
134  /// Fetch a bound buffer view (TBO in GL) by the given name (may be null)
135  /// Return false if the binding doesn't exist or isn't a buffer view.
136  bool getBufferView(const UT_StringRef& name, RV_VKBuffer*& out_buffer);
137  /// Fetch a bound buffer view (TBO in GL) by the given name (may be null)
138  /// Return false if the binding doesn't exist or isn't a buffer view.
139  bool getBufferView(const UT_StringRef& name, const RV_VKBuffer*&) const;
140  /// Fetch a bound buffer view (TBO in GL) by index (may be null)
141  /// Return false if the binding doesn't exist or isn't a buffer view.
142  bool getBufferView(int binding_num, RV_VKBuffer*& out_buffer);
143  /// Fetch a bound buffer view (TBO in GL) by index (may be null)
144  /// Return false if the binding doesn't exist or isn't a buffer view.
145  bool getBufferView(int binding_num, const RV_VKBuffer*& out_buffer) const;
146 
147  /// Fetch a bound acceleration structure by the given name (may be null)
148  /// Return false if the binding doesn't exist or isn't an acceleration structure.
149  bool getAccelStruct(const UT_StringRef& name, RV_VKAccelerationStructure*& out_as);
150  /// Fetch a bound acceleration structure by the given name (may be null)
151  /// Return false if the binding doesn't exist or isn't an acceleration structure.
152  bool getAccelStruct(const UT_StringRef& name, const RV_VKAccelerationStructure*& out_as) const;
153  /// Fetch a bound acceleration structure by the given index (may be null)
154  /// Return false if the binding doesn't exist or isn't an acceleration structure.
155  bool getAccelStruct(int binding_num, RV_VKAccelerationStructure*& out_as);
156  /// Fetch a bound acceleration structure by the given index (may be null)
157  /// Return false if the binding doesn't exist or isn't an acceleration structure.
158  bool getAccelStruct(int binding_num, const RV_VKAccelerationStructure*& out_as) const;
159 
160  // Must attach buffers before using to draw
161  // Marks the buffer as used by the Descriptor Set
162  // Will wait until used for a draw to actually update the set
163 
164  /// Attach a UBO or SSBO to this variable set. Returns false if the binding
165  /// name doesn't exist, the block is null, or it isn't compatible with the
166  /// layout of the binding.
167  bool attachBufferBlock(
168  RV_Instance* inst,
169  const UT_StringRef& name,
170  RV_ShaderBlock* buffer_block,
171  int index = 0);
172  /// Attach a UBO or SSBO to this variable set. Returns false if the binding
173  /// index doesn't exist, the block is null, or it isn't compatible with the
174  /// layout of the binding.
175  bool attachBufferBlock(
176  RV_Instance* inst,
177  int binding_num,
178  RV_ShaderBlock* buffer_block,
179  int index = 0);
180 
181  /// Attach a buffer view (TBO in GL) to this variable set. Returns false if
182  /// the binding name doesn't exist, the buffer is null, or it isn't
183  /// compatible with the layout of the binding.
184  bool attachBufferView(
185  RV_Instance* inst,
186  const UT_StringRef& name,
188  int index = 0);
189  /// Attach a buffer view (TBO in GL) to this variable set. Returns false if
190  /// the binding index doesn't exist, the buffer is null, or it isn't
191  /// compatible with the layout of the binding.
192  bool attachBufferView(
193  RV_Instance* inst,
194  int binding_num,
196  int index = 0);
197 
198  /// Attach a buffer view (TBO in GL) to this variable set. Returns false if
199  /// the binding name doesn't exist, the buffer is null, or it isn't
200  /// compatible with the layout of the binding.
201  bool attachBuffer(
202  RV_Instance* inst,
203  const UT_StringRef& name,
205  int index = 0);
206  /// Attach a buffer view (TBO in GL) to this variable set. Returns false if
207  /// the binding index doesn't exist, the buffer is null, or it isn't
208  /// compatible with the layout of the binding.
209  bool attachBuffer(
210  RV_Instance* inst,
211  int binding_num,
213  int index = 0);
214 
215  /// Attach a texture or image to this variable set. Returns false if
216  /// the binding name doesn't exist, the image is null, or it isn't
217  /// compatible with the sampler type of the binding.
218  bool attachTexture(
219  RV_Instance* inst,
220  const UT_StringRef& name,
221  RV_VKImage* image,
222  RV_VKSampler* opt_sampler,
223  int index = 0);
224  /// Attach a texture or image to this variable set. Returns false if
225  /// the binding index doesn't exist, the image is null, or it isn't
226  /// compatible with the sampler type of the binding.
227  bool attachTexture(
228  RV_Instance* inst,
229  int binding_num,
230  RV_VKImage* image,
231  RV_VKSampler* opt_sampler,
232  int index = 0);
233  /// Attach a texture or image to this variable set. Returns false if
234  /// the binding name doesn't exist, the image is null, or it isn't
235  /// compatible with the sampler type of the binding.
236  bool attachTexture(
237  RV_Instance* inst,
238  const UT_StringRef& name,
239  RV_VKImage* image,
240  int index = 0);
241  /// Attach a texture or image to this variable set. Returns false if
242  /// the binding index doesn't exist, the image is null, or it isn't
243  /// compatible with the sampler type of the binding.
244  bool attachTexture(
245  RV_Instance* inst,
246  int binding_num,
247  RV_VKImage* image,
248  int index = 0);
249 
250  /// Attach an acceleration structure to this variable set. Returns
251  /// false if the binding name doesn't exist or the acceleration
252  /// structure is null
253  bool attachAccelStruct(
254  RV_Instance* inst,
255  const UT_StringRef& name,
256  RV_VKAccelerationStructure* accel_struct,
257  int index = 0);
258  /// Attach an acceleration structure to this variable set. Returns
259  /// false if the binding index doesn't exist or the acceleration
260  /// structure is null
261  bool attachAccelStruct(
262  RV_Instance* inst,
263  int binding_num,
264  RV_VKAccelerationStructure* accel_struct,
265  int index = 0);
266 
267  /// Clear a bound UBO, SSBO, buffer view, or texture from binding 'name'
268  void clearBinding(const UT_StringRef& name);
269  void clearBinding(RV_Render* r, const UT_StringRef& name);
270 
271  /// Clear a bound UBO, SSBO, buffer view, or texture from the binding index
272  void clearBinding(int binding_num);
273  void clearBinding(RV_Render* r, int binding_num);
274 
275  void clearExtraBindings();
276 
277  /// Take any pending bindings and write them to the descriptor set
278  void commitBindings(RV_Render* r);
279 
280  // check whether the resources attached to each binding are valid
281  // (i.e. haven't been deleted)
282  bool validateBindings(RV_Instance* inst) const;
283  bool validateBinding(RV_Instance* inst, int binding_num);
284  bool validateBinding(RV_Instance* inst, int binding_num) const;
285 
286  // Update bindings as needed before a render pass.
287  // If called during a render pass, may interrupt render pass if needed
288  void updateBindings(RV_Render* rv);
289 
290  void recordBindings(RV_VKCommandBuffer *cb) const;
291 
292  // check that all bindings have been assigned
293  // -- also must check that all buffers/images are valid (have memory backing them, have not been deleted)
294  //
295 
296  /// Return true if all bindings have been assigned to the set
297  bool isReady(RV_Instance* inst) const;
298 
299  /// Return true if the set has been modified since the last commit
300  bool isDirty() const
301  {
302  UT_ASSERT_P(myIsSetDirty == !myDirtyBindings.isEmpty());
303  return myIsSetDirty;
304  }
305 
306  // Shader Layout info
307 
308  /// Return if this variable set is compatible with the given pipeline binding
309  /// layout of the shader.
310  bool isCompatibleToBind(const RV_VKDescriptorSetInfo& pipe_layout) const;
311 
312  /// Return the binding number of the set that this set was created with.
313  inline int getSetNumber() const { return mySetNumber; }
314 
315  /// Return the layout ID of the set that this set was created with.
316  inline int getLayoutID() const { return mySetID; }
317 
318  // -------------------------------------------------------------------
319  // DEBUG
320 
321  /// Debug dump to stderr all information about the bindings
322  void print() const;
323 
324  /// Build list of which binding numbers are dirty
325  void getDirtyBindings(UT_Array<int> &out_list) const
326  {
327  for (auto &binding : myDirtyBindings)
328  out_list.append(std::get<0>(binding));
329  }
330 
331 private:
332  friend class RV_Render;
333 
334  // Returns true if binding exists and has a resource bound to it
335  bool isValidBinding(uint32_t binding_num, int index=0) const;
336 
337  bool privGetBinding(
338  const UT_StringRef& name,
339  int& out_binding_num,
340  const RV_VKDescriptorBinding*& out_binding) const;
341 
343  privWriteNewSet(
344  RV_Instance* inst,
345  const RV_ShaderVariableSet* opt_base);
346 
347 
348  // Only called by RV_Render
349  bool bindSet(RV_Render* r,
351 
352  bool bindSet(RV_Render* r,
353  const RV_ShaderProgramBase* shader) const;
354 
355  /// Pipeline Layout for shader
356  const RV_VKDescriptorSetInfo *myLayout;
357  UT_StringHolder myName;
358  int mySetNumber;
359  exint mySetID;
360 
361  // Bindings:
362  // Mapping of Binding Names to Binding number in the layout
363  const UT_ArrayStringMap<int> *myBindingTable;
364  UT_Array<int> myBindingResourceIdx;
365 
366  // lists of resources
367  typedef std::pair<RV_ShaderBlock*, RV_ResourceID> BufferBlockResource;
368  typedef std::pair<RV_VKBuffer*, RV_ResourceID> BufferResource;
369  typedef std::tuple<RV_VKImage*, RV_ResourceID, RV_VKSampler*> TextureResource;
370  typedef std::pair<RV_VKAccelerationStructure*, RV_ResourceID> AccelStructResource;
371 
372  // TODO: combine the resource lists for the 3 buffer types
373  UT_Array<BufferBlockResource> myBufferBlocks;
374  UT_Array<BufferResource> myBufferViews;
375  UT_Array<BufferResource> myBufferArrays;
376  UT_Array<TextureResource> myTextures;
377  UT_Array<AccelStructResource> myAccelStructs;
378 
379  enum RV_BindingType
380  {
381  RV_BINDING_UNKNOWN = 0,
382  RV_BINDING_BLOCK_BUFFER,
383  RV_BINDING_TEXEL_BUFFER,
384  RV_BINDING_SSBO_ARRAY_BUFFER,
385  RV_BINDING_IMAGE,
386  RV_BINDING_ACCELERATION_STRUCTURE,
387  };
388 
389  static RV_BindingType getBindingType(const RV_VKDescriptorBinding& binding);
390 
391  // Simple variant/union-like struct
392  struct BindingResource;
393 
394  // Extra Bindings -- Attached to the set by name but not
395  // part of the layout, so will not be bound as part of our set
396  // keep to copy into other sets if we transfer our resources
397  void privAttachExtraResource(const UT_StringHolder& name,
398  const BindingResource &res);
399  UT_StringMap<BindingResource> myExtraBindings;
400 
401  // Descriptor Sets:
402  // - DescriptorSets: Current descriptor sets
403  // - PendingUpdates: Updates to set that will be commited before use
404 
405  /// Our current up-to-date VK_DescriptorSet object
406  UT_UniquePtr<RV_VKDescriptorSet> myDescriptorSet;
407  const RV_VKDescriptorLayout *myDescriptorLayout;
408  RV_Instance *myInst;
409  RV_ResourceID myId;
410 
411  /// pending writes for descriptor set
412  typedef std::tuple<int, int, RV_BindingType> BindingRef;
413  UT_Array<BindingRef> myDirtyBindings;
415  bool myIsSetDirty = false;
416 };
417 
418 #endif
419 
A collection of Vulkan UBO, SSBO, and Image shader bindings (descriptor set)
const UT_StringHolder & getName() const
Label for debugging.
int64 exint
Definition: SYS_Types.h:125
bool isDirty() const
Return true if the set has been modified since the last commit.
RV_VKDescriptorSet * getRVDescriptorSet()
GLenum GLenum GLsizei void * image
Definition: glad.h:5132
const RV_VKDescriptorSetInfo & getSetInfo() const
The raw Vulkan descritor set create info.
GLuint buffer
Definition: glcorearb.h:660
void getDirtyBindings(UT_Array< int > &out_list) const
Build list of which binding numbers are dirty.
std::unique_ptr< T, Deleter > UT_UniquePtr
A smart pointer for unique ownership of dynamically allocated objects.
Definition: UT_UniquePtr.h:39
#define UT_ASSERT_P(ZZ)
Definition: UT_Assert.h:164
#define RV_API
Definition: RV_API.h:10
const RV_ResourceID & getID() const
Return unique ID for descriptorSet object.
GLuint const GLchar * name
Definition: glcorearb.h:786
Handle to the main interface of Vulkan.
Definition: RV_Instance.h:48
exint append()
Definition: UT_Array.h:142
bool hasBinding(uint32_t binding_num) const
Returns true if binding exists.
int getSetNumber() const
Return the binding number of the set that this set was created with.
GLuint shader
Definition: glcorearb.h:785
GLuint index
Definition: glcorearb.h:786
GLboolean r
Definition: glcorearb.h:1222
A vulkan buffer object.
Definition: RV_VKBuffer.h:75
FMT_INLINE void print(format_string< T...> fmt, T &&...args)
Definition: core.h:2903
int getLayoutID() const
Return the layout ID of the set that this set was created with.
bool bindSet(RV_ShaderVariableSet *set, const RV_ShaderProgramBase *shr)
Bind a variable set to the specific shader program.