HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
RV_VKDescriptorSet.h
Go to the documentation of this file.
1 /*
2  * PROPRIETARY INFORMATION. This software is proprietary to
3  * Side Effects Software Inc., and is not to be reproduced,
4  * transmitted, or disclosed in any way without written permission.
5  *
6  * NAME: RV_VKDescriptorSet.h ( RV Library, C++)
7  *
8  * COMMENTS:
9  * Descriptor Sets for Vulkan Pipelines
10  *
11  * Note on naming: trying to keep the naming a little less
12  * confusing than the Vulkan types:
13  * A Descriptor is a single resource in the shader
14  * A Descriptor Binding is a named binding point for
15  * a set of descriptors with the same type
16  * e.g. for array bindings, each element is a descriptor,
17  * for non-arrays the binding is 1 descriptor
18  * A Descriptor [Set/Layout] is a collection of bindings
19  * A Descriptor Set Layout is just an object descibing the layout
20  * A Descriptor Set is the actual object bindable to the pipeline
21  * A Pipeline Layout is a collection of Sets (+ Push Constant ranges)
22  *
23  * Trying to use these terms consistently, as they are less verboase than
24  * the Vulkan types:
25  * [RV Name] [Vulkan Name]
26  * PipelineLayout -> PipelineLayout
27  * DescriptorSet -> DescriptorSet
28  * DescriptorLayout -> DescriptorSetLayout
29  * DescriptorBinding* -> DescriptorSetLayoutBinding*
30  *
31  * * VkDescriptorSetLayoutBinding struct describes binding,
32  * (i.e. is the layout info). There is no object representing
33  * a binding itself, only whole sets
34  *
35  * ALSO adding the uniform, which isn't part of the spec. Uniform refers
36  * struct members for UBO and SSBO types, or the binding itself for other
37  * types: but with extra type info (e.g. the type of sampler/image)
38  *
39  * */
40 
41 #ifndef RV_VKDescriptorSet_h
42 #define RV_VKDescriptorSet_h
43 
44 #include "RV_API.h"
45 
46 #include <SYS/SYS_Hash.h>
47 #include <UT/UT_Array.h>
48 #include <UT/UT_Map.h>
49 #include <UT/UT_Lock.h>
50 #include <UT/UT_StringHolder.h>
51 #include <UT/UT_UniquePtr.h>
52 #include <UT/UT_RWLock.h>
53 
54 #include <VE/VE_VK.h>
55 #include "RV_Type.h"
56 #include "RV_TypePtrs.h"
57 
58 class RV_Instance;
59 class RV_VKCommandBuffer;
61 
62 void
64  int &out_typesize, // size of base type in bytes (e.g 4 or 8)
65  bool &out_is_int, // whether base type is int or float
66  int &out_size, // size of vector type (must do: out_size * out_col_num for matrix size)
67  int &out_align, // alignment of vector elment
68  int &out_vec_num, // number of vector elements
69  int &out_col_num // number of columns
70  );
71 
72 // -----------------
73 // RV_Uniform
74 //
75 // Will be used for UBO members, push constants, opaque-type bindings, etc.
76 /// Type info for a single variable in a shader
78 {
79 public:
80  RV_Uniform() = default;
81 
82  // ctor for opaque type
84  const UT_StringHolder &name,
86  uint32_t count,
87  uint32_t set,
88  uint32_t binding)
89  : RV_Uniform(name, type, count, set, binding,
90  0, 0, 0, 0, UT_Array<RV_Uniform>(), false)
91  {}
92 
93  // ctor for struct members
95  const UT_StringHolder &name,
97  uint32_t count,
98  uint32_t set,
99  uint32_t binding,
100  uint32_t offset,
101  uint32_t base_size,
102  uint32_t array_stride,
103  uint32_t matrix_stride,
104  const UT_Array<RV_Uniform>& members,
105  bool is_active)
106  : myName(name)
107  , myType(type)
108  , arraySize(count)
109  , set(set)
110  , binding(binding)
111  , offset(offset)
112  , baseSize(base_size)
113  , arrayStride(array_stride)
114  , matrixStride(matrix_stride)
115  , members(members)
116  , myIsActive(is_active)
117  {}
118 
119  /// Returns true if there is an SSBO array size for the variable
120  bool isRuntimeArray() const { return arraySize == 0; }
121 
122  // General properties
125  uint32_t arraySize = 1;
126 
127  // Locational info within set
128  uint32_t set = 0;
129  uint32_t binding = 0;
130 
131  // Properties only for Struct Members
132  /// byte offset of member in buffer block
133  uint32_t offset = 0;
134  /// size of base type. Will be raw size for vector/scalar/struct
135  /// and column vec size for matrix
136  uint32_t baseSize = 0;
137  /// offset between elements in an array
138  uint32_t arrayStride = 0;
139  /// offset between columns in a matrix
140  uint32_t matrixStride = 0;
141  /// list of members for struct types
143  // Whether or not the uniform is accessed in shader
144  bool myIsActive = true;
145  // list of members for struct type
147 };
148 
149 // -----------------
150 // RV_VKDescriptorBinding
151 //
152 // A single named binding point in a descriptor set
153 // Also contains RV_Uniforms with extra type info
155 {
156  bool isValid() const;
157 
158  RV_VKDescriptorBinding() = default;
159 
161  const UT_StringHolder& name,
163  uint32_t count,
165  uint32_t binding,
166  uint32_t set,
167  RV_UniformType uniform_type);
168 
170  const UT_StringHolder& name,
171  VkDescriptorType type,
172  uint32_t count,
173  VkShaderStageFlags stages,
174  uint32_t binding,
175  uint32_t set,
176  uint32_t buffer_size,
177  const UT_Array<RV_Uniform>& members);
178 
179  bool isCompatibleToMerge();
180  bool isCompatibleToBind();
181 
182  bool compare(
183  const RV_VKDescriptorBinding& other,
184  bool compare_uniforms_types,
185  bool compare_uniforms_names,
186  bool compare_binding_location,
187  bool compare_binding_stages) const;
188 
189  void merge(const RV_VKDescriptorBinding& other);
190 
191  // Basic Descriptor Type info
193  uint32_t myCount = 0;
194 
195  // Locational info, required for set creation
197  uint32_t myBindingNumber;
198 
199  // Extra info Provided by reflection
200  uint32_t mySetNumber;
202  uint32_t myBufferSize;
204 };
205 
206 // -----------------
207 // RV_VKDescriptorSetInfo
208 //
209 // Info used to create a DescriptorSetLayout object
211 {
212 public:
213  RV_VKDescriptorSetInfo() = default;
214  RV_VKDescriptorSetInfo(int set);
216  int set,
217  const UT_Array<RV_VKDescriptorBinding>& bindings);
218 
220 
221  // Non-const modifiers MUST invalidate hash
222  bool mergeDescriptorSet(const RV_VKDescriptorSetInfo &set);
223  void addBinding(const RV_VKDescriptorBinding& binding);
224 
225  bool isValid() const;
226 
227  // Fill Vulkan create info
228  void fillCreateInfo(
231 
232  bool isCompatibleToBind(const RV_VKDescriptorSetInfo& other) const;
233  bool isCompatibleToMerge(const RV_VKDescriptorSetInfo& other) const;
234  bool isCompatibleToCopy(const RV_VKDescriptorSetInfo& other) const;
235 
236  bool compare( const RV_VKDescriptorSetInfo& other,
237  bool allow_missing_bindings,
238  bool allow_different_stages,
239  UT_WorkBuffer* msg) const;
240 
241  int getSetNumber() const { return mySet; }
242 
243  exint getLayoutID() const { return myLayoutId; }
244 
245  bool hasBinding(uint32_t b_num) const
246  {
247  return b_num < myBindings.size() &&
248  myBindings(b_num).isValid();
249  }
250  const UT_Array<RV_VKDescriptorBinding>& getBindings() const { return myBindings; }
251 
252  void print() const;
253  void printDiff(const RV_VKDescriptorSetInfo& other) const;
254 
255 public:
256  // Saves hash AND fetches unique ID for layoud from global ID cache
257  void saveHash(RV_Instance* inst);
258  bool isHashValid() const { return myHashValid; }
259 
260  friend SYS_HashType calc_hash(const RV_VKDescriptorSetInfo& in);
262 
263  friend bool operator==( const RV_VKDescriptorSetInfo& lhs,
264  const RV_VKDescriptorSetInfo& rhs);
265 private:
266  int mySet = -1;
269 
270  friend class RV_VKDescriptorSet;
271 
272 private:
273  bool myHashValid = false;
274  size_t myHash;
275  exint myLayoutId;
276 };
277 
278 // -----------------
279 // RV_VKDescriptorLayout
280 //
281 // RAII wrapper for VKDescriptorSetLayout
283 {
284 public:
285  VkDescriptorSetLayout getVkDescriptorSetLayout() const
286  {
287  return myVkDescriptorSetLayout;
288  }
289 
291  RV_Instance* inst,
292  const RV_VKDescriptorSetInfo* info);
293 
295  : myInst(other.myInst)
296  , myVkDescriptorSetLayout(other.myVkDescriptorSetLayout)
297  {
298  other.myVkDescriptorSetLayout = nullptr;
299  other.myVkDescriptorSetLayout = VK_NULL_HANDLE;
300  }
301 
305 
307 
308 private:
309  struct PassKey {};
310 public:
312  RV_Instance* inst,
313  VkDescriptorSetLayout vk_layout,
314  const PassKey&)
315  : myInst(inst), myVkDescriptorSetLayout(vk_layout)
316  {
317  }
318 
319 private:
320  RV_Instance* myInst = nullptr;
321  VkDescriptorSetLayout myVkDescriptorSetLayout = VK_NULL_HANDLE;
322 };
323 
324 // ------------------------
325 // RV_VKDescriptorSetUpdates
326 //
327 // Grouped set of updates to apply to a descriptor set
328 // Doesn't have any knowledge of the DescriptorSetLayout
330 {
331 public:
332  bool hasBinding(uint32_t binding, uint32_t element = 0);
333 
334  // NOTE: specific descriptor type for buffer are left out
335  // They will be set from the layout when the updates
336  // are committed
337  void bindBuffer(
338  uint32_t binding,
339  uint32_t element,
340  VkBuffer vk_buf,
342  VkDeviceSize offset = 0,
344 
345  void bindImage(
346  uint32_t binding,
347  uint32_t element,
348  VkImageView img,
349  VkSampler sampler,
350  VkImageLayout layout,
351  VkDescriptorType type);
352 
353  void bindBufferView(
354  uint32_t binding,
355  uint32_t element,
356  VkBufferView buffer_view,
357  VkDescriptorType type);
358 
359  void copyBinding(
360  uint32_t dst_binding,
361  uint32_t dst_element,
362  uint32_t src_binding,
363  uint32_t src_element,
364  uint32_t count = 1);
365 
366  bool isDirty() const;
367 
368  void clear();
369 
372  RV_VKDescriptorSetUpdates() = default;
374 private:
375  // Vk Descriptor Set Updaate Descriptions
378 
379  //
380  // stored as arrays to ptrs, so the memory locations can't move
381  // if the array grows
384  UT_Array<UT_UniquePtr<VkBufferView>> myBufferViewWrites;
385 
386  friend class RV_VKDescriptorSet;
387 };
388 
389 // --------------------
390 // RV_VKDescriptorSet
391 //
392 // RAII Wrapper for VkDescriptorSet object
393 // and also contains RV_VKDescriptorSetInfo used to create it
395 {
396 public:
397  static UT_UniquePtr<RV_VKDescriptorSet> create(
398  RV_Instance* inst,
399  class RV_DescriptorAllocator& allocator,
400  const RV_VKDescriptorSetInfo& info,
401  RV_VKDescriptorSetUpdates& descriptor_writes,
402  const RV_VKDescriptorLayout *layout = nullptr,
403  const RV_VKDescriptorSet *copy_src = nullptr,
404  const char* name = nullptr);
405 
407  RV_Instance* inst,
408  VkDescriptorSet vk_set,
409  const RV_VKDescriptorSetInfo& info,
411 
413 
414  VkDescriptorSet getVkDescriptorSet() { return myVkDescriptorSet; }
415  const RV_VKDescriptorSetInfo* getInfo() const { return &myInfo; }
416 
417  bool bindSet(
418  RV_Instance* inst,
419  RV_VKCommandBuffer* cb,
420  const RV_VKPipelineLayout* pipe_layout);
421 
422 private:
423  // UpdateSet should only be called once after creation, to simplify.
424  // If some descriptors need to be changes, a new set must be allocated
425  void updateSet(
426  RV_VKDescriptorSetUpdates& set_updates,
427  const RV_VKDescriptorSet* copy_src = nullptr);
428 
429  RV_Instance* myInst;
430  VkDescriptorSet myVkDescriptorSet;
431  RV_VKDescriptorSetInfo myInfo;
432 
433  // NOTE: DON'T directly access, may be NULL if set created
434  // with externally owned layout. Shouldn't need to access,
435  // but `vkUpdateDescriptorSets()` CAN implicity access the
436  // layout used to create dst/src arguments, so we need
437  // to keep it around, instead of destroying immediately,
438  // if it was created just-in-time during our creation
439  // TODO: probably just always provide externally
441 };
442 
443 // --------------------
444 // RV_VKDescriptorPool
445 //
446 // Wrapper for VkDescriptorPool object used to allocate sets
448 {
449 public:
451  RV_Instance* inst,
453  VkDescriptorPool vk_desc_pool)
454  : myInst(inst), mySizes(sizes), myVkDescPool(vk_desc_pool)
455  {}
456 
457 
459 
460  VkResult allocateSet(VkDescriptorSetLayout layout, VkDescriptorSet& set);
461  VkResult freeSet(VkDescriptorSet set);
462 
463  static RV_VKDescriptorPoolPtr createPool(
464  RV_Instance* inst,
465  uint32_t max_sets,
467 
468  // create with random size ratios
469  static RV_VKDescriptorPoolPtr createPool(
470  RV_Instance* inst,
471  uint32_t max_sets);
472 
473 private:
474  VkDescriptorPool myVkDescPool = VK_NULL_HANDLE;
475  RV_Instance* myInst = nullptr;
477 };
478 
479 // ------------------------
480 // RV_DescriptorAllocator
481 //
482 // Higher level object to handle descriptor set allocations
483 // Used by RV_VKDescriptorSet::create to create Sets, and
484 // allocates more Descriptor Pools as needed
485 //
486 // TODO: track owned allocations for cleanup ?
488 {
489 public:
490 
492 
493  VkDescriptorSet allocateVkDescriptorSet(VkDescriptorSetLayout vk_layout);
494  void freeVkDescriptorSet(VkDescriptorSet vk_set);
495 
497 
498  RV_DescriptorAllocator() = delete;
501 
502  exint getIdForSetLayout(const RV_VKDescriptorSetInfo& info);
503 private:
504  void allocateNewPool();
505 
506  RV_Instance* myInst;
508  uint32_t mySetSize;
509 
510  UT_Lock myPoolLock;
512  UT_Map<VkDescriptorSet, int> mySetToPoolTable;
513 
514  // Lock access of `layoutIdCache` and `myNextId` behind `myIdCacheLock`
515  // TODO: look into using more general cache class?
516  UT_RWLock myIdCacheLock;
517  exint myNextId = 1;
519 };
520 
521 #endif
GLuint GLsizei const GLuint const GLintptr const GLsizeiptr * sizes
Definition: glcorearb.h:2621
const RV_VKDescriptorSetInfo * getInfo() const
RV_Uniform(const UT_StringHolder &name, RV_UniformType type, uint32_t count, uint32_t set, uint32_t binding, uint32_t offset, uint32_t base_size, uint32_t array_stride, uint32_t matrix_stride, const UT_Array< RV_Uniform > &members, bool is_active)
#define VK_NULL_HANDLE
Definition: vulkan_core.h:45
VkResult
Definition: vulkan_core.h:139
GLbitfield stages
Definition: glcorearb.h:1931
VkShaderStageFlags myStages
int64 exint
Definition: SYS_Types.h:125
std::size_t SYS_HashType
Define the type for hash values.
Definition: SYS_Hash.h:19
void RVgetUniformSize(RV_UniformType type, int &out_typesize, bool &out_is_int, int &out_size, int &out_align, int &out_vec_num, int &out_col_num)
GLuint sampler
Definition: glcorearb.h:1656
VkDescriptorSet getVkDescriptorSet()
UT_UniquePtr< RV_VKDescriptorPool > RV_VKDescriptorPoolPtr
Definition: RV_TypePtrs.h:59
UT_Array< RV_Uniform > myUniforms
UT_StringHolder myName
std::unique_ptr< T, Deleter > UT_UniquePtr
A smart pointer for unique ownership of dynamically allocated objects.
Definition: UT_UniquePtr.h:39
VkDescriptorType
Definition: vulkan_core.h:2048
bool operator==(const BaseDimensions< T > &a, const BaseDimensions< Y > &b)
Definition: Dimensions.h:137
CompareResults OIIO_API compare(const ImageBuf &A, const ImageBuf &B, float failthresh, float warnthresh, ROI roi={}, int nthreads=0)
#define VK_WHOLE_SIZE
Definition: vulkan_core.h:131
GLintptr offset
Definition: glcorearb.h:665
bool isRuntimeArray() const
Returns true if there is an SSBO array size for the variable.
RV_UniformType
Definition: RV_Type.h:284
#define RV_API
Definition: RV_API.h:10
RV_Uniform(const UT_StringHolder &name, RV_UniformType type, uint32_t count, uint32_t set, uint32_t binding)
GLuint const GLchar * name
Definition: glcorearb.h:786
Handle to the main interface of Vulkan.
Definition: RV_Instance.h:38
GLint void * img
Definition: glcorearb.h:556
const UT_Array< RV_VKDescriptorBinding > & getBindings() const
RV_VKDescriptorLayout(RV_Instance *inst, VkDescriptorSetLayout vk_layout, const PassKey &)
VkFlags VkDescriptorSetLayoutCreateFlags
Definition: vulkan_core.h:2693
GLsizeiptr size
Definition: glcorearb.h:664
VkImageLayout
Definition: vulkan_core.h:1250
LeafData & operator=(const LeafData &)=delete
UT_Array< RV_Uniform > members
list of members for struct types
UT_Array< RV_Uniform > myMembers
uint64_t VkDeviceSize
Definition: vulkan_core.h:95
bool hasBinding(uint32_t b_num) const
RV_VKDescriptorLayout(RV_VKDescriptorLayout &&other)
Reader/Writer mutex class.
Definition: UT_RWLock.h:48
size_t hash_value(const CH_ChannelRef &ref)
type
Definition: core.h:1059
FMT_INLINE void print(format_string< T...> fmt, T &&...args)
Definition: core.h:2976
VkDescriptorSetLayout getVkDescriptorSetLayout() const
Type info for a single variable in a shader.
GLint GLsizei count
Definition: glcorearb.h:405
RV_VKDescriptorPool(RV_Instance *inst, const UT_Array< VkDescriptorPoolSize > &sizes, VkDescriptorPool vk_desc_pool)
VkFlags VkShaderStageFlags
Definition: vulkan_core.h:2660