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_VKCommandBuffer;
34 class RV_VKBuffer;
35 class RV_VKImage;
36 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,
54  const char* name = nullptr);
56 
58  RV_Instance* inst,
59  const RV_VKDescriptorSetInfo* layout,
60  const RV_ShaderVariableSet* opt_base = nullptr,
61  const char* name = 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  /// The raw Vulkan descritor set create info
84  { return *myLayout.get(); }
85 
86  // --------------------------------
87  // Bound Resources
88  // TODO: make return value ptr, instead of output var?
89 
90  /// Fetch a bound UBO or SSBO with the given name (may be null)
91  /// Return false if the binding doesn't exist or isn't a buffer object.
92  bool getBufferBlock(const UT_StringRef& name, RV_ShaderBlock*& out_block);
93  /// Fetch a bound UBO or SSBO with the given name (may be null)
94  /// Return false if the binding doesn't exist or isn't a buffer object.
95  bool getBufferBlock(const UT_StringRef& name, const RV_ShaderBlock*&) const;
96  /// Fetch a bound UBO or SSBO by index (may be null).
97  /// Return false if the binding doesn't exist or isn't a buffer object.
98  bool getBufferBlock(int binding_num, RV_ShaderBlock*& out_block);
99  /// Fetch a bound UBO or SSBO by index (may be null).
100  /// Return false if the binding doesn't exist or isn't a buffer object.
101  bool getBufferBlock(int binding_num, const RV_ShaderBlock*& out_block)
102  const;
103 
104  /// Fetch a bound texture with the given name (may be null)
105  /// Return false if the binding doesn't exist or isn't a texture.
106  bool getTexture(const UT_StringRef& name, RV_VKImage*& out_image);
107  /// Fetch a bound texture with the given name (may be null)
108  /// Return false if the binding doesn't exist or isn't a texture.
109  bool getTexture(const UT_StringRef& name, const RV_VKImage*&) const;
110  /// Fetch a bound texture by index (may be null)
111  /// Return false if the binding doesn't exist or isn't a texture.
112  bool getTexture(int binding_num, RV_VKImage*& out_image);
113  /// Fetch a bound texture by index (may be null)
114  /// Return false if the binding doesn't exist or isn't a texture.
115  bool getTexture(int binding_num, const RV_VKImage*& out_image) const;
116 
117  /// Fetch a bound buffer view (TBO in GL) by the given name (may be null)
118  /// Return false if the binding doesn't exist or isn't a buffer view.
119  bool getBufferView(const UT_StringRef& name, RV_VKBuffer*& out_buffer);
120  /// Fetch a bound buffer view (TBO in GL) by the given name (may be null)
121  /// Return false if the binding doesn't exist or isn't a buffer view.
122  bool getBufferView(const UT_StringRef& name, const RV_VKBuffer*&) const;
123  /// Fetch a bound buffer view (TBO in GL) by index (may be null)
124  /// Return false if the binding doesn't exist or isn't a buffer view.
125  bool getBufferView(int binding_num, RV_VKBuffer*& out_buffer);
126  /// Fetch a bound buffer view (TBO in GL) by index (may be null)
127  /// Return false if the binding doesn't exist or isn't a buffer view.
128  bool getBufferView(int binding_num, const RV_VKBuffer*& out_buffer) const;
129 
130  // Must attach buffers before using to draw
131  // Marks the buffer as used by the Descriptor Set
132  // Will wait until used for a draw to actually update the set
133 
134  /// Attach a UBO or SSBO to this variable set. Returns false if the binding
135  /// name doesn't exist, the block is null, or it isn't compatible with the
136  /// layout of the binding.
137  bool attachBufferBlock(
138  RV_Instance* inst,
139  const UT_StringRef& name,
140  RV_ShaderBlock* buffer_block,
141  int index = 0);
142  /// Attach a UBO or SSBO to this variable set. Returns false if the binding
143  /// index doesn't exist, the block is null, or it isn't compatible with the
144  /// layout of the binding.
145  bool attachBufferBlock(
146  RV_Instance* inst,
147  int binding_num,
148  RV_ShaderBlock* buffer_block,
149  int index = 0);
150 
151  /// Attach a buffer view (TBO in GL) to this variable set. Returns false if
152  /// the binding name doesn't exist, the buffer is null, or it isn't
153  /// compatible with the layout of the binding.
154  bool attachBufferView(
155  RV_Instance* inst,
156  const UT_StringRef& name,
158  int index = 0);
159  /// Attach a buffer view (TBO in GL) to this variable set. Returns false if
160  /// the binding index doesn't exist, the buffer is null, or it isn't
161  /// compatible with the layout of the binding.
162  bool attachBufferView(
163  RV_Instance* inst,
164  int binding_num,
166  int index = 0);
167 
168  /// Attach a texture or image to this variable set. Returns false if
169  /// the binding name doesn't exist, the image is null, or it isn't
170  /// compatible with the sampler type of the binding.
171  bool attachTexture(
172  RV_Instance* inst,
173  const UT_StringRef& name,
174  RV_VKImage* image,
175  RV_VKSampler* opt_sampler,
176  int index = 0);
177  /// Attach a texture or image to this variable set. Returns false if
178  /// the binding index doesn't exist, the image is null, or it isn't
179  /// compatible with the sampler type of the binding.
180  bool attachTexture(
181  RV_Instance* inst,
182  int binding_num,
183  RV_VKImage* image,
184  RV_VKSampler* opt_sampler,
185  int index = 0);
186  /// Attach a texture or image to this variable set. Returns false if
187  /// the binding name doesn't exist, the image is null, or it isn't
188  /// compatible with the sampler type of the binding.
189  bool attachTexture(
190  RV_Instance* inst,
191  const UT_StringRef& name,
192  RV_VKImage* image,
193  int index = 0);
194  /// Attach a texture or image to this variable set. Returns false if
195  /// the binding index doesn't exist, the image is null, or it isn't
196  /// compatible with the sampler type of the binding.
197  bool attachTexture(
198  RV_Instance* inst,
199  int binding_num,
200  RV_VKImage* image,
201  int index = 0);
202 
203  /// Clear a bound UBO, SSBO, buffer view, or texture from binding 'name'
204  void clearBinding(const UT_StringRef& name);
205  void clearBinding(RV_Render* r, const UT_StringRef& name);
206 
207  /// Clear a bound UBO, SSBO, buffer view, or texture from the binding index
208  void clearBinding(int binding_num);
209  void clearBinding(RV_Render* r, int binding_num);
210 
211  void clearExtraBindings();
212 
213  /// Take any pending bindings and write them to the descriptor set
214  void commitBindings(RV_Instance* inst, RV_VKCommandBuffer* cb);
215 
216  // check that all bindings have been assigned
217  // -- also must check that all buffers/images are valid (have memory backing them, have not been deleted)
218  //
219 
220  /// Return true if all bindings have been assigned to the set
221  bool isReady(RV_Instance* inst) const;
222 
223  /// Return true if the set has been modified since the last commit
224  inline bool isDirty() const;
225 
226  // Shader Layout info
227 
228  /// Return if this variable set is compatible with the given pipeline binding
229  /// layout of the shader.
230  bool isCompatibleToBind(const RV_VKDescriptorSetInfo& pipe_layout) const
231  { return pipe_layout.isCompatibleToBind(*myLayout); }
232 
233 
234  /// Return the binding number of the set that this set was created with.
235  inline int getSetNumber() const
236  { return mySetNumber; }
237 
238  /// Return the layout ID of the set that this set was created with.
239  inline int getLayoutID() const
240  { return mySetID; }
241 
242  // -------------------------------------------------------------------
243  // DEBUG
244 
245  /// Debug dump to stderr all information about the bindings
246  void print() const;
247 
248 private:
249  friend class RV_Render;
250 
251  // Returns true if binding exists and has a resource bound to it
252  bool isValidBinding(uint32_t binding_num, int index=0) const;
253 
254  bool privGetBinding(
255  const UT_StringRef& name,
256  int& out_binding_num,
257  const RV_VKDescriptorBinding*& out_binding) const;
258 
260  privWriteNewSet(
261  RV_Instance* inst,
262  const RV_ShaderVariableSet* opt_base);
263 
264 
265  // Only called by RV_Render
266  bool bindSet(
267  RV_Instance* r,
268  RV_VKCommandBuffer* cb,
270 
271  bool bindSet(
272  RV_Instance* r,
273  RV_VKCommandBuffer* cb,
274  const RV_ShaderProgramBase* shader) const;
275 
276  /// Pipeline Layout for shader
278  UT_StringHolder myName;
279  int mySetNumber;
280  exint mySetID;
281 
282  // Uniform Blocks:
283  /// Mapping of uniform names, to indices in myUniforms
284  UT_ArrayStringMap<int> myUniformTable;
285  UT_Array<const RV_Uniform*> myUniforms;
286 
287  // Bindings:
288  // Mapping of Binding Names to Binding number in the layout
289  UT_ArrayStringMap<int> myBindingTable;
290  UT_Array<int> myBindingResourceIdx;
291 
292  // lists of resources
293  typedef std::pair<RV_ShaderBlock*, exint> BufferBlockResource;
294  typedef std::pair<RV_VKBuffer*, exint> BufferResource;
295  typedef std::tuple<RV_VKImage*, exint, RV_VKSampler*> TextureResource;
296 
297  UT_Array<BufferBlockResource> myBufferBlocks;
298  UT_Array<BufferResource> myBufferViews;
299  UT_Array<TextureResource> myTextures;
300 
301  enum RV_BindingType
302  {
303  RV_BINDING_UNKNOWN = 0,
304  RV_BINDING_BLOCK,
305  RV_BINDING_BUFFER,
306  RV_BINDING_IMAGE,
307  };
308 
309  // Simple variant/union-like struct
310  struct BindingResource
311  {
312  BindingResource() {}
313 
314  BindingResource(RV_BindingType type,
315  RV_ShaderBlock* block,
318  : myType(type)
319  , myBlock(block)
320  , myBuffer(buffer)
321  , myTexture(texture)
322  {}
323 
324  BindingResource(RV_ShaderBlock* v)
325  : myType(RV_BINDING_BLOCK)
326  , myBlock(v)
327  {}
328 
329  BindingResource(RV_VKBuffer* v)
330  : myType(RV_BINDING_BUFFER)
331  , myBuffer(v)
332  {}
333 
334  BindingResource(RV_VKImage* v, RV_VKSampler* s)
335  : myType(RV_BINDING_IMAGE)
336  , myTexture(v)
337  , mySampler(s)
338  {}
339 
340  RV_BindingType myType = RV_BINDING_UNKNOWN;
341  RV_ShaderBlock* myBlock = nullptr;
342  RV_VKBuffer* myBuffer = nullptr;
343  RV_VKImage* myTexture = nullptr;
344  RV_VKSampler* mySampler = nullptr;
345  };
346 
347  // Extra Bindings -- Attached to the set by name but not
348  // part of the layout, so will not be bound as part of our set
349  // keep to copy into other sets if we transfer our resources
350  void privAttachExtraResource(const UT_StringHolder& name,
351  const BindingResource &res);
352  UT_StringMap<BindingResource> myExtraBindings;
353 
354  // Descriptor Sets:
355  // - DescriptorSets: Current descriptor sets
356  // - PendingUpdates: Updates to set that will be commited before use
357 
358  /// Our current up-to-date VK_DescriptorSet object
359  UT_UniquePtr<RV_VKDescriptorSet> myDescriptorSet;
360  UT_UniquePtr<RV_VKDescriptorLayout> myDescriptorLayout;
361 
362  /// pending writes for descriptor set
363  typedef std::tuple<int, int, RV_BindingType> BindingRef;
364  UT_Array<BindingRef> myDirtyBindings;
366  bool myIsSetDirty = false;
367 };
368 
369 #endif
370 
A collection of Vulkan UBO, SSBO, and Image shader bindings (descriptor set)
const GLdouble * v
Definition: glcorearb.h:837
int64 exint
Definition: SYS_Types.h:125
GLdouble s
Definition: glad.h:3009
GLenum GLenum GLsizei void * image
Definition: glad.h:5132
const RV_VKDescriptorSetInfo & getSetInfo() const
The raw Vulkan descritor set create info.
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
Definition: core.h:760
#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:38
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
type
Definition: core.h:1059
FMT_INLINE void print(format_string< T...> fmt, T &&...args)
Definition: core.h:2976
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.