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_NonCopyable.h>
19 #include <UT/UT_UniquePtr.h>
20 
21 #include <RE/RE_UniformBlock.h>
22 #include <RE/RE_Shader.h>
23 
24 #include <VE/VE_ShaderCompile.h>
25 
26 #include "RV_Type.h"
27 
28 struct RV_SpvProgramCompileImpl;
29 struct RV_SpvStageCompileImpl;
30 class RV_ShaderInput;
31 class RV_VKShaderModule;
34 class UT_StringRef;
35 
37 {
40 
41  RV_LOC_P = 0,
42  RV_LOC_CD = 1,
44  RV_LOC_N = 3,
48  RV_LOC_UV = 6,
53 
54  RV_LOC_TAN = 10,
57 
59 };
60 
61 // Helper functions for default-attribute-mapping
62 RV_API bool RVisDefaultAttrib(const RV_ShaderInput &input);
64 RV_API bool RVgetDefaultAttribFormat( int loc,
65  RV_GPUType *out_type,
66  int *out_vec_size);
67 // Helper functions to convert between VE and RE enums for shader type.
70 
71 // ~~ Overview
72 // takes a collection of GLSL shader files
73 // compiles them into SPIR-V modules
74 // optionally does linkage checks as well
75 
76 // ~~ Shader Compiler Ownership
77 // Implemented using glslang library
78 // glslang interface has the quirks that:
79 // - shaders cannot be detatched from a program
80 // - shaders cannot be used in multiple programs
81 // - shaders must be destroyed after program
82 // so, the program compiler takes ownership of any shaders
83 // added to it
84 
86 {
87 public:
89  {}
91  {}
92 
94  UT_WorkBuffer &messages_out);
95 };
96 
97 // Class for a single vulkan glsl shader
99 {
100 public:
102  const char *name,
103  RE_ShaderType stage,
104  int version = 0)
105  : VE_ShaderStageCompiler(source, name, RVshaderTypeToVE(stage),
106  version)
107  {}
109  {}
110 
112  {
114  }
115 };
116 
117 
118 // Implementation of Shader Compiler
119 // Inherits from RE_Shader, to use functions for shader file,
120 // loading, prog file loading, etc.
121 // Can be passed GLSL shaders and compile them into SPIR-V
122 
123 // The compiler class has the requirements that
124 // it takes ownership of the shader objects
125 // and that objects cannot be detatched
126 // So we must make new shaderCompiler +
127 // programCompilers as needed
128 
130 {
131 public:
132  RV_VKShader(const char* name, int shader_version = 460);
133  ~RV_VKShader() override;
134 
135  int64 getMemoryUsage(bool inclusive) const override
136  {
137 
138  return 0;
139  }
140 
142  UT_WorkBuffer &messages_out)
143  {
144  if (!myProgram)
145  {
146  return false;
147  }
148 
149  return myProgram->getSpvModules(modules_out, messages_out);
150  }
151 
153  {
154  public:
155  RE_Shader* newShader(const char *name, int shader_version, RE_ShaderLanguage lang) override
156  {
159  return new RV_VKShader(name, shader_version);
160  }
161  ~Factory() override {}
162  };
163 
164  // basic Shader handling
165  bool attachShader(RE_Render *r,
167  UT_String *messages = nullptr) override;
168  bool detachShader(RE_Render *r, RE_ShaderStage *shader) override;
169  bool linkShaders(RE_Render *r, UT_String *messages_out = nullptr) override;
170 
171 
172  void clearShaders(RE_Render *r, RE_ShaderType stype = RE_SHADER_ALL) override;
173  RE_ShaderStage *newShader(RE_ShaderType stage, const char* name=0) override;
174 
175  bool validateShader(RE_Render *r, UT_String *messages = nullptr) override
176  {
177  if (!myProgram)
178  {
179  return false;
180  }
181 
182  return myProgram->isValid();
183  }
184 
185 
186  // pre-linking settings
188  int max_vertices,
189  RE_PrimType input,
190  RE_PrimType output) override
191  { return false;}
192 
194  const char *name,
195  int vertex_index) override
196  { return false;}
197 
199  const char *name,
200  int buffer_num) override
201  { return false;}
202 
203  // variable binidng
205  const UT_StringHolder &name,
206  const char *mapname,
207  const char *relative_to) override
208  { return false; }
209 
211  const UT_StringHolder &name) override
212  { return RE_TEXTURE_NONE; }
213 
215  const UT_StringHolder &name, const int *val,
216  int array_size=1, int *saved_idx = nullptr) override
217  { return false;}
219  const UT_StringHolder &name, const int *val,
220  int array_size=1, int *saved_idx = nullptr) override
221  { return false;}
223  const UT_StringHolder &name, const int *val,
224  int array_size=1, int *saved_idx = nullptr) override
225  { return false;}
227  const UT_StringHolder &name, const int *val,
228  int array_size=1, int *saved_idx = nullptr) override
229  { return false;}
231  const UT_StringHolder &name, uint64 *val,
232  int array_size = 1, int *saved_idx = nullptr) override
233  { return false;}
235  const UT_StringHolder &name, const fpreal32 *val,
236  int array_size=1, int *saved_idx = nullptr) override
237  { return false;}
239  const UT_StringHolder &name, const fpreal32 *val,
240  int array_size=1, int *saved_idx = nullptr) override
241  { return false;}
243  const UT_StringHolder &name, const fpreal32 *val,
244  int array_size=1, int *saved_idx = nullptr) override
245  { return false;}
247  const UT_StringHolder &name, const fpreal32 *val,
248  int array_size=1, int *saved_idx = nullptr) override
249  { return false;}
251  const UT_StringHolder &name, const fpreal64 *val,
252  int array_size=1, int *saved_idx = nullptr) override
253  { return false;}
255  const UT_StringHolder &name, const fpreal64 *val,
256  int array_size=1, int *saved_idx = nullptr) override
257  { return false;}
259  const UT_StringHolder &name, const fpreal64 *val,
260  int array_size=1, int *saved_idx = nullptr) override
261  { return false;}
263  const UT_StringHolder &name, const fpreal64 *val,
264  int array_size=1, int *saved_idx = nullptr) override
265  { return false;}
266 
268  const UT_StringHolder &name, const fpreal32 *val,
269  int array_size=1, int *saved_idx = nullptr) override
270  { return false;}
272  const UT_StringHolder &name, const fpreal32 *val,
273  int array_size=1, int *saved_idx = nullptr) override
274  { return false;}
276  const UT_StringHolder &name, const fpreal32 *val,
277  int array_size=1, int *saved_idx = nullptr) override
278  { return false;}
280  const UT_StringHolder &name, const fpreal64 *val,
281  int array_size=1, int *saved_idx = nullptr) override
282  { return false;}
284  const UT_StringHolder &name, const fpreal64 *val,
285  int array_size=1, int *saved_idx = nullptr) override
286  { return false;}
288  const UT_StringHolder &name, const fpreal64 *val,
289  int array_size=1, int *saved_idx = nullptr) override
290  { return false;}
292  const UT_StringHolder &name,
293  RE_Texture *tex,
294  int *saved_idx = nullptr) override
295  { return false;}
297  const UT_StringHolder &name,
298  RE_Texture *image,
299  RE_BufferAccess image_access) override
300  { return false;}
302  const UT_StringHolder &name,
303  RE_Texture *image,
304  RE_BufferAccess image_access,
305  int layer) override
306  { return false;}
308  std::ostream *os = nullptr) const override
309  { }
310  void loadShaderTexMaps(RE_Render *r) override {}
311  void loadBoundTextures(RE_Render *r) override {}
312  void unloadBoundTextures(RE_Render *r) override {}
313 
314  // This should set the shader as current.
315  void applyShader(RE_Render *r, bool update_re = true) override {}
316  // This should do a cleanup and unset any current shader.
317  void removeShader(RE_Render *r, bool update_re = true) override {}
318  // This should cleanup after the shader, but leave it set as current.
319  void cleanup(RE_Render *r) override {}
320 
321  re_LibFunc* getShaderLibrary() const override;
322 
323  const char* getPlatformDefines(RE_Render* r) const override;
324 
325 private:
326  void createInternalProgram();
328 };
329 
330 // RV_VKShaderStage
331 // A glsl shader stage to be compiled by RV_VKShader
332 // internally holds an RV_VKShaderStageCompiler
333 // created when the source is set.
334 //
335 // The RV_VKShaderProgramCompiler takes ownership
336 // of the stage when it's added, so we have
337 // functions to recreate it, as needed
338 
340 {
341 public:
342  RV_VKShaderStage(RE_ShaderType stage, const char *name = nullptr);
343 
344  ~RV_VKShaderStage() override;
345 
346  bool setSource(RE_Render *r,
347  const char *source_code,
348  int version,
349  UT_String *messages = nullptr,
350  bool dump_source_on_error = true) override;
351  bool getSource(RE_Render *r, UT_String &source) override
352  {
353  if (!mySource.isstring())
354  {
355  return false;
356  }
357 
358  source = mySource;
359  return true;
360  }
361 
362  // return valid if we have valid shader code
363  bool isValid() const
364  {
365  if (myStageCompiler)
366  {
367  return myStageCompiler->isValid();
368  }
369  else if (mySource.isstring())
370  {
371  // Source is only stored if compilation succeeds
372  // so having source means we are valid
373  // but must regen impl before use
374  return mySource;
375  }
376  return false;
377  }
378 private:
379  // recreate the compiler impl object, with the same
380  // source, stage, and settings
381  void resetImpl();
382 
383  UT_StringHolder mySource;
385 
386  friend class RV_VKShader;
387 };
388 
389 #include <RE/RE_ShaderHandle.h>
390 #include <RE/RE_ShaderAtlas.h>
391 
392 // --------------------
393 // RV_ShaderHandle
394 //
395 // Shader handle used to compile a GLSL shader or Houdini Prog file
396 // into SPIR-V. Does not handle compiling SPIR-V into a Vulkan pipeline
398 {
399 public:
400  RV_ShaderHandle(const char *program_file, bool reg_sh, const char *defines)
401  : RE_ShaderHandle(program_file, reg_sh, defines,
403  {}
404  ~RV_ShaderHandle() override;
405 
407 
408  // Get what the filename for compiled spv stage should be
409  // NOTE: this should only be used for individually loaded Shaders,
410  // shaders loaded through an Atlas should use
411  // `RV_ShaderAtlas::getSpirvPath()` instead
412  UT_StringHolder getSpirvPath(RE_ShaderType stage = RE_SHADER_ALL);
413 
414 private:
415  UT_UniquePtr<RE_Shader> compileImpl(RE_Render *r,
416  UT_String *errors)
417  const override;
418 
419 };
420 
421 // --------------------
422 // RV_ShaderAtlas
423 //
424 // Shader handle used to compile a Houdini Shader Atlas into SPIR-V
425 // modules. Does not handle compiling SPIR-V into Vulkan pipelines
427 {
428 public:
429  RV_ShaderAtlas(const UT_StringRef &shader_atlas_file)
430  : RE_ShaderAtlas(shader_atlas_file)
431  {
432  }
433  ~RV_ShaderAtlas() override
434  {}
435 
436  // Get what the filename for compiled spv stage should be
437  UT_StringHolder getSpirvPath(exint shbits, RE_ShaderType stage);
438  UT_StringHolder getCompiledPath();
439 
441  {
442  // All shader keys, separated into lists of which
443  // ones have identical pipeline layouts
445 
446  // Map of shader module binaries, for each program
448  };
449 
450  // Read and write to compiled atlas files
451  static void writeCompiled(const UT_StringRef &filename,
452  RV_ShaderAtlas &atlas);
453 
454  static bool readCompiled(const UT_StringRef &filename,
455  CompiledAtlas &out);
456 
457 protected:
459  createShaderImpl(const char* program, const char* defines) override;
460 };
461 #endif
UT_Map< exint, UT_Map< RE_ShaderType, UT_Array< uint8_t > > > Programs
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)
GT_API const UT_StringHolder filename
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:109
bool bindVariable2(RE_Render *r, const UT_StringHolder &name, const fpreal64 *val, int array_size=1, int *saved_idx=nullptr) override
Generic Integer scalar.
*get result *(waiting if necessary)*A common idiom is to fire a bunch of sub tasks at the and then *wait for them to all complete We provide a helper class
Definition: thread.h:632
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
RV_API RE_ShaderType RVshaderTypeFromVE(VE_ShaderType type)
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.
virtual const char * getPlatformDefines(RE_Render *r) const
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:235
bool getSpvModules(UT_Map< VE_ShaderType, UT_Array< T >> &modules_out, UT_WorkBuffer &messages_out)
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
GLint GLint GLsizei GLint GLenum GLenum type
Definition: glcorearb.h:108
VE_ShaderType
RV_ShaderHandle(const char *program_file, bool reg_sh, 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)
UT_Array< UT_Array< exint > > SharedLayouts
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 UT_NON_COPYABLE(CLASS)
Define deleted copy constructor and assignment operator inside a class.
#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
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
RAII wrapper class for Vk Shader Module.
RV_VKShaderStage(RE_ShaderType stage, const char *name=nullptr)
GLuint shader
Definition: glcorearb.h:785
~RV_VKShaderStage() override
RE_BufferAccess
Definition: RE_Types.h:321
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:40
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.
RV_VKShaderStageCompiler(const char *source, const char *name, RE_ShaderType stage, int version=0)
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
RV_API VE_ShaderType RVshaderTypeToVE(RE_ShaderType type)
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
GLboolean r
Definition: glcorearb.h:1222
RE_ShaderLanguage
Definition: RE_Types.h:263
VE_ShaderType getStageType()
RE_PrimType
Definition: RE_Types.h:199
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.