[Mesa-dev] [PATCH 8/9] mesa: add Uniform Buffer Object API implementation
vlj
vljn at ovi.com
Sun Oct 16 15:37:21 PDT 2011
---
src/mesa/main/bufferobj.c | 2 +
src/mesa/main/uniforms.c | 187 +++++++++++++++++++++++++++++++++++++++++++++
src/mesa/main/uniforms.h | 15 ++++
3 files changed, 204 insertions(+), 0 deletions(-)
diff --git a/src/mesa/main/bufferobj.c b/src/mesa/main/bufferobj.c
index c453f9c..cddb0b4 100644
--- a/src/mesa/main/bufferobj.c
+++ b/src/mesa/main/bufferobj.c
@@ -98,6 +98,8 @@ get_buffer_target(struct gl_context *ctx, GLenum target)
return &ctx->Texture.BufferObject;
}
break;
+ case GL_UNIFORM_BUFFER:
+ return &ctx->UniformBufferObject.UniformObj;
default:
return NULL;
}
diff --git a/src/mesa/main/uniforms.c b/src/mesa/main/uniforms.c
index fe1ce6d..253e5cf 100644
--- a/src/mesa/main/uniforms.c
+++ b/src/mesa/main/uniforms.c
@@ -45,12 +45,14 @@
#include "main/shaderapi.h"
#include "main/shaderobj.h"
#include "main/uniforms.h"
+#include "main/hash.h"
#include "program/prog_parameter.h"
#include "program/prog_statevars.h"
#include "program/prog_uniform.h"
#include "program/prog_instruction.h"
+
static GLenum
base_uniform_type(GLenum type)
{
@@ -1064,6 +1066,121 @@ _mesa_uniform_matrix(struct gl_context *ctx, struct gl_shader_program *shProg,
uniform->Initialized = GL_TRUE;
}
+static void
+_mesa_query_ubo_general(struct gl_context *ctx, struct gl_shader_program *shProg, GLint ubo_index,
+ GLenum query, int* data)
+{
+ if(ubo_index > shProg->UBOCount || ubo_index < 0)
+ _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveUniformBlock(uniformBlockIndex)");
+
+ struct ubo current_ubo = *(shProg->UniformBufferObject[ubo_index]);
+
+ switch(query)
+ {
+ case GL_UNIFORM_BLOCK_BINDING:
+ *data = current_ubo.BoundBuffer;
+ break;
+ case GL_UNIFORM_BLOCK_DATA_SIZE:
+ *data = 0;
+ break;
+ case GL_UNIFORM_BLOCK_NAME_LENGTH:
+ *data = strlen(current_ubo.Name);
+ break;
+ case GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS:
+ *data = current_ubo.NumberOfVariables;
+ break;
+ case GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:
+ case GL_UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER:
+ case GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:
+ *data = 0;
+ break;
+ default:
+ break;
+ }
+}
+
+/**
+ * TODO : Switch to hash table
+ */
+static GLuint
+getIndices(const struct gl_shader_program* prog, const char* name)
+{
+ unsigned i,k;
+ for (k = 0; k < prog->Uniforms->Size; k++)
+ {
+ struct gl_uniform* current_uniform = &(prog->Uniforms->Uniforms[k]);
+ if(strcmp(name,current_uniform->Name)==0)
+ {
+ return k;
+ }
+ }
+ for (i = 0;i < prog->UBOVariableCount; i++)
+ {
+ struct UBOVariableInfo* var = prog->IndexedUniformsInUBO[i];
+ if(strcmp(name,var->Name)==0)
+ {
+ return i + prog->Uniforms->Size;
+ }
+ }
+ return GL_INVALID_INDEX;
+}
+
+static void
+_mesa_get_ubo_name(struct gl_context *ctx, struct gl_shader_program *shProg, GLint index,
+ GLsizei bufsize, GLsizei* length, char* buffer)
+{
+ if(index >= shProg->UBOCount || index < 0) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "GetActiveUniformBlockName(uniformBlockIndex)");
+ return;
+ }
+
+ struct ubo current_ubo = *(shProg->UniformBufferObject[index]);
+ GLsizei temp_length = strlen(current_ubo.Name);
+ if(bufsize - 1 < temp_length) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "GetActiveUniformBlockName(bufSize)");
+ return;
+ }
+
+ memcpy(buffer,current_ubo.Name,temp_length);
+ buffer[temp_length] = '\0';
+ if(length != NULL)
+ *length = temp_length;
+}
+
+static void
+_mesa_link_buffer_uniform(struct gl_context* ctx,struct gl_shader_program *shProg, GLint ubo_index,
+ GLint buffer_index)
+{
+ if(ubo_index > shProg->UBOCount || ubo_index < 0)
+ _mesa_error(ctx, GL_INVALID_VALUE, "UniformBlockBinding(uniformBlockIndex)");
+
+ FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS);
+
+ shProg->UniformBufferObject[ubo_index]->BoundBuffer = buffer_index;
+}
+
+static
+GLint GetLoneUniformInfo(struct gl_shader_program* sh, GLuint index, GLenum pname) {
+ uint n = sh->Uniforms->Size;
+ if(index >= n) {
+ struct UBOVariableInfo *var = sh->IndexedUniformsInUBO[index - n];
+ switch(pname) {
+ case GL_UNIFORM_TYPE:
+ return var->Type;
+ case GL_UNIFORM_SIZE:
+ case GL_UNIFORM_BLOCK_NAME_LENGTH:
+ case GL_UNIFORM_BLOCK_INDEX:
+ return var->UBO->Index;
+ case GL_UNIFORM_OFFSET:
+ return var->Offset;
+ case GL_UNIFORM_ARRAY_STRIDE:
+ case GL_UNIFORM_MATRIX_STRIDE:
+ return var->Stride;
+ case GL_UNIFORM_IS_ROW_MAJOR:
+ return sh->UniformBufferObject[var->UBO->Index]->MatrixLayout == rowmajor;
+ }
+ }
+}
void GLAPIENTRY
_mesa_Uniform1fARB(GLint location, GLfloat v0)
@@ -1452,6 +1569,69 @@ _mesa_GetActiveUniformARB(GLhandleARB program, GLuint index,
type, name);
}
+void GLAPIENTRY
+_mesa_GetActiveUniformBlockInfo(GLuint program,GLuint ubo_index,GLenum pname, GLint* params)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_shader_program *shProg =
+ _mesa_lookup_shader_program_err(ctx, program, "GetActiveUniformBlockiv");
+ _mesa_query_ubo_general(ctx,shProg,ubo_index,pname,params);
+}
+
+void GLAPIENTRY
+_mesa_GetActiveUniformBlockName(GLuint program,GLuint ubo_index,GLsizei bufsize, GLint* length, char* name)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_shader_program *shProg =
+ _mesa_lookup_shader_program_err(ctx, program, "GetActiveUniformBlockName");
+ _mesa_get_ubo_name(ctx,shProg,ubo_index,bufsize,length,name);
+}
+
+/* Note : location and index are the same */
+void GLAPIENTRY
+_mesa_GetUniformIndices(GLuint program, GLsizei number_of_variables, const char** names, GLuint* indices)
+{
+ unsigned i;
+ GET_CURRENT_CONTEXT(ctx);
+
+ struct gl_shader_program *shProg =
+ _mesa_lookup_shader_program_err(ctx, program, "GetUniformIndices");
+ for (i=0; i < number_of_variables; i++)
+ {
+ indices[i] = getIndices(shProg,names[i]);
+ }
+}
+
+void GLAPIENTRY
+_mesa_GetActiveUniformName(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, char* uniformName)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_shader_program *shProg =
+ _mesa_lookup_shader_program_err(ctx, program, "GetActiveUniformName");
+ const char* name = shProg->Uniforms->Uniforms[index].Name;
+ unsigned n = strlen(name);
+ if(n + 1 <= bufsize) {
+ memcpy(uniformName,name,n);
+ uniformName[n]='\0';
+ }
+ if(length) {
+ *length = n;
+ }
+}
+
+void GLAPIENTRY
+_mesa_GetActiveUniformsiv(GLuint program, GLsizei uniformCount, const GLuint* uniformIndices, GLenum pname, GLint* param)
+{
+ unsigned k;
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_shader_program *shProg =
+ _mesa_lookup_shader_program_err(ctx, program, "GetActiveUniformsiv");
+
+
+ for(k = 0; k < uniformCount; k++) {
+ param[k] = GetLoneUniformInfo(shProg,uniformIndices[k],pname);
+ }
+}
/**
* Plug in shader uniform-related functions into API dispatch table.
@@ -1510,5 +1690,12 @@ _mesa_init_shader_uniform_dispatch(struct _glapi_table *exec)
SET_GetnUniformuivARB(exec, _mesa_GetnUniformuivARB);
SET_GetnUniformdvARB(exec, _mesa_GetnUniformdvARB); /* GL 4.0 */
+ /* GL_ARB_Uniform_Buffer_Object */
+ SET_GetActiveUniformBlockiv(exec, _mesa_GetActiveUniformBlockInfo);
+ SET_GetActiveUniformBlockName(exec, _mesa_GetActiveUniformBlockName);
+ SET_GetUniformIndices(exec, _mesa_GetUniformIndices);
+ SET_GetActiveUniformName(exec, _mesa_GetActiveUniformName);
+ SET_GetActiveUniformsiv(exec,_mesa_GetActiveUniformsiv);
+
#endif /* FEATURE_GL */
}
diff --git a/src/mesa/main/uniforms.h b/src/mesa/main/uniforms.h
index b024cb3..dfcf16b 100644
--- a/src/mesa/main/uniforms.h
+++ b/src/mesa/main/uniforms.h
@@ -169,6 +169,21 @@ _mesa_GetnUniformdvARB(GLhandleARB, GLint, GLsizei, GLdouble *);
extern GLint GLAPIENTRY
_mesa_GetUniformLocationARB(GLhandleARB, const GLcharARB *);
+void GLAPIENTRY
+_mesa_GetActiveUniformBlockInfo(GLuint, GLuint, GLenum, GLint *);
+
+extern void GLAPIENTRY
+_mesa_GetActiveUniformBlockName(GLuint, GLuint, GLsizei, GLint *, char *);
+
+extern void GLAPIENTRY
+_mesa_GetUniformIndices(GLuint, GLsizei, const char **, GLuint *);
+
+extern void GLAPIENTRY
+_mesa_GetActiveUniformName(GLuint, GLuint, GLsizei, GLsizei*, char*);
+
+void GLAPIENTRY
+_mesa_GetActiveUniformsiv(GLuint, GLsizei, const GLuint*, GLenum, GLint*);
+
GLint
_mesa_get_uniform_location(struct gl_context *ctx, struct gl_shader_program *shProg,
const GLchar *name);
--
1.7.6.4
More information about the mesa-dev
mailing list