From 2659ee9dfb32f76ae2b93d0d7234053a246d400a Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 3 Nov 2006 21:30:16 +0000 Subject: Use inlined uniform() helper function in all the glUniform*() function to reduce duplicated code. Finish up _program_ReadUniform() for non-float types. Implement _mesa_GetUniformivARB(). Simplify the _program_WriteUniform() function a bit. --- src/mesa/shader/shaderobjects.c | 278 ++++++++------------------------- src/mesa/shader/shaderobjects.h | 2 +- src/mesa/shader/shaderobjects_3dlabs.c | 183 +++++++++++++++------- 3 files changed, 193 insertions(+), 270 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/shader/shaderobjects.c b/src/mesa/shader/shaderobjects.c index b9068d4a96..9c4d8ab528 100644 --- a/src/mesa/shader/shaderobjects.c +++ b/src/mesa/shader/shaderobjects.c @@ -349,299 +349,146 @@ _mesa_ValidateProgramARB(GLhandleARB programObj) } } -GLvoid GLAPIENTRY -_mesa_Uniform1fARB(GLint location, GLfloat v0) + +/** + * Helper function for all the _mesa_Uniform*() functions below. + */ +static INLINE void +uniform(GLint location, GLsizei count, const GLvoid *values, GLenum type, + const char *caller) { GET_CURRENT_CONTEXT(ctx); - GET_CURRENT_LINKED_PROGRAM(pro, "glUniform1fARB"); + GET_CURRENT_LINKED_PROGRAM(pro, caller); FLUSH_VERTICES(ctx, _NEW_PROGRAM); - if (pro != NULL) { - if (!(**pro).WriteUniform(pro, location, 1, &v0, GL_FLOAT)) - _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform1fARB"); - } + if (!pro) + return; + + if (!(**pro).WriteUniform(pro, location, count, values, type)) + _mesa_error(ctx, GL_INVALID_OPERATION, caller); } + GLvoid GLAPIENTRY -_mesa_Uniform2fARB(GLint location, GLfloat v0, GLfloat v1) +_mesa_Uniform1fARB(GLint location, GLfloat v0) { - GET_CURRENT_CONTEXT(ctx); - GET_CURRENT_LINKED_PROGRAM(pro, "glUniform2fARB"); - - FLUSH_VERTICES(ctx, _NEW_PROGRAM); - - if (pro != NULL) { - GLfloat v[2]; - v[0] = v0; - v[1] = v1; + uniform(location, 1, &v0, GL_FLOAT, "glUniform1fARB"); +} - if (!(**pro).WriteUniform(pro, location, 1, v, GL_FLOAT_VEC2)) - _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform2fARB"); - } +GLvoid GLAPIENTRY +_mesa_Uniform2fARB(GLint location, GLfloat v0, GLfloat v1) +{ + GLfloat v[2]; + v[0] = v0; + v[1] = v1; + uniform(location, 1, v, GL_FLOAT_VEC2, "glUniform2fARB"); } GLvoid GLAPIENTRY _mesa_Uniform3fARB(GLint location, GLfloat v0, GLfloat v1, GLfloat v2) { - GET_CURRENT_CONTEXT(ctx); - GET_CURRENT_LINKED_PROGRAM(pro, "glUniform3fARB"); - - FLUSH_VERTICES(ctx, _NEW_PROGRAM); - - if (pro != NULL) { - GLfloat v[3]; - v[0] = v0; - v[1] = v1; - v[2] = v2; - - if (!(**pro).WriteUniform(pro, location, 1, v, GL_FLOAT_VEC3)) - _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform3fARB"); - } + GLfloat v[3]; + v[0] = v0; + v[1] = v1; + v[2] = v2; + uniform(location, 1, v, GL_FLOAT_VEC3, "glUniform3fARB"); } GLvoid GLAPIENTRY _mesa_Uniform4fARB(GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) { - GET_CURRENT_CONTEXT(ctx); - GET_CURRENT_LINKED_PROGRAM(pro, "glUniform4fARB"); - - FLUSH_VERTICES(ctx, _NEW_PROGRAM); - - if (pro != NULL) { - GLfloat v[4]; - v[0] = v0; - v[1] = v1; - v[2] = v2; - v[3] = v3; - - if (!(**pro).WriteUniform(pro, location, 1, v, GL_FLOAT_VEC4)) - _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform4fARB"); - } + GLfloat v[4]; + v[0] = v0; + v[1] = v1; + v[2] = v2; + v[3] = v3; + uniform(location, 1, v, GL_FLOAT_VEC4, "glUniform4fARB"); } GLvoid GLAPIENTRY _mesa_Uniform1iARB(GLint location, GLint v0) { - GET_CURRENT_CONTEXT(ctx); - GET_CURRENT_LINKED_PROGRAM(pro, "glUniform1iARB"); - - FLUSH_VERTICES(ctx, _NEW_PROGRAM); - - if (pro != NULL) { - if (!(**pro).WriteUniform(pro, location, 1, &v0, GL_INT)) - _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform1iARB"); - } + uniform(location, 1, &v0, GL_INT, "glUniform1iARB"); } GLvoid GLAPIENTRY _mesa_Uniform2iARB(GLint location, GLint v0, GLint v1) { - GET_CURRENT_CONTEXT(ctx); - GET_CURRENT_LINKED_PROGRAM(pro, "glUniform2iARB"); - - FLUSH_VERTICES(ctx, _NEW_PROGRAM); - - if (pro != NULL) { - GLint v[2]; - v[0] = v0; - v[1] = v1; - - if (!(**pro).WriteUniform(pro, location, 1, v, GL_INT_VEC2)) - _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform2iARB"); - } + GLint v[2]; + v[0] = v0; + v[1] = v1; + uniform(location, 1, v, GL_INT_VEC2, "glUniform2iARB"); } GLvoid GLAPIENTRY _mesa_Uniform3iARB(GLint location, GLint v0, GLint v1, GLint v2) { - GET_CURRENT_CONTEXT(ctx); - GET_CURRENT_LINKED_PROGRAM(pro, "glUniform3iARB"); - - FLUSH_VERTICES(ctx, _NEW_PROGRAM); - - if (pro != NULL) { - GLint v[3]; - v[0] = v0; - v[1] = v1; - v[2] = v2; - - if (!(**pro).WriteUniform(pro, location, 1, v, GL_INT_VEC3)) - _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform3iARB"); - } + GLint v[3]; + v[0] = v0; + v[1] = v1; + v[2] = v2; + uniform(location, 1, v, GL_INT_VEC3, "glUniform3iARB"); } GLvoid GLAPIENTRY _mesa_Uniform4iARB(GLint location, GLint v0, GLint v1, GLint v2, GLint v3) { - GET_CURRENT_CONTEXT(ctx); - GET_CURRENT_LINKED_PROGRAM(pro, "glUniform4iARB"); - - FLUSH_VERTICES(ctx, _NEW_PROGRAM); - - if (pro != NULL) { - GLint v[4]; - v[0] = v0; - v[1] = v1; - v[2] = v2; - v[3] = v3; - - if (!(**pro).WriteUniform(pro, location, 1, v, GL_INT_VEC4)) - _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform4iARB"); - } + GLint v[4]; + v[0] = v0; + v[1] = v1; + v[2] = v2; + v[3] = v3; + uniform(location, 1, v, GL_INT_VEC4, "glUniform4iARB"); } GLvoid GLAPIENTRY _mesa_Uniform1fvARB(GLint location, GLsizei count, const GLfloat * value) { - GET_CURRENT_CONTEXT(ctx); - GET_CURRENT_LINKED_PROGRAM(pro, "glUniform1fvARB"); - - if (value == NULL) { - _mesa_error(ctx, GL_INVALID_VALUE, "glUniform1fvARB"); - return; - } - - FLUSH_VERTICES(ctx, _NEW_PROGRAM); - - if (pro != NULL) { - if (!(**pro).WriteUniform(pro, location, count, value, GL_FLOAT)) - _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform1fvARB"); - } + uniform(location, count, value, GL_FLOAT, "glUniform1fvARB"); } GLvoid GLAPIENTRY _mesa_Uniform2fvARB(GLint location, GLsizei count, const GLfloat * value) { - GET_CURRENT_CONTEXT(ctx); - GET_CURRENT_LINKED_PROGRAM(pro, "glUniform2fvARB"); - - if (value == NULL) { - _mesa_error(ctx, GL_INVALID_VALUE, "glUniform2fvARB"); - return; - } - - FLUSH_VERTICES(ctx, _NEW_PROGRAM); - - if (pro != NULL) { - if (!(**pro).WriteUniform(pro, location, count, value, GL_FLOAT_VEC2)) - _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform2fvARB"); - } + uniform(location, count, value, GL_FLOAT_VEC2, "glUniform2fvARB"); } GLvoid GLAPIENTRY _mesa_Uniform3fvARB(GLint location, GLsizei count, const GLfloat * value) { - GET_CURRENT_CONTEXT(ctx); - GET_CURRENT_LINKED_PROGRAM(pro, "glUniform3fvARB"); - - if (value == NULL) { - _mesa_error(ctx, GL_INVALID_VALUE, "glUniform3fvARB"); - return; - } - - FLUSH_VERTICES(ctx, _NEW_PROGRAM); - - if (pro != NULL) { - if (!(**pro).WriteUniform(pro, location, count, value, GL_FLOAT_VEC3)) - _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform3fvARB"); - } + uniform(location, count, value, GL_FLOAT_VEC3, "glUniform3fvARB"); } GLvoid GLAPIENTRY _mesa_Uniform4fvARB(GLint location, GLsizei count, const GLfloat * value) { - GET_CURRENT_CONTEXT(ctx); - GET_CURRENT_LINKED_PROGRAM(pro, "glUniform4fvARB"); - - if (value == NULL) { - _mesa_error(ctx, GL_INVALID_VALUE, "glUniform4fvARB"); - return; - } - - FLUSH_VERTICES(ctx, _NEW_PROGRAM); - - if (pro != NULL) { - if (!(**pro).WriteUniform(pro, location, count, value, GL_FLOAT_VEC4)) - _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform4fvARB"); - } + uniform(location, count, value, GL_FLOAT_VEC4, "glUniform4fvARB"); } GLvoid GLAPIENTRY _mesa_Uniform1ivARB(GLint location, GLsizei count, const GLint * value) { - GET_CURRENT_CONTEXT(ctx); - GET_CURRENT_LINKED_PROGRAM(pro, "glUniform1ivARB"); - - if (value == NULL) { - _mesa_error(ctx, GL_INVALID_VALUE, "glUniform1ivARB"); - return; - } - - FLUSH_VERTICES(ctx, _NEW_PROGRAM); - - if (pro != NULL) { - if (!(**pro).WriteUniform(pro, location, count, value, GL_INT)) - _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform1ivARB"); - } + uniform(location, count, value, GL_INT, "glUniform1ivARB"); } GLvoid GLAPIENTRY _mesa_Uniform2ivARB(GLint location, GLsizei count, const GLint * value) { - GET_CURRENT_CONTEXT(ctx); - GET_CURRENT_LINKED_PROGRAM(pro, "glUniform2ivARB"); - - if (value == NULL) { - _mesa_error(ctx, GL_INVALID_VALUE, "glUniform2ivARB"); - return; - } - - FLUSH_VERTICES(ctx, _NEW_PROGRAM); - - if (pro != NULL) { - if (!(**pro).WriteUniform(pro, location, count, value, GL_INT_VEC2)) - _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform2ivARB"); - } + uniform(location, count, value, GL_INT_VEC2, "glUniform2ivARB"); } GLvoid GLAPIENTRY _mesa_Uniform3ivARB(GLint location, GLsizei count, const GLint * value) { - GET_CURRENT_CONTEXT(ctx); - GET_CURRENT_LINKED_PROGRAM(pro, "glUniform3ivARB"); - - if (value == NULL) { - _mesa_error(ctx, GL_INVALID_VALUE, "glUniform3ivARB"); - return; - } - - FLUSH_VERTICES(ctx, _NEW_PROGRAM); - - if (pro != NULL) { - if (!(**pro).WriteUniform(pro, location, count, value, GL_INT_VEC3)) - _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform3ivARB"); - } + uniform(location, count, value, GL_INT_VEC3, "glUniform3ivARB"); } GLvoid GLAPIENTRY _mesa_Uniform4ivARB(GLint location, GLsizei count, const GLint * value) { - GET_CURRENT_CONTEXT(ctx); - GET_CURRENT_LINKED_PROGRAM(pro, "glUniform4ivARB"); - - if (value == NULL) { - _mesa_error(ctx, GL_INVALID_VALUE, "glUniform4ivARB"); - return; - } - - FLUSH_VERTICES(ctx, _NEW_PROGRAM); - - if (pro != NULL) { - if (!(**pro).WriteUniform(pro, location, count, value, GL_INT_VEC4)) - _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform4ivARB"); - } + uniform(location, count, value, GL_INT_VEC4, "glUniform4ivARB"); } @@ -1015,10 +862,8 @@ _mesa_GetUniformfvARB(GLhandleARB programObj, GLint location, GLfloat * params) GET_CURRENT_CONTEXT(ctx); GET_LINKED_PROGRAM(pro, programObj, "glGetUniformfvARB"); - /* XXX error-check location here */ - if (pro != NULL) { - if (!(**pro).ReadUniform(pro, location, 1, params)) + if (!(**pro).ReadUniform(pro, location, 1, params, GL_FLOAT)) _mesa_error(ctx, GL_INVALID_OPERATION, "glGetUniformfvARB"); RELEASE_PROGRAM(pro); } @@ -1031,7 +876,8 @@ _mesa_GetUniformivARB(GLhandleARB programObj, GLint location, GLint * params) GET_LINKED_PROGRAM(pro, programObj, "glGetUniformivARB"); if (pro != NULL) { - /* TODO */ + if (!(**pro).ReadUniform(pro, location, 1, params, GL_INT)) + _mesa_error(ctx, GL_INVALID_OPERATION, "glGetUniformivARB"); RELEASE_PROGRAM(pro); } } diff --git a/src/mesa/shader/shaderobjects.h b/src/mesa/shader/shaderobjects.h index 3afd0c9b29..09ba807255 100644 --- a/src/mesa/shader/shaderobjects.h +++ b/src/mesa/shader/shaderobjects.h @@ -105,7 +105,7 @@ struct gl2_program_intf GLboolean (* WriteUniform) (struct gl2_program_intf **, GLint loc, GLsizei count, const GLvoid *data, GLenum type); GLboolean (* ReadUniform) (struct gl2_program_intf **, GLint loc, GLsizei count, - GLfloat *data); + GLvoid *data, GLenum type); GLvoid (* GetActiveAttrib) (struct gl2_program_intf **, GLuint index, GLsizei maxLength, GLsizei *length, GLint *size, GLenum *type, GLchar *name); GLuint (* GetActiveAttribMaxLength) (struct gl2_program_intf **); diff --git a/src/mesa/shader/shaderobjects_3dlabs.c b/src/mesa/shader/shaderobjects_3dlabs.c index 0209e868ad..3ead1a1784 100755 --- a/src/mesa/shader/shaderobjects_3dlabs.c +++ b/src/mesa/shader/shaderobjects_3dlabs.c @@ -1383,6 +1383,10 @@ _program_GetUniformLocation(struct gl2_program_intf **intf, return -1; } +/** + * Write a uniform variable into program's memory. + * \return GL_TRUE for success, GL_FALSE if error + */ static GLboolean _program_WriteUniform(struct gl2_program_intf **intf, GLint loc, GLsizei count, const GLvoid * data, GLenum type) @@ -1396,9 +1400,7 @@ _program_WriteUniform(struct gl2_program_intf **intf, GLint loc, GLboolean convert_int_to_float = GL_FALSE; GLboolean types_match = GL_FALSE; - if (loc == -1) - return GL_TRUE; - if (loc >= uniforms->count) + if (loc < 0 || loc >= uniforms->count) return GL_FALSE; uniform = &uniforms->table[loc]; @@ -1460,86 +1462,161 @@ _program_WriteUniform(struct gl2_program_intf **intf, GLint loc, break; } - if (convert_float_to_bool) { - for (i = 0; i < SLANG_SHADER_MAX; i++) - if (uniform->address[i] != ~0) { + for (i = 0; i < SLANG_SHADER_MAX; i++) { + if (uniform->address[i] != ~0) { + void *dest + = &impl->_obj.prog.machines[i]->mem[uniform->address[i] / 4]; + /* total number of values to copy */ + GLuint total + = count * slang_export_data_quant_components(uniform->quant); + GLuint j; + if (convert_float_to_bool) { const GLfloat *src = (GLfloat *) (data); - GLfloat *dst = (GLfloat *) - (&impl->_obj.prog.machines[i]->mem[uniform->address[i] / 4]); - GLuint j; - GLuint total = - count * slang_export_data_quant_components(uniform->quant); - + GLfloat *dst = (GLfloat *) dest; for (j = 0; j < total; j++) dst[j] = src[j] != 0.0f ? 1.0f : 0.0f; + break; } - } - else if (convert_int_to_bool) { - for (i = 0; i < SLANG_SHADER_MAX; i++) - if (uniform->address[i] != ~0) { - const GLuint *src = (GLuint *) (data); - GLfloat *dst = (GLfloat *) - (&impl->_obj.prog.machines[i]->mem[uniform->address[i] / 4]); - GLuint j; - GLuint total = - count * slang_export_data_quant_components(uniform->quant); - + else if (convert_int_to_bool) { + const GLint *src = (GLint *) (data); + GLfloat *dst = (GLfloat *) dest; for (j = 0; j < total; j++) dst[j] = src[j] ? 1.0f : 0.0f; + break; } - } - else if (convert_int_to_float) { - for (i = 0; i < SLANG_SHADER_MAX; i++) - if (uniform->address[i] != ~0) { - const GLuint *src = (GLuint *) (data); - GLfloat *dst = (GLfloat *) - (&impl->_obj.prog.machines[i]->mem[uniform->address[i] / 4]); - GLuint j; - GLuint total = - count * slang_export_data_quant_components(uniform->quant); - + else if (convert_int_to_float) { + const GLint *src = (GLint *) (data); + GLfloat *dst = (GLfloat *) dest; for (j = 0; j < total; j++) dst[j] = (GLfloat) src[j]; + break; } - } - else { - for (i = 0; i < SLANG_SHADER_MAX; i++) - if (uniform->address[i] != ~0) { - _mesa_memcpy(&impl->_obj.prog.machines[i]-> - mem[uniform->address[i] / 4], data, - count * - slang_export_data_quant_size(uniform->quant)); + else { + _mesa_memcpy(dest, data, total * sizeof(GLfloat)); + break; } + break; + } } return GL_TRUE; } +/** + * Read a uniform variable from program's memory. + * \return GL_TRUE for success, GL_FALSE if error + */ static GLboolean _program_ReadUniform(struct gl2_program_intf **intf, GLint loc, - GLsizei count, GLfloat *data) + GLsizei count, GLvoid *data, GLenum type) { struct gl2_program_impl *impl = (struct gl2_program_impl *) (intf); const slang_uniform_bindings *uniforms = &impl->_obj.prog.uniforms; const slang_uniform_binding *uniform; - GLint i, j; + GLuint i; + GLboolean convert_bool_to_float = GL_FALSE; + GLboolean convert_bool_to_int = GL_FALSE; + GLboolean convert_float_to_int = GL_FALSE; + GLboolean types_match = GL_FALSE; if (loc < 0 || loc >= uniforms->count) return GL_FALSE; uniform = &uniforms->table[loc]; - /* loop over shader types (fragment, vertex) */ + if (slang_export_data_quant_struct(uniform->quant)) + return GL_FALSE; + + switch (slang_export_data_quant_type(uniform->quant)) { + case GL_BOOL_ARB: + types_match = (type == GL_FLOAT) || (type == GL_INT); + if (type == GL_FLOAT) + convert_bool_to_float = GL_TRUE; + else + convert_bool_to_int = GL_TRUE; + break; + case GL_BOOL_VEC2_ARB: + types_match = (type == GL_FLOAT_VEC2_ARB) || (type == GL_INT_VEC2_ARB); + if (type == GL_FLOAT_VEC2_ARB) + convert_bool_to_float = GL_TRUE; + else + convert_bool_to_int = GL_TRUE; + break; + case GL_BOOL_VEC3_ARB: + types_match = (type == GL_FLOAT_VEC3_ARB) || (type == GL_INT_VEC3_ARB); + if (type == GL_FLOAT_VEC3_ARB) + convert_bool_to_float = GL_TRUE; + else + convert_bool_to_int = GL_TRUE; + break; + case GL_BOOL_VEC4_ARB: + types_match = (type == GL_FLOAT_VEC4_ARB) || (type == GL_INT_VEC4_ARB); + if (type == GL_FLOAT_VEC4_ARB) + convert_bool_to_float = GL_TRUE; + else + convert_bool_to_int = GL_TRUE; + break; + case GL_SAMPLER_1D_ARB: + case GL_SAMPLER_2D_ARB: + case GL_SAMPLER_3D_ARB: + case GL_SAMPLER_CUBE_ARB: + case GL_SAMPLER_1D_SHADOW_ARB: + case GL_SAMPLER_2D_SHADOW_ARB: + types_match = (type == GL_INT); + break; + default: + /* uniform is a float type */ + types_match = (type == GL_FLOAT); + break; + } + + if (!types_match) + return GL_FALSE; + + switch (type) { + case GL_INT: + case GL_INT_VEC2_ARB: + case GL_INT_VEC3_ARB: + case GL_INT_VEC4_ARB: + convert_float_to_int = GL_TRUE; + break; + } + for (i = 0; i < SLANG_SHADER_MAX; i++) { if (uniform->address[i] != ~0) { - GLfloat *src = (GLfloat *) - (&impl->_obj.prog.machines[i]->mem[uniform->address[i] / 4]); - GLuint total = - count * slang_export_data_quant_components(uniform->quant); - for (j = 0; j < total; j++) - data[j] = src[j]; + /* XXX if bools are really implemented as floats, some of this + * could probably be culled out. + */ + const void *source + = &impl->_obj.prog.machines[i]->mem[uniform->address[i] / 4]; + /* total number of values to copy */ + const GLuint total + = count * slang_export_data_quant_components(uniform->quant); + GLuint j; + if (convert_bool_to_float) { + GLfloat *dst = (GLfloat *) (data); + const GLfloat *src = (GLfloat *) source; + for (j = 0; j < total; j++) + dst[j] = src[j] == 0.0 ? 0.0 : 1.0; + } + else if (convert_bool_to_int) { + GLint *dst = (GLint *) (data); + const GLfloat *src = (GLfloat *) source; + for (j = 0; j < total; j++) + dst[j] = src[j] == 0.0 ? 0 : 1; + } + else if (convert_float_to_int) { + GLint *dst = (GLint *) (data); + const GLfloat *src = (GLfloat *) source; + for (j = 0; j < total; j++) + dst[j] = (GLint) src[j]; + } + else { + /* no type conversion needed */ + _mesa_memcpy(data, source, total * sizeof(GLfloat)); + } break; - } - } + } /* if */ + } /* for */ return GL_TRUE; } -- cgit v1.2.3