glsl/linker: Make separate ir_variable field to mean "unmatched".
authorPaul Berry <stereotype441@gmail.com>
Tue, 4 Dec 2012 23:17:01 +0000 (15:17 -0800)
committerPaul Berry <stereotype441@gmail.com>
Fri, 14 Dec 2012 18:48:38 +0000 (10:48 -0800)
Previously, the linker used a value of -1 in ir_variable::location to
denote a generic input or output of the shader that had not yet been
matched up to a variable in another pipeline stage.

This patch introduces a new ir_variable field,
is_unmatched_generic_inout, for that purpose.

In future patches, this will allow us to separate the process of
matching varyings between shader stages from the processes of
assigning locations to those varying.  That will in turn pave the way
for packing varyings.

Reviewed-by: Eric Anholt <eric@anholt.net>
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
src/glsl/ir.h
src/glsl/linker.cpp

index 89c516c877d166ebac04fd594e028717b9ca5ff6..e2ecb3d9dfdef515521961a7402ca712259789fa 100644 (file)
@@ -436,6 +436,15 @@ public:
     */
    unsigned has_initializer:1;
 
+   /**
+    * Is this variable a generic output or input that has not yet been matched
+    * up to a variable in another stage of the pipeline?
+    *
+    * This is used by the linker as scratch storage while assigning locations
+    * to generic inputs and outputs.
+    */
+   unsigned is_unmatched_generic_inout:1;
+
    /**
     * \brief Layout qualifier for gl_FragDepth.
     *
index 2523dc99d6ff97fe2bc295957af6d702d1feee9c..ee6dc2596d04f2274dfea25061928008ebba4079 100644 (file)
@@ -225,6 +225,11 @@ link_invalidate_variable_locations(gl_shader *sh, int input_base,
        */
       if ((var->location >= base) && !var->explicit_location)
          var->location = -1;
+
+      if ((var->location == -1) && !var->explicit_location)
+         var->is_unmatched_generic_inout = 1;
+      else
+         var->is_unmatched_generic_inout = 0;
    }
 }
 
@@ -1362,6 +1367,7 @@ assign_attribute_or_color_locations(gl_shader_program *prog,
         if (prog->AttributeBindings->get(binding, var->name)) {
            assert(binding >= VERT_ATTRIB_GENERIC0);
            var->location = binding;
+            var->is_unmatched_generic_inout = 0;
         }
       } else if (target_index == MESA_SHADER_FRAGMENT) {
         unsigned binding;
@@ -1370,6 +1376,7 @@ assign_attribute_or_color_locations(gl_shader_program *prog,
         if (prog->FragDataBindings->get(binding, var->name)) {
            assert(binding >= FRAG_RESULT_DATA0);
            var->location = binding;
+            var->is_unmatched_generic_inout = 0;
 
            if (prog->FragDataIndexBindings->get(index, var->name)) {
               var->index = index;
@@ -1485,6 +1492,7 @@ assign_attribute_or_color_locations(gl_shader_program *prog,
       }
 
       to_assign[i].var->location = generic_base + location;
+      to_assign[i].var->is_unmatched_generic_inout = 0;
       used_locations |= (use_mask << location);
    }
 
@@ -1508,7 +1516,7 @@ demote_shader_inputs_and_outputs(gl_shader *sh, enum ir_variable_mode mode)
        * its value is used by other shader stages.  This will cause the variable
        * to have a location assigned.
        */
-      if (var->location == -1) {
+      if (var->is_unmatched_generic_inout) {
         var->mode = ir_var_auto;
       }
    }
@@ -1985,7 +1993,7 @@ void
 assign_varying_location(ir_variable *input_var, ir_variable *output_var,
                         unsigned *input_index, unsigned *output_index)
 {
-   if (output_var->location != -1) {
+   if (!output_var->is_unmatched_generic_inout) {
       /* Location already assigned. */
       return;
    }
@@ -1993,9 +2001,11 @@ assign_varying_location(ir_variable *input_var, ir_variable *output_var,
    if (input_var) {
       assert(input_var->location == -1);
       input_var->location = *input_index;
+      input_var->is_unmatched_generic_inout = 0;
    }
 
    output_var->location = *output_index;
+   output_var->is_unmatched_generic_inout = 0;
 
    /* FINISHME: Support for "varying" records in GLSL 1.50. */
    assert(!output_var->type->is_record());
@@ -2105,7 +2115,7 @@ assign_varying_locations(struct gl_context *ctx,
 
          if (!tfeedback_decls[i].is_assigned() &&
              tfeedback_decls[i].matches_var(output_var)) {
-            if (output_var->location == -1) {
+            if (output_var->is_unmatched_generic_inout) {
                assign_varying_location(input_var, output_var, &input_index,
                                        &output_index);
             }
@@ -2124,7 +2134,7 @@ assign_varying_locations(struct gl_context *ctx,
          if ((var == NULL) || (var->mode != ir_var_in))
             continue;
 
-         if (var->location == -1) {
+         if (var->is_unmatched_generic_inout) {
             if (prog->Version <= 120) {
                /* On page 25 (page 31 of the PDF) of the GLSL 1.20 spec:
                 *