[Mesa-dev] [PATCH 2/6] glsl: Add ir support for `sample` qualifier; adjust compiler and linker

Chris Forbes chrisf at ijw.co.nz
Fri Nov 29 00:54:36 PST 2013


Signed-off-by: Chris Forbes <chrisf at ijw.co.nz>
---
 src/glsl/ast_to_hir.cpp                   | 15 +++++++++++++++
 src/glsl/builtin_variables.cpp            |  2 ++
 src/glsl/glsl_types.cpp                   |  5 +++++
 src/glsl/glsl_types.h                     |  6 ++++++
 src/glsl/ir.cpp                           |  5 +++--
 src/glsl/ir.h                             |  1 +
 src/glsl/ir_clone.cpp                     |  1 +
 src/glsl/ir_print_visitor.cpp             |  5 +++--
 src/glsl/ir_reader.cpp                    |  2 ++
 src/glsl/link_varyings.cpp                | 14 ++++++++++++++
 src/glsl/linker.cpp                       |  6 ++++++
 src/glsl/lower_named_interface_blocks.cpp |  1 +
 src/glsl/lower_packed_varyings.cpp        |  1 +
 13 files changed, 60 insertions(+), 4 deletions(-)

diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp
index 43cf497..d525096 100644
--- a/src/glsl/ast_to_hir.cpp
+++ b/src/glsl/ast_to_hir.cpp
@@ -2180,6 +2180,9 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual,
    if (qual->flags.q.centroid)
       var->centroid = 1;
 
+   if (qual->flags.q.sample)
+      var->sample = 1;
+
    if (qual->flags.q.attribute && state->target != vertex_shader) {
       var->type = glsl_type::error_type;
       _mesa_glsl_error(loc, state,
@@ -3277,6 +3280,14 @@ ast_declarator_list::hir(exec_list *instructions,
                           "'centroid in' cannot be used in a vertex shader");
       }
 
+      if (state->target == vertex_shader
+          && this->type->qualifier.flags.q.sample
+          && this->type->qualifier.flags.q.in) {
+
+         _mesa_glsl_error(&loc, state,
+                        "'sample in' cannot be used in a vertex shader");
+      }
+
       /* Section 4.3.6 of the GLSL 1.30 specification states:
        * "It is an error to use centroid out in a fragment shader."
        *
@@ -4662,6 +4673,7 @@ ast_process_structure_or_interface_block(exec_list *instructions,
          fields[i].interpolation =
             interpret_interpolation_qualifier(qual, var_mode, state, &loc);
          fields[i].centroid = qual->flags.q.centroid ? 1 : 0;
+         fields[i].sample = qual->flags.q.sample ? 1 : 0;
 
          if (qual->flags.q.row_major || qual->flags.q.column_major) {
             if (!qual->flags.q.uniform) {
@@ -4930,6 +4942,8 @@ ast_interface_block::hir(exec_list *instructions,
                earlier_per_vertex->fields.structure[j].interpolation;
             fields[i].centroid =
                earlier_per_vertex->fields.structure[j].centroid;
+            fields[i].sample =
+               earlier_per_vertex->fields.structure[j].sample;
          }
       }
 
@@ -5084,6 +5098,7 @@ ast_interface_block::hir(exec_list *instructions,
                                    var_mode);
          var->interpolation = fields[i].interpolation;
          var->centroid = fields[i].centroid;
+         var->sample = fields[i].sample;
          var->init_interface_type(block_type);
 
          if (redeclaring_per_vertex) {
diff --git a/src/glsl/builtin_variables.cpp b/src/glsl/builtin_variables.cpp
index d57324c..d0e76e3 100644
--- a/src/glsl/builtin_variables.cpp
+++ b/src/glsl/builtin_variables.cpp
@@ -332,6 +332,7 @@ per_vertex_accumulator::add_field(int slot, const glsl_type *type,
    this->fields[this->num_fields].location = slot;
    this->fields[this->num_fields].interpolation = INTERP_QUALIFIER_NONE;
    this->fields[this->num_fields].centroid = 0;
+   this->fields[this->num_fields].sample = 0;
    this->num_fields++;
 }
 
@@ -937,6 +938,7 @@ builtin_variable_generator::generate_varyings()
                          fields[i].location);
          var->interpolation = fields[i].interpolation;
          var->centroid = fields[i].centroid;
+         var->sample = fields[i].sample;
          var->init_interface_type(per_vertex_out_type);
       }
    }
diff --git a/src/glsl/glsl_types.cpp b/src/glsl/glsl_types.cpp
index f740130..12d4ac0 100644
--- a/src/glsl/glsl_types.cpp
+++ b/src/glsl/glsl_types.cpp
@@ -103,6 +103,7 @@ glsl_type::glsl_type(const glsl_struct_field *fields, unsigned num_fields,
       this->fields.structure[i].location = fields[i].location;
       this->fields.structure[i].interpolation = fields[i].interpolation;
       this->fields.structure[i].centroid = fields[i].centroid;
+      this->fields.structure[i].sample = fields[i].sample;
       this->fields.structure[i].row_major = fields[i].row_major;
    }
 }
@@ -130,6 +131,7 @@ glsl_type::glsl_type(const glsl_struct_field *fields, unsigned num_fields,
       this->fields.structure[i].location = fields[i].location;
       this->fields.structure[i].interpolation = fields[i].interpolation;
       this->fields.structure[i].centroid = fields[i].centroid;
+      this->fields.structure[i].sample = fields[i].sample;
       this->fields.structure[i].row_major = fields[i].row_major;
    }
 }
@@ -483,6 +485,9 @@ glsl_type::record_key_compare(const void *a, const void *b)
       if (key1->fields.structure[i].centroid
           != key2->fields.structure[i].centroid)
          return 1;
+      if (key1->fields.structure[i].sample
+          != key2->fields.structure[i].sample)
+         return 1;
    }
 
    return 0;
diff --git a/src/glsl/glsl_types.h b/src/glsl/glsl_types.h
index 96eee5e..fb7c928 100644
--- a/src/glsl/glsl_types.h
+++ b/src/glsl/glsl_types.h
@@ -634,6 +634,12 @@ struct glsl_struct_field {
     * in ir_variable::centroid).  0 otherwise.
     */
    unsigned centroid:1;
+
+   /**
+    * For interface blocks, 1 if this variable uses sample interpolation (as
+    * in ir_variable::sample). 0 otherwise.
+    */
+   unsigned sample:1;
 };
 
 static inline unsigned int
