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 <UT/UT_Array.h>
20 #include <UT/UT_ArrayStringMap.h>
21 #include <UT/UT_UniquePtr.h>
22 #include <UT/UT_StringHolder.h>
23 #include <UT/UT_StringMap.h>
24 
25 #include <utility>
26 
27 #include "RV_VKDescriptorSet.h"
28 
29 class RV_Instance;
30 class RV_Render;
31 class RV_ShaderBlock;
33 class RV_VKBuffer;
34 class RV_VKImage;
35 class RV_VKSampler;
37 
38 // ~~~~~~~~~~
39 // RV_ShaderVariableSet
40 //
41 // High level class for variable bindings used in shaders (i.e. desciptor sets)
42 // Stores the layout, the values.
43 //
44 // Mutable and not thread safe
45 
46 /// A collection of Vulkan UBO, SSBO, and Image shader bindings (descriptor set)
48 {
49 public:
51  RV_Instance* inst,
52  const RV_VKDescriptorSetInfo* layout,
56 
58  RV_Instance* inst,
59  const RV_VKDescriptorSetInfo* layout,
60  const RV_ShaderVariableSet* opt_base = nullptr,
62 
63  /// Returns true if binding named 'name' exists
64  bool hasBinding(const UT_StringRef& name) const;
65 
66  /// Returns true if binding exists
67  bool hasBinding(uint32_t binding_num) const
68  {
69  return myBindingResourceIdx.isValidIndex(binding_num) &&
70  myBindingResourceIdx[binding_num] != -1;
71  }
72 
73  /// The list of bindings
74  const UT_Array<RV_VKDescriptorBinding>& getBindings() const;
75  /// Return a single binding by index
76  const RV_VKDescriptorBinding& getBinding(uint32_t binding_num) const;
77  /// Return a single binding by name
78  RV_VKDescriptorBinding getBinding(const UT_StringRef& name) const;
79 
80  /// The raw Vulkan descriptor set which this set represents.
81  VkDescriptorSet getVkDescriptorSet();
82 
84  { return myDescriptorSet.get(); };
85 
86  const RV_ResourceID &getDescriptorSetId() const;
87 
88  /// The raw Vulkan descritor set create info
90  { return *myLayout.get(); }
91 
92  /// Label for debugging
93  const UT_StringHolder &getName() const { return myName; }
94 
95  // --------------------------------
96  // Bound Resources
97  // TODO: make return value ptr, instead of output var?
98 
99  /// Fetch a bound UBO or SSBO with the given name (may be null)
100  /// Return false if the binding doesn't exist or isn't a buffer object.
101  bool getBufferBlock(const UT_StringRef& name, RV_ShaderBlock*& out_block);
102  /// Fetch a bound UBO or SSBO with the given name (may be null)
103  /// Return false if the binding doesn't exist or isn't a buffer object.
104  bool getBufferBlock(const UT_StringRef& name, const RV_ShaderBlock*&) const;
105  /// Fetch a bound UBO or SSBO by index (may be null).
106  /// Return false if the binding doesn't exist or isn't a buffer object.
107  bool getBufferBlock(int binding_num, RV_ShaderBlock*& out_block);
108  /// Fetch a bound UBO or SSBO by index (may be null).
109  /// Return false if the binding doesn't exist or isn't a buffer object.
110  bool getBufferBlock(int binding_num, const RV_ShaderBlock*& out_block)
111  const;
112 
113  /// Fetch a bound texture with the given name (may be null)
114  /// Return false if the binding doesn't exist or isn't a texture.
115  bool getTexture(const UT_StringRef& name, RV_VKImage*& out_image);
116  /// Fetch a bound texture with the given name (may be null)
117  /// Return false if the binding doesn't exist or isn't a texture.
118  bool getTexture(const UT_StringRef& name, const RV_VKImage*&) const;
119  /// Fetch a bound texture by index (may be null)
120  /// Return false if the binding doesn't exist or isn't a texture.
121  bool getTexture(int binding_num, RV_VKImage*& out_image);
122  /// Fetch a bound texture by index (may be null)
123  /// Return false if the binding doesn't exist or isn't a texture.
124  bool getTexture(int binding_num, const RV_VKImage*& out_image) const;
125 
126  /// Fetch a bound buffer view (TBO in GL) by the given name (may be null)
127  /// Return false if the binding doesn't exist or isn't a buffer view.
128  bool getBufferView(const UT_StringRef& name, RV_VKBuffer*& out_buffer);
129  /// Fetch a bound buffer view (TBO in GL) by the given name (may be null)
130  /// Return false if the binding doesn't exist or isn't a buffer view.
131  bool getBufferView(const UT_StringRef& name, const RV_VKBuffer*&) const;
132  /// Fetch a bound buffer view (TBO in GL) by index (may be null)
133  /// Return false if the binding doesn't exist or isn't a buffer view.
134  bool getBufferView(int binding_num, RV_VKBuffer*& out_buffer);
135  /// Fetch a bound buffer view (TBO in GL) by index (may be null)
136  /// Return false if the binding doesn't exist or isn't a buffer view.
137  bool getBufferView(int binding_num, const RV_VKBuffer*& out_buffer) const;
138 
139  /// Fetch a bound acceleration structure by the given name (may be null)
140  /// Return false if the binding doesn't exist or isn't an acceleration structure.
141  bool getAccelStruct(const UT_StringRef& name, RV_VKAccelerationStructure*& out_as);
142  /// Fetch a bound acceleration structure by the given name (may be null)
143  /// Return false if the binding doesn't exist or isn't an acceleration structure.
144  bool getAccelStruct(const UT_StringRef& name, const RV_VKAccelerationStructure*& out_as) const;
145  /// Fetch a bound acceleration structure by the given index (may be null)
146  /// Return false if the binding doesn't exist or isn't an acceleration structure.
147  bool getAccelStruct(int binding_num, RV_VKAccelerationStructure*& out_as);
148  /// Fetch a bound acceleration structure by the given index (may be null)
149  /// Return false if the binding doesn't exist or isn't an acceleration structure.
150  bool getAccelStruct(int binding_num, const RV_VKAccelerationStructure*& out_as) const;
151 
152  // Must attach buffers before using to draw
153  // Marks the buffer as used by the Descriptor Set
154  // Will wait until used for a draw to actually update the set
155 
156  /// Attach a UBO or SSBO to this variable set. Returns false if the binding
157  /// name doesn't exist, the block is null, or it isn't compatible with the
158  /// layout of the binding.
159  bool attachBufferBlock(
160  RV_Instance* inst,
161  const UT_StringRef& name,
162  RV_ShaderBlock* buffer_block,
163  int index = 0);
164  /// Attach a UBO or SSBO to this variable set. Returns false if the binding
165  /// index 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  int binding_num,
170  RV_ShaderBlock* buffer_block,
171  int index = 0);
172 
173  /// Attach a buffer view (TBO in GL) to this variable set. Returns false if
174  /// the binding name doesn't exist, the buffer is null, or it isn't
175  /// compatible with the layout of the binding.
176  bool attachBufferView(
177  RV_Instance* inst,
178  const UT_StringRef& name,
180  int index = 0);
181  /// Attach a buffer view (TBO in GL) to this variable set. Returns false if
182  /// the binding index 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  int binding_num,
188  int index = 0);
189 
190  /// Attach a buffer view (TBO in GL) to this variable set. Returns false if
191  /// the binding name doesn't exist, the buffer is null, or it isn't
192  /// compatible with the layout of the binding.
193  bool attachBuffer(
194  RV_Instance* inst,
195  const UT_StringRef& name,
197  int index = 0);
198  /// Attach a buffer view (TBO in GL) to this variable set. Returns false if
199  /// the binding index 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  int binding_num,
205  int index = 0);
206 
207  /// Attach a texture or image to this variable set. Returns false if
208  /// the binding name doesn't exist, the image is null, or it isn't
209  /// compatible with the sampler type of the binding.
210  bool attachTexture(
211  RV_Instance* inst,
212  const UT_StringRef& name,
213  RV_VKImage* image,
214  RV_VKSampler* opt_sampler,
215  int index = 0);
216  /// Attach a texture or image to this variable set. Returns false if
217  /// the binding index doesn't exist, the image is null, or it isn't
218  /// compatible with the sampler type of the binding.
219  bool attachTexture(
220  RV_Instance* inst,
221  int binding_num,
222  RV_VKImage* image,
223  RV_VKSampler* opt_sampler,
224  int index = 0);
225  /// Attach a texture or image to this variable set. Returns false if
226  /// the binding name doesn't exist, the image is null, or it isn't
227  /// compatible with the sampler type of the binding.
228  bool attachTexture(
229  RV_Instance* inst,
230  const UT_StringRef& name,
231  RV_VKImage* image,
232  int index = 0);
233  /// Attach a texture or image to this variable set. Returns false if
234  /// the binding index 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  int binding_num,
239  RV_VKImage* image,
240  int index = 0);
241 
242  /// Attach an acceleration structure to this variable set. Returns
243  /// false if the binding name doesn't exist or the acceleration
244  /// structure is null
245  bool attachAccelStruct(
246  RV_Instance* inst,
247  const UT_StringRef& name,
248  RV_VKAccelerationStructure* accel_struct,
249  int index = 0);
250  /// Attach an acceleration structure to this variable set. Returns
251  /// false if the binding index doesn't exist or the acceleration
252  /// structure is null
253  bool attachAccelStruct(
254  RV_Instance* inst,
255  int binding_num,
256  RV_VKAccelerationStructure* accel_struct,
257  int index = 0);
258 
259  /// Clear a bound UBO, SSBO, buffer view, or texture from binding 'name'
260  void clearBinding(const UT_StringRef& name);
261  void clearBinding(RV_Render* r, const UT_StringRef& name);
262 
263  /// Clear a bound UBO, SSBO, buffer view, or texture from the binding index
264  void clearBinding(int binding_num);
265  void clearBinding(RV_Render* r, int binding_num);
266 
267  void clearExtraBindings();
268 
269  /// Take any pending bindings and write them to the descriptor set
270  void commitBindings(RV_Render* r);
271 
272  bool validateBinding(RV_Instance* inst, int binding_num);
273  bool validateBinding(RV_Instance* inst, int binding_num) const;
274  bool validateBindings(RV_Instance* inst) const;
275 
276  void recordBindings(RV_VKCommandBuffer *cb) const;
277 
278  // check that all bindings have been assigned
279  // -- also must check that all buffers/images are valid (have memory backing them, have not been deleted)
280  //
281 
282  /// Return true if all bindings have been assigned to the set
283  bool isReady(RV_Instance* inst) const;
284 
285  /// Return true if the set has been modified since the last commit
286  bool isDirty() const
287  {
288  UT_ASSERT_P(myIsSetDirty == !myDirtyBindings.isEmpty());
289  return myIsSetDirty;
290  }
291 
292  // Shader Layout info
293 
294  /// Return if this variable set is compatible with the given pipeline binding
295  /// layout of the shader.
296  bool isCompatibleToBind(const RV_VKDescriptorSetInfo& pipe_layout) const
297  { return pipe_layout.isCompatibleToBind(*myLayout); }
298 
299 
300  /// Return the binding number of the set that this set was created with.
301  inline int getSetNumber() const
302  { return mySetNumber; }
303 
304  /// Return the layout ID of the set that this set was created with.
305  inline int getLayoutID() const
306  { return mySetID; }
307 
308  // -------------------------------------------------------------------
309  // DEBUG
310 
311  /// Debug dump to stderr all information about the bindings
312  void print() const;
313 
314 private:
315  friend class RV_Render;
316 
317  // Returns true if binding exists and has a resource bound to it
318  bool isValidBinding(uint32_t binding_num, int index=0) const;
319 
320  bool privGetBinding(
321  const UT_StringRef& name,
322  int& out_binding_num,
323  const RV_VKDescriptorBinding*& out_binding) const;
324 
326  privWriteNewSet(
327  RV_Instance* inst,
328  const RV_ShaderVariableSet* opt_base);
329 
330 
331  // Only called by RV_Render
332  bool bindSet(RV_Render* r,
334 
335  bool bindSet(RV_Render* r,
336  const RV_ShaderProgramBase* shader) const;
337 
338  /// Pipeline Layout for shader
340  UT_StringHolder myName;
341  int mySetNumber;
342  exint mySetID;
343 
344  // Bindings:
345  // Mapping of Binding Names to Binding number in the layout
346  UT_ArrayStringMap<int> myBindingTable;
347  UT_Array<int> myBindingResourceIdx;
348 
349  // lists of resources
350  typedef std::pair<RV_ShaderBlock*, RV_ResourceID> BufferBlockResource;
351  typedef std::pair<RV_VKBuffer*, RV_ResourceID> BufferResource;
352  typedef std::tuple<RV_VKImage*, RV_ResourceID, RV_VKSampler*> TextureResource;
353  typedef std::pair<RV_VKAccelerationStructure*, RV_ResourceID> AccelStructResource;
354 
355  // TODO: combine the resource lists for the 3 buffer types
356  UT_Array<BufferBlockResource> myBufferBlocks;
357  UT_Array<BufferResource> myBufferViews;
358  UT_Array<BufferResource> myBufferArrays;
359  UT_Array<TextureResource> myTextures;
360  UT_Array<AccelStructResource> myAccelStructs;
361 
362  enum RV_BindingType
363  {
364  RV_BINDING_UNKNOWN = 0,
365  RV_BINDING_BLOCK_BUFFER,
366  RV_BINDING_TEXEL_BUFFER,
367  RV_BINDING_SSBO_ARRAY_BUFFER,
368  RV_BINDING_IMAGE,
369  RV_BINDING_ACCELERATION_STRUCTURE,
370  };
371 
372  // Simple variant/union-like struct
373  struct BindingResource
374  {
375  BindingResource() {}
376 
377  BindingResource(RV_BindingType type,
378  RV_ShaderBlock* block,
381  : myType(type)
382  , myBlock(block)
383  , myBuffer(buffer)
384  , myTexture(texture)
385  {}
386 
387  BindingResource(RV_ShaderBlock* v)
388  : myType(RV_BINDING_BLOCK_BUFFER)
389  , myBlock(v)
390  {}
391 
392  // NOTE: will be created by TEXEL_BUFFER or SSBO_ARRAY_BUFFER
393  BindingResource(RV_VKBuffer* v)
394  : myType(RV_BINDING_TEXEL_BUFFER)
395  , myBuffer(v)
396  {}
397 
398  BindingResource(RV_VKImage* v, RV_VKSampler* s)
399  : myType(RV_BINDING_IMAGE)
400  , myTexture(v)
401  , mySampler(s)
402  {}
403 
404  BindingResource(RV_VKAccelerationStructure* v)
405  : myType(RV_BINDING_ACCELERATION_STRUCTURE)
406  , myAccelStruct(v)
407  {}
408 
409  RV_BindingType myType = RV_BINDING_UNKNOWN;
410  RV_ShaderBlock* myBlock = nullptr;
411  RV_VKBuffer* myBuffer = nullptr;
412  RV_VKImage* myTexture = nullptr;
413  RV_VKSampler* mySampler = nullptr;
414  RV_VKAccelerationStructure* myAccelStruct = nullptr;
415  };
416 
417  // Extra Bindings -- Attached to the set by name but not
418  // part of the layout, so will not be bound as part of our set
419  // keep to copy into other sets if we transfer our resources
420  void privAttachExtraResource(const UT_StringHolder& name,
421  const BindingResource &res);
422  UT_StringMap<BindingResource> myExtraBindings;
423 
424  // Descriptor Sets:
425  // - DescriptorSets: Current descriptor sets
426  // - PendingUpdates: Updates to set that will be commited before use
427 
428  /// Our current up-to-date VK_DescriptorSet object
429  UT_UniquePtr<RV_VKDescriptorSet> myDescriptorSet;
430  UT_UniquePtr<RV_VKDescriptorLayout> myDescriptorLayout;
431 
432  /// pending writes for descriptor set
433  typedef std::tuple<int, int, RV_BindingType> BindingRef;
434  UT_Array<BindingRef> myDirtyBindings;
436  bool myIsSetDirty = false;
437 };
438 
439 #endif
440 
A collection of Vulkan UBO, SSBO, and Image shader bindings (descriptor set)
const UT_StringHolder & getName() const
Label for debugging.
const GLdouble * v
Definition: glcorearb.h:837
int64 exint
Definition: SYS_Types.h:125
bool isDirty() const
Return true if the set has been modified since the last commit.
GLdouble s
Definition: glad.h:3009
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
bool isCompatibleToBind(const RV_VKDescriptorSetInfo &other) const
std::unique_ptr< T, Deleter > UT_UniquePtr
A smart pointer for unique ownership of dynamically allocated objects.
Definition: UT_UniquePtr.h:39
GLint GLint GLsizei GLint GLenum GLenum type
Definition: glcorearb.h:108
#define UT_ASSERT_P(ZZ)
Definition: UT_Assert.h:155
#define RV_API
Definition: RV_API.h:10
GLuint const GLchar * name
Definition: glcorearb.h:786
Handle to the main interface of Vulkan.
Definition: RV_Instance.h:44
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
bool isCompatibleToBind(const RV_VKDescriptorSetInfo &pipe_layout) const
GLuint texture
Definition: glcorearb.h:415
GLboolean r
Definition: glcorearb.h:1222
A vulkan buffer object.
Definition: RV_VKBuffer.h:81
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.