OSDN Git Service

Added OpenGL 2.1 glUniformMatrix* functions.
authorBrian Paul <brian.paul@tungstengraphics.com>
Fri, 3 Nov 2006 17:29:31 +0000 (17:29 +0000)
committerBrian Paul <brian.paul@tungstengraphics.com>
Fri, 3 Nov 2006 17:29:31 +0000 (17:29 +0000)
Refactor the _mesa_UniformMatrix() functions to use a helper function.
Implement GetUniformfv function (might need more work someday).

src/mesa/shader/shaderobjects.c
src/mesa/shader/shaderobjects.h
src/mesa/shader/shaderobjects_3dlabs.c

index 6540525..b9068d4 100644 (file)
@@ -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
index ebcf591..3afd0c9 100644 (file)
@@ -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
index aed6a96..0209e86 100755 (executable)
@@ -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,