--- 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 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev