Use inlined uniform() helper function in all the glUniform*() function to
authorBrian Paul <brian.paul@tungstengraphics.com>
Fri, 3 Nov 2006 21:30:16 +0000 (21:30 +0000)
committerBrian Paul <brian.paul@tungstengraphics.com>
Fri, 3 Nov 2006 21:30:16 +0000 (21:30 +0000)
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
src/mesa/shader/shaderobjects.h
src/mesa/shader/shaderobjects_3dlabs.c

index b9068d4a966b1969f60f72ee40b4f496a32e196b..9c4d8ab5289c90549699e7c86690276e79ad5b6f 100644 (file)
@@ -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);
    }
 }
index 3afd0c9b292ab8ee09f698d45c2ea418d7e13a15..09ba807255e770856fca72940354c74f8ea6d742 100644 (file)
@@ -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 **);
index 0209e868adee3e1a547d7fbd7bf6919560112392..3ead1a178412c333c7a51b6d74305fa66ce4ebea 100755 (executable)
@@ -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;
 }