summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/mesa/main/shader_query.cpp51
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