HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
RV_VKShaderCompile.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_VKShaderCompile.h ( RV Library, C++)
7  *
8  * COMMENTS:
9  * Helper for compiling glsl code into Vulkan SPIR-V
10  */
11 
12 #ifndef RV_VKShaderCompile_h
13 #define RV_VKShaderCompile_h
14 
15 #include "RV_API.h"
16 
17 #include <UT/UT_Array.h>
18 #include <UT/UT_UniquePtr.h>
19 
20 #include <RE/RE_UniformBlock.h>
21 #include <RE/RE_Shader.h>
22 
23 #include "RV_Type.h"
24 
25 struct RV_SpvProgramCompileImpl;
26 struct RV_SpvStageCompileImpl;
27 class RV_ShaderInput;
28 class RV_VKShaderModule;
31 class UT_StringRef;
32 
34 {
37 
38  RV_LOC_P = 0,
39  RV_LOC_CD = 1,
41  RV_LOC_N = 3,
42  RV_LOC_CE = 3,
43  RV_LOC_UV = 4,
49 
53 
55 };
56 
57 // Helper functions for default-attribute-mapping
58 RV_API bool RVisDefaultAttrib(const RV_ShaderInput &input);
60 RV_API bool RVgetDefaultAttribFormat( int loc,
61  RV_GPUType *out_type,
62  int *out_vec_size);
63 
64 // ~~ Overview
65 // takes a collection of GLSL shader files
66 // compiles them into SPIR-V modules
67 // optionally does linkage checks as well
68 
69 // ~~ Shader Compiler Ownership
70 // Implemented using glslang library
71 // glslang interface has the quirks that:
72 // - shaders cannot be detatched from a program
73 // - shaders cannot be used in multiple programs
74 // - shaders must be destroyed after program
75 // so, the program compiler takes ownership of any shaders
76 // added to it
77 
79 {
80 public:
83 
85 
86  // Must be called in order:
87  // add shaders, compile, link, get modules
88  bool addShader(UT_UniquePtr<RV_VKShaderStageCompiler> &&shr);
89  bool compileShaders(UT_WorkBuffer &messages_out);
90  bool linkShaders(UT_WorkBuffer &messages_out);
91  bool getSpvModules(UT_Map<RE_ShaderType, UT_Array<uint8_t>> &modules_out,
92  UT_WorkBuffer &messages_out);
93 
94  bool isValid() const;
95 
96 private:
98  friend RV_SpvProgramCompileImpl;
99 };
100 
101 // Class for a single vulkan glsl shader
102 
104 {
105 public:
106  RV_VKShaderStageCompiler(const char *source,
107  const char *name,
108  RE_ShaderType stage,
109  int version = 0);
111  bool compile(UT_WorkBuffer &messages_out);
112 
113  bool isCompiled();
114  bool isValid();
115 
116  RE_ShaderType getStage();
117  void getString(UT_WorkBuffer& string);
118  const char* getName() { return myName; };
119 
120 private:
121 
122  UT_StringHolder myName;
123  UT_StringHolder mySource;
124  RE_ShaderType myStage;
126  int myVersion;
127  friend RV_SpvStageCompileImpl;
129 };
130 
131 
132 // Implementation of Shader Compiler
133 // Inherits from RE_Shader, to use functions for shader file,
134 // loading, prog file loading, etc.
135 // Can be passed GLSL shaders and compile them into SPIR-V
136 
137 // The compiler class has the requirements that
138 // it takes ownership of the shader objects
139 // and that objects cannot be detatched
140 // So we must make new shaderCompiler +
141 // programCompilers as needed
142 
144 {
145 public:
146  RV_VKShader(const char* name, int shader_version = 450);
147  ~RV_VKShader() override;
148 
149  int64 getMemoryUsage(bool inclusive) const override
150  {
151 
152  return 0;
153  }
154 
156  UT_WorkBuffer &messages_out)
157  {
158  if (!myProgram)
159  {
160  return false;
161  }
162 
163  return myProgram->getSpvModules(modules_out, messages_out);
164  }
165 
167  {
168  public:
169  RE_Shader* newShader(const char *name, int shader_version, RE_ShaderLanguage lang) override
170  {
173  return new RV_VKShader(name, shader_version);
174  }
175  ~Factory() override {}
176  };
177 
178  // basic Shader handling
179  bool attachShader(RE_Render *r,
181  UT_String *messages = nullptr) override;
182  bool detachShader(RE_Render *r, RE_ShaderStage *shader) override;
183  bool linkShaders(RE_Render *r, UT_String *messages_out = nullptr) override;
184 
185 
186  void clearShaders(RE_Render *r, RE_ShaderType stype = RE_SHADER_ALL) override;
187  RE_ShaderStage *newShader(RE_ShaderType stage, const char* name=0) override;
188 
189  bool validateShader(RE_Render *r, UT_String *messages = nullptr) override
190  {
191  if (!myProgram)
192  {
193  return false;
194  }
195 
196  return myProgram->isValid();
197  }
198 
199 
200  // pre-linking settings
202  int max_vertices,
203  RE_PrimType input,
204  RE_PrimType output) override
205  { return false;}
206 
208  const char *name,
209  int vertex_index) override
210  { return false;}
211 
213  const char *name,
214  int buffer_num) override
215  { return false;}
216 
217  // variable binidng
219  const UT_StringHolder &name,
220  const char *mapname,
221  const char *relative_to) override
222  { return false; }
223 
225  const UT_StringHolder &name) override
226  { return RE_TEXTURE_NONE; }
227 
229  const UT_StringHolder &name, const int *val,
230  int array_size=1, int *saved_idx = nullptr) override
231  { return false;}
233  const UT_StringHolder &name, const int *val,
234  int array_size=1, int *saved_idx = nullptr) override
235  { return false;}
237  const UT_StringHolder &name, const int *val,
238  int array_size=1, int *saved_idx = nullptr) override
239  { return false;}
241  const UT_StringHolder &name, const int *val,
242  int array_size=1, int *saved_idx = nullptr) override
243  { return false;}
245  const UT_StringHolder &name, uint64 *val,
246  int array_size = 1, int *saved_idx = nullptr) override
247  { return false;}
249  const UT_StringHolder &name, const fpreal32 *val,
250  int array_size=1, int *saved_idx = nullptr) override
251  { return false;}
253  const UT_StringHolder &name, const fpreal32 *val,
254  int array_size=1, int *saved_idx = nullptr) override
255  { return false;}
257  const UT_StringHolder &name, const fpreal32 *val,
258  int array_size=1, int *saved_idx = nullptr) override
259  { return false;}
261  const UT_StringHolder &name, const fpreal32 *val,
262  int array_size=1, int *saved_idx = nullptr) override
263  { return false;}
265  const UT_StringHolder &name, const fpreal64 *val,
266  int array_size=1, int *saved_idx = nullptr) override
267  { return false;}
269  const UT_StringHolder &name, const fpreal64 *val,
270  int array_size=1, int *saved_idx = nullptr) override
271  { return false;}
273  const UT_StringHolder &name, const fpreal64 *val,
274  int array_size=1, int *saved_idx = nullptr) override
275  { return false;}
277  const UT_StringHolder &name, const fpreal64 *val,
278  int array_size=1, int *saved_idx = nullptr) override
279  { return false;}
280 
282  const UT_StringHolder &name, const fpreal32 *val,
283  int array_size=1, int *saved_idx = nullptr) override
284  { return false;}
286  const UT_StringHolder &name, const fpreal32 *val,
287  int array_size=1, int *saved_idx = nullptr) override
288  { return false;}
290  const UT_StringHolder &name, const fpreal32 *val,
291  int array_size=1, int *saved_idx = nullptr) override
292  { return false;}
294  const UT_StringHolder &name, const fpreal64 *val,
295  int array_size=1, int *saved_idx = nullptr) override
296  { return false;}
298  const UT_StringHolder &name, const fpreal64 *val,
299  int array_size=1, int *saved_idx = nullptr) override
300  { return false;}
302  const UT_StringHolder &name, const fpreal64 *val,
303  int array_size=1, int *saved_idx = nullptr) override
304  { return false;}
306  const UT_StringHolder &name,
307  RE_Texture *tex,
308  int *saved_idx = nullptr) override
309  { return false;}
311  const UT_StringHolder &name,
312  RE_Texture *image,
313  RE_BufferAccess image_access) override
314  { return false;}
316  const UT_StringHolder &name,
317  RE_Texture *image,
318  RE_BufferAccess image_access,
319  int layer) override
320  { return false;}
322  std::ostream *os = nullptr) const override
323  { }
324  void loadShaderTexMaps(RE_Render *r) override {}
325  void loadBoundTextures(RE_Render *r) override {}
326  void unloadBoundTextures(RE_Render *r) override {}
327 
328  // This should set the shader as current.
329  void applyShader(RE_Render *r, bool update_re = true) override {}
330  // This should do a cleanup and unset any current shader.
331  void removeShader(RE_Render *r, bool update_re = true) override {}
332  // This should cleanup after the shader, but leave it set as current.
333  void cleanup(RE_Render *r) override {}
334 
335  re_LibFunc* getShaderLibrary() const override;
336 
337 private:
338  void createInternalProgram();
340 };
341 
342 // RV_VKShaderStage
343 // A glsl shader stage to be compiled by RV_VKShader
344 // internally holds an RV_VKShaderStageCompiler
345 // created when the source is set.
346 //
347 // The RV_VKShaderProgramCompiler takes ownership
348 // of the stage when it's added, so we have
349 // functions to recreate it, as needed
350 
352 {
353 public:
354  RV_VKShaderStage(RE_ShaderType stage, const char *name = nullptr);
355 
356  ~RV_VKShaderStage() override;
357 
358  bool setSource(RE_Render *r,
359  const char *source_code,
360  int version,
361  UT_String *messages = nullptr,
362  bool dump_source_on_error = true) override;
363  bool getSource(RE_Render *r, UT_String &source) override
364  {
365  if (!mySource.isstring())
366  {
367  return false;
368  }
369 
370  source = mySource;
371  return true;
372  }
373 
374  // return valid if we have valid shader code
375  bool isValid() const
376  {
377  if (myStageCompiler)
378  {
379  return myStageCompiler->isValid();
380  }
381  else if (mySource.isstring())
382  {
383  // Source is only stored if compilation succeeds
384  // so having source means we are valid
385  // but must regen impl before use
386  return mySource;
387  }
388  return false;
389  }
390 private:
391  // recreate the compiler impl object, with the same
392  // source, stage, and settings
393  void resetImpl();
394 
395  UT_StringHolder mySource;
397 
398  friend class RV_VKShader;
399 };
400 
401 #include <RE/RE_ShaderHandle.h>
402 #include <RE/RE_ShaderAtlas.h>
403 
404 // --------------------
405 // RV_ShaderHandle
406 //
407 // Shader handle used to compile a GLSL shader or Houdini Prog file
408 // into SPIR-V. Does not handle compiling SPIR-V into a Vulkan pipeline
410 {
411 public:
412  RV_ShaderHandle(const char *program_file, bool reg_sh, const char *defines)
413  : RE_ShaderHandle(program_file, reg_sh, defines,
415  {}
416  ~RV_ShaderHandle() override
417  {}
418 
419  // Get what the filename for compiled spv stage should be
420  // NOTE: this should only be used for individually loaded Shaders,
421  // shaders loaded through an Atlas should use
422  // `RV_ShaderAtlas::getSpirvPath()` instead
423  UT_StringHolder getSpirvPath(RE_ShaderType stage = RE_SHADER_ALL);
424 
425  static void initializeDriverInformation();
426 
427 private:
429  UT_String *errors)
430  const override;
431 
432 };
433 
434 // --------------------
435 // RV_ShaderAtlas
436 //
437 // Shader handle used to compile a Houdini Shader Atlas into SPIR-V
438 // modules. Does not handle compiling SPIR-V into Vulkan pipelines
440 {
441 public:
442  RV_ShaderAtlas(const UT_StringRef &shader_atlas_file)
443  : RE_ShaderAtlas(shader_atlas_file)
444  {
445  }
446  ~RV_ShaderAtlas() override
447  {}
448 
449  // Get what the filename for compiled spv stage should be
450  UT_StringHolder getSpirvPath(exint shbits, RE_ShaderType stage);
451 
452 protected:
454  createShaderImpl(const char* program, const char* defines) override;
455 };
456 
457 #endif
void loadShaderTexMaps(RE_Render *r) override
Loads texture maps specified by the RE_TextureMap bindTextureMap()
void printUniforms(RE_Render *r, std::ostream *os=nullptr) const override
Prints all the active uniforms plus their values to stream os (or cerr)
virtual UT_UniquePtr< RE_Shader > compileImpl(RE_Render *r, UT_String *errors) const
virtual void clearShaders(RE_Render *r, RE_ShaderType types=RE_SHADER_ALL)
Clears and deletes all the shader objects of a certain type (or all)
Unsorted map container.
Definition: UT_Map.h:107
bool bindVariable2(RE_Render *r, const UT_StringHolder &name, const fpreal64 *val, int array_size=1, int *saved_idx=nullptr) override
Generic Integer scalar.
UT_SharedPtr< RE_ShaderHandle > RE_ShaderHandlePtr
bool bindMatrix3(RE_Render *r, const UT_StringHolder &name, const fpreal64 *val, int array_size=1, int *saved_idx=nullptr) override
Generic Integer scalar.
int64 getMemoryUsage(bool inclusive) const override
bool bindImage(RE_Render *r, const UT_StringHolder &name, RE_Texture *image, RE_BufferAccess image_access) override
bool bindMatrix4(RE_Render *r, const UT_StringHolder &name, const fpreal32 *val, int array_size=1, int *saved_idx=nullptr) override
Generic Integer scalar.
virtual bool linkShaders(RE_Render *r, UT_String *messages=nullptr)
bool bindVariableInt3(RE_Render *r, const UT_StringHolder &name, const int *val, int array_size=1, int *saved_idx=nullptr) override
Generic Integer vector-3.
int64 exint
Definition: SYS_Types.h:125
bool bindMatrix3(RE_Render *r, const UT_StringHolder &name, const fpreal32 *val, int array_size=1, int *saved_idx=nullptr) override
Generic Integer scalar.
RV_ShaderAtlas(const UT_StringRef &shader_atlas_file)
GLenum GLenum GLsizei void * image
Definition: glad.h:5132
RE_TextureDimension
~RV_ShaderAtlas() override
RV_API bool RVisDefaultAttrib(const RV_ShaderInput &input)
unsigned long long uint64
Definition: SYS_Types.h:117
float fpreal32
Definition: SYS_Types.h:200
bool bindVariable3(RE_Render *r, const UT_StringHolder &name, const fpreal32 *val, int array_size=1, int *saved_idx=nullptr) override
Generic Integer scalar.
bool setSource(RE_Render *r, const char *source_code, int version, UT_String *messages=nullptr, bool dump_source_on_error=true) override
virtual bool detachShader(RE_Render *r, RE_ShaderStage *obj)
GLenum GLuint GLint GLint layer
Definition: glcorearb.h:1299
std::unique_ptr< T, Deleter > UT_UniquePtr
A smart pointer for unique ownership of dynamically allocated objects.
Definition: UT_UniquePtr.h:39
bool bindVariable4(RE_Render *r, const UT_StringHolder &name, const fpreal32 *val, int array_size=1, int *saved_idx=nullptr) override
Generic Integer scalar.
double fpreal64
Definition: SYS_Types.h:201
RE_TextureDimension getTextureMapType(RE_Render *r, const UT_StringHolder &name) override
Return the texture type for the sampler named 'name'.
RE_ShaderType
Definition: RE_Types.h:228
bool validateShader(RE_Render *r, UT_String *messages=nullptr) override
bool bindTextureMap(RE_Render *r, const UT_StringHolder &name, const char *mapname, const char *relative_to) override
virtual RE_ShaderStage * newShader(RE_ShaderType type, const char *name=0)=0
RV_ShaderHandle(const char *program_file, bool reg_sh, const char *defines)
virtual RE_ShaderHandlePtr createShaderImpl(const char *program, const char *defines)
bool bindVariable3(RE_Render *r, const UT_StringHolder &name, const fpreal64 *val, int array_size=1, int *saved_idx=nullptr) override
Generic Integer scalar.
bool getSpvModules(UT_Map< RE_ShaderType, UT_Array< uint8_t >> &modules_out, UT_WorkBuffer &messages_out)
bool bindVariableInt2(RE_Render *r, const UT_StringHolder &name, const int *val, int array_size=1, int *saved_idx=nullptr) override
Generic Integer vector-2.
GLsizei GLsizei GLchar * source
Definition: glcorearb.h:803
#define RV_API
Definition: RV_API.h:10
bool bindUint64(RE_Render *r, const UT_StringHolder &name, uint64 *val, int array_size=1, int *saved_idx=nullptr) override
64b Integer handle for bindless texturing
static void initializeDriverInformation(RE_Render *r)
bool bindMatrix4(RE_Render *r, const UT_StringHolder &name, const fpreal64 *val, int array_size=1, int *saved_idx=nullptr) override
Generic Integer scalar.
long long int64
Definition: SYS_Types.h:116
bool bindVariable1(RE_Render *r, const UT_StringHolder &name, const fpreal64 *val, int array_size=1, int *saved_idx=nullptr) override
Generic Integer scalar.
bool getSource(RE_Render *r, UT_String &source) override
bool bindVariableInt(RE_Render *r, const UT_StringHolder &name, const int *val, int array_size=1, int *saved_idx=nullptr) override
Generic Integer scalar.
GLuint const GLchar * name
Definition: glcorearb.h:786
bool bindVariableInt4(RE_Render *r, const UT_StringHolder &name, const int *val, int array_size=1, int *saved_idx=nullptr) override
Generic Integer vector-4.
bool bindMatrix2(RE_Render *r, const UT_StringHolder &name, const fpreal32 *val, int array_size=1, int *saved_idx=nullptr) override
Generic Integer scalar.
bool setVertexInput(RE_Render *r, const char *name, int vertex_index) override
bool bindVariable2(RE_Render *r, const UT_StringHolder &name, const fpreal32 *val, int array_size=1, int *saved_idx=nullptr) override
Generic Integer scalar.
bool setGeometryParms(RE_Render *r, int max_vertices, RE_PrimType input, RE_PrimType output) override
Specify geometry shader parameters.
GT_API const UT_StringHolder version
bool bindMatrix2(RE_Render *r, const UT_StringHolder &name, const fpreal64 *val, int array_size=1, int *saved_idx=nullptr) override
Generic Integer scalar.
bool isValid() const
RV_VKShaderStage(RE_ShaderType stage, const char *name=nullptr)
GLuint shader
Definition: glcorearb.h:785
~RV_VKShaderStage() override
RE_BufferAccess
Definition: RE_Types.h:314
bool bindTexture(RE_Render *r, const UT_StringHolder &name, RE_Texture *tex, int *saved_idx=nullptr) override
RV_API int RVgetDefaultAttribLocation(const UT_StringRef &)
void loadBoundTextures(RE_Render *r) override
RV_GPUType
Definition: RV_Type.h:37
bool bindVariable4(RE_Render *r, const UT_StringHolder &name, const fpreal64 *val, int array_size=1, int *saved_idx=nullptr) override
Generic Integer scalar.
bool bindImageLayer(RE_Render *r, const UT_StringHolder &name, RE_Texture *image, RE_BufferAccess image_access, int layer) override
bool bindVariable1(RE_Render *r, const UT_StringHolder &name, const fpreal32 *val, int array_size=1, int *saved_idx=nullptr) override
Generic Integer scalar.
GLuint GLfloat * val
Definition: glcorearb.h:1608
void unloadBoundTextures(RE_Render *r) override
RV_DefaultAttributeLoc
RE_Shader * newShader(const char *name, int shader_version, RE_ShaderLanguage lang) override
virtual bool attachShader(RE_Render *r, RE_ShaderStage *obj, UT_String *messages=nullptr)
void cleanup(RE_Render *r) override
#define UT_ASSERT(ZZ)
Definition: UT_Assert.h:156
void removeShader(RE_Render *r, bool update_re=true) override
~RV_ShaderHandle() override
GLboolean r
Definition: glcorearb.h:1222
RE_ShaderLanguage
Definition: RE_Types.h:257
RE_PrimType
Definition: RE_Types.h:193
GLbitfield GLuint program
Definition: glcorearb.h:1931
RV_API bool RVgetDefaultAttribFormat(int loc, RV_GPUType *out_type, int *out_vec_size)
SYS_FORCE_INLINE bool isstring() const
virtual re_LibFunc * getShaderLibrary() const
bool setFragmentOutput(RE_Render *r, const char *name, int buffer_num) override
void applyShader(RE_Render *r, bool update_re=true) override
Simple interface to building a shader from a .prog file.