[Mesa-dev] [PATCH 05/11] mesa: add double uniform support.

Dave Airlie airlied at gmail.com
Thu Aug 14 03:52:36 PDT 2014


From: Dave Airlie <airlied at redhat.com>

This adds support for the new uniform interfaces
from ARB_gpu_shader_fp64.

Signed-off-by: Dave Airlie <airlied at redhat.com>
---
 src/mesa/main/uniform_query.cpp   | 50 +++++++++++++++++----
 src/mesa/main/uniforms.c          | 91 +++++++++++++++++++++++++++++++--------
 src/mesa/main/uniforms.h          |  3 +-
 src/mesa/program/ir_to_mesa.cpp   | 17 +++++++-
 src/mesa/program/prog_parameter.c | 16 ++++---
 5 files changed, 143 insertions(+), 34 deletions(-)

diff --git a/src/mesa/main/uniform_query.cpp b/src/mesa/main/uniform_query.cpp
index 7e630e6..d7024cb 100644
--- a/src/mesa/main/uniform_query.cpp
+++ b/src/mesa/main/uniform_query.cpp
@@ -449,6 +449,9 @@ log_uniform(const void *values, enum glsl_base_type basicType,
       case GLSL_TYPE_FLOAT:
 	 printf("%g ", v[i].f);
 	 break;
+      case GLSL_TYPE_DOUBLE:
+	 printf("%g ", *(double* )&v[i * 2].f);
+	 break;
       default:
 	 assert(!"Should not get here.");
 	 break;
@@ -509,11 +512,11 @@ _mesa_propagate_uniforms_to_driver_storage(struct gl_uniform_storage *uni,
     */
    const unsigned components = MAX2(1, uni->type->vector_elements);
    const unsigned vectors = MAX2(1, uni->type->matrix_columns);
-
+   const int dmul = uni->type->base_type == GLSL_TYPE_DOUBLE ? 2 : 1;
    /* Store the data in the driver's requested type in the driver's storage
     * areas.
     */
-   unsigned src_vector_byte_stride = components * 4;
+   unsigned src_vector_byte_stride = components * 4 * dmul;
 
    for (i = 0; i < uni->num_driver_storage; i++) {
       struct gl_uniform_driver_storage *const store = &uni->driver_storage[i];
@@ -612,6 +615,7 @@ _mesa_uniform(struct gl_context *ctx, struct gl_shader_program *shProg,
    unsigned components;
    unsigned src_components;
    enum glsl_base_type basicType;
+   int size_mul = 1;
 
    struct gl_uniform_storage *const uni =
       validate_uniform_parameters(ctx, shProg, location, count,
@@ -670,6 +674,26 @@ _mesa_uniform(struct gl_context *ctx, struct gl_shader_program *shProg,
       basicType = GLSL_TYPE_INT;
       src_components = 4;
       break;
+   case GL_DOUBLE:
+      basicType = GLSL_TYPE_DOUBLE;
+      src_components = 1;
+      size_mul = 2;
+      break;
+   case GL_DOUBLE_VEC2:
+      basicType = GLSL_TYPE_DOUBLE;
+      src_components = 2;
+      size_mul = 2;
+      break;
+   case GL_DOUBLE_VEC3:
+      basicType = GLSL_TYPE_DOUBLE;
+      src_components = 3;
+      size_mul = 2;
+      break;
+   case GL_DOUBLE_VEC4:
+      basicType = GLSL_TYPE_DOUBLE;
+      src_components = 4;
+      size_mul = 2;
+      break;
    case GL_BOOL:
    case GL_BOOL_VEC2:
    case GL_BOOL_VEC3:
@@ -683,6 +707,15 @@ _mesa_uniform(struct gl_context *ctx, struct gl_shader_program *shProg,
    case GL_FLOAT_MAT4x2:
    case GL_FLOAT_MAT4x3:
    case GL_FLOAT_MAT4:
+   case GL_DOUBLE_MAT2:
+   case GL_DOUBLE_MAT2x3:
+   case GL_DOUBLE_MAT2x4:
+   case GL_DOUBLE_MAT3x2:
+   case GL_DOUBLE_MAT3:
+   case GL_DOUBLE_MAT3x4:
+   case GL_DOUBLE_MAT4x2:
+   case GL_DOUBLE_MAT4x3:
+   case GL_DOUBLE_MAT4:
    default:
       _mesa_problem(NULL, "Invalid type in %s", __func__);
       return;
@@ -789,7 +822,7 @@ _mesa_uniform(struct gl_context *ctx, struct gl_shader_program *shProg,
     */
    if (!uni->type->is_boolean()) {
       memcpy(&uni->storage[components * offset], values,
-	     sizeof(uni->storage[0]) * components * count);
+	     sizeof(uni->storage[0]) * components * count * size_mul);
    } else {
       const union gl_constant_value *src =
 	 (const union gl_constant_value *) values;
@@ -892,13 +925,14 @@ extern "C" void
 _mesa_uniform_matrix(struct gl_context *ctx, struct gl_shader_program *shProg,
 		     GLuint cols, GLuint rows,
                      GLint location, GLsizei count,
-                     GLboolean transpose, const GLfloat *values)
+                     GLboolean transpose,
+                     const GLvoid *values, GLenum type)
 {
    unsigned offset;
    unsigned vectors;
    unsigned components;
    unsigned elements;
-
+   int size_mul = mesa_type_is_double(type) ? 2 : 1;
    struct gl_uniform_storage *const uni =
       validate_uniform_parameters(ctx, shProg, location, count,
                                   &offset, "glUniformMatrix", false);
@@ -936,7 +970,7 @@ _mesa_uniform_matrix(struct gl_context *ctx, struct gl_shader_program *shProg,
    }
 
    if (ctx->_Shader->Flags & GLSL_UNIFORMS) {
-      log_uniform(values, GLSL_TYPE_FLOAT, components, vectors, count,
+      log_uniform(values, uni->type->base_type, components, vectors, count,
 		  bool(transpose), shProg, location, uni);
    }
 
@@ -963,11 +997,11 @@ _mesa_uniform_matrix(struct gl_context *ctx, struct gl_shader_program *shProg,
 
    if (!transpose) {
       memcpy(&uni->storage[elements * offset], values,
-	     sizeof(uni->storage[0]) * elements * count);
+	     sizeof(uni->storage[0]) * elements * count * size_mul);
    } else {
       /* Copy and transpose the matrix.
        */
-      const float *src = values;
+      const float *src = (const float *)values;
       float *dst = &uni->storage[elements * offset].f;
 
       for (int i = 0; i < count; i++) {
diff --git a/src/mesa/main/uniforms.c b/src/mesa/main/uniforms.c
index 6bd7e42..88909f53 100644
--- a/src/mesa/main/uniforms.c
+++ b/src/mesa/main/uniforms.c
@@ -539,7 +539,7 @@ _mesa_UniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose,
 {
    GET_CURRENT_CONTEXT(ctx);
    _mesa_uniform_matrix(ctx, ctx->_Shader->ActiveProgram,
-			2, 2, location, count, transpose, value);
+			2, 2, location, count, transpose, value, GL_FLOAT);
 }
 
 void GLAPIENTRY
@@ -548,7 +548,7 @@ _mesa_UniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose,
 {
    GET_CURRENT_CONTEXT(ctx);
    _mesa_uniform_matrix(ctx, ctx->_Shader->ActiveProgram,
-			3, 3, location, count, transpose, value);
+			3, 3, location, count, transpose, value, GL_FLOAT);
 }
 
 void GLAPIENTRY
@@ -557,7 +557,7 @@ _mesa_UniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose,
 {
    GET_CURRENT_CONTEXT(ctx);
    _mesa_uniform_matrix(ctx, ctx->_Shader->ActiveProgram,
-			4, 4, location, count, transpose, value);
+			4, 4, location, count, transpose, value, GL_FLOAT);
 }
 
 /** Same as above with direct state access **/
@@ -669,7 +669,7 @@ _mesa_ProgramUniformMatrix2fv(GLuint program, GLint location, GLsizei count,
    struct gl_shader_program *shProg =
       _mesa_lookup_shader_program_err(ctx, program,
             "glProgramUniformMatrix2fv");
-   _mesa_uniform_matrix(ctx, shProg, 2, 2, location, count, transpose, value);
+   _mesa_uniform_matrix(ctx, shProg, 2, 2, location, count, transpose, value, GL_FLOAT);
 }
 
 void GLAPIENTRY
@@ -680,7 +680,7 @@ _mesa_ProgramUniformMatrix3fv(GLuint program, GLint location, GLsizei count,
    struct gl_shader_program *shProg =
       _mesa_lookup_shader_program_err(ctx, program,
             "glProgramUniformMatrix3fv");
-   _mesa_uniform_matrix(ctx, shProg, 3, 3, location, count, transpose, value);
+   _mesa_uniform_matrix(ctx, shProg, 3, 3, location, count, transpose, value, GL_FLOAT);
 }
 
 void GLAPIENTRY
@@ -691,7 +691,7 @@ _mesa_ProgramUniformMatrix4fv(GLuint program, GLint location, GLsizei count,
    struct gl_shader_program *shProg =
       _mesa_lookup_shader_program_err(ctx, program,
             "glProgramUniformMatrix4fv");
-   _mesa_uniform_matrix(ctx, shProg, 4, 4, location, count, transpose, value);
+   _mesa_uniform_matrix(ctx, shProg, 4, 4, location, count, transpose, value, GL_FLOAT);
 }
 
 
@@ -704,7 +704,7 @@ _mesa_UniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose,
 {
    GET_CURRENT_CONTEXT(ctx);
    _mesa_uniform_matrix(ctx, ctx->_Shader->ActiveProgram,
-			2, 3, location, count, transpose, value);
+			2, 3, location, count, transpose, value, GL_FLOAT);
 }
 
 void GLAPIENTRY
@@ -713,7 +713,7 @@ _mesa_UniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose,
 {
    GET_CURRENT_CONTEXT(ctx);
    _mesa_uniform_matrix(ctx, ctx->_Shader->ActiveProgram,
-			3, 2, location, count, transpose, value);
+			3, 2, location, count, transpose, value, GL_FLOAT);
 }
 
 void GLAPIENTRY
@@ -722,7 +722,7 @@ _mesa_UniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose,
 {
    GET_CURRENT_CONTEXT(ctx);
    _mesa_uniform_matrix(ctx, ctx->_Shader->ActiveProgram,
-			2, 4, location, count, transpose, value);
+			2, 4, location, count, transpose, value, GL_FLOAT);
 }
 
 void GLAPIENTRY
@@ -731,7 +731,7 @@ _mesa_UniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose,
 {
    GET_CURRENT_CONTEXT(ctx);
    _mesa_uniform_matrix(ctx, ctx->_Shader->ActiveProgram,
-			4, 2, location, count, transpose, value);
+			4, 2, location, count, transpose, value, GL_FLOAT);
 }
 
 void GLAPIENTRY
@@ -740,7 +740,7 @@ _mesa_UniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose,
 {
    GET_CURRENT_CONTEXT(ctx);
    _mesa_uniform_matrix(ctx, ctx->_Shader->ActiveProgram,
-			3, 4, location, count, transpose, value);
+			3, 4, location, count, transpose, value, GL_FLOAT);
 }
 
 void GLAPIENTRY
@@ -749,7 +749,7 @@ _mesa_UniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose,
 {
    GET_CURRENT_CONTEXT(ctx);
    _mesa_uniform_matrix(ctx, ctx->_Shader->ActiveProgram,
-			4, 3, location, count, transpose, value);
+			4, 3, location, count, transpose, value, GL_FLOAT);
 }
 
 /** Same as above with direct state access **/
@@ -762,7 +762,7 @@ _mesa_ProgramUniformMatrix2x3fv(GLuint program, GLint location, GLsizei count,
    struct gl_shader_program *shProg =
       _mesa_lookup_shader_program_err(ctx, program,
             "glProgramUniformMatrix2x3fv");
-   _mesa_uniform_matrix(ctx, shProg, 2, 3, location, count, transpose, value);
+   _mesa_uniform_matrix(ctx, shProg, 2, 3, location, count, transpose, value, GL_FLOAT);
 }
 
 void GLAPIENTRY
@@ -773,7 +773,7 @@ _mesa_ProgramUniformMatrix3x2fv(GLuint program, GLint location, GLsizei count,
    struct gl_shader_program *shProg =
       _mesa_lookup_shader_program_err(ctx, program,
             "glProgramUniformMatrix3x2fv");
-   _mesa_uniform_matrix(ctx, shProg, 3, 2, location, count, transpose, value);
+   _mesa_uniform_matrix(ctx, shProg, 3, 2, location, count, transpose, value, GL_FLOAT);
 }
 
 void GLAPIENTRY
@@ -784,7 +784,7 @@ _mesa_ProgramUniformMatrix2x4fv(GLuint program, GLint location, GLsizei count,
    struct gl_shader_program *shProg =
       _mesa_lookup_shader_program_err(ctx, program,
             "glProgramUniformMatrix2x4fv");
-   _mesa_uniform_matrix(ctx, shProg, 2, 4, location, count, transpose, value);
+   _mesa_uniform_matrix(ctx, shProg, 2, 4, location, count, transpose, value, GL_FLOAT);
 }
 
 void GLAPIENTRY
@@ -795,7 +795,7 @@ _mesa_ProgramUniformMatrix4x2fv(GLuint program, GLint location, GLsizei count,
    struct gl_shader_program *shProg =
       _mesa_lookup_shader_program_err(ctx, program,
             "glProgramUniformMatrix4x2fv");
-   _mesa_uniform_matrix(ctx, shProg, 4, 2, location, count, transpose, value);
+   _mesa_uniform_matrix(ctx, shProg, 4, 2, location, count, transpose, value, GL_FLOAT);
 }
 
 void GLAPIENTRY
@@ -806,7 +806,7 @@ _mesa_ProgramUniformMatrix3x4fv(GLuint program, GLint location, GLsizei count,
    struct gl_shader_program *shProg =
       _mesa_lookup_shader_program_err(ctx, program,
             "glProgramUniformMatrix3x4fv");
-   _mesa_uniform_matrix(ctx, shProg, 3, 4, location, count, transpose, value);
+   _mesa_uniform_matrix(ctx, shProg, 3, 4, location, count, transpose, value, GL_FLOAT);
 }
 
 void GLAPIENTRY
@@ -817,7 +817,7 @@ _mesa_ProgramUniformMatrix4x3fv(GLuint program, GLint location, GLsizei count,
    struct gl_shader_program *shProg =
       _mesa_lookup_shader_program_err(ctx, program,
             "glProgramUniformMatrix4x3fv");
-   _mesa_uniform_matrix(ctx, shProg, 4, 3, location, count, transpose, value);
+   _mesa_uniform_matrix(ctx, shProg, 4, 3, location, count, transpose, value, GL_FLOAT);
 }
 
 
@@ -1328,94 +1328,149 @@ _mesa_GetActiveAtomicCounterBufferiv(GLuint program, GLuint bufferIndex,
 void GLAPIENTRY
 _mesa_Uniform1d(GLint location, GLdouble v0)
 {
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_uniform(ctx, ctx->_Shader->ActiveProgram, location, 1, &v0, GL_DOUBLE);
 }
 
 void GLAPIENTRY
 _mesa_Uniform2d(GLint location, GLdouble v0, GLdouble v1)
 {
+   GET_CURRENT_CONTEXT(ctx);
+   GLdouble v[2];
+   v[0] = v0;
+   v[1] = v1;
+   _mesa_uniform(ctx, ctx->_Shader->ActiveProgram, location, 1, v, GL_DOUBLE_VEC2);
 }
 
 void GLAPIENTRY
 _mesa_Uniform3d(GLint location, GLdouble v0, GLdouble v1, GLdouble v2)
 {
+   GET_CURRENT_CONTEXT(ctx);
+   GLdouble v[3];
+   v[0] = v0;
+   v[1] = v1;
+   v[2] = v2;
+   _mesa_uniform(ctx, ctx->_Shader->ActiveProgram, location, 1, v, GL_DOUBLE_VEC3);
 }
 
 void GLAPIENTRY
 _mesa_Uniform4d(GLint location, GLdouble v0, GLdouble v1, GLdouble v2,
                    GLdouble v3)
 {
+   GET_CURRENT_CONTEXT(ctx);
+   GLdouble v[4];
+   v[0] = v0;
+   v[1] = v1;
+   v[2] = v2;
+   v[3] = v3;
+   _mesa_uniform(ctx, ctx->_Shader->ActiveProgram, location, 1, v, GL_DOUBLE_VEC4);
 }
 
 void GLAPIENTRY
 _mesa_Uniform1dv(GLint location, GLsizei count, const GLdouble * value)
 {
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_uniform(ctx, ctx->_Shader->ActiveProgram, location, count, value, GL_DOUBLE);
 }
 
 void GLAPIENTRY
 _mesa_Uniform2dv(GLint location, GLsizei count, const GLdouble * value)
 {
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_uniform(ctx, ctx->_Shader->ActiveProgram, location, count, value, GL_DOUBLE_VEC2);
 }
 
 void GLAPIENTRY
 _mesa_Uniform3dv(GLint location, GLsizei count, const GLdouble * value)
 {
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_uniform(ctx, ctx->_Shader->ActiveProgram, location, count, value, GL_DOUBLE_VEC3);
 }
 
 void GLAPIENTRY
 _mesa_Uniform4dv(GLint location, GLsizei count, const GLdouble * value)
 {
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_uniform(ctx, ctx->_Shader->ActiveProgram, location, count, value, GL_DOUBLE_VEC4);
 }
 
 void GLAPIENTRY
 _mesa_UniformMatrix2dv(GLint location, GLsizei count, GLboolean transpose,
                           const GLdouble * value)
 {
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_uniform_matrix(ctx, ctx->_Shader->ActiveProgram,
+			2, 2, location, count, transpose, value, GL_DOUBLE);
 }
 
 void GLAPIENTRY
 _mesa_UniformMatrix3dv(GLint location, GLsizei count, GLboolean transpose,
                           const GLdouble * value)
 {
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_uniform_matrix(ctx, ctx->_Shader->ActiveProgram,
+			3, 3, location, count, transpose, value, GL_DOUBLE);
 }
 
 void GLAPIENTRY
 _mesa_UniformMatrix4dv(GLint location, GLsizei count, GLboolean transpose,
                           const GLdouble * value)
 {
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_uniform_matrix(ctx, ctx->_Shader->ActiveProgram,
+			4, 4, location, count, transpose, value, GL_DOUBLE);
 }
 
 void GLAPIENTRY
 _mesa_UniformMatrix2x3dv(GLint location, GLsizei count, GLboolean transpose,
                          const GLdouble *value)
 {
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_uniform_matrix(ctx, ctx->_Shader->ActiveProgram,
+			2, 3, location, count, transpose, value, GL_DOUBLE);
 }
 
 void GLAPIENTRY
 _mesa_UniformMatrix3x2dv(GLint location, GLsizei count, GLboolean transpose,
                          const GLdouble *value)
 {
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_uniform_matrix(ctx, ctx->_Shader->ActiveProgram,
+			3, 2, location, count, transpose, value, GL_DOUBLE);
 }
 
 void GLAPIENTRY
 _mesa_UniformMatrix2x4dv(GLint location, GLsizei count, GLboolean transpose,
                          const GLdouble *value)
 {
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_uniform_matrix(ctx, ctx->_Shader->ActiveProgram,
+			2, 4, location, count, transpose, value, GL_DOUBLE);
 }
 
 void GLAPIENTRY
 _mesa_UniformMatrix4x2dv(GLint location, GLsizei count, GLboolean transpose,
                          const GLdouble *value)
 {
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_uniform_matrix(ctx, ctx->_Shader->ActiveProgram,
+			4, 2, location, count, transpose, value, GL_DOUBLE);
 }
 
 void GLAPIENTRY
 _mesa_UniformMatrix3x4dv(GLint location, GLsizei count, GLboolean transpose,
                          const GLdouble *value)
 {
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_uniform_matrix(ctx, ctx->_Shader->ActiveProgram,
+			3, 4, location, count, transpose, value, GL_DOUBLE);
 }
 
 void GLAPIENTRY
 _mesa_UniformMatrix4x3dv(GLint location, GLsizei count, GLboolean transpose,
                          const GLdouble *value)
 {
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_uniform_matrix(ctx, ctx->_Shader->ActiveProgram,
+			4, 3, location, count, transpose, value, GL_DOUBLE);
 }
diff --git a/src/mesa/main/uniforms.h b/src/mesa/main/uniforms.h
index ea9f729..8309872 100644
--- a/src/mesa/main/uniforms.h
+++ b/src/mesa/main/uniforms.h
@@ -314,7 +314,8 @@ void
 _mesa_uniform_matrix(struct gl_context *ctx, struct gl_shader_program *shProg,
 		     GLuint cols, GLuint rows,
                      GLint location, GLsizei count,
-                     GLboolean transpose, const GLfloat *values);
+                     GLboolean transpose,
+                     const GLvoid *values, GLenum type);
 
 void
 _mesa_get_uniform(struct gl_context *ctx, GLuint program, GLint location,
diff --git a/src/mesa/program/ir_to_mesa.cpp b/src/mesa/program/ir_to_mesa.cpp
index 4c246d1..f7eb87d 100644
--- a/src/mesa/program/ir_to_mesa.cpp
+++ b/src/mesa/program/ir_to_mesa.cpp
@@ -608,6 +608,14 @@ type_size(const struct glsl_type *type)
 	  */
 	 return 1;
       }
+      break;
+   case GLSL_TYPE_DOUBLE:
+      if (type->is_matrix()) {
+	 return type->matrix_columns * 2;
+      } else {
+         return 2;
+      }
+      break;
    case GLSL_TYPE_ARRAY:
       assert(type->length > 0);
       return type_size(type->fields.array) * type->length;
@@ -2528,6 +2536,7 @@ _mesa_associate_uniform_storage(struct gl_context *ctx,
 	 enum gl_uniform_driver_format format = uniform_native;
 
 	 unsigned columns = 0;
+	 int dmul = 4 * sizeof(float);
 	 switch (storage->type->base_type) {
 	 case GLSL_TYPE_UINT:
 	    assert(ctx->Const.NativeIntegers);
@@ -2539,6 +2548,10 @@ _mesa_associate_uniform_storage(struct gl_context *ctx,
 	       (ctx->Const.NativeIntegers) ? uniform_native : uniform_int_float;
 	    columns = 1;
 	    break;
+
+	 case GLSL_TYPE_DOUBLE:
+	    dmul = 4 * sizeof(GLdouble);
+	    /* fallthrough */
 	 case GLSL_TYPE_FLOAT:
 	    format = uniform_native;
 	    columns = storage->type->matrix_columns;
@@ -2568,8 +2581,8 @@ _mesa_associate_uniform_storage(struct gl_context *ctx,
 	 }
 
 	 _mesa_uniform_attach_driver_storage(storage,
-					     4 * sizeof(float) * columns,
-					     4 * sizeof(float),
+					     dmul * columns,
+					     dmul,
 					     format,
 					     &params->ParameterValues[i]);
 
diff --git a/src/mesa/program/prog_parameter.c b/src/mesa/program/prog_parameter.c
index 54531d2..63368c3 100644
--- a/src/mesa/program/prog_parameter.c
+++ b/src/mesa/program/prog_parameter.c
@@ -111,7 +111,13 @@ _mesa_add_parameter(struct gl_program_parameter_list *paramList,
                     const gl_state_index state[STATE_LENGTH])
 {
    const GLuint oldNum = paramList->NumParameters;
-   const GLuint sz4 = (size + 3) / 4; /* no. of new param slots needed */
+   GLuint sz4 = (size + 3) / 4; /* no. of new param slots needed */
+   int actual_size = size;
+
+   if (mesa_type_is_double(datatype)) {
+      actual_size *= 2;
+      sz4 = ((actual_size + 3) / 4);
+   }
 
    assert(size > 0);
 
@@ -151,15 +157,15 @@ _mesa_add_parameter(struct gl_program_parameter_list *paramList,
          struct gl_program_parameter *p = paramList->Parameters + oldNum + i;
          p->Name = name ? _mesa_strdup(name) : NULL;
          p->Type = type;
-         p->Size = size;
+         p->Size = actual_size;
          p->DataType = datatype;
          if (values) {
-            if (size >= 4) {
+            if (actual_size >= 4) {
                COPY_4V(paramList->ParameterValues[oldNum + i], values);
             }
             else {
                /* copy 1, 2 or 3 values */
-               GLuint remaining = size % 4;
+               GLuint remaining = actual_size % 4;
                assert(remaining < 4);
                for (j = 0; j < remaining; j++) {
                   paramList->ParameterValues[oldNum + i][j].f = values[j].f;
@@ -177,7 +183,7 @@ _mesa_add_parameter(struct gl_program_parameter_list *paramList,
             for (j = 0; j < 4; j++)
             	paramList->ParameterValues[oldNum + i][j].f = 0;
          }
-         size -= 4;
+         actual_size -= 4;
       }
 
       if (state) {
-- 
1.9.3



More information about the mesa-dev mailing list