glsl: introduce data section to ir_variable
authorTapani Pälli <tapani.palli@intel.com>
Thu, 12 Dec 2013 10:57:57 +0000 (12:57 +0200)
committerTapani Pälli <tapani.palli@intel.com>
Thu, 12 Dec 2013 15:28:06 +0000 (17:28 +0200)
Data section helps serialization and cloning of a ir_variable. This
patch includes the helper bits used for read only ir_variables.

Signed-off-by: Tapani Pälli <tapani.palli@intel.com>
Reviewed-by: Paul Berry <stereotype441@gmail.com>
18 files changed:
src/glsl/ast_function.cpp
src/glsl/ast_to_hir.cpp
src/glsl/builtin_variables.cpp
src/glsl/ir.cpp
src/glsl/ir.h
src/glsl/ir_clone.cpp
src/glsl/ir_print_visitor.cpp
src/glsl/ir_reader.cpp
src/glsl/ir_set_program_inouts.cpp
src/glsl/link_varyings.cpp
src/glsl/linker.cpp
src/glsl/loop_analysis.h
src/glsl/lower_named_interface_blocks.cpp
src/glsl/lower_packed_varyings.cpp
src/glsl/opt_cse.cpp
src/glsl/opt_function_inlining.cpp
src/glsl/tests/builtin_variable_test.cpp
src/mesa/drivers/dri/i965/brw_fs.cpp

index 64237594e13e19baf021c101501d00f754aedbc9..8202116324f57e0e8622292bbe012a07b8b89276 100644 (file)
@@ -157,7 +157,7 @@ verify_parameter_modes(_mesa_glsl_parse_state *state,
         if (var)
            var->assigned = true;
 
-        if (var && var->read_only) {
+        if (var && var->data.read_only) {
            _mesa_glsl_error(&loc, state,
                             "function parameter '%s %s' references the "
                             "read-only variable '%s'",
index f35d8679e70e0d7414f48c586b55f4369f1ea6b4..0278f97cb170afe776a0f6979a0138d55e42fc7c 100644 (file)
@@ -776,7 +776,7 @@ do_assignment(exec_list *instructions, struct _mesa_glsl_parse_state *state,
                          non_lvalue_description);
         error_emitted = true;
       } else if (lhs->variable_referenced() != NULL
-                && lhs->variable_referenced()->read_only) {
+                && lhs->variable_referenced()->data.read_only) {
          _mesa_glsl_error(&lhs_loc, state,
                           "assignment to read-only variable '%s'",
                           lhs->variable_referenced()->name);
@@ -2168,20 +2168,20 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual,
                          "`invariant' after being used",
                          var->name);
       } else {
-        var->invariant = 1;
+        var->data.invariant = 1;
       }
    }
 
    if (qual->flags.q.constant || qual->flags.q.attribute
        || qual->flags.q.uniform
        || (qual->flags.q.varying && (state->target == fragment_shader)))
-      var->read_only = 1;
+      var->data.read_only = 1;
 
    if (qual->flags.q.centroid)
-      var->centroid = 1;
+      var->data.centroid = 1;
 
    if (qual->flags.q.sample)
-      var->sample = 1;
+      var->data.sample = 1;
 
    if (qual->flags.q.attribute && state->target != vertex_shader) {
       var->type = glsl_type::error_type;
@@ -2275,16 +2275,16 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual,
       switch (state->target) {
       case vertex_shader:
         if (var->mode == ir_var_shader_out)
-           var->invariant = true;
+           var->data.invariant = true;
         break;
       case geometry_shader:
         if ((var->mode == ir_var_shader_in)
              || (var->mode == ir_var_shader_out))
-           var->invariant = true;
+           var->data.invariant = true;
         break;
       case fragment_shader:
         if (var->mode == ir_var_shader_in)
-           var->invariant = true;
+           var->data.invariant = true;
         break;
       }
    }
@@ -2650,9 +2650,9 @@ process_initializer(ir_variable *var, ast_declaration *decl,
    }
 
    if (rhs && !rhs->type->is_error()) {
-      bool temp = var->read_only;
+      bool temp = var->data.read_only;
       if (type->qualifier.flags.q.constant)
-        var->read_only = false;
+        var->data.read_only = false;
 
       /* Never emit code to initialize a uniform.
        */
@@ -2691,7 +2691,7 @@ process_initializer(ir_variable *var, ast_declaration *decl,
        */
       var->type = initializer_type;
 
-      var->read_only = temp;
+      var->data.read_only = temp;
    }
 
    return result;
@@ -2859,7 +2859,7 @@ ast_declarator_list::hir(exec_list *instructions,
                             "`invariant' after being used",
                             earlier->name);
         } else {
-           earlier->invariant = true;
+           earlier->data.invariant = true;
         }
       }
 
@@ -3077,7 +3077,7 @@ ast_declarator_list::hir(exec_list *instructions,
                             mode, var->name, extra);
         }
       } else if (var->mode == ir_var_shader_in) {
-         var->read_only = true;
+         var->data.read_only = true;
 
         if (state->target == vertex_shader) {
            bool error_emitted = false;
@@ -5097,8 +5097,8 @@ ast_interface_block::hir(exec_list *instructions,
                                    ralloc_strdup(state, fields[i].name),
                                    var_mode);
          var->interpolation = fields[i].interpolation;
-         var->centroid = fields[i].centroid;
-         var->sample = fields[i].sample;
+         var->data.centroid = fields[i].centroid;
+         var->data.sample = fields[i].sample;
          var->init_interface_type(block_type);
 
          if (redeclaring_per_vertex) {
index d0e76e3a402b682d6eb45d0291061c27b56e5bb4..9cc11b77c857b6b1bd98fcc3b5e85e8ebaef5973 100644 (file)
@@ -442,7 +442,7 @@ builtin_variable_generator::add_variable(const char *name,
    case ir_var_shader_in:
    case ir_var_uniform:
    case ir_var_system_value:
-      var->read_only = true;
+      var->data.read_only = true;
       break;
    case ir_var_shader_out:
       break;
@@ -937,8 +937,8 @@ builtin_variable_generator::generate_varyings()
             add_variable(fields[i].name, fields[i].type, ir_var_shader_out,
                          fields[i].location);
          var->interpolation = fields[i].interpolation;
-         var->centroid = fields[i].centroid;
-         var->sample = fields[i].sample;
+         var->data.centroid = fields[i].centroid;
+         var->data.sample = fields[i].sample;
          var->init_interface_type(per_vertex_out_type);
       }
    }
index 623bc1bb2e97398448ed57f47cb1f2f7ce43b541..a3ca4ef7fd4b057384a2b6da41f459fe71f22fe5 100644 (file)
@@ -1359,7 +1359,7 @@ ir_dereference::is_lvalue() const
 
    /* Every l-value derference chain eventually ends in a variable.
     */
-   if ((var == NULL) || var->read_only)
+   if ((var == NULL) || var->data.read_only)
       return false;
 
    /* From page 17 (page 23 of the PDF) of the GLSL 1.20 spec:
@@ -1580,7 +1580,6 @@ 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), sample(false), invariant(false),
      how_declared(ir_var_declared_normally), mode(mode),
      interpolation(INTERP_QUALIFIER_NONE), atomic()
 {
@@ -1598,10 +1597,14 @@ ir_variable::ir_variable(const struct glsl_type *type, const char *name,
    this->pixel_center_integer = false;
    this->depth_layout = ir_depth_layout_none;
    this->used = false;
+   this->data.read_only = false;
+   this->data.centroid = false;
+   this->data.sample = false;
+   this->data.invariant = false;
 
    if (type != NULL) {
       if (type->base_type == GLSL_TYPE_SAMPLER)
-         this->read_only = true;
+         this->data.read_only = true;
 
       if (type->is_interface())
          this->init_interface_type(type);
@@ -1701,11 +1704,11 @@ ir_function_signature::qualifiers_match(exec_list *params)
       ir_variable *a = (ir_variable *)iter_a.get();
       ir_variable *b = (ir_variable *)iter_b.get();
 
-      if (a->read_only != b->read_only ||
+      if (a->data.read_only != b->data.read_only ||
          !modes_match(a->mode, b->mode) ||
          a->interpolation != b->interpolation ||
-         a->centroid != b->centroid ||
-         a->sample != b->sample) {
+         a->data.centroid != b->data.centroid ||
+         a->data.sample != b->data.sample) {
 
         /* parameter a's qualifiers don't match */
         return a->name;
@@ -1891,7 +1894,7 @@ mode_string(const ir_variable *var)
 {
    switch (var->mode) {
    case ir_var_auto:
-      return (var->read_only) ? "global constant" : "global variable";
+      return (var->data.read_only) ? "global constant" : "global variable";
 
    case ir_var_uniform:
       return "uniform";
index 7a939a236b8331e2a8058d6e9db23cd5f25199f6..cdede59d86465b5181aaec8f6666d25efc5b7871 100644 (file)
@@ -522,16 +522,20 @@ public:
     */
    unsigned *max_ifc_array_access;
 
-   /**
-    * Is the variable read-only?
-    *
-    * This is set for variables declared as \c const, shader inputs,
-    * and uniforms.
-    */
-   unsigned read_only:1;
-   unsigned centroid:1;
-   unsigned sample:1;
-   unsigned invariant:1;
+   struct ir_variable_data {
+
+      /**
+       * Is the variable read-only?
+       *
+       * This is set for variables declared as \c const, shader inputs,
+       * and uniforms.
+       */
+      unsigned read_only:1;
+      unsigned centroid:1;
+      unsigned sample:1;
+      unsigned invariant:1;
+
+   } data;
 
    /**
     * Has this variable been used for reading or writing?
index df6e971f41a0d5f251fd710346e8b0a8b166695e..a781cf0d24da06d9cc4da1453199101bae30420d 100644 (file)
@@ -50,10 +50,10 @@ ir_variable::clone(void *mem_ctx, struct hash_table *ht) const
       memcpy(var->max_ifc_array_access, this->max_ifc_array_access,
              this->interface_type->length * sizeof(unsigned));
    }
-   var->read_only = this->read_only;
-   var->centroid = this->centroid;
-   var->sample = this->sample;
-   var->invariant = this->invariant;
+   var->data.read_only = this->data.read_only;
+   var->data.centroid = this->data.centroid;
+   var->data.sample = this->data.sample;
+   var->data.invariant = this->data.invariant;
    var->interpolation = this->interpolation;
    var->location = this->location;
    var->index = this->index;
index 2beefedf16ee1b83f27a0c93cf2a02ad56351db1..ae5074ba9a2f2fa0606dda01fd22166bd6fdd2e7 100644 (file)
@@ -148,9 +148,9 @@ 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 cent = (ir->data.centroid) ? "centroid " : "";
+   const char *const samp = (ir->data.sample) ? "sample " : "";
+   const char *const inv = (ir->data.invariant) ? "invariant " : "";
    const char *const mode[] = { "", "uniform ", "shader_in ", "shader_out ",
                                 "in ", "out ", "inout ",
                                "const_in ", "sys ", "temporary " };
index 4afe28101390bc831b6825f3e7afc39df9a5bb44..127358cf6df9409eeefc348befd30401c63f2559 100644 (file)
@@ -412,11 +412,11 @@ ir_reader::read_declaration(s_expression *expr)
 
       // FINISHME: Check for duplicate/conflicting qualifiers.
       if (strcmp(qualifier->value(), "centroid") == 0) {
-        var->centroid = 1;
+        var->data.centroid = 1;
       } else if (strcmp(qualifier->value(), "sample") == 0) {
-         var->sample = 1;
+         var->data.sample = 1;
       } else if (strcmp(qualifier->value(), "invariant") == 0) {
-        var->invariant = 1;
+        var->data.invariant = 1;
       } else if (strcmp(qualifier->value(), "uniform") == 0) {
         var->mode = ir_var_uniform;
       } else if (strcmp(qualifier->value(), "auto") == 0) {
index 1a36527397e2db24440f38d4621ef6040b786044..2d824395c744c6c98af116ec0719572d31185eb1 100644 (file)
@@ -100,9 +100,9 @@ mark(struct gl_program *prog, ir_variable *var, int offset, int len,
             gl_fragment_program *fprog = (gl_fragment_program *) prog;
             fprog->InterpQualifier[var->location + var->index + offset + i] =
                (glsl_interp_qualifier) var->interpolation;
-            if (var->centroid)
+            if (var->data.centroid)
                fprog->IsCentroid |= bitfield;
-            if (var->sample)
+            if (var->data.sample)
                fprog->IsSample |= bitfield;
          }
       } else if (var->mode == ir_var_system_value) {
index 097cee5e4cb8dddecaba3a2b97f7c1cca8b02fc4..53a9d75e3cd8b49f729f92ec0444ac78e90254b1 100644 (file)
@@ -93,39 +93,39 @@ cross_validate_types_and_qualifiers(struct gl_shader_program *prog,
 
    /* Check that all of the qualifiers match between stages.
     */
-   if (input->centroid != output->centroid) {
+   if (input->data.centroid != output->data.centroid) {
       linker_error(prog,
                    "%s shader output `%s' %s centroid qualifier, "
                    "but %s shader input %s centroid qualifier\n",
                    _mesa_glsl_shader_target_name(producer_type),
                    output->name,
-                   (output->centroid) ? "has" : "lacks",
+                   (output->data.centroid) ? "has" : "lacks",
                    _mesa_glsl_shader_target_name(consumer_type),
-                   (input->centroid) ? "has" : "lacks");
+                   (input->data.centroid) ? "has" : "lacks");
       return;
    }
 
-   if (input->sample != output->sample) {
+   if (input->data.sample != output->data.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",
+                   (output->data.sample) ? "has" : "lacks",
                    _mesa_glsl_shader_target_name(consumer_type),
-                   (input->sample) ? "has" : "lacks");
+                   (input->data.sample) ? "has" : "lacks");
       return;
    }
 
-   if (input->invariant != output->invariant) {
+   if (input->data.invariant != output->data.invariant) {
       linker_error(prog,
                    "%s shader output `%s' %s invariant qualifier, "
                    "but %s shader input %s invariant qualifier\n",
                    _mesa_glsl_shader_target_name(producer_type),
                    output->name,
-                   (output->invariant) ? "has" : "lacks",
+                   (output->data.invariant) ? "has" : "lacks",
                    _mesa_glsl_shader_target_name(consumer_type),
-                   (input->invariant) ? "has" : "lacks");
+                   (input->data.invariant) ? "has" : "lacks");
       return;
    }
 
@@ -764,13 +764,13 @@ varying_matches::record(ir_variable *producer_var, ir_variable *consumer_var)
        * regardless of where they appear.  We can trivially satisfy that
        * requirement by changing the interpolation type to flat here.
        */
-      producer_var->centroid = false;
-      producer_var->sample = false;
+      producer_var->data.centroid = false;
+      producer_var->data.sample = false;
       producer_var->interpolation = INTERP_QUALIFIER_FLAT;
 
       if (consumer_var) {
-         consumer_var->centroid = false;
-         consumer_var->sample = false;
+         consumer_var->data.centroid = false;
+         consumer_var->data.sample = false;
          consumer_var->interpolation = INTERP_QUALIFIER_FLAT;
       }
    }
@@ -887,7 +887,7 @@ varying_matches::compute_packing_class(ir_variable *var)
     *
     * Therefore, the packing class depends only on the interpolation type.
     */
-   unsigned packing_class = var->centroid | (var->sample << 1);
+   unsigned packing_class = var->data.centroid | (var->data.sample << 1);
    packing_class *= 4;
    packing_class += var->interpolation;
    return packing_class;
index 9e8eca5cc9e41742fb231e5a1a31129b351f8628..38bf579805fd0c43f2de5d241d5e6bfdd53a3965 100644 (file)
@@ -753,19 +753,19 @@ cross_validate_globals(struct gl_shader_program *prog,
               existing->has_initializer = true;
            }
 
-           if (existing->invariant != var->invariant) {
+           if (existing->data.invariant != var->data.invariant) {
               linker_error(prog, "declarations for %s `%s' have "
                            "mismatching invariant qualifiers\n",
                            mode_string(var), var->name);
               return;
            }
-            if (existing->centroid != var->centroid) {
+            if (existing->data.centroid != var->data.centroid) {
                linker_error(prog, "declarations for %s `%s' have "
                            "mismatching centroid qualifiers\n",
                            mode_string(var), var->name);
                return;
             }
-            if (existing->sample != var->sample) {
+            if (existing->data.sample != var->data.sample) {
                linker_error(prog, "declarations for %s `%s` have "
                             "mismatching sample qualifiers\n",
                             mode_string(var), var->name);
index 6799f876cd76128e97a615c08b2fdfe01dba61f1..f841042f02688946ba31b0510b69d52896c1b388 100644 (file)
@@ -217,7 +217,8 @@ public:
 
       /* Variables that are marked read-only *MUST* be loop constant.
        */
-      assert(!this->var->read_only || (this->var->read_only && is_const));
+      assert(!this->var->data.read_only
+            || (this->var->data.read_only && is_const));
 
       return is_const;
    }
index aa4c11070e5490285d7be6658b4446314ed080c3..0775375f614e0ac71c7cd8b75f7654c33770922b 100644 (file)
@@ -156,8 +156,8 @@ flatten_named_interface_blocks_declarations::run(exec_list *instructions)
             new_var->explicit_location = (new_var->location >= 0);
             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->data.centroid = iface_t->fields.structure[i].centroid;
+            new_var->data.sample = iface_t->fields.structure[i].sample;
 
             new_var->init_interface_type(iface_t);
             hash_table_insert(interface_namespace, new_var,
index e097e81f1b3f336af68574f11617b46d4f060f89..498914e312dc45bb4909d9c61f137d4d2076127a 100644 (file)
@@ -564,8 +564,8 @@ 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->data.centroid = unpacked_var->data.centroid;
+      packed_var->data.sample = unpacked_var->data.sample;
       packed_var->interpolation = unpacked_var->interpolation;
       packed_var->location = location;
       unpacked_var->insert_before(packed_var);
index 8f73940d85436c9a54955dfd6af081a88f233bcc..a2b63ee99ba5f7d0a5ef85ddf350b263353fd4ac 100644 (file)
@@ -193,7 +193,7 @@ is_cse_candidate_visitor::visit(ir_dereference_variable *ir)
    /* Currently, since we don't handle kills of the ae based on variables
     * getting assigned, we can only handle constant variables.
     */
-   if (ir->var->read_only) {
+   if (ir->var->data.read_only) {
       return visit_continue;
    } else {
       ok = false;
index f8033a095d89d5a940315ebd8d360ff1fc0cdff6..86d0fa3618a064d4f00cccfcd4647d283e6b76f5 100644 (file)
@@ -139,7 +139,7 @@ ir_call::generate_inline(ir_instruction *next_ir)
          * read-only and the inlined function is inside a loop, the loop
          * analysis code will get confused.
          */
-        parameters[i]->read_only = false;
+        parameters[i]->data.read_only = false;
         next_ir->insert_before(parameters[i]);
       }
 
index 366fbce018a54ac7d167b8807c15ea65e7c723cc..accdd9155e4000837a8f25475ac8df73be6b2f8b 100644 (file)
@@ -129,7 +129,7 @@ common_builtin::constants_are_constant()
 
       EXPECT_FALSE(var->explicit_location);
       EXPECT_EQ(-1, var->location);
-      EXPECT_TRUE(var->read_only);
+      EXPECT_TRUE(var->data.read_only);
    }
 }
 
index dbd93e7abcad0f9015e1e9b88045d16b6f5536ee..374801fab207eb19c9ce64790b69221b7dc4901f 100644 (file)
@@ -1084,8 +1084,8 @@ fs_visitor::emit_general_interpolation(ir_variable *ir)
                */
                struct brw_reg interp = interp_reg(location, k);
                emit_linterp(attr, fs_reg(interp), interpolation_mode,
-                            ir->centroid);
-               if (brw->needs_unlit_centroid_workaround && ir->centroid) {
+                            ir->data.centroid);
+               if (brw->needs_unlit_centroid_workaround && ir->data.centroid) {
                   /* Get the pixel/sample mask into f0 so that we know
                    * which pixels are lit.  Then, for each channel that is
                    * unlit, replace the centroid data with non-centroid