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