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