diff --git a/src/glsl/ir.cpp b/src/glsl/ir.cpp
index ffff297..ab77d15 100644
--- a/src/glsl/ir.cpp
+++ b/src/glsl/ir.cpp
@@ -1585,7 +1585,7 @@ ir_swizzle::variable_referenced() const
 ir_variable::ir_variable(const struct glsl_type *type, const char *name,
 			 ir_variable_mode mode)
    : max_array_access(0), max_ifc_array_access(NULL),
-     read_only(false), centroid(false), invariant(false),
+     read_only(false), centroid(false), sample(false), invariant(false),
      how_declared(ir_var_declared_normally), mode(mode),
      interpolation(INTERP_QUALIFIER_NONE), atomic()
 {
@@ -1709,7 +1709,8 @@ ir_function_signature::qualifiers_match(exec_list *params)
       if (a->read_only != b->read_only ||
 	  !modes_match(a->mode, b->mode) ||
 	  a->interpolation != b->interpolation ||
-	  a->centroid != b->centroid) {
+	  a->centroid != b->centroid ||
+         a->sample != b->sample) {
 
 	 /* parameter a's qualifiers don't match */
 	 return a->name;
diff --git a/src/glsl/ir.h b/src/glsl/ir.h
index 4f775da..dacd418 100644
--- a/src/glsl/ir.h
+++ b/src/glsl/ir.h
@@ -529,6 +529,7 @@ public:
     */
    unsigned read_only:1;
    unsigned centroid:1;
+   unsigned sample:1;
    unsigned invariant:1;
 
    /**
diff --git a/src/glsl/ir_clone.cpp b/src/glsl/ir_clone.cpp
index 40ed33a..f336789 100644
--- a/src/glsl/ir_clone.cpp
+++ b/src/glsl/ir_clone.cpp
@@ -52,6 +52,7 @@ ir_variable::clone(void *mem_ctx, struct hash_table *ht) const
    }
    var->read_only = this->read_only;
    var->centroid = this->centroid;
+   var->sample = this->sample;
    var->invariant = this->invariant;
    var->interpolation = this->interpolation;
    var->location = this->location;
diff --git a/src/glsl/ir_print_visitor.cpp b/src/glsl/ir_print_visitor.cpp
index f85e573..ffbeb7e 100644
--- a/src/glsl/ir_print_visitor.cpp
+++ b/src/glsl/ir_print_visitor.cpp
@@ -149,6 +149,7 @@ void ir_print_visitor::visit(ir_variable *ir)
    printf("(declare ");
 
    const char *const cent = (ir->centroid) ? "centroid " : "";
+   const char *const samp = (ir->sample) ? "sample " : "";
    const char *const inv = (ir->invariant) ? "invariant " : "";
    const char *const mode[] = { "", "uniform ", "shader_in ", "shader_out ",
                                 "in ", "out ", "inout ",
@@ -157,8 +158,8 @@ void ir_print_visitor::visit(ir_variable *ir)
    const char *const interp[] = { "", "smooth", "flat", "noperspective" };
    STATIC_ASSERT(ARRAY_SIZE(interp) == INTERP_QUALIFIER_COUNT);
 
-   printf("(%s%s%s%s) ",
-	  cent, inv, mode[ir->mode], interp[ir->interpolation]);
+   printf("(%s%s%s%s%s) ",
+	  cent, samp, inv, mode[ir->mode], interp[ir->interpolation]);
 
    print_type(ir->type);
    printf(" %s)", unique_name(ir));
diff --git a/src/glsl/ir_reader.cpp b/src/glsl/ir_reader.cpp
index 00e2db9..7fcb34d 100644
--- a/src/glsl/ir_reader.cpp
+++ b/src/glsl/ir_reader.cpp
@@ -413,6 +413,8 @@ ir_reader::read_declaration(s_expression *expr)
       // FINISHME: Check for duplicate/conflicting qualifiers.
       if (strcmp(qualifier->value(), "centroid") == 0) {
 	 var->centroid = 1;
+      } else if (strcmp(qualifier->value(), "sample") == 0) {
+         var->sample = 1;
       } else if (strcmp(qualifier->value(), "invariant") == 0) {
 	 var->invariant = 1;
       } else if (strcmp(qualifier->value(), "uniform") == 0) {
diff --git a/src/glsl/link_varyings.cpp b/src/glsl/link_varyings.cpp
index be36b5f..d2a4fc8 100644
--- a/src/glsl/link_varyings.cpp
+++ b/src/glsl/link_varyings.cpp
@@ -105,6 +105,18 @@ cross_validate_types_and_qualifiers(struct gl_shader_program *prog,
       return;
    }
 
+   if (input->sample != output->sample) {
+      linker_error(prog,
+                   "%s shader output `%s' %s sample qualifier, "
+                   "but %s shader input %s sample qualifier\n",
+                   _mesa_glsl_shader_target_name(producer_type),
+                   output->name,
+                   (output->sample) ? "has" : "lacks",
+                   _mesa_glsl_shader_target_name(consumer_type),
+                   (input->sample) ? "has" : "lacks");
+      return;
+   }
+
    if (input->invariant != output->invariant) {
       linker_error(prog,
                    "%s shader output `%s' %s invariant qualifier, "
@@ -753,10 +765,12 @@ varying_matches::record(ir_variable *producer_var, ir_variable *consumer_var)
        * requirement by changing the interpolation type to flat here.
        */
       producer_var->centroid = false;
+      producer_var->sample = false;
       producer_var->interpolation = INTERP_QUALIFIER_FLAT;
 
       if (consumer_var) {
          consumer_var->centroid = false;
+         consumer_var->sample = false;
          consumer_var->interpolation = INTERP_QUALIFIER_FLAT;
       }
    }
diff --git a/src/glsl/linker.cpp b/src/glsl/linker.cpp
index 1366077..edf0919 100644
--- a/src/glsl/linker.cpp
+++ b/src/glsl/linker.cpp
@@ -765,6 +765,12 @@ cross_validate_globals(struct gl_shader_program *prog,
 			    mode_string(var), var->name);
                return;
             }
