}
-static struct gl_program_parameter *
-get_uniform_parameter(const struct gl_shader_program *shProg, GLuint index)
+/**
+ * Given a uniform index, return the vertex/geometry/fragment program
+ * that has that parameter, plus the position of the parameter in the
+ * parameter/constant buffer.
+ * \param shProg the shader program
+ * \param index the uniform index in [0, NumUniforms-1]
+ * \param progOut returns containing program
+ * \param posOut returns position of the uniform in the param/const buffer
+ * \return GL_TRUE for success, GL_FALSE for invalid index
+ */
+static GLboolean
+find_uniform_parameter_pos(struct gl_shader_program *shProg, GLint index,
+ struct gl_program **progOut, GLint *posOut)
{
- const struct gl_program *prog = NULL;
- GLint progPos;
+ struct gl_program *prog = NULL;
+ GLint pos;
- progPos = shProg->Uniforms->Uniforms[index].VertPos;
- if (progPos >= 0) {
+ if (!shProg->Uniforms ||
+ index < 0 ||
+ index >= (GLint) shProg->Uniforms->NumUniforms) {
+ return GL_FALSE;
+ }
+
+ pos = shProg->Uniforms->Uniforms[index].VertPos;
+ if (pos >= 0) {
prog = &shProg->VertexProgram->Base;
}
else {
- progPos = shProg->Uniforms->Uniforms[index].FragPos;
- if (progPos >= 0) {
+ pos = shProg->Uniforms->Uniforms[index].FragPos;
+ if (pos >= 0) {
prog = &shProg->FragmentProgram->Base;
- } else {
- progPos = shProg->Uniforms->Uniforms[index].GeomPos;
- if (progPos >= 0) {
+ }
+ else {
+ pos = shProg->Uniforms->Uniforms[index].GeomPos;
+ if (pos >= 0) {
prog = &shProg->GeometryProgram->Base;
}
}
}
- if (!prog || progPos < 0)
- return NULL; /* should never happen */
+ if (!prog || pos < 0)
+ return GL_FALSE; /* should really never happen */
+
+ *progOut = prog;
+ *posOut = pos;
+
+ return GL_TRUE;
+}
+
+
+/**
+ * Return pointer to a gl_program_parameter which corresponds to a uniform.
+ * \param shProg the shader program
+ * \param index the uniform index in [0, NumUniforms-1]
+ * \return gl_program_parameter point or NULL if index is invalid
+ */
+static const struct gl_program_parameter *
+get_uniform_parameter(struct gl_shader_program *shProg, GLint index)
+{
+ struct gl_program *prog;
+ GLint progPos;
- return &prog->Parameters->Parameters[progPos];
+ if (find_uniform_parameter_pos(shProg, index, &prog, &progPos))
+ return &prog->Parameters->Parameters[progPos];
+ else
+ return NULL;
}
GLsizei maxLength, GLsizei *length, GLint *size,
GLenum *type, GLchar *nameOut)
{
- const struct gl_shader_program *shProg;
- const struct gl_program *prog = NULL;
+ struct gl_shader_program *shProg;
const struct gl_program_parameter *param;
- GLint progPos;
shProg = _mesa_lookup_shader_program_err(ctx, program, "glGetActiveUniform");
if (!shProg)
return;
}
- progPos = shProg->Uniforms->Uniforms[index].VertPos;
- if (progPos >= 0) {
- prog = &shProg->VertexProgram->Base;
- }
- else {
- progPos = shProg->Uniforms->Uniforms[index].FragPos;
- if (progPos >= 0) {
- prog = &shProg->FragmentProgram->Base;
- } else {
- progPos = shProg->Uniforms->Uniforms[index].GeomPos;
- if (progPos >= 0) {
- prog = &shProg->GeometryProgram->Base;
- }
- }
- }
-
- if (!prog || progPos < 0)
- return; /* should never happen */
-
- ASSERT(progPos < prog->Parameters->NumParameters);
- param = &prog->Parameters->Parameters[progPos];
+ param = get_uniform_parameter(shProg, index);
+ if (!param)
+ return;
if (nameOut) {
_mesa_copy_string(nameOut, maxLength, length, param->Name);
}
-/**
- * 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 void
-lookup_uniform_parameter(struct gl_context *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");
- 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;
- }
- else {
- progPos = shProg->Uniforms->Uniforms[location].FragPos;
- if (progPos >= 0) {
- prog = &shProg->FragmentProgram->Base;
- } else {
- progPos = shProg->Uniforms->Uniforms[location].GeomPos;
- if (progPos >= 0) {
- prog = &shProg->GeometryProgram->Base;
- }
- }
- }
- }
- }
-
- *progOut = prog;
- *paramPosOut = progPos;
-}
-
-
/**
* GLGL uniform arrays and structs require special handling.
*
_mesa_get_uniformfv(struct gl_context *ctx, GLuint program, GLint location,
GLsizei bufSize, GLfloat *params)
{
+ struct gl_shader_program *shProg =
+ _mesa_lookup_shader_program_err(ctx, program, "glGetUniformfv");
struct gl_program *prog;
GLint paramPos, offset;
- split_location_offset(&location, &offset);
+ if (!shProg)
+ return;
- lookup_uniform_parameter(ctx, program, location, &prog, ¶mPos);
+ split_location_offset(&location, &offset);
- if (prog) {
+ if (!find_uniform_parameter_pos(shProg, location, &prog, ¶mPos)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glGetUniformfv(location)");
+ }
+ else {
const struct gl_program_parameter *p =
&prog->Parameters->Parameters[paramPos];
GLint rows, cols, i, j, k;
_mesa_get_uniformiv(struct gl_context *ctx, GLuint program, GLint location,
GLsizei bufSize, GLint *params)
{
+ struct gl_shader_program *shProg
+ = _mesa_lookup_shader_program_err(ctx, program, "glGetUniformiv");
struct gl_program *prog;
GLint paramPos, offset;
- split_location_offset(&location, &offset);
+ if (!shProg)
+ return;
- lookup_uniform_parameter(ctx, program, location, &prog, ¶mPos);
+ split_location_offset(&location, &offset);
- if (prog) {
+ if (!find_uniform_parameter(shProg, location, &prog, ¶mPos)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glGetUniformiv(location)");
+ }
+ else {
const struct gl_program_parameter *p =
&prog->Parameters->Parameters[paramPos];
GLint rows, cols, i, j, k;
_mesa_get_uniformuiv(struct gl_context *ctx, GLuint program, GLint location,
GLsizei bufSize, GLuint *params)
{
+ struct gl_shader_program *shProg
+ = _mesa_lookup_shader_program_err(ctx, program, "glGetUniformuiv");
struct gl_program *prog;
GLint paramPos, offset;
- split_location_offset(&location, &offset);
+ if (!shProg)
+ return;
- lookup_uniform_parameter(ctx, program, location, &prog, ¶mPos);
+ split_location_offset(&location, &offset);
- if (prog) {
+ if (!find_uniform_parameter(shProg, location, &prog, ¶mPos)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glGetUniformuiv(location)");
+ }
+ else {
const struct gl_program_parameter *p =
&prog->Parameters->Parameters[paramPos];
GLint rows, cols, i, j, k;
const GLint element = atoi(c + 1);
if (element > 0) {
/* get type of the uniform array element */
- struct gl_program_parameter *p;
- p = get_uniform_parameter(shProg, location);
+ const struct gl_program_parameter *p =
+ get_uniform_parameter(shProg, location);
if (p) {
GLint rows, cols;
get_matrix_dims(p->DataType, &rows, &cols);