HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
RV_ShaderProgram.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_ShaderProgram.h ( RV Library, C++)
8  *
9  * COMMENTS:
10  * Class to handle creating Shaders, a collection of
11  * Vulkan Pipeline Objects
12  */
13 
14 #ifndef RV_ShaderProgram_h
15 #define RV_ShaderProgram_h
16 
17 
18 #include <typeinfo>
19 
20 #include "RV_API.h"
21 
22 #include <utility>
23 
24 #include <UT/UT_Array.h>
25 #include <UT/UT_ArrayStringMap.h>
26 #include <UT/UT_Lock.h>
27 #include <UT/UT_StringArray.h>
28 #include <UT/UT_StringHolder.h>
29 #include <UT/UT_Tuple.h>
30 #include <UT/UT_UniquePtr.h>
31 
32 #include "RV_VK.h"
33 #include "RV_Type.h"
34 #include "RV_VKDescriptorSet.h"
35 #include "RV_VKPipeline.h"
36 #include "RV_VKPipelineLayout.h"
37 
38 class RV_Geometry;
39 class RV_Instance;
41 class RV_VKCommandBuffer;
42 class RV_VKShader;
43 class RV_VKShaderModule;
44 
45 // load definition of a UBO from a .blk file
46 extern RV_API RV_VKDescriptorBinding loadShaderBlock(RV_Instance *inst, const char *block);
47 
49 {
50 public:
52  RV_GPUType type, int vec_size)
53  : myName(name), myLocation(location)
54  , myType(type), myVecSize(vec_size)
55  {}
56 
60  int myVecSize;
61 };
62 
64 {
65 public:
67  : myDefaultAttributes(0)
68  {}
69 
70  // Bitfield of which attributes match the default definition
72 
73  // Full info for custom attribs
76 };
77 
78 // ~~~~~~~~~~~
79 // RV_ShaderProgramBase
80 //
81 /// class for shared functionality between different types of shaders:
82 /// mainly accessing the the pipeline layout. Other shader types
83 /// can build on extra functionality, e.g. input attributes for Graphics
85 {
86 public:
88  virtual ~RV_ShaderProgramBase();
89 
90  /// Set a descriptive name for the shader
91  void setName(const UT_StringHolder &name) { myName = name; }
92  /// Descriptive name of the shader
93  const UT_StringHolder &name() const { return myName; }
94 
95  /// Type of shader - graphics or compute
96  virtual RV_ShaderType getShaderType() const = 0;
97 
98  // ------------------------------------
99  // Sets
100 
101  /// The number of descriptor sets in the shader
102  int getMaxSetNumber() const
103  {
104  return myLayout->getInfo().myDescriptorSets.size() - 1;
105  }
106  /// Query if set 'set_num' is used by the shader
107  bool hasSet(int set_num) const
108  {
109  return set_num >= 0
110  && set_num < myLayout->getInfo().myDescriptorSets.size()
111  && myLayout->getInfo().myDescriptorSets[set_num].isValid();
112  }
113  /// Return true if 'set' is compatable with the set layout in this shader.
114  bool isSetCompatible(const RV_ShaderVariableSet& set) const;
115  /// Query information on set 'set_num'
116  const RV_VKDescriptorSetInfo* getSetInfo(int set_num) const
117  {
118  return hasSet(set_num)
119  ? &getLayout().getInfo().myDescriptorSets[set_num]
120  : nullptr;
121  }
122  /// Create a shader varaible set (descriptor set) for set 'set_num'
123  UT_UniquePtr<RV_ShaderVariableSet> createSet(RV_Instance* inst, int set_num)
124  const;
125 
126  // ------------------------------------
127  // Full Layout
128 
129  /// The layout of all sets and inputs of the shader
130  const RV_VKPipelineLayout& getLayout() const { return *myLayout; }
131 
132  // ------------------------------------
133  // Bindings
134 
135  /// Query if a binding named 'name' exists
136  bool hasBinding(const UT_StringRef& name) const;
137  /// Return a binding at index 'binding' for set index 'set'
138  const RV_VKDescriptorBinding* getBinding(int set, int binding) const;
139  /// Return a binding for 'name'
140  const RV_VKDescriptorBinding* getBinding(const UT_StringRef& name) const;
141  /// Return the list of set bindings
142  const UT_Array<const RV_VKDescriptorBinding*>& getBindingList() const;
143 
144  // ------------------------------------
145  // Uniforms
146 
147  /// Query if the uniform named 'name' exists
148  bool hasUniform(const UT_StringRef& name) const;
149  /// Return type, size, and offset information about the uniform
150  const RV_Uniform* getUniform(const UT_StringRef& name) const;
151  /// Return a list of all uniforms in this shader
152  const UT_Array<const RV_Uniform*>& getUniformList() const;
153 
154  // ------------------------------------
155  // Push Constants
156 
157  /// Query if push constant with 'name' exists
158  bool hasPushConstant(const UT_StringRef& name) const;
159  /// Fetch the push constant 'name' with an optional array index
160  const RV_Uniform* getPushConstant(const UT_StringRef& name, int* opt_idx) const;
161  const UT_Array<RV_VKPushConstantRange>& getPushConstantRanges() const;
162 
163  /// Debug print message
164  virtual void print() const {};
165 protected:
166  // ~~~~~~~~~~~~~
167  // Helper functions to load pipeline layouts
168 
169  // Create Shader from prog file, using pre-compiled spir-v if found
170  // or compiling if no spir-v found, and sources have been copied to hfs
171  // NOTE: providing extra defines forces compilation
172  static RV_VKPipelineLayout* loadShaderProgram(
173  RV_Instance* inst,
174  const char* program,
175  const char* extra_defines = nullptr);
176 
177  // Create Shader using GLSL to SPIR-V compiler object
178  static RV_VKPipelineLayout* createShaderProgram(
179  RV_Instance* inst,
181  const char* name = nullptr);
182 
183  // Create Shader using list of SPIR-V binary filenames
184  static RV_VKPipelineLayout* createShaderProgram(
185  RV_Instance* inst,
186  const UT_StringArray& filenames,
187  const char* name = nullptr);
188 
189  // -------------------------------
190  // Attributes
191  // info shared between shader program, geometry, descriptor set, pipeline
193  // mapping of input name to place in table
195 
196  // -------------------------------
197  // Layout info:
198  // Pipeline Layout for shader
200 
201  // -------------------------------
202  // Uniforms
204  /// Mapping of uniform names, to indices in myUniforms
206 
207  // -------------------------------
208  // Bindings
210  /// mapping of binding name to set + binding number
212 
213  // -------------------------------
214  // Push Constants:
217 
219 
220  friend RV_Geometry;
222 };
223 
224 // ~~~~~~~~~~~
225 // RV_ShaderProgram
226 //
227 // Represents a single shader program that can be bound to the render state
228 // Holds pipeline layout and collection of cached pipeline objects
229 //
230 // Creates pipeline objects just before use, since actually pipeline construction
231 // requires knowledge of render state.
232 //
233 // Must be thread-safe (so the same pipeline can be used in multiple threads)
234 //
235 // Does not store active descriptorsets, but has helper functions to bind them,
236 // check them, and commit them to the render state
237 //
238 // Usually used with an RV_Geometry object to draw geometry
239 
240 // Shader works with lazy binding. Setting shader writes it to render state
241 // but no changes made to command buffer state until `commitBinding()` called
242 // -- usually called just before usage
243 
244 // Commit the shader to the Command Buffer. Must:
245 // - build final pipeline
246 // - commit descriptor set writes
247 // - bind shader
248 // - bind descriptor sets
249 //
250 
251 /// A single graphics shader program that can be bound to the render state
252 /// Holds pipeline layout and collection of cached pipeline objects
254 {
255 public:
256  /// Create Shader from prog file, using pre-compiled spir-v if found
257  /// or compiling if no spir-v found, and sources have been copied to hfs
258  /// NOTE: providing extra defines forces compilation
260  RV_Instance* inst,
261  const char* program,
262  const char* extra_defines = nullptr);
263 
264  /// Create Shader using GLSL to SPIR-V compiler object
266  RV_Instance* inst,
268  const char* name = nullptr);
269 
270  /// Create Shader using list of SPIR-V binary filenames
272  RV_Instance* inst,
273  const UT_StringArray& filenames,
274  const char* name = nullptr);
275 
276  // Create Shader using list of SPIR-V module filenames
278  RV_Instance* inst,
280  const char* name = nullptr);
281 
282  /// Type of the shader, Graphics or Compute
283  RV_ShaderType getShaderType() const override
284  {
285  return RV_SHADER_GRAPHICS;
286  };
287 
288  ~RV_ShaderProgram() override;
289 
290 
291  // TODO: rename: commitRenderState or compileState
292 
293  /// Finalize all set bindings in preparation for a draw
294  bool prepareForDraw(
295  RV_Instance* inst,
296  RV_VKCommandBuffer* cb,
297  const RV_VKPipelineStateInfo& pipe_state,
298  const RV_VKPipelineInputInfo& pipe_input);
299 
300  // ------------------------------------
301  // Attributes
302 
303  /// Query if a vertex shader input 'name' exists
304  bool hasAttribute(const UT_StringRef& name) const;
305  /// Query the information about a vertex shader input
306  bool getAttribute(const UT_StringRef& name,
307  int& out_location,
308  RV_GPUType& out_type,
309  int& out_vec_size) const;
310  /// The list of vertex shader inputs (attributes)
312  {
313  return myInputs;
314  }
315 
316  /// The list and state of vertex shader inputs (attributes)
318  {
319  return myInputState;
320  }
321 
322  /// Debug Print function; dump all shader variable sets and inputs/outputs
323  void print() const override;
324 
325 private:
327  RV_Instance* inst,
328  RV_VKPipelineLayout* layout);
329 
330  RV_ShaderProgram(RV_Instance* inst, RV_VKPipelineLayout* pipe_layout);
331 
332  // Cache of pipeline objects already created for this shader
333  // and the pipeline state they were created for
334  // TODO: hash pipeline state for faster lookup
335  typedef UT_Tuple<
338  PipelineCreateInfo;
339 
340  UT_Array<std::pair<
341  PipelineCreateInfo,
343  myPipelineCache;
344  // Lock for accessing pipeline cache accross multiple threads
345  // TODO: add "immutable" pipeline-cache for lock-free accesss
346  UT_Lock myPipelineCacheLock;
347 
348  // -------------------------------
349  // Attributes
350  // info shared between shader program, geometry, descriptor set, pipeline
352  RV_ShaderInputState myInputState;
353  // mapping of input name to place in table
355 
356 
357  friend RV_Geometry;
358  friend RV_ShaderVariableSet;
359 };
360 
361 
362 // ~~~~~~~~~~~
363 // RV_ShaderCompute
364 //
365 /// Compute shader object
367 {
368 public:
369  // /Create Shader from prog file, using pre-compiled spir-v if found
370  /// or compiling if no spir-v found, and sources have been copied to hfs
371  /// NOTE: providing extra defines forces compilation
373  RV_Instance* inst,
374  const char* program,
375  const char* extra_defines = nullptr);
376 
377  /// Create Shader using GLSL to SPIR-V compiler object
379  RV_Instance* inst,
381 
382  /// Create Shader using list of SPIR-V binary filenames
384  RV_Instance* inst,
385  const UT_StringArray& filenames);
386 
387  /// Create Shader using list of SPIR-V module filenames
389  RV_Instance* inst,
391 
392  RV_ShaderType getShaderType() const override
393  {
394  return RV_SHADER_COMPUTE;
395  };
396 
397  bool prepareForDraw(
398  RV_Instance* inst,
399  RV_VKCommandBuffer* cb);
400 
401  // Debug Print function
402  void print() const override;
403 
404 protected:
406  RV_Instance* inst,
407  RV_VKPipelineLayout* layout);
408 
410  RV_Instance* inst,
411  RV_VKPipelineLayout* pipe_layout,
412  RV_VKPipeline* pipeline);
413 
415 };
416 
417 #endif
A collection of Vulkan UBO, SSBO, and Image shader bindings (descriptor set)
UT_Array< const RV_VKDescriptorBinding * > myBindings
int int32
Definition: SYS_Types.h:39
UT_Array< RV_ShaderInput > myInputs
RV_ShaderType getShaderType() const override
Type of the shader, Graphics or Compute.
UT_StringHolder myName
RV_GPUType myType
Object that represents drawable geometry. This object holds vertex, instancing and index buffers for ...
Definition: RV_Geometry.h:164
int getMaxSetNumber() const
The number of descriptor sets in the shader.
std::tuple< Types...> UT_Tuple
Definition: UT_Tuple.h:53
const RV_VKDescriptorSetInfo * getSetInfo(int set_num) const
Query information on set 'set_num'.
UT_ArrayStringMap< int > myInputTable
std::unique_ptr< T, Deleter > UT_UniquePtr
A smart pointer for unique ownership of dynamically allocated objects.
Definition: UT_UniquePtr.h:39
const UT_StringHolder & name() const
Descriptive name of the shader.
bool hasSet(int set_num) const
Query if set 'set_num' is used by the shader.
Compute shader object.
UT_ArrayStringMap< int > myInputTable
UT_Array< RV_ShaderInput > myCustomInputs
RAII wrapper class for VkPipeline.
RV_API RV_VKDescriptorBinding loadShaderBlock(RV_Instance *inst, const char *block)
UT_ArrayStringMap< int > myUniformTable
Mapping of uniform names, to indices in myUniforms.
#define RV_API
Definition: RV_API.h:10
UT_ArrayStringMap< std::pair< int, int > > myBindingTable
mapping of binding name to set + binding number
GLint location
Definition: glcorearb.h:805
GLuint const GLchar * name
Definition: glcorearb.h:786
UT_UniquePtr< const RV_VKPipelineLayout > myLayout
virtual void print() const
Debug print message.
Handle to the main interface of Vulkan.
Definition: RV_Instance.h:36
const RV_ShaderInputState & getInputState() const
The list and state of vertex shader inputs (attributes)
RV_ShaderType
Definition: RV_Type.h:405
UT_StringHolder myName
void setName(const UT_StringHolder &name)
Set a descriptive name for the shader.
UT_Array< const RV_Uniform * > myPushConstants
GLuint shader
Definition: glcorearb.h:785
static RV_VKPipelineLayout * loadShaderProgram(RV_Instance *inst, const char *program, const char *extra_defines=nullptr)
RV_ShaderInput(const UT_StringHolder &name, int location, RV_GPUType type, int vec_size)
RV_GPUType
Definition: RV_Type.h:37
UT_ArrayStringMap< int > myPushConstTable
UT_UniquePtr< RV_VKPipeline > myPipeline
const RV_VKPipelineLayout & getLayout() const
The layout of all sets and inputs of the shader.
UT_Array< const RV_Uniform * > myUniforms
type
Definition: core.h:1059
Type info for a single variable in a shader.
GLbitfield GLuint program
Definition: glcorearb.h:1931
static RV_VKPipelineLayout * createShaderProgram(RV_Instance *inst, RV_VKShader &shader, const char *name=nullptr)
const UT_Array< RV_ShaderInput > & getAttributeList() const
The list of vertex shader inputs (attributes)
RV_ShaderType getShaderType() const override
Type of shader - graphics or compute.