diff options
Diffstat (limited to 'mesalib/src/mesa/main/uniforms.c')
-rw-r--r-- | mesalib/src/mesa/main/uniforms.c | 137 |
1 files changed, 79 insertions, 58 deletions
diff --git a/mesalib/src/mesa/main/uniforms.c b/mesalib/src/mesa/main/uniforms.c index cda840fe2..fe1ce6d7b 100644 --- a/mesalib/src/mesa/main/uniforms.c +++ b/mesalib/src/mesa/main/uniforms.c @@ -55,17 +55,24 @@ static GLenum base_uniform_type(GLenum type) { switch (type) { -#if 0 /* not needed, for now */ case GL_BOOL: case GL_BOOL_VEC2: case GL_BOOL_VEC3: case GL_BOOL_VEC4: return GL_BOOL; -#endif case GL_FLOAT: case GL_FLOAT_VEC2: case GL_FLOAT_VEC3: case GL_FLOAT_VEC4: + case GL_FLOAT_MAT2: + case GL_FLOAT_MAT2x3: + case GL_FLOAT_MAT2x4: + case GL_FLOAT_MAT3x2: + case GL_FLOAT_MAT3: + case GL_FLOAT_MAT3x4: + case GL_FLOAT_MAT4x2: + case GL_FLOAT_MAT4x3: + case GL_FLOAT_MAT4: return GL_FLOAT; case GL_UNSIGNED_INT: case GL_UNSIGNED_INT_VEC2: @@ -408,8 +415,12 @@ get_uniform(struct gl_context *ctx, GLuint program, GLint location, else { const struct gl_program_parameter *p = &prog->Parameters->Parameters[paramPos]; + gl_constant_value (*values)[4]; GLint rows, cols, i, j, k; GLsizei numBytes; + GLenum storage_type; + + values = prog->Parameters->ParameterValues + paramPos + offset; get_uniform_rows_cols(p, &rows, &cols); @@ -421,62 +432,72 @@ get_uniform(struct gl_context *ctx, GLuint program, GLint location, return; } - switch (returnType) { - case GL_FLOAT: - { - GLfloat *params = (GLfloat *) paramsOut; - k = 0; - for (i = 0; i < rows; i++) { - const int base = paramPos + offset + i; - for (j = 0; j < cols; j++ ) { - params[k++] = prog->Parameters->ParameterValues[base][j].f; - } - } - } - break; - case GL_DOUBLE: - { - GLfloat *params = (GLfloat *) paramsOut; - k = 0; - for (i = 0; i < rows; i++) { - const int base = paramPos + offset + i; - for (j = 0; j < cols; j++ ) { - params[k++] = (GLdouble) - prog->Parameters->ParameterValues[base][j].f; - } - } - } - break; - case GL_INT: - { - GLint *params = (GLint *) paramsOut; - k = 0; - for (i = 0; i < rows; i++) { - const int base = paramPos + offset + i; - for (j = 0; j < cols; j++ ) { - params[k++] = ctx->Const.NativeIntegers ? - prog->Parameters->ParameterValues[base][j].i : - (GLint) prog->Parameters->ParameterValues[base][j].f; - } - } - } - break; - case GL_UNSIGNED_INT: - { - GLuint *params = (GLuint *) paramsOut; - k = 0; - for (i = 0; i < rows; i++) { - const int base = paramPos + offset + i; - for (j = 0; j < cols; j++ ) { - params[k++] = ctx->Const.NativeIntegers ? - prog->Parameters->ParameterValues[base][j].u : - (GLuint) prog->Parameters->ParameterValues[base][j].f; - } - } - } - break; - default: - _mesa_problem(ctx, "bad returnType in get_uniform()"); + if (ctx->Const.NativeIntegers) { + storage_type = base_uniform_type(p->DataType); + } else { + storage_type = GL_FLOAT; + } + + k = 0; + for (i = 0; i < rows; i++) { + for (j = 0; j < cols; j++ ) { + void *out = (char *)paramsOut + 4 * k; + + switch (returnType) { + case GL_FLOAT: + switch (storage_type) { + case GL_FLOAT: + *(float *)out = values[i][j].f; + break; + case GL_INT: + case GL_BOOL: /* boolean is just an integer 1 or 0. */ + *(float *)out = values[i][j].i; + break; + case GL_UNSIGNED_INT: + *(float *)out = values[i][j].u; + break; + } + break; + + case GL_INT: + case GL_UNSIGNED_INT: + switch (storage_type) { + case GL_FLOAT: + /* While the GL 3.2 core spec doesn't explicitly + * state how conversion of float uniforms to integer + * values works, in section 6.2 "State Tables" on + * page 267 it says: + * + * "Unless otherwise specified, when floating + * point state is returned as integer values or + * integer state is returned as floating-point + * values it is converted in the fashion + * described in section 6.1.2" + * + * That section, on page 248, says: + * + * "If GetIntegerv or GetInteger64v are called, + * a floating-point value is rounded to the + * nearest integer..." + */ + *(int *)out = IROUND(values[i][j].f); + break; + + case GL_INT: + case GL_UNSIGNED_INT: + case GL_BOOL: + /* type conversions for these to int/uint are just + * copying the data. + */ + *(int *)out = values[i][j].i; + break; + break; + } + break; + } + + k++; + } } } } |