summaryrefslogtreecommitdiff
path: root/src/mesa
diff options
context:
space:
mode:
authorBrian Paul <brianp@vmware.com>2009-02-11 09:03:16 -0700
committerBrian Paul <brianp@vmware.com>2009-02-11 09:17:21 -0700
commit4ef7a93296dd7d7480dfa00a2b085009ca8c4814 (patch)
treef27d20c41627080f16f1cc5ea295f4c8b99f98f3 /src/mesa
parent2c1ea0720deb9b1f90fc294a7a731270d4f4bad6 (diff)
glsl: rework _mesa_get_uniform[fi]v() to avoid using a fixed size intermediate array
Diffstat (limited to 'src/mesa')
-rw-r--r--src/mesa/shader/shader_api.c103
1 files changed, 59 insertions, 44 deletions
diff --git a/src/mesa/shader/shader_api.c b/src/mesa/shader/shader_api.c
index 8b9281a086..290717ff55 100644
--- a/src/mesa/shader/shader_api.c
+++ b/src/mesa/shader/shader_api.c
@@ -1185,24 +1185,30 @@ get_uniform_rows_cols(const struct gl_program_parameter *p,
}
-#define MAX_UNIFORM_ELEMENTS 16
-
/**
- * Helper for GetUniformfv(), GetUniformiv()
- * Returns number of elements written to 'params' output.
+ * Helper for get_uniform[fi]v() functions.
+ * Given a shader program name and uniform location, return a pointer
+ * to the shader program and return the program parameter position.
*/
-static GLuint
-get_uniformfv(GLcontext *ctx, GLuint program, GLint location,
- GLfloat *params)
+static void
+lookup_uniform_parameter(GLcontext *ctx, GLuint program, GLint location,
+ struct gl_program **progOut, GLint *paramPosOut)
{
struct gl_shader_program *shProg
= _mesa_lookup_shader_program_err(ctx, program, "glGetUniform[if]v");
- if (shProg) {
- if (shProg->Uniforms &&
- location >= 0 && location < (GLint) shProg->Uniforms->NumUniforms) {
- GLint progPos;
- const struct gl_program *prog = NULL;
+ struct gl_program *prog = NULL;
+ GLint progPos = -1;
+
+ /* if shProg is NULL, we'll have already recorded an error */
+ if (shProg) {
+ if (!shProg->Uniforms ||
+ location < 0 ||
+ location >= (GLint) shProg->Uniforms->NumUniforms) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glGetUniformfv(location)");
+ }
+ else {
+ /* OK, find the gl_program and program parameter location */
progPos = shProg->Uniforms->Uniforms[location].VertPos;
if (progPos >= 0) {
prog = &shProg->VertexProgram->Base;
@@ -1213,33 +1219,11 @@ get_uniformfv(GLcontext *ctx, GLuint program, GLint location,
prog = &shProg->FragmentProgram->Base;
}
}
-
- ASSERT(prog);
- if (prog) {
- const struct gl_program_parameter *p =
- &prog->Parameters->Parameters[progPos];
- GLint rows, cols, i, j, k;
-
- /* See uniformiv() below */
- assert(p->Size <= MAX_UNIFORM_ELEMENTS);
-
- get_uniform_rows_cols(p, &rows, &cols);
-
- k = 0;
- for (i = 0; i < rows; i++) {
- for (j = 0; j < cols; j++ ) {
- params[k++] = prog->Parameters->ParameterValues[progPos+i][j];
- }
- }
-
- return p->Size;
- }
- }
- else {
- _mesa_error(ctx, GL_INVALID_OPERATION, "glGetUniformfv(location)");
}
}
- return 0;
+
+ *progOut = prog;
+ *paramPosOut = progPos;
}
@@ -1250,23 +1234,54 @@ static void
_mesa_get_uniformfv(GLcontext *ctx, GLuint program, GLint location,
GLfloat *params)
{
- (void) get_uniformfv(ctx, program, location, params);
+ struct gl_program *prog;
+ GLint paramPos;
+
+ lookup_uniform_parameter(ctx, program, location, &prog, &paramPos);
+
+ if (prog) {
+ const struct gl_program_parameter *p =
+ &prog->Parameters->Parameters[paramPos];
+ GLint rows, cols, i, j, k;
+
+ get_uniform_rows_cols(p, &rows, &cols);
+
+ k = 0;
+ for (i = 0; i < rows; i++) {
+ for (j = 0; j < cols; j++ ) {
+ params[k++] = prog->Parameters->ParameterValues[paramPos+i][j];
+ }
+ }
+ }
}
/**
* Called via ctx->Driver.GetUniformiv().
+ * \sa _mesa_get_uniformfv, only difference is a cast.
*/
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];
+ struct gl_program *prog;
+ GLint paramPos;
+
+ lookup_uniform_parameter(ctx, program, location, &prog, &paramPos);
+
+ if (prog) {
+ const struct gl_program_parameter *p =
+ &prog->Parameters->Parameters[paramPos];
+ GLint rows, cols, i, j, k;
+
+ get_uniform_rows_cols(p, &rows, &cols);
+
+ k = 0;
+ for (i = 0; i < rows; i++) {
+ for (j = 0; j < cols; j++ ) {
+ params[k++] = (GLint) prog->Parameters->ParameterValues[paramPos+i][j];
+ }
+ }
}
}