diff options
author | Ian Romanick <[email protected]> | 2010-08-13 12:30:41 -0700 |
---|---|---|
committer | Ian Romanick <[email protected]> | 2010-08-13 14:50:48 -0700 |
commit | c33e78f62bed762d8e5987e111a6e0424dc26c76 (patch) | |
tree | c681cabe4b222f4d0c485e5f4e2aa6c484bd77c9 | |
parent | 204d4cbea0de81f6f162ae0348e476de6c916ca8 (diff) |
linker: Assign attrib location 0 if gl_Vertex is not used
If gl_Vertex is not used in the shader, then attribute location 0 is
available for use.
Fixes piglit test case glsl-getattriblocation (bugzilla #29540).
-rw-r--r-- | src/glsl/linker.cpp | 37 |
1 files changed, 36 insertions, 1 deletions
diff --git a/src/glsl/linker.cpp b/src/glsl/linker.cpp index c462d31ef3d..7bff859d554 100644 --- a/src/glsl/linker.cpp +++ b/src/glsl/linker.cpp @@ -116,6 +116,38 @@ private: }; +/** + * Visitor that determines whether or not a variable is ever read. + */ +class find_deref_visitor : public ir_hierarchical_visitor { +public: + find_deref_visitor(const char *name) + : name(name), found(false) + { + /* empty */ + } + + virtual ir_visitor_status visit(ir_dereference_variable *ir) + { + if (strcmp(this->name, ir->var->name) == 0) { + this->found = true; + return visit_stop; + } + + return visit_continue; + } + + bool variable_found() const + { + return this->found; + } + +private: + const char *name; /**< Find writes to a variable with this name. */ + bool found; /**< Was a write to the variable found? */ +}; + + void linker_error_printf(gl_shader_program *prog, const char *fmt, ...) { @@ -1042,7 +1074,10 @@ assign_attribute_locations(gl_shader_program *prog, unsigned max_attribute_index * be explicitly assigned by via glBindAttribLocation. Mark it as reserved * to prevent it from being automatically allocated below. */ - used_locations |= (1 << 0); + find_deref_visitor find("gl_Vertex"); + find.run(sh->ir); + if (find.variable_found()) + used_locations |= (1 << 0); for (unsigned i = 0; i < num_attr; i++) { /* Mask representing the contiguous slots that will be used by this |