summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Romanick <ian.d.romanick@intel.com>2010-08-13 12:30:41 -0700
committerIan Romanick <ian.d.romanick@intel.com>2010-08-13 14:50:48 -0700
commitc33e78f62bed762d8e5987e111a6e0424dc26c76 (patch)
treec681cabe4b222f4d0c485e5f4e2aa6c484bd77c9
parent204d4cbea0de81f6f162ae0348e476de6c916ca8 (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.cpp37
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