[Mesa-dev] [PATCH 2/4] glsl: add support for ARB_blend_func_extended

Dave Airlie airlied at gmail.com
Mon Mar 26 11:14:02 PDT 2012


From: Dave Airlie <airlied at redhat.com>

This adds index support to the GLSL compiler.

I'm not 100% sure of my approach here, esp without how output ordering
happens wrt location, index pairs, in the "mark" function.

Since current hw doesn't ever have a location > 0 with an index > 0,
we don't have to work out if the output ordering the hw requires is
location, index, location, index or location, location, index, index.
But we have no hw to know, so punt on it for now.

Signed-off-by: Dave Airlie <airlied at redhat.com>
---
 src/glsl/ast.h                     |   12 ++++++++++++
 src/glsl/ast_to_hir.cpp            |    3 ++-
 src/glsl/builtin_variables.cpp     |    1 +
 src/glsl/glsl_parser.yy            |   20 ++++++++++++++++++++
 src/glsl/ir.h                      |    2 ++
 src/glsl/ir_clone.cpp              |    4 ++++
 src/glsl/ir_set_program_inouts.cpp |   12 ++++++------
 src/glsl/linker.cpp                |   13 +++++++++----
 8 files changed, 56 insertions(+), 11 deletions(-)

diff --git a/src/glsl/ast.h b/src/glsl/ast.h
index 1f78af8..9a7b2a2 100644
--- a/src/glsl/ast.h
+++ b/src/glsl/ast.h
@@ -363,6 +363,11 @@ struct ast_type_qualifier {
 	  * qualifier is used.
 	  */
 	 unsigned explicit_location:1;
+	 /**
+	  * Flag set if GL_ARB_explicit_attrib_location "index" layout
+	  * qualifier is used.
+	  */
+	 unsigned explicit_index:1;
 
          /** \name Layout qualifiers for GL_AMD_conservative_depth */
          /** \{ */
@@ -386,6 +391,13 @@ struct ast_type_qualifier {
     * This field is only valid if \c explicit_location is set.
     */
    int location;
+   /**
+    * Index specified via GL_ARB_explicit_attrib_location layout
+    *
+    * \note
+    * This field is only valid if \c explicit_index is set.
+    */
+   int index;
 
    /**
     * Return true if and only if an interpolation qualifier is present.
diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp
index ff56e33..2967519 100644
--- a/src/glsl/ast_to_hir.cpp
+++ b/src/glsl/ast_to_hir.cpp
@@ -2099,7 +2099,8 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual,
     */
    const bool uses_layout = qual->flags.q.pixel_center_integer
       || qual->flags.q.origin_upper_left
-      || qual->flags.q.explicit_location;
+      || qual->flags.q.explicit_location
+      || qual->flags.q.explicit_index;
 
    /* Does the declaration use the deprecated 'attribute' or 'varying'
     * keywords?
diff --git a/src/glsl/builtin_variables.cpp b/src/glsl/builtin_variables.cpp
index 516a69c..03b64c9 100644
--- a/src/glsl/builtin_variables.cpp
+++ b/src/glsl/builtin_variables.cpp
@@ -408,6 +408,7 @@ add_variable(exec_list *instructions, glsl_symbol_table *symtab,
 
    var->location = slot;
    var->explicit_location = (slot >= 0);
+   var->explicit_index = 0;
 
    /* Once the variable is created an initialized, add it to the symbol table
     * and add the declaration to the IR stream.
diff --git a/src/glsl/glsl_parser.yy b/src/glsl/glsl_parser.yy
index 64506b6..e45089a 100644
--- a/src/glsl/glsl_parser.yy
+++ b/src/glsl/glsl_parser.yy
@@ -1103,8 +1103,14 @@ layout_qualifier_id_list:
 	   if ($1.flags.q.explicit_location)
 	      $$.location = $1.location;
 
+	   if ($1.flags.q.explicit_index)
+	      $$.index = $1.index;
+
 	   if ($3.flags.q.explicit_location)
 	      $$.location = $3.location;
+
+	   if ($3.flags.q.explicit_index)
+	      $$.index = $3.index;
 	}
 	;
 
@@ -1191,6 +1197,20 @@ layout_qualifier_id:
 		    YYERROR;
 		 }
 	      }
+
+	      if (strcmp("index", $1) == 0) {
+	      	 got_one = true;
+
+		 $$.flags.q.explicit_index = 1;
+
+		 if ($3 >= 0) {
+		    $$.index = $3;
+		 } else {
+		    _mesa_glsl_error(& @3, state,
+		                     "invalid index %d specified\n", $3);
+                    YYERROR;
+                 }
+              }
 	   }
 
 	   /* If the identifier didn't match any known layout identifiers,
diff --git a/src/glsl/ir.h b/src/glsl/ir.h
index 1faae3c..0dbba79 100644
--- a/src/glsl/ir.h
+++ b/src/glsl/ir.h
@@ -363,6 +363,7 @@ public:
     * no effect).
     */
    unsigned explicit_location:1;
+   unsigned explicit_index:1;
 
    /**
     * Does this variable have an initializer?
@@ -397,6 +398,7 @@ public:
     */
    int location;
 
+   int index;
    /**
     * Built-in state that backs this uniform
     *
diff --git a/src/glsl/ir_clone.cpp b/src/glsl/ir_clone.cpp
index c63615c..ae0d689 100644
--- a/src/glsl/ir_clone.cpp
+++ b/src/glsl/ir_clone.cpp
@@ -50,6 +50,7 @@ ir_variable::clone(void *mem_ctx, struct hash_table *ht) const
    var->origin_upper_left = this->origin_upper_left;
    var->pixel_center_integer = this->pixel_center_integer;
    var->explicit_location = this->explicit_location;
+   var->explicit_index = this->explicit_index;
    var->has_initializer = this->has_initializer;
    var->depth_layout = this->depth_layout;
 
@@ -67,6 +68,9 @@ ir_variable::clone(void *mem_ctx, struct hash_table *ht) const
    if (this->explicit_location)
       var->location = this->location;
 
+   if (this->explicit_index)
+      var->index = this->index;
+
    if (this->constant_value)
       var->constant_value = this->constant_value->clone(mem_ctx, ht);
 
diff --git a/src/glsl/ir_set_program_inouts.cpp b/src/glsl/ir_set_program_inouts.cpp
index 8c2bc30..8bcb5b4 100644
--- a/src/glsl/ir_set_program_inouts.cpp
+++ b/src/glsl/ir_set_program_inouts.cpp
@@ -69,7 +69,7 @@ public:
 };
 
 static void
-mark(struct gl_program *prog, ir_variable *var, int offset, int len,
+mark(struct gl_program *prog, ir_variable *var, int offset, int idx_offset, int len,
      bool is_fragment_shader)
 {
    /* As of GLSL 1.20, varyings can only be floats, floating-point
@@ -81,12 +81,12 @@ mark(struct gl_program *prog, ir_variable *var, int offset, int len,
     */
 
    for (int i = 0; i < len; i++) {
-      GLbitfield64 bitfield = BITFIELD64_BIT(var->location + offset + i);
+      GLbitfield64 bitfield = BITFIELD64_BIT(var->location + (idx_offset * var->index) + offset + i);
       if (var->mode == ir_var_in) {
 	 prog->InputsRead |= bitfield;
          if (is_fragment_shader) {
             gl_fragment_program *fprog = (gl_fragment_program *) prog;
-            fprog->InterpQualifier[var->location + offset + i] =
+            fprog->InterpQualifier[var->location + (var->index * idx_offset) + offset + i] =
                (glsl_interp_qualifier) var->interpolation;
          }
       } else if (var->mode == ir_var_system_value) {
@@ -105,11 +105,11 @@ ir_set_program_inouts_visitor::visit(ir_dereference_variable *ir)
       return visit_continue;
 
    if (ir->type->is_array()) {
-      mark(this->prog, ir->var, 0,
+      mark(this->prog, ir->var, 0, 4,
 	   ir->type->length * ir->type->fields.array->matrix_columns,
            this->is_fragment_shader);
    } else {
-      mark(this->prog, ir->var, 0, ir->type->matrix_columns,
+      mark(this->prog, ir->var, 0, 4, ir->type->matrix_columns,
            this->is_fragment_shader);
    }
 
@@ -136,7 +136,7 @@ ir_set_program_inouts_visitor::visit_enter(ir_dereference_array *ir)
 	 width = deref_var->type->fields.array->matrix_columns;
       }
 
-      mark(this->prog, var, index->value.i[0] * width, width,
+      mark(this->prog, var, index->value.i[0] * width, 4, width,
            this->is_fragment_shader);
       return visit_continue_with_parent;
    }
diff --git a/src/glsl/linker.cpp b/src/glsl/linker.cpp
index 09ffdff..7eaf6d6 100644
--- a/src/glsl/linker.cpp
+++ b/src/glsl/linker.cpp
@@ -1264,10 +1264,15 @@ assign_attribute_or_color_locations(gl_shader_program *prog,
 	 }
       } else if (target_index == MESA_SHADER_FRAGMENT) {
 	 unsigned binding;
+	 unsigned index;
 
 	 if (prog->FragDataBindings->get(binding, var->name)) {
 	    assert(binding >= FRAG_RESULT_DATA0);
 	    var->location = binding;
+
+	    if (prog->FragDataIndexBindings->get(index, var->name)) {
+	       var->index = index;
+	    }
 	 }
       }
 
@@ -1278,7 +1283,7 @@ assign_attribute_or_color_locations(gl_shader_program *prog,
        */
       const unsigned slots = count_attribute_slots(var->type);
       if (var->location != -1) {
-	 if (var->location >= generic_base) {
+	 if (var->location >= generic_base && var->index < 1) {
 	    /* From page 61 of the OpenGL 4.0 spec:
 	     *
 	     *     "LinkProgram will fail if the attribute bindings assigned
@@ -1323,8 +1328,8 @@ assign_attribute_or_color_locations(gl_shader_program *prog,
 		  ? "vertex shader input" : "fragment shader output";
 	       linker_error(prog,
 			    "insufficient contiguous locations "
-			    "available for %s `%s'", string,
-			    var->name);
+			    "available for %s `%s' %d %d %d", string,
+			    var->name, used_locations, use_mask, attr);
 	       return false;
 	    }
 
@@ -2311,7 +2316,7 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
       goto done;
    }
 
-   if (!assign_attribute_or_color_locations(prog, MESA_SHADER_FRAGMENT, ctx->Const.MaxDrawBuffers)) {
+   if (!assign_attribute_or_color_locations(prog, MESA_SHADER_FRAGMENT, MAX2(ctx->Const.MaxDrawBuffers, ctx->Const.MaxDualSourceDrawBuffers))) {
       goto done;
    }
 
-- 
1.7.7.6



More information about the mesa-dev mailing list