Mesa (master): glsl: Track explicit location in AST to IR translation

Ian Romanick idr at kemper.freedesktop.org
Fri Oct 8 21:25:00 UTC 2010


Module: Mesa
Branch: master
Commit: eee68d3631813580a14fa51fda6f0c959279256c
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=eee68d3631813580a14fa51fda6f0c959279256c

Author: Ian Romanick <ian.d.romanick at intel.com>
Date:   Thu Oct  7 15:13:38 2010 -0700

glsl: Track explicit location in AST to IR translation

---

 src/glsl/ast_to_hir.cpp |   47 +++++++++++++++++++++++++++++++++++++++++++++++
 src/glsl/ir.cpp         |    1 +
 src/glsl/ir.h           |    9 +++++++++
 src/glsl/ir_clone.cpp   |    3 +++
 4 files changed, 60 insertions(+), 0 deletions(-)

diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp
index fb25dc1..47fe7a3 100644
--- a/src/glsl/ast_to_hir.cpp
+++ b/src/glsl/ast_to_hir.cpp
@@ -1627,6 +1627,53 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual,
 		       qual_string);
    }
 
+   if (qual->flags.q.explicit_location) {
+      const bool global_scope = (state->current_function == NULL);
+      bool fail = false;
+      const char *string = "";
+
+      /* In the vertex shader only shader inputs can be given explicit
+       * locations.
+       *
+       * In the fragment shader only shader outputs can be given explicit
+       * locations.
+       */
+      switch (state->target) {
+      case vertex_shader:
+	 if (!global_scope || (var->mode != ir_var_in)) {
+	    fail = true;
+	    string = "input";
+	 }
+	 break;
+
+      case geometry_shader:
+	 _mesa_glsl_error(loc, state,
+			  "geometry shader variables cannot be given "
+			  "explicit locations\n");
+	 break;
+
+      case fragment_shader:
+	 if (!global_scope || (var->mode != ir_var_in)) {
+	    fail = true;
+	    string = "output";
+	 }
+	 break;
+      }
+
+      if (fail) {
+	 _mesa_glsl_error(loc, state,
+			  "only %s shader %s variables can be given an "
+			  "explicit location\n",
+			  _mesa_glsl_shader_target_name(state->target),
+			  string);
+      } else {
+	 var->explicit_location = true;
+	 var->location = (state->target == vertex_shader)
+	    ? (qual->location + VERT_ATTRIB_GENERIC0)
+	    : (qual->location + FRAG_RESULT_DATA0);
+      }
+   }
+
    if (var->type->is_array() && state->language_version != 110) {
       var->array_lvalue = true;
    }
diff --git a/src/glsl/ir.cpp b/src/glsl/ir.cpp
index 5e2109e..fd1c5d9 100644
--- a/src/glsl/ir.cpp
+++ b/src/glsl/ir.cpp
@@ -1071,6 +1071,7 @@ ir_variable::ir_variable(const struct glsl_type *type, const char *name,
    this->ir_type = ir_type_variable;
    this->type = type;
    this->name = talloc_strdup(this, name);
+   this->explicit_location = false;
    this->location = -1;
    this->warn_extension = NULL;
    this->constant_value = NULL;
diff --git a/src/glsl/ir.h b/src/glsl/ir.h
index fa246b5..3503bc9 100644
--- a/src/glsl/ir.h
+++ b/src/glsl/ir.h
@@ -289,6 +289,15 @@ public:
    /*@}*/
 
    /**
+    * Was the location explicitly set in the shader?
+    *
+    * If the location is explicitly set in the shader, it \b cannot be changed
+    * by the linker or by the API (e.g., calls to \c glBindAttribLocation have
+    * no effect).
+    */
+   unsigned explicit_location:1;
+
+   /**
     * Storage location of the base of this variable
     *
     * The precise meaning of this field depends on the nature of the variable.
diff --git a/src/glsl/ir_clone.cpp b/src/glsl/ir_clone.cpp
index 18543a3..a3cc8db 100644
--- a/src/glsl/ir_clone.cpp
+++ b/src/glsl/ir_clone.cpp
@@ -51,6 +51,9 @@ ir_variable::clone(void *mem_ctx, struct hash_table *ht) const
    var->warn_extension = this->warn_extension;
    var->origin_upper_left = this->origin_upper_left;
    var->pixel_center_integer = this->pixel_center_integer;
+   var->explicit_location = this->explicit_location;
+   if (this->explicit_location)
+      var->location = this->location;
 
    if (this->constant_value)
       var->constant_value = this->constant_value->clone(mem_ctx, ht);




More information about the mesa-commit mailing list