+            if (existing->sample != var->sample) {
+               linker_error(prog, "declarations for %s `%s` have "
+                            "mismatching sample qualifiers\n",
+                            mode_string(var), var->name);
+               return;
+            }
 	 } else
 	    variables.add_variable(var);
       }
diff --git a/src/glsl/lower_named_interface_blocks.cpp b/src/glsl/lower_named_interface_blocks.cpp
index d59d111..aa4c110 100644
--- a/src/glsl/lower_named_interface_blocks.cpp
+++ b/src/glsl/lower_named_interface_blocks.cpp
@@ -157,6 +157,7 @@ flatten_named_interface_blocks_declarations::run(exec_list *instructions)
             new_var->interpolation =
                iface_t->fields.structure[i].interpolation;
             new_var->centroid = iface_t->fields.structure[i].centroid;
+            new_var->sample = iface_t->fields.structure[i].sample;
 
             new_var->init_interface_type(iface_t);
             hash_table_insert(interface_namespace, new_var,
diff --git a/src/glsl/lower_packed_varyings.cpp b/src/glsl/lower_packed_varyings.cpp
index 61ee692..e097e81 100644
--- a/src/glsl/lower_packed_varyings.cpp
+++ b/src/glsl/lower_packed_varyings.cpp
@@ -565,6 +565,7 @@ lower_packed_varyings_visitor::get_packed_varying_deref(
          packed_var->max_array_access = this->gs_input_vertices - 1;
       }
       packed_var->centroid = unpacked_var->centroid;
+      packed_var->sample = unpacked_var->sample;
       packed_var->interpolation = unpacked_var->interpolation;
       packed_var->location = location;
       unpacked_var->insert_before(packed_var);
-- 
1.8.4.2



More information about the mesa-dev mailing list