diff options
-rw-r--r-- | src/mesa/main/shader_query.cpp | 51 |
1 files changed, 38 insertions, 13 deletions
diff --git a/src/mesa/main/shader_query.cpp b/src/mesa/main/shader_query.cpp index 6e81564f225..3a40a243ffb 100644 --- a/src/mesa/main/shader_query.cpp +++ b/src/mesa/main/shader_query.cpp @@ -33,6 +33,7 @@ #include "ir.h" #include "shaderobj.h" #include "program/hash_table.h" +#include "../glsl/program.h" extern "C" { #include "shaderapi.h" @@ -85,35 +86,59 @@ _mesa_BindAttribLocationARB(GLhandleARB program, GLuint index, } void GLAPIENTRY -_mesa_GetActiveAttribARB(GLhandleARB program, GLuint index, +_mesa_GetActiveAttribARB(GLhandleARB program, GLuint desired_index, GLsizei maxLength, GLsizei * length, GLint * size, GLenum * type, GLcharARB * name) { GET_CURRENT_CONTEXT(ctx); - const struct gl_program_parameter_list *attribs = NULL; struct gl_shader_program *shProg; shProg = _mesa_lookup_shader_program_err(ctx, program, "glGetActiveAttrib"); if (!shProg) return; - if (shProg->VertexProgram) - attribs = shProg->VertexProgram->Base.Attributes; + if (!shProg->LinkStatus) { + _mesa_error(ctx, GL_INVALID_VALUE, + "glGetActiveAttrib(program not linked)"); + return; + } - if (!attribs || index >= attribs->NumParameters) { - _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveAttrib(index)"); + if (shProg->_LinkedShaders[MESA_SHADER_VERTEX] == NULL) { + _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveAttrib(no vertex shader)"); return; } - _mesa_copy_string(name, maxLength, length, - attribs->Parameters[index].Name); + exec_list *const ir = shProg->_LinkedShaders[MESA_SHADER_VERTEX]->ir; + unsigned current_index = 0; + + foreach_list(node, ir) { + const ir_variable *const var = ((ir_instruction *) node)->as_variable(); + + if (var == NULL + || var->mode != ir_var_in + || var->location == -1 + || var->location < VERT_ATTRIB_GENERIC0) + continue; + + if (current_index == desired_index) { + _mesa_copy_string(name, maxLength, length, var->name); + + if (size) + *size = (var->type->is_array()) ? var->type->length : 1; - if (size) - *size = attribs->Parameters[index].Size - / _mesa_sizeof_glsl_type(attribs->Parameters[index].DataType); + if (type) + *type = var->type->gl_type; - if (type) - *type = attribs->Parameters[index].DataType; + return; + } + + current_index++; + } + + /* If the loop did not return early, the caller must have asked for + * an index that did not exit. Set an error. + */ + _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveAttrib(index)"); } GLint GLAPIENTRY |