mesa: implement glGetUniformiv() with new ctx->Driver function
authorBrian Paul <brian.paul@tungstengraphics.com>
Tue, 8 Jul 2008 22:17:04 +0000 (16:17 -0600)
committerBrian Paul <brian.paul@tungstengraphics.com>
Tue, 8 Jul 2008 22:17:04 +0000 (16:17 -0600)
The old implementation could overwrite the caller's param buffer.

src/mesa/main/dd.h
src/mesa/main/shaders.c
src/mesa/shader/shader_api.c

index e3ded41acac53edeb4b0fb82604801dceeb198e0..8edcfaf8c6e8c7e043ee8dced5b48b692f98e9e0 100644 (file)
@@ -868,6 +868,8 @@ struct dd_function_table {
                            GLsizei *length, GLcharARB *sourceOut);
    void (*GetUniformfv)(GLcontext *ctx, GLuint program, GLint location,
                         GLfloat *params);
+   void (*GetUniformiv)(GLcontext *ctx, GLuint program, GLint location,
+                        GLint *params);
    GLint (*GetUniformLocation)(GLcontext *ctx, GLuint program,
                                const GLcharARB *name);
    GLboolean (*IsProgram)(GLcontext *ctx, GLuint name);
index b7b2f791a520add535ad49c29f8a0554f11a32d1..a2670fda32a586c32f79a9e1dfd9c377c4e72aea 100644 (file)
@@ -128,6 +128,7 @@ _mesa_DeleteObjectARB(GLhandleARB obj)
 void GLAPIENTRY
 _mesa_DeleteProgram(GLuint name)
 {
+   printf("%s name=%u\n", __FUNCTION__, name);
    if (name) {
       GET_CURRENT_CONTEXT(ctx);
       ctx->Driver.DeleteProgram2(ctx, name);
@@ -309,11 +310,7 @@ void GLAPIENTRY
 _mesa_GetUniformivARB(GLhandleARB program, GLint location, GLint * params)
 {
    GET_CURRENT_CONTEXT(ctx);
-   GLfloat fparams[16]; /* XXX is 16 enough? */
-   GLuint i;
-   ctx->Driver.GetUniformfv(ctx, program, location, fparams);
-   for (i = 0; i < 16; i++)
-      params[i] = (GLint) fparams[i];  /* XXX correct? */
+   ctx->Driver.GetUniformiv(ctx, program, location, params);
 }
 
 
index 6cfdf57a494d1913987a4321cef282dc3635cc7f..105f76be28167027bf1bda31535fbe1434cc3f96 100644 (file)
@@ -955,12 +955,15 @@ _mesa_get_shader_source(GLcontext *ctx, GLuint shader, GLsizei maxLength,
 }
 
 
+#define MAX_UNIFORM_ELEMENTS 16
+
 /**
- * Called via ctx->Driver.GetUniformfv().
+ * Helper for GetUniformfv(), GetUniformiv()
+ * Returns number of elements written to 'params' output.
  */
-static void
-_mesa_get_uniformfv(GLcontext *ctx, GLuint program, GLint location,
-                    GLfloat *params)
+static GLuint
+get_uniformfv(GLcontext *ctx, GLuint program, GLint location,
+              GLfloat *params)
 {
    struct gl_shader_program *shProg
       = _mesa_lookup_shader_program(ctx, program);
@@ -984,9 +987,13 @@ _mesa_get_uniformfv(GLcontext *ctx, GLuint program, GLint location,
 
          ASSERT(prog);
          if (prog) {
+            /* See uniformiv() below */                    
+            assert(prog->Parameters->Parameters[progPos].Size <= MAX_UNIFORM_ELEMENTS);
+
             for (i = 0; i < prog->Parameters->Parameters[progPos].Size; i++) {
                params[i] = prog->Parameters->ParameterValues[progPos][i];
             }
+            return prog->Parameters->Parameters[progPos].Size;
          }
       }
       else {
@@ -996,6 +1003,35 @@ _mesa_get_uniformfv(GLcontext *ctx, GLuint program, GLint location,
    else {
       _mesa_error(ctx, GL_INVALID_OPERATION, "glGetUniformfv(program)");
    }
+   return 0;
+}
+
+
+/**
+ * Called via ctx->Driver.GetUniformfv().
+ */
+static void
+_mesa_get_uniformfv(GLcontext *ctx, GLuint program, GLint location,
+                    GLfloat *params)
+{
+   (void) get_uniformfv(ctx, program, location, params);
+}
+
+
+/**
+ * Called via ctx->Driver.GetUniformiv().
+ */
+static void
+_mesa_get_uniformiv(GLcontext *ctx, GLuint program, GLint location,
+                    GLint *params)
+{
+   GLfloat fparams[MAX_UNIFORM_ELEMENTS];
+   GLuint n = get_uniformfv(ctx, program, location, fparams);
+   GLuint i;
+   assert(n <= MAX_UNIFORM_ELEMENTS);
+   for (i = 0; i < n; i++) {
+      params[i] = (GLint) fparams[i];
+   }
 }
 
 
@@ -1413,6 +1449,7 @@ _mesa_init_glsl_driver_functions(struct dd_function_table *driver)
    driver->GetShaderInfoLog = _mesa_get_shader_info_log;
    driver->GetShaderSource = _mesa_get_shader_source;
    driver->GetUniformfv = _mesa_get_uniformfv;
+   driver->GetUniformiv = _mesa_get_uniformiv;
    driver->GetUniformLocation = _mesa_get_uniform_location;
    driver->IsProgram = _mesa_is_program;
    driver->IsShader = _mesa_is_shader;