From bdb251bcbf94e71f3adba4183c363259c01cde60 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 3 Nov 2006 17:29:31 +0000 Subject: Added OpenGL 2.1 glUniformMatrix* functions. Refactor the _mesa_UniformMatrix() functions to use a helper function. Implement GetUniformfv function (might need more work someday). --- src/mesa/shader/shaderobjects.c | 264 +++++++++++++++++---------------- src/mesa/shader/shaderobjects.h | 30 ++++ src/mesa/shader/shaderobjects_3dlabs.c | 32 ++++ 3 files changed, 199 insertions(+), 127 deletions(-) diff --git a/src/mesa/shader/shaderobjects.c b/src/mesa/shader/shaderobjects.c index 6540525e6e..b9068d4a96 100644 --- a/src/mesa/shader/shaderobjects.c +++ b/src/mesa/shader/shaderobjects.c @@ -50,6 +50,8 @@ #define RELEASE_SHADER(x)\ (**x)._generic._unknown.Release ((struct gl2_unknown_intf **) (x)) + + static struct gl2_unknown_intf ** lookup_handle(GLcontext * ctx, GLhandleARB handle, enum gl2_uiid uiid, const char *function) @@ -57,20 +59,21 @@ lookup_handle(GLcontext * ctx, GLhandleARB handle, enum gl2_uiid uiid, struct gl2_unknown_intf **unk; /* - * Note: _mesa_HashLookup() requires non-zero input values, so the passed-in handle value - * must be checked beforehand. + * Note: _mesa_HashLookup() requires non-zero input values, so the + * passed-in handle value must be checked beforehand. */ if (handle == 0) { _mesa_error(ctx, GL_INVALID_VALUE, function); return NULL; } _glthread_LOCK_MUTEX(ctx->Shared->Mutex); - unk = - (struct gl2_unknown_intf - **) (_mesa_HashLookup(ctx->Shared->GL2Objects, handle)); + unk = (struct gl2_unknown_intf **) + (_mesa_HashLookup(ctx->Shared->GL2Objects, handle)); _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex); - if (unk == NULL) + + if (unk == NULL) { _mesa_error(ctx, GL_INVALID_VALUE, function); + } else { unk = (**unk).QueryInterface(unk, uiid); if (unk == NULL) @@ -641,138 +644,88 @@ _mesa_Uniform4ivARB(GLint location, GLsizei count, const GLint * value) } } -GLvoid GLAPIENTRY -_mesa_UniformMatrix2fvARB(GLint location, GLsizei count, GLboolean transpose, - const GLfloat * value) + +/** + * Helper function used by UniformMatrix**vARB() functions below. + */ +static void +uniform_matrix(GLint cols, GLint rows, const char *caller, + GLenum matrixType, + GLint location, GLsizei count, GLboolean transpose, + const GLfloat *values) { + const GLint matElements = rows * cols; GET_CURRENT_CONTEXT(ctx); - GET_CURRENT_LINKED_PROGRAM(pro, "glUniformMatrix2fvARB"); + GET_CURRENT_LINKED_PROGRAM(pro, caller); - if (value == NULL) { - _mesa_error(ctx, GL_INVALID_VALUE, "glUniformMatrix2fvARB"); + if (values == NULL) { + _mesa_error(ctx, GL_INVALID_VALUE, caller); return; } FLUSH_VERTICES(ctx, _NEW_PROGRAM); - if (pro != NULL) { - if (transpose) { - GLfloat *trans, *pt; - const GLfloat *pv; - - trans = (GLfloat *) _mesa_malloc(count * 4 * sizeof(GLfloat)); - if (trans == NULL) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glUniformMatrix2fvARB"); - return; - } - for (pt = trans, pv = value; pt != trans + count * 4; - pt += 4, pv += 4) { - pt[0] = pv[0]; - pt[1] = pv[2]; - pt[2] = pv[1]; - pt[3] = pv[3]; - } - if (!(**pro). - WriteUniform(pro, location, count, trans, GL_FLOAT_MAT2)) - _mesa_error(ctx, GL_INVALID_OPERATION, "glUniformMatrix2fvARB"); - _mesa_free(trans); + if (!pro) + return; /* no error? */ + + if (transpose) { + GLfloat *trans, *pt; + const GLfloat *pv; + GLint i, j, k; + + trans = (GLfloat *) _mesa_malloc(count * matElements * sizeof(GLfloat)); + if (!trans) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, caller); + return; } - else { - if (!(**pro). - WriteUniform(pro, location, count, value, GL_FLOAT_MAT2)) - _mesa_error(ctx, GL_INVALID_OPERATION, "glUniformMatrix2fvARB"); + + pt = trans; + pv = values; + for (i = 0; i < count; i++) { + /* transpose from pv matrix into pt matrix */ + for (j = 0; j < cols; j++) { + for (k = 0; k < rows; k++) { + /* XXX verify this */ + pt[j * rows + k] = pv[k * cols + j]; + } + } + pt += matElements; + pv += matElements; } + + if (!(**pro).WriteUniform(pro, location, count, trans, matrixType)) + _mesa_error(ctx, GL_INVALID_OPERATION, caller); + _mesa_free(trans); } + else { + if (!(**pro).WriteUniform(pro, location, count, values, matrixType)) + _mesa_error(ctx, GL_INVALID_OPERATION, caller); + } +} + + +GLvoid GLAPIENTRY +_mesa_UniformMatrix2fvARB(GLint location, GLsizei count, GLboolean transpose, + const GLfloat * value) +{ + uniform_matrix(2, 2, "glUniformMatrix2fvARB", GL_FLOAT_MAT2, + location, count, transpose, value); } GLvoid GLAPIENTRY _mesa_UniformMatrix3fvARB(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) { - GET_CURRENT_CONTEXT(ctx); - GET_CURRENT_LINKED_PROGRAM(pro, "glUniformMatrix3fvARB"); - - if (value == NULL) { - _mesa_error(ctx, GL_INVALID_VALUE, "glUniformMatrix3fvARB"); - return; - } - - FLUSH_VERTICES(ctx, _NEW_PROGRAM); - - if (pro != NULL) { - if (transpose) { - GLfloat *trans, *pt; - const GLfloat *pv; - - trans = (GLfloat *) _mesa_malloc(count * 9 * sizeof(GLfloat)); - if (trans == NULL) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glUniformMatrix3fvARB"); - return; - } - for (pt = trans, pv = value; pt != trans + count * 9; - pt += 9, pv += 9) { - pt[0] = pv[0]; - pt[1] = pv[3]; - pt[2] = pv[6]; - pt[3] = pv[1]; - pt[4] = pv[4]; - pt[5] = pv[7]; - pt[6] = pv[2]; - pt[7] = pv[5]; - pt[8] = pv[8]; - } - if (!(**pro). - WriteUniform(pro, location, count, trans, GL_FLOAT_MAT3)) - _mesa_error(ctx, GL_INVALID_OPERATION, "glUniformMatrix3fvARB"); - _mesa_free(trans); - } - else { - if (!(**pro). - WriteUniform(pro, location, count, value, GL_FLOAT_MAT3)) - _mesa_error(ctx, GL_INVALID_OPERATION, "glUniformMatrix3fvARB"); - } - } + uniform_matrix(3, 3, "glUniformMatrix3fvARB", GL_FLOAT_MAT3, + location, count, transpose, value); } GLvoid GLAPIENTRY _mesa_UniformMatrix4fvARB(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) { - GET_CURRENT_CONTEXT(ctx); - GET_CURRENT_LINKED_PROGRAM(pro, "glUniformMatrix4fvARB"); - - if (value == NULL) { - _mesa_error(ctx, GL_INVALID_VALUE, "glUniformMatrix4fvARB"); - return; - } - - FLUSH_VERTICES(ctx, _NEW_PROGRAM); - - if (pro != NULL) { - if (transpose) { - GLfloat *trans, *pt; - const GLfloat *pv; - - trans = (GLfloat *) _mesa_malloc(count * 16 * sizeof(GLfloat)); - if (trans == NULL) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glUniformMatrix4fvARB"); - return; - } - for (pt = trans, pv = value; pt != trans + count * 16; - pt += 16, pv += 16) { - _math_transposef(pt, pv); - } - if (!(**pro). - WriteUniform(pro, location, count, trans, GL_FLOAT_MAT4)) - _mesa_error(ctx, GL_INVALID_OPERATION, "glUniformMatrix4fvARB"); - _mesa_free(trans); - } - else { - if (!(**pro). - WriteUniform(pro, location, count, value, GL_FLOAT_MAT4)) - _mesa_error(ctx, GL_INVALID_OPERATION, "glUniformMatrix4fvARB"); - } - } + uniform_matrix(4, 4, "glUniformMatrix4fvARB", GL_FLOAT_MAT4, + location, count, transpose, value); } static GLboolean @@ -783,8 +736,8 @@ _mesa_get_object_parameter(GLhandleARB obj, GLenum pname, GLvoid * params, GLint *ipar = (GLint *) params; /* set default values */ - *integral = GL_TRUE; /* indicates param type, TRUE: GLint, FALSE: GLfloat */ - *size = 1; /* param array size */ + *integral = GL_TRUE; /* indicates param type, TRUE: GLint, FALSE: GLfloat */ + *size = 1; /* param array size */ switch (pname) { case GL_OBJECT_TYPE_ARB: @@ -830,7 +783,6 @@ _mesa_get_object_parameter(GLhandleARB obj, GLenum pname, GLvoid * params, case GL_OBJECT_SHADER_SOURCE_LENGTH_ARB: { const GLcharARB *src = (**sha).GetSource(sha); - if (src == NULL) *ipar = 0; else @@ -904,14 +856,14 @@ _mesa_GetObjectParameterfvARB(GLhandleARB obj, GLenum pname, GLfloat * params) assert(sizeof(GLfloat) == sizeof(GLint)); - if (_mesa_get_object_parameter - (obj, pname, (GLvoid *) params, &integral, &size)) + if (_mesa_get_object_parameter(obj, pname, (GLvoid *) params, + &integral, &size)) { if (integral) { GLint i; - for (i = 0; i < size; i++) params[i] = (GLfloat) ((GLint *) params)[i]; } + } } GLvoid GLAPIENTRY @@ -928,14 +880,14 @@ _mesa_GetObjectParameterivARB(GLhandleARB obj, GLenum pname, GLint * params) assert(sizeof(GLfloat) == sizeof(GLint)); - if (_mesa_get_object_parameter - (obj, pname, (GLvoid *) params, &integral, &size)) + if (_mesa_get_object_parameter(obj, pname, (GLvoid *) params, + &integral, &size)) { if (!integral) { GLint i; - for (i = 0; i < size; i++) params[i] = (GLint) ((GLfloat *) params)[i]; } + } } @@ -1058,14 +1010,16 @@ _mesa_GetActiveUniformARB(GLhandleARB programObj, GLuint index, } GLvoid GLAPIENTRY -_mesa_GetUniformfvARB(GLhandleARB programObj, GLint location, - GLfloat * params) +_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) { - /* TODO */ + if (!(**pro).ReadUniform(pro, location, 1, params)) + _mesa_error(ctx, GL_INVALID_OPERATION, "glGetUniformfvARB"); RELEASE_PROGRAM(pro); } } @@ -1250,6 +1204,62 @@ _mesa_IsShader(GLuint shader) } +/** + ** 2.1 functions + **/ + +void GLAPIENTRY +_mesa_UniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, + const GLfloat *value) +{ + uniform_matrix(2, 3, "glUniformMatrix2x3fv", GL_FLOAT_MAT2x3, + location, count, transpose, value); +} + +void GLAPIENTRY +_mesa_UniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, + const GLfloat *value) +{ + uniform_matrix(3, 2, "glUniformMatrix3x2fv", GL_FLOAT_MAT3x2, + location, count, transpose, value); +} + +void GLAPIENTRY +_mesa_UniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, + const GLfloat *value) +{ + uniform_matrix(2, 4, "glUniformMatrix2x4fv", GL_FLOAT_MAT2x4, + location, count, transpose, value); +} + +void GLAPIENTRY +_mesa_UniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, + const GLfloat *value) +{ + uniform_matrix(4, 2, "glUniformMatrix4x2fv", GL_FLOAT_MAT4x2, + location, count, transpose, value); +} + +void GLAPIENTRY +_mesa_UniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, + const GLfloat *value) +{ + uniform_matrix(3, 4, "glUniformMatrix3x4fv", GL_FLOAT_MAT3x4, + location, count, transpose, value); +} + +void GLAPIENTRY +_mesa_UniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, + const GLfloat *value) +{ + uniform_matrix(4, 3, "glUniformMatrix4x3fv", GL_FLOAT_MAT4x3, + location, count, transpose, value); +} + + + + + #endif GLvoid diff --git a/src/mesa/shader/shaderobjects.h b/src/mesa/shader/shaderobjects.h index ebcf591611..3afd0c9b29 100644 --- a/src/mesa/shader/shaderobjects.h +++ b/src/mesa/shader/shaderobjects.h @@ -104,6 +104,8 @@ struct gl2_program_intf GLint (* GetUniformLocation) (struct gl2_program_intf **, const GLchar *name); 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 (* GetActiveAttrib) (struct gl2_program_intf **, GLuint index, GLsizei maxLength, GLsizei *length, GLint *size, GLenum *type, GLchar *name); GLuint (* GetActiveAttribMaxLength) (struct gl2_program_intf **); @@ -315,6 +317,34 @@ extern GLboolean GLAPIENTRY _mesa_IsShader(GLuint shader); + +/* 2.1 */ +extern void GLAPIENTRY +_mesa_UniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, + const GLfloat *value); + +extern void GLAPIENTRY +_mesa_UniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, + const GLfloat *value); + +extern void GLAPIENTRY +_mesa_UniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, + const GLfloat *value); + +extern void GLAPIENTRY +_mesa_UniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, + const GLfloat *value); + +extern void GLAPIENTRY +_mesa_UniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, + const GLfloat *value); + +extern void GLAPIENTRY +_mesa_UniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, + const GLfloat *value); + + + #endif /* FEATURE_ARB_shader_objects */ extern void diff --git a/src/mesa/shader/shaderobjects_3dlabs.c b/src/mesa/shader/shaderobjects_3dlabs.c index aed6a96c6a..0209e868ad 100755 --- a/src/mesa/shader/shaderobjects_3dlabs.c +++ b/src/mesa/shader/shaderobjects_3dlabs.c @@ -1514,6 +1514,37 @@ _program_WriteUniform(struct gl2_program_intf **intf, GLint loc, return GL_TRUE; } +static GLboolean +_program_ReadUniform(struct gl2_program_intf **intf, GLint loc, + GLsizei count, GLfloat *data) +{ + 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; + + if (loc < 0 || loc >= uniforms->count) + return GL_FALSE; + + uniform = &uniforms->table[loc]; + + /* loop over shader types (fragment, vertex) */ + 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]; + break; + } + } + + return GL_TRUE; +} + + static GLvoid _program_GetActiveAttrib(struct gl2_program_intf **intf, GLuint index, GLsizei maxLength, GLsizei * length, GLint * size, @@ -1647,6 +1678,7 @@ static struct gl2_program_intf _program_vftbl = { _program_GetActiveUniformCount, _program_GetUniformLocation, _program_WriteUniform, + _program_ReadUniform, _program_GetActiveAttrib, _program_GetActiveAttribMaxLength, _program_GetActiveAttribCount, -- cgit v1.2.3