HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
RE_UniformBlock.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: RE_UniformBlock.h ( RE Library, C++)
7  *
8  * COMMENTS:
9  * Encapsulates a uniform buffer object and provides high-level interface
10  * for setting the variables within. Setting a variable will mark the block
11  * dirty, so the next time it is bound it will be uploaded again.
12  */
13 #ifndef RE_UniformBlock_h
14 #define RE_UniformBlock_h
15 
16 #include "RE_Shader.h"
17 #include <UT/UT_IntrusivePtr.h>
18 #include <UT/UT_NonCopyable.h>
19 
21 class RE_Render;
22 class RE_UniformBlock;
24 
26 
27 /// A uniform block is a structure of uniforms used by a GLSL shader. This
28 /// class can represent either a Uniform Buffer Object (UBO) or a
29 /// Shader Storage Buffer Objects (SSBO, GL4.3).
30 class RE_API RE_UniformBlock : public UT_IntrusiveRefCounter<RE_UniformBlock>
31 {
32 public:
33  explicit RE_UniformBlock(const char *name = nullptr);
34  ~RE_UniformBlock();
35 
37 
38  /// Returns the amount of main memory (NOT graphics memory!)
39  /// owned by this RE_UniformBlock.
40  int64 getMemoryUsage(bool inclusive) const;
41 
42  /// Name of the uniform block (uniform <name> { } )
43  const char * getName() const;
44 
45  /// Optional instance name of the uniform block (uniform block { } <name>)
46  /// This will need to be specified to bind a UBO to a specific instance
47  /// when instanced UBOs are used by the shader.
48  void setInstanceName(const char *name);
49 
50  /// Optional instance name of the uniform block (uniform block { } <name>)
51  const char * getInstanceName() const;
52 
53  /// Array length of variably sized arrays (for GL4 SSBOs).
54  int getArrayLength() const { return myArrayLength; }
55 
56  /// Creates a new uniform block with its own buffer based on the structure
57  /// of this uniform block. If data_too is true, the data inside the uniform
58  /// block is also copied.
59  RE_UniformBlock *duplicate(bool block_data_too = true) const;
60 
61  /// Create a new shader storage block, specifying an array size for
62  /// array member data with an unspecified array size. If there are no
63  /// arrays with unspecified bounds, array_size is ignored.
64  /// Data is left uninitialized.
65  RE_UniformBlock *arrayDuplicate(int array_size) const;
66 
67  /// returns true if 'block' shares the same size and structure as this block
68  bool isCompatible(const RE_UniformBlock *block) const;
69 
70  /// Size of the underlying GL buffer.
71  int getSizeB() const;
72 
73  /// Returns true if this block has a member variable called 'name'
74  bool hasUniform(const UT_StringHolder &name) const;
75  /// Number of member variables in the uniform block.
76  int getNumUniforms() const;
77  /// Returns the name of the member variable at 'index'
78  const char *getUniformName(int index) const;
79  /// Which UBO or SSBO index this uniform block was created for.
80  int getUniformShaderIndex(int index) const;
81 
82 
83  /// Copy the data for uniform 'name' into the buffer. If name does not
84  /// exist in the buffer, or its type/array size doesn't match,
85  /// bind...() will return false. If its value is not different from the
86  /// current value in the block, it will not cause an upload.
87  /// Shader Storage Blocks can have open-ended arrays, and variables within
88  /// those arrays can specify their array index with 'array_index'.
89  bool bindInt(const UT_StringHolder &name, int v,
90  int array_index = 0);
91  /// Bind a single float value.
92  bool bindFloat(const UT_StringHolder &name, fpreal32 v,
93  int array_index = 0);
94  /// Bind a single double value. GPU must support native FP64 values.
95  bool bindDouble(const UT_StringHolder &name, fpreal64 v,
96  int array_index = 0);
97  /// Bind a single handle value to a sampler. GPU must support bindless
98  /// textures.
99  bool bindUint64(const UT_StringHolder &name,
100  uint64 v,
101  int array_index = 0);
102 
103  /// Set values for a fixed-length integer array.
104  bool bindInts(const UT_StringHolder &name,
105  const int *valarray,
106  int array_size,
107  int array_index = 0);
108  /// Set values for a fixed-length float array.
109  bool bindFloats(const UT_StringHolder &name,
110  const fpreal32 *valarray,
111  int array_size,
112  int array_index = 0);
113  /// Set values for a fixed-length double array.
114  bool bindDoubles(const UT_StringHolder &name,
115  const fpreal64 *valarray,
116  int array_size,
117  int array_index = 0);
118  /// Set values for a uint64 handle array.
119  bool bindUint64s(const UT_StringHolder &name,
120  const uint64 *valarray,
121  int array_size,
122  int array_index = 0);
123 
124  /// vec3 is a little different, as it is padded to vec4 in uniform blocks.
125  /// SSBOs with std420 packing should use bindVector().
126 
127  /// bind a series of ivec3s, using std140 packing (padded to ivec4)
128  bool bindIntVector3(const UT_StringHolder &name,
129  const int *valarray,
130  int array_size,
131  int array_index = 0);
132  /// bind a series of vec3s, using std140 packing (padded to ivec4)
133  bool bindVector3(const UT_StringHolder &name,
134  const fpreal32 *valarray,
135  int array_size,
136  int array_index = 0);
137  /// bind a series of dvec3s, using std140 packing (padded to ivec4)
138  bool bindDVector3(const UT_StringHolder &name,
139  const fpreal64 *valarray,
140  int array_size,
141  int array_index = 0);
142 
143  /// Bind a single vec2 uniform value.
144  bool bindVector(const UT_StringHolder &name,
145  const UT_Vector2F &v,
146  int array_index = 0);
147  /// Bind a single vec3 uniform value.
148  bool bindVector(const UT_StringHolder &name,
149  const UT_Vector3F &v,
150  int array_index = 0);
151  /// Bind a single vec4 uniform value.
152  bool bindVector(const UT_StringHolder &name,
153  const UT_Vector4F &v,
154  int array_index = 0);
155 
156  /// Bind a single dvec2 uniform value.
157  bool bindVector(const UT_StringHolder &name,
158  const UT_Vector2D &v,
159  int array_index = 0);
160  /// Set a single dvec3 uniform value.
161  bool bindVector(const UT_StringHolder &name,
162  const UT_Vector3D &v,
163  int array_index = 0);
164  /// Set a single dvec4 uniform value.
165  bool bindVector(const UT_StringHolder &name,
166  const UT_Vector4D &v,
167  int array_index = 0);
168 
169  /// Set a single 2x2 matrix value.
170  bool bindMatrix(const UT_StringHolder &name,
171  const UT_Matrix2F &m,
172  int array_index = 0);
173  /// Set a single 3x3 matrix value.
174  bool bindMatrix(const UT_StringHolder &name,
175  const UT_Matrix3F &m,
176  int array_index = 0);
177  /// Set a single 4x4 matrix value.
178  bool bindMatrix(const UT_StringHolder &name,
179  const UT_Matrix4F &m,
180  int array_index = 0);
181 
182  /// Set a single 2x2 matrix value (dmat2).
183  bool bindMatrix(const UT_StringHolder &name,
184  const UT_Matrix2D &m,
185  int array_index = 0);
186  /// Set a single 3x3 matrix value (dmat3).
187  bool bindMatrix(const UT_StringHolder &name,
188  const UT_Matrix3D &m,
189  int array_index = 0);
190  /// Set a single 4x4 matrix value (dmat4).
191  bool bindMatrix(const UT_StringHolder &name,
192  const UT_Matrix4D &m,
193  int array_index = 0);
194 
195  // Note that you cannot include texture samplers in a uniform block, so
196  // there are no bindTextureMap() calls here.
197 
198 
199  /// commits any changes to the buffer object, creating the buffer object
200  /// if required.
201  void uploadBuffer(RE_Render *r);
202 
203  /// Fetches the contents of the GL buffer into the main mem block contained
204  /// by this class.
205  void downloadBuffer(RE_Render *r);
206 
207  /// The raw GL id of the buffer. Will not exist unless uploadBuffer() was
208  /// previously called. Returns -1 if there is no buffer object.
209  int getID() const { return myID; }
210 
211  /// Debug printout of the block, including currently bound values.
212  void print(std::ostream *os = nullptr);
213 
214  static void dirtyAllUniformBlocks() { theResetCounter++; }
215 
216 
217  // ---------------------------------------------------------------------
218  // The remaining methods should only be called by RE_Shader.
219 
220  /// Name of the uniform block (uniform <name> { } ), generally set by the
221  /// shader.
222  void setName(const char *name);
223 
224  /// Size of the underlying GL buffer, in bytes. Generally set by the shader.
225  void setSize(int bytes);
226 
227  /// Called during shader intitialization to layout the structure of this
228  /// block.
229  void addUniform(const UT_StringHolder &name,
231  int array_size,
232  int offset,
233  int location,
234  int top_array_size,
235  int top_array_stride);
236  void clearUniforms();
237  void setBufferSizes(int fixed_size_bytes,
238  int variable_size_bytes);
239 
240  /// Update the passed uniform block with the uniforms found in this block.
241  /// This is generally done by the shader before a draw call.
242  bool updateBlock(RE_UniformBlock *b,
243  const RE_Shader *sh) const;
244 
245  /// Whether this block requires uploading to the GPU.
246  bool isDirty() const { return myDirtyFlag ||
247  myResetCount!=theResetCounter;}
248  /// Which shader this block is currently laid out for.
249  void setInitializedFor(const RE_Shader *sh);
250  /// Which shader this block is currently laid out for.
251  bool isInitializedFor(const RE_Shader *sh) const;
252  /// Which shader this block is currently laid out for.
253  const RE_Shader *getInitializedShader() const { return myInitShader; }
254  /// Program ID of the program this block was created from.
255  void setOriginProgramID(int pid) { myLastProgramID = pid; }
256 
257 
258 private:
259  int getUniformIndex(const UT_StringHolder &name) const;
260  void copyToBuffer(const void *data, int len, int offset,
261  const UT_StringHolder &uniform_name);
262  void copyToBuffer3(const void *data, int len, int dsize,
263  int stride, int offset,
264  const UT_StringHolder &uniform_name);
265  void printMember(std::ostream &os, int idx,
266  int maxlen, int offset);
267 
268  UT_String myName;
269  UT_String myInstanceName;
270  RE_OGLUniformBuffer *myBufferObject;
271  void *myBuffer;
272  bool myDirtyFlag;
273 
275 
276  mutable UT_StringMap<int> myUniformsIndexMap;
277  mutable UT_StringMap<int> myUniformsInstanceIndexMap;
278 
279  int mySize;
280  int myID;
281  UT_IntArray myDataMatch;
282  const RE_Shader *myInitShader;
283 
284  // for buffer storage objects, which can have a non-array section at the
285  // beginning of the block (fixed), followed by array data at the end
286  // (variable). myArrayLength determines the number of entries in the array.
287  int myFixedSize;
288  int myVariableSize;
289  int myArrayLength;
290 
291  int myLastProgramID;
292  int myResetCount;
293  static int theResetCounter;
294 };
295 
296 inline const char *
298 {
299  return myName;
300 }
301 
302 inline const char *
304 {
305  return myInstanceName;
306 }
307 
308 inline void
310 {
311  myInitShader = sh;
312 }
313 
314 inline bool
316 {
317  return myInitShader == sh;
318 }
319 
320 #endif
int getArrayLength() const
Array length of variably sized arrays (for GL4 SSBOs).
#define RE_API
Definition: RE_API.h:10
const GLdouble * v
Definition: glcorearb.h:837
const char * getInstanceName() const
Optional instance name of the uniform block (uniform block { } <name>)
RE_UniformType
Definition: RE_Uniform.h:145
unsigned long long uint64
Definition: SYS_Types.h:117
A reference counter base class for use with UT_IntrusivePtr.
float fpreal32
Definition: SYS_Types.h:200
const char * getName() const
Name of the uniform block (uniform <name> { } )
UT_IntrusivePtr< RE_UniformBlock > RE_UniformBlockHandle
double fpreal64
Definition: SYS_Types.h:201
GLint GLint GLsizei GLint GLenum GLenum type
Definition: glcorearb.h:108
GLintptr offset
Definition: glcorearb.h:665
PXL_API const char * getName(const ColorSpace *space)
Return the name of the color space.
GLint GLenum GLboolean GLsizei stride
Definition: glcorearb.h:872
#define UT_NON_COPYABLE(CLASS)
Define deleted copy constructor and assignment operator inside a class.
bool isDirty() const
Whether this block requires uploading to the GPU.
long long int64
Definition: SYS_Types.h:116
GLint location
Definition: glcorearb.h:805
const RE_Shader * getInitializedShader() const
Which shader this block is currently laid out for.
GLuint const GLchar * name
Definition: glcorearb.h:786
GLboolean GLboolean GLboolean b
Definition: glcorearb.h:1222
void setInitializedFor(const RE_Shader *sh)
Which shader this block is currently laid out for.
void setOriginProgramID(int pid)
Program ID of the program this block was created from.
int getID() const
GLuint index
Definition: glcorearb.h:786
static void dirtyAllUniformBlocks()
GLboolean r
Definition: glcorearb.h:1222
FMT_INLINE void print(format_string< T...> fmt, T &&...args)
Definition: core.h:2903
Definition: format.h:1821
Definition: format.h:4365
bool isInitializedFor(const RE_Shader *sh) const
Which shader this block is currently laid out for.