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 UT_StringHolder &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 UT_StringHolder &name, int v,
87  int array_index = 0);
88  /// Bind a single float value.
89  bool bindFloat(const UT_StringHolder &name, fpreal32 v,
90  int array_index = 0);
91  /// Bind a single double value. GPU must support native FP64 values.
92  bool bindDouble(const UT_StringHolder &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 UT_StringHolder &name,
97  uint64 v,
98  int array_index = 0);
99 
100  /// Set values for a fixed-length integer array.
101  bool bindInts(const UT_StringHolder &name,
102  const int *valarray,
103  int array_size,
104  int array_index = 0);
105  /// Set values for a fixed-length float array.
106  bool bindFloats(const UT_StringHolder &name,
107  const fpreal32 *valarray,
108  int array_size,
109  int array_index = 0);
110  /// Set values for a fixed-length double array.
111  bool bindDoubles(const UT_StringHolder &name,
112  const fpreal64 *valarray,
113  int array_size,
114  int array_index = 0);
115  /// Set values for a uint64 handle array.
116  bool bindUint64s(const UT_StringHolder &name,
117  const uint64 *valarray,
118  int array_size,
119  int array_index = 0);
120 
121  /// vec3 is a little different, as it is padded to vec4 in uniform blocks.
122  /// SSBOs with std420 packing should use bindVector().
123 
124  /// bind a series of ivec3s, using std140 packing (padded to ivec4)
125  bool bindIntVector3(const UT_StringHolder &name,
126  const int *valarray,
127  int array_size,
128  int array_index = 0);
129  /// bind a series of vec3s, using std140 packing (padded to ivec4)
130  bool bindVector3(const UT_StringHolder &name,
131  const fpreal32 *valarray,
132  int array_size,
133  int array_index = 0);
134  /// bind a series of dvec3s, using std140 packing (padded to ivec4)
135  bool bindDVector3(const UT_StringHolder &name,
136  const fpreal64 *valarray,
137  int array_size,
138  int array_index = 0);
139 
140  /// Bind a single vec2 uniform value.
141  bool bindVector(const UT_StringHolder &name,
142  const UT_Vector2F &v,
143  int array_index = 0);
144  /// Bind a single vec3 uniform value.
145  bool bindVector(const UT_StringHolder &name,
146  const UT_Vector3F &v,
147  int array_index = 0);
148  /// Bind a single vec4 uniform value.
149  bool bindVector(const UT_StringHolder &name,
150  const UT_Vector4F &v,
151  int array_index = 0);
152 
153  /// Bind a single dvec2 uniform value.
154  bool bindVector(const UT_StringHolder &name,
155  const UT_Vector2D &v,
156  int array_index = 0);
157  /// Set a single dvec3 uniform value.
158  bool bindVector(const UT_StringHolder &name,
159  const UT_Vector3D &v,
160  int array_index = 0);
161  /// Set a single dvec4 uniform value.
162  bool bindVector(const UT_StringHolder &name,
163  const UT_Vector4D &v,
164  int array_index = 0);
165 
166  /// Set a single 2x2 matrix value.
167  bool bindMatrix(const UT_StringHolder &name,
168  const UT_Matrix2F &m,
169  int array_index = 0);
170  /// Set a single 3x3 matrix value.
171  bool bindMatrix(const UT_StringHolder &name,
172  const UT_Matrix3F &m,
173  int array_index = 0);
174  /// Set a single 4x4 matrix value.
175  bool bindMatrix(const UT_StringHolder &name,
176  const UT_Matrix4F &m,
177  int array_index = 0);
178 
179  /// Set a single 2x2 matrix value (dmat2).
180  bool bindMatrix(const UT_StringHolder &name,
181  const UT_Matrix2D &m,
182  int array_index = 0);
183  /// Set a single 3x3 matrix value (dmat3).
184  bool bindMatrix(const UT_StringHolder &name,
185  const UT_Matrix3D &m,
186  int array_index = 0);
187  /// Set a single 4x4 matrix value (dmat4).
188  bool bindMatrix(const UT_StringHolder &name,
189  const UT_Matrix4D &m,
190  int array_index = 0);
191 
192  // Note that you cannot include texture samplers in a uniform block, so
193  // there are no bindTextureMap() calls here.
194 
195 
196  /// commits any changes to the buffer object, creating the buffer object
197  /// if required.
198  void uploadBuffer(RE_Render *r);
199 
200  /// Fetches the contents of the GL buffer into the main mem block contained
201  /// by this class.
202  void downloadBuffer(RE_Render *r);
203 
204  /// The raw GL id of the buffer. Will not exist unless uploadBuffer() was
205  /// previously called. Returns -1 if there is no buffer object.
206  int getID() const { return myID; }
207 
208  /// Debug printout of the block, including currently bound values.
209  void print(std::ostream *os = NULL);
210 
211  static void dirtyAllUniformBlocks() { theResetCounter++; }
212 
213 
214  // ---------------------------------------------------------------------
215  // The remaining methods should only be called by RE_Shader.
216 
217  /// Name of the uniform block (uniform <name> { } ), generally set by the
218  /// shader.
219  void setName(const char *name);
220 
221  /// Size of the underlying GL buffer, in bytes. Generally set by the shader.
222  void setSize(int bytes);
223 
224  /// Called during shader intitialization to layout the structure of this
225  /// block.
226  void addUniform(const UT_StringHolder &name,
228  int array_size,
229  int offset,
230  int location,
231  int top_array_size,
232  int top_array_stride);
233  void clearUniforms();
234  void setBufferSizes(int fixed_size_bytes,
235  int variable_size_bytes);
236 
237  /// Update the passed uniform block with the uniforms found in this block.
238  /// This is generally done by the shader before a draw call.
239  bool updateBlock(RE_UniformBlock *b,
240  const RE_Shader *sh) const;
241 
242  /// Whether this block requires uploading to the GPU.
243  bool isDirty() const { return myDirtyFlag ||
244  myResetCount!=theResetCounter;}
245  /// Which shader this block is currently laid out for.
246  void setInitializedFor(const RE_Shader *sh);
247  /// Which shader this block is currently laid out for.
248  bool isInitializedFor(const RE_Shader *sh) const;
249  /// Which shader this block is currently laid out for.
250  const RE_Shader *getInitializedShader() const { return myInitShader; }
251  /// Program ID of the program this block was created from.
252  void setOriginProgramID(int pid) { myLastProgramID = pid; }
253 
254 
255 private:
256  int getUniformIndex(const UT_StringHolder &name) const;
257  void copyToBuffer(const void *data, int len, int offset,
258  const UT_StringHolder &uniform_name);
259  void copyToBuffer3(const void *data, int len, int dsize,
260  int stride, int offset,
261  const UT_StringHolder &uniform_name);
262  void printMember(std::ostream &os, int idx,
263  int maxlen, int offset);
264 
265  UT_String myName;
266  UT_String myInstanceName;
267  RE_OGLUniformBuffer *myBufferObject;
268  void *myBuffer;
269  bool myDirtyFlag;
270 
272 
273  mutable UT_StringMap<int> myUniformsIndexMap;
274  mutable UT_StringMap<int> myUniformsInstanceIndexMap;
275 
276  int mySize;
277  int myID;
278  UT_IntArray myDataMatch;
279  const RE_Shader *myInitShader;
280 
281  // for buffer storage objects, which can have a non-array section at the
282  // beginning of the block (fixed), followed by array data at the end
283  // (variable). myArrayLength determines the number of entries in the array.
284  int myFixedSize;
285  int myVariableSize;
286  int myArrayLength;
287 
288  int myLastProgramID;
289  int myResetCount;
290  static int theResetCounter;
291 };
292 
293 inline const char *
295 {
296  return myName;
297 }
298 
299 inline const char *
301 {
302  return myInstanceName;
303 }
304 
305 inline void
307 {
308  myInitShader = sh;
309 }
310 
311 inline bool
313 {
314  return myInitShader == sh;
315 }
316 
317 #endif
int getArrayLength() const
Array length of variably sized arrays (for GL4 SSBOs).
GLuint const GLchar * name
Definition: glew.h:1814
#define RE_API
Definition: RE_API.h:10
GLuint index
Definition: glew.h:1814
const char * getInstanceName() const
Optional instance name of the uniform block (uniform block { } <name>)
const GLdouble * m
Definition: glew.h:9124
const GLdouble * v
Definition: glew.h:1391
RE_UniformType
Definition: RE_Uniform.h:137
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 GLenum GLsizei GLint GLsizei const void * data
Definition: glew.h:1379
bool isDirty() const
Whether this block requires uploading to the GPU.
long long int64
Definition: SYS_Types.h:116
const RE_Shader * getInitializedShader() const
Which shader this block is currently laid out for.
GLuint GLuint GLsizei GLenum type
Definition: glew.h:1253
GLsizei stride
Definition: glew.h:1523
void setInitializedFor(const RE_Shader *sh)
Which shader this block is currently laid out for.
GLdouble GLdouble GLdouble b
Definition: glew.h:9122
void setOriginProgramID(int pid)
Program ID of the program this block was created from.
int getID() const
GLdouble GLdouble GLdouble r
Definition: glew.h:1406
static void dirtyAllUniformBlocks()
GLint location
Definition: glew.h:1835
bool isInitializedFor(const RE_Shader *sh) const
Which shader this block is currently laid out for.
GLenum GLsizei len
Definition: glew.h:7752
GLintptr offset
Definition: glew.h:1682
std::enable_if< internal::is_string< S >::value >::type print(std::basic_ostream< FMT_CHAR(S)> &os, const S &format_str, const Args &...args)
Definition: ostream.h:146