mesa: Use shared code for converting shader targets to short strings.
[mesa.git] / src / glsl / linker.cpp
index 9463f53055e767533d7026e5f17b2e4fa189f768..c168e47e0c81ffc061336929ca9ec4f0031f5ddf 100644 (file)
 
 #include "main/core.h"
 #include "glsl_symbol_table.h"
+#include "glsl_parser_extras.h"
 #include "ir.h"
 #include "program.h"
 #include "program/hash_table.h"
 #include "linker.h"
+#include "link_varyings.h"
 #include "ir_optimization.h"
 
 extern "C" {
@@ -101,13 +103,13 @@ public:
 
    virtual ir_visitor_status visit_enter(ir_call *ir)
    {
-      exec_list_iterator sig_iter = ir->get_callee()->parameters.iterator();
+      exec_list_iterator sig_iter = ir->callee->parameters.iterator();
       foreach_iter(exec_list_iterator, iter, *ir) {
         ir_rvalue *param_rval = (ir_rvalue *)iter.get();
         ir_variable *sig_param = (ir_variable *)sig_iter.get();
 
-        if (sig_param->mode == ir_var_out ||
-            sig_param->mode == ir_var_inout) {
+        if (sig_param->mode == ir_var_function_out ||
+            sig_param->mode == ir_var_function_inout) {
            ir_variable *var = param_rval->variable_referenced();
            if (var && strcmp(name, var->name) == 0) {
               found = true;
@@ -117,6 +119,15 @@ public:
         sig_iter.next();
       }
 
+      if (ir->return_deref != NULL) {
+        ir_variable *const var = ir->return_deref->variable_referenced();
+
+        if (strcmp(name, var->name) == 0) {
+           found = true;
+           return visit_stop;
+        }
+      }
+
       return visit_continue_with_parent;
    }
 
@@ -190,20 +201,98 @@ linker_warning(gl_shader_program *prog, const char *fmt, ...)
 }
 
 
+/**
+ * Given a string identifying a program resource, break it into a base name
+ * and an optional array index in square brackets.
+ *
+ * If an array index is present, \c out_base_name_end is set to point to the
+ * "[" that precedes the array index, and the array index itself is returned
+ * as a long.
+ *
+ * If no array index is present (or if the array index is negative or
+ * mal-formed), \c out_base_name_end, is set to point to the null terminator
+ * at the end of the input string, and -1 is returned.
+ *
+ * Only the final array index is parsed; if the string contains other array
+ * indices (or structure field accesses), they are left in the base name.
+ *
+ * No attempt is made to check that the base name is properly formed;
+ * typically the caller will look up the base name in a hash table, so
+ * ill-formed base names simply turn into hash table lookup failures.
+ */
+long
+parse_program_resource_name(const GLchar *name,
+                            const GLchar **out_base_name_end)
+{
+   /* Section 7.3.1 ("Program Interfaces") of the OpenGL 4.3 spec says:
+    *
+    *     "When an integer array element or block instance number is part of
+    *     the name string, it will be specified in decimal form without a "+"
+    *     or "-" sign or any extra leading zeroes. Additionally, the name
+    *     string will not include white space anywhere in the string."
+    */
+
+   const size_t len = strlen(name);
+   *out_base_name_end = name + len;
+
+   if (len == 0 || name[len-1] != ']')
+      return -1;
+
+   /* Walk backwards over the string looking for a non-digit character.  This
+    * had better be the opening bracket for an array index.
+    *
+    * Initially, i specifies the location of the ']'.  Since the string may
+    * contain only the ']' charcater, walk backwards very carefully.
+    */
+   unsigned i;
+   for (i = len - 1; (i > 0) && isdigit(name[i-1]); --i)
+      /* empty */ ;
+
+   if ((i == 0) || name[i-1] != '[')
+      return -1;
+
+   long array_index = strtol(&name[i], NULL, 10);
+   if (array_index < 0)
+      return -1;
+
+   *out_base_name_end = name + (i - 1);
+   return array_index;
+}
+
+
 void
-invalidate_variable_locations(gl_shader *sh, enum ir_variable_mode mode,
-                             int generic_base)
+link_invalidate_variable_locations(gl_shader *sh, int input_base,
+                                   int output_base)
 {
    foreach_list(node, sh->ir) {
       ir_variable *const var = ((ir_instruction *) node)->as_variable();
 
-      if ((var == NULL) || (var->mode != (unsigned) mode))
-        continue;
+      if (var == NULL)
+         continue;
+
+      int base;
+      switch (var->mode) {
+      case ir_var_shader_in:
+         base = input_base;
+         break;
+      case ir_var_shader_out:
+         base = output_base;
+         break;
+      default:
+         continue;
+      }
 
       /* Only assign locations for generic attributes / varyings / etc.
        */
-      if ((var->location >= generic_base) && !var->explicit_location)
-         var->location = -1;
+      if ((var->location >= base) && !var->explicit_location)
+         var->location = -1;
+
+      if ((var->location == -1) && !var->explicit_location) {
+         var->is_unmatched_generic_inout = 1;
+         var->location_frac = 0;
+      } else {
+         var->is_unmatched_generic_inout = 0;
+      }
    }
 }
 
@@ -246,7 +335,8 @@ count_attribute_slots(const glsl_type *t)
 /**
  * Verify that a vertex shader executable meets all semantic requirements.
  *
- * Also sets prog->Vert.UsesClipDistance as a side effect.
+ * Also sets prog->Vert.UsesClipDistance and prog->Vert.ClipDistanceArraySize
+ * as a side effect.
  *
  * \param shader  Vertex shader executable to be verified
  */
@@ -257,19 +347,52 @@ validate_vertex_shader_executable(struct gl_shader_program *prog,
    if (shader == NULL)
       return true;
 
-   find_assignment_visitor find("gl_Position");
-   find.run(shader->ir);
-   if (!find.variable_found()) {
-      linker_error(prog, "vertex shader does not write to `gl_Position'\n");
-      return false;
+   /* From the GLSL 1.10 spec, page 48:
+    *
+    *     "The variable gl_Position is available only in the vertex
+    *      language and is intended for writing the homogeneous vertex
+    *      position. All executions of a well-formed vertex shader
+    *      executable must write a value into this variable. [...] The
+    *      variable gl_Position is available only in the vertex
+    *      language and is intended for writing the homogeneous vertex
+    *      position. All executions of a well-formed vertex shader
+    *      executable must write a value into this variable."
+    *
+    * while in GLSL 1.40 this text is changed to:
+    *
+    *     "The variable gl_Position is available only in the vertex
+    *      language and is intended for writing the homogeneous vertex
+    *      position. It can be written at any time during shader
+    *      execution. It may also be read back by a vertex shader
+    *      after being written. This value will be used by primitive
+    *      assembly, clipping, culling, and other fixed functionality
+    *      operations, if present, that operate on primitives after
+    *      vertex processing has occurred. Its value is undefined if
+    *      the vertex shader executable does not write gl_Position."
+    *
+    * GLSL ES 3.00 is similar to GLSL 1.40--failing to write to gl_Position is
+    * not an error.
+    */
+   if (prog->Version < (prog->IsES ? 300 : 140)) {
+      find_assignment_visitor find("gl_Position");
+      find.run(shader->ir);
+      if (!find.variable_found()) {
+        linker_error(prog, "vertex shader does not write to `gl_Position'\n");
+        return false;
+      }
    }
 
-   if (prog->Version >= 130) {
+   prog->Vert.ClipDistanceArraySize = 0;
+
+   if (!prog->IsES && prog->Version >= 130) {
       /* From section 7.1 (Vertex Shader Special Variables) of the
        * GLSL 1.30 spec:
        *
        *   "It is an error for a shader to statically write both
        *   gl_ClipVertex and gl_ClipDistance."
+       *
+       * This does not apply to GLSL ES shaders, since GLSL ES defines neither
+       * gl_ClipVertex nor gl_ClipDistance.
        */
       find_assignment_visitor clip_vertex("gl_ClipVertex");
       find_assignment_visitor clip_distance("gl_ClipDistance");
@@ -282,6 +405,10 @@ validate_vertex_shader_executable(struct gl_shader_program *prog,
          return false;
       }
       prog->Vert.UsesClipDistance = clip_distance.variable_found();
+      ir_variable *clip_distance_var =
+         shader->symbols->get_variable("gl_ClipDistance");
+      if (clip_distance_var)
+         prog->Vert.ClipDistanceArraySize = clip_distance_var->type->length;
    }
 
    return true;
@@ -326,10 +453,9 @@ mode_string(const ir_variable *var)
    case ir_var_auto:
       return (var->read_only) ? "global constant" : "global variable";
 
-   case ir_var_uniform: return "uniform";
-   case ir_var_in:      return "shader input";
-   case ir_var_out:     return "shader output";
-   case ir_var_inout:   return "shader inout";
+   case ir_var_uniform:    return "uniform";
+   case ir_var_shader_in:  return "shader input";
+   case ir_var_shader_out: return "shader output";
 
    case ir_var_const_in:
    case ir_var_temporary:
@@ -415,43 +541,63 @@ cross_validate_globals(struct gl_shader_program *prog,
               existing->explicit_location = true;
            }
 
-        /* Validate layout qualifiers for gl_FragDepth.
-         *
-         * From the AMD/ARB_conservative_depth specs:
-         *    "If gl_FragDepth is redeclared in any fragment shader in
-         *    a program, it must be redeclared in all fragment shaders in that
-         *    program that have static assignments to gl_FragDepth. All
-         *    redeclarations of gl_FragDepth in all fragment shaders in
-         *    a single program must have the same set of qualifiers."
-         */
-        if (strcmp(var->name, "gl_FragDepth") == 0) {
-           bool layout_declared = var->depth_layout != ir_depth_layout_none;
-           bool layout_differs = var->depth_layout != existing->depth_layout;
-           if (layout_declared && layout_differs) {
-              linker_error(prog,
-                 "All redeclarations of gl_FragDepth in all fragment shaders "
-                 "in a single program must have the same set of qualifiers.");
-           }
-           if (var->used && layout_differs) {
-              linker_error(prog,
-                    "If gl_FragDepth is redeclared with a layout qualifier in"
-                    "any fragment shader, it must be redeclared with the same"
-                    "layout qualifier in all fragment shaders that have"
-                    "assignments to gl_FragDepth");
-           }
-        }
-
-           /* FINISHME: Handle non-constant initializers.
+           /* Validate layout qualifiers for gl_FragDepth.
+            *
+            * From the AMD/ARB_conservative_depth specs:
+            *
+            *    "If gl_FragDepth is redeclared in any fragment shader in a
+            *    program, it must be redeclared in all fragment shaders in
+            *    that program that have static assignments to
+            *    gl_FragDepth. All redeclarations of gl_FragDepth in all
+            *    fragment shaders in a single program must have the same set
+            *    of qualifiers."
+            */
+           if (strcmp(var->name, "gl_FragDepth") == 0) {
+              bool layout_declared = var->depth_layout != ir_depth_layout_none;
+              bool layout_differs =
+                 var->depth_layout != existing->depth_layout;
+
+              if (layout_declared && layout_differs) {
+                 linker_error(prog,
+                              "All redeclarations of gl_FragDepth in all "
+                              "fragment shaders in a single program must have "
+                              "the same set of qualifiers.");
+              }
+
+              if (var->used && layout_differs) {
+                 linker_error(prog,
+                              "If gl_FragDepth is redeclared with a layout "
+                              "qualifier in any fragment shader, it must be "
+                              "redeclared with the same layout qualifier in "
+                              "all fragment shaders that have assignments to "
+                              "gl_FragDepth");
+              }
+           }
+
+           /* Page 35 (page 41 of the PDF) of the GLSL 4.20 spec says:
+            *
+            *     "If a shared global has multiple initializers, the
+            *     initializers must all be constant expressions, and they
+            *     must all have the same value. Otherwise, a link error will
+            *     result. (A shared global having only one initializer does
+            *     not require that initializer to be a constant expression.)"
+            *
+            * Previous to 4.20 the GLSL spec simply said that initializers
+            * must have the same value.  In this case of non-constant
+            * initializers, this was impossible to determine.  As a result,
+            * no vendor actually implemented that behavior.  The 4.20
+            * behavior matches the implemented behavior of at least one other
+            * vendor, so we'll implement that for all GLSL versions.
             */
-           if (var->constant_value != NULL) {
-              if (existing->constant_value != NULL) {
-                 if (!var->constant_value->has_value(existing->constant_value)) {
+           if (var->constant_initializer != NULL) {
+              if (existing->constant_initializer != NULL) {
+                 if (!var->constant_initializer->has_value(existing->constant_initializer)) {
                     linker_error(prog, "initializers for %s "
                                  "`%s' have differing values\n",
                                  mode_string(var), var->name);
                     return false;
                  }
-              } else
+              } else {
                  /* If the first-seen instance of a particular uniform did not
                   * have an initializer but a later instance does, copy the
                   * initializer to the version stored in the symbol table.
@@ -464,8 +610,29 @@ cross_validate_globals(struct gl_shader_program *prog,
                   * FINISHME: modify the shader, and linking with the second
                   * FINISHME: will fail.
                   */
-                 existing->constant_value =
-                    var->constant_value->clone(ralloc_parent(existing), NULL);
+                 existing->constant_initializer =
+                    var->constant_initializer->clone(ralloc_parent(existing),
+                                                     NULL);
+              }
+           }
+
+           if (var->has_initializer) {
+              if (existing->has_initializer
+                  && (var->constant_initializer == NULL
+                      || existing->constant_initializer == NULL)) {
+                 linker_error(prog,
+                              "shared global variable `%s' has multiple "
+                              "non-constant initializers.\n",
+                              var->name);
+                 return false;
+              }
+
+              /* Some instance had an initializer, so keep track of that.  In
+               * this location, all sorts of initializers (constant or
+               * otherwise) will propagate the existence to the variable
+               * stored in the symbol table.
+               */
+              existing->has_initializer = true;
            }
 
            if (existing->invariant != var->invariant) {
@@ -499,121 +666,43 @@ cross_validate_uniforms(struct gl_shader_program *prog)
                                 MESA_SHADER_TYPES, true);
 }
 
-
 /**
- * Validate that outputs from one stage match inputs of another
+ * Accumulates the array of prog->UniformBlocks and checks that all
+ * definitons of blocks agree on their contents.
  */
-bool
-cross_validate_outputs_to_inputs(struct gl_shader_program *prog,
-                                gl_shader *producer, gl_shader *consumer)
+static bool
+interstage_cross_validate_uniform_blocks(struct gl_shader_program *prog)
 {
-   glsl_symbol_table parameters;
-   /* FINISHME: Figure these out dynamically. */
-   const char *const producer_stage = "vertex";
-   const char *const consumer_stage = "fragment";
-
-   /* Find all shader outputs in the "producer" stage.
-    */
-   foreach_list(node, producer->ir) {
-      ir_variable *const var = ((ir_instruction *) node)->as_variable();
-
-      /* FINISHME: For geometry shaders, this should also look for inout
-       * FINISHME: variables.
-       */
-      if ((var == NULL) || (var->mode != ir_var_out))
-        continue;
-
-      parameters.add_variable(var);
+   unsigned max_num_uniform_blocks = 0;
+   for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) {
+      if (prog->_LinkedShaders[i])
+        max_num_uniform_blocks += prog->_LinkedShaders[i]->NumUniformBlocks;
    }
 
+   for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) {
+      struct gl_shader *sh = prog->_LinkedShaders[i];
 
-   /* Find all shader inputs in the "consumer" stage.  Any variables that have
-    * matching outputs already in the symbol table must have the same type and
-    * qualifiers.
-    */
-   foreach_list(node, consumer->ir) {
-      ir_variable *const input = ((ir_instruction *) node)->as_variable();
+      prog->UniformBlockStageIndex[i] = ralloc_array(prog, int,
+                                                    max_num_uniform_blocks);
+      for (unsigned int j = 0; j < max_num_uniform_blocks; j++)
+        prog->UniformBlockStageIndex[i][j] = -1;
 
-      /* FINISHME: For geometry shaders, this should also look for inout
-       * FINISHME: variables.
-       */
-      if ((input == NULL) || (input->mode != ir_var_in))
+      if (sh == NULL)
         continue;
 
-      ir_variable *const output = parameters.get_variable(input->name);
-      if (output != NULL) {
-        /* Check that the types match between stages.
-         */
-        if (input->type != output->type) {
-           /* There is a bit of a special case for gl_TexCoord.  This
-            * built-in is unsized by default.  Applications that variable
-            * access it must redeclare it with a size.  There is some
-            * language in the GLSL spec that implies the fragment shader
-            * and vertex shader do not have to agree on this size.  Other
-            * driver behave this way, and one or two applications seem to
-            * rely on it.
-            *
-            * Neither declaration needs to be modified here because the array
-            * sizes are fixed later when update_array_sizes is called.
-            *
-            * From page 48 (page 54 of the PDF) of the GLSL 1.10 spec:
-            *
-            *     "Unlike user-defined varying variables, the built-in
-            *     varying variables don't have a strict one-to-one
-            *     correspondence between the vertex language and the
-            *     fragment language."
-            */
-           if (!output->type->is_array()
-               || (strncmp("gl_", output->name, 3) != 0)) {
-              linker_error(prog,
-                           "%s shader output `%s' declared as type `%s', "
-                           "but %s shader input declared as type `%s'\n",
-                           producer_stage, output->name,
-                           output->type->name,
-                           consumer_stage, input->type->name);
-              return false;
-           }
-        }
+      for (unsigned int j = 0; j < sh->NumUniformBlocks; j++) {
+        int index = link_cross_validate_uniform_block(prog,
+                                                      &prog->UniformBlocks,
+                                                      &prog->NumUniformBlocks,
+                                                      &sh->UniformBlocks[j]);
 
-        /* Check that all of the qualifiers match between stages.
-         */
-        if (input->centroid != output->centroid) {
-           linker_error(prog,
-                        "%s shader output `%s' %s centroid qualifier, "
-                        "but %s shader input %s centroid qualifier\n",
-                        producer_stage,
-                        output->name,
-                        (output->centroid) ? "has" : "lacks",
-                        consumer_stage,
-                        (input->centroid) ? "has" : "lacks");
+        if (index == -1) {
+           linker_error(prog, "uniform block `%s' has mismatching definitions",
+                        sh->UniformBlocks[j].Name);
            return false;
         }
 
-        if (input->invariant != output->invariant) {
-           linker_error(prog,
-                        "%s shader output `%s' %s invariant qualifier, "
-                        "but %s shader input %s invariant qualifier\n",
-                        producer_stage,
-                        output->name,
-                        (output->invariant) ? "has" : "lacks",
-                        consumer_stage,
-                        (input->invariant) ? "has" : "lacks");
-           return false;
-        }
-
-        if (input->interpolation != output->interpolation) {
-           linker_error(prog,
-                        "%s shader output `%s' specifies %s "
-                        "interpolation qualifier, "
-                        "but %s shader input specifies %s "
-                        "interpolation qualifier\n",
-                        producer_stage,
-                        output->name,
-                        output->interpolation_string(),
-                        consumer_stage,
-                        input->interpolation_string());
-           return false;
-        }
+        prog->UniformBlockStageIndex[i][index] = j;
       }
    }
 
@@ -757,6 +846,8 @@ move_non_declarations(exec_list *instructions, exec_node *last,
         continue;
 
       assert(inst->as_assignment()
+             || inst->as_call()
+             || inst->as_if() /* for initializers with the ?: operator */
             || ((var != NULL) && (var->mode == ir_var_temporary)));
 
       if (make_copies) {
@@ -807,6 +898,26 @@ get_main_function_signature(gl_shader *sh)
 }
 
 
+/**
+ * This class is only used in link_intrastage_shaders() below but declaring
+ * it inside that function leads to compiler warnings with some versions of
+ * gcc.
+ */
+class array_sizing_visitor : public ir_hierarchical_visitor {
+public:
+   virtual ir_visitor_status visit(ir_variable *var)
+   {
+      if (var->type->is_array() && (var->type->length == 0)) {
+         const glsl_type *type =
+            glsl_type::get_array_instance(var->type->fields.array,
+                                          var->max_array_access + 1);
+         assert(type != NULL);
+         var->type = type;
+      }
+      return visit_continue;
+   }
+};
+
 /**
  * Combine a group of shaders for a single stage to generate a linked shader
  *
@@ -821,11 +932,26 @@ link_intrastage_shaders(void *mem_ctx,
                        struct gl_shader **shader_list,
                        unsigned num_shaders)
 {
+   struct gl_uniform_block *uniform_blocks = NULL;
+
    /* Check that global variables defined in multiple shaders are consistent.
     */
    if (!cross_validate_globals(prog, shader_list, num_shaders, false))
       return NULL;
 
+   /* Check that interface blocks defined in multiple shaders are consistent.
+    */
+   if (!validate_intrastage_interface_blocks((const gl_shader **)shader_list,
+                                             num_shaders))
+      return NULL;
+
+   /* Check that uniform blocks between shaders for a stage agree. */
+   const int num_uniform_blocks =
+      link_uniform_blocks(mem_ctx, prog, shader_list, num_shaders,
+                          &uniform_blocks);
+   if (num_uniform_blocks < 0)
+      return NULL;
+
    /* Check that there is only a single definition of each function signature
     * across all shaders.
     */
@@ -884,8 +1010,7 @@ link_intrastage_shaders(void *mem_ctx,
 
    if (main == NULL) {
       linker_error(prog, "%s shader lacks `main'\n",
-                  (shader_list[0]->Type == GL_VERTEX_SHADER)
-                  ? "vertex" : "fragment");
+                  _mesa_glsl_shader_target_name(shader_list[0]->Type));
       return NULL;
    }
 
@@ -893,6 +1018,10 @@ link_intrastage_shaders(void *mem_ctx,
    linked->ir = new(linked) exec_list;
    clone_ir_list(mem_ctx, linked->ir, main->ir);
 
+   linked->UniformBlocks = uniform_blocks;
+   linked->NumUniformBlocks = num_uniform_blocks;
+   ralloc_steal(linked, linked->UniformBlocks);
+
    populate_symbol_table(linked);
 
    /* The a pointer to the main function in the final linked shader (i.e., the
@@ -944,35 +1073,18 @@ link_intrastage_shaders(void *mem_ctx,
 
    free(linking_shaders);
 
-#ifdef DEBUG
    /* At this point linked should contain all of the linked IR, so
     * validate it to make sure nothing went wrong.
     */
    if (linked)
       validate_ir_tree(linked->ir);
-#endif
 
    /* Make a pass over all variable declarations to ensure that arrays with
     * unspecified sizes have a size specified.  The size is inferred from the
     * max_array_access field.
     */
    if (linked != NULL) {
-      class array_sizing_visitor : public ir_hierarchical_visitor {
-      public:
-        virtual ir_visitor_status visit(ir_variable *var)
-        {
-           if (var->type->is_array() && (var->type->length == 0)) {
-              const glsl_type *type =
-                 glsl_type::get_array_instance(var->type->fields.array,
-                                               var->max_array_access + 1);
-
-              assert(type != NULL);
-              var->type = type;
-           }
-
-           return visit_continue;
-        }
-      } v;
+      array_sizing_visitor v;
 
       v.run(linked->ir);
    }
@@ -980,13 +1092,6 @@ link_intrastage_shaders(void *mem_ctx,
    return linked;
 }
 
-
-struct uniform_node {
-   exec_node link;
-   struct gl_uniform *u;
-   unsigned slots;
-};
-
 /**
  * Update the sizes of linked shader uniform arrays to the maximum
  * array index used.
@@ -1013,11 +1118,18 @@ update_array_sizes(struct gl_shader_program *prog)
         ir_variable *const var = ((ir_instruction *) node)->as_variable();
 
         if ((var == NULL) || (var->mode != ir_var_uniform &&
-                              var->mode != ir_var_in &&
-                              var->mode != ir_var_out) ||
+                              var->mode != ir_var_shader_in &&
+                              var->mode != ir_var_shader_out) ||
             !var->type->is_array())
            continue;
 
+        /* GL_ARB_uniform_buffer_object says that std140 uniforms
+         * will not be eliminated.  Since we always do std140, just
+         * don't resize arrays in UBOs.
+         */
+        if (var->is_in_uniform_block())
+           continue;
+
         unsigned int size = var->max_array_access;
         for (unsigned j = 0; j < MESA_SHADER_TYPES; j++) {
               if (prog->_LinkedShaders[j] == NULL)
@@ -1059,151 +1171,6 @@ update_array_sizes(struct gl_shader_program *prog)
    }
 }
 
-static void
-add_uniform(void *mem_ctx, exec_list *uniforms, struct hash_table *ht,
-           const char *name, const glsl_type *type, GLenum shader_type,
-           unsigned *next_shader_pos, unsigned *total_uniforms)
-{
-   if (type->is_record()) {
-      for (unsigned int i = 0; i < type->length; i++) {
-        const glsl_type *field_type = type->fields.structure[i].type;
-        char *field_name = ralloc_asprintf(mem_ctx, "%s.%s", name,
-                                           type->fields.structure[i].name);
-
-        add_uniform(mem_ctx, uniforms, ht, field_name, field_type,
-                    shader_type, next_shader_pos, total_uniforms);
-      }
-   } else {
-      uniform_node *n = (uniform_node *) hash_table_find(ht, name);
-      unsigned int vec4_slots;
-      const glsl_type *array_elem_type = NULL;
-
-      if (type->is_array()) {
-        array_elem_type = type->fields.array;
-        /* Array of structures. */
-        if (array_elem_type->is_record()) {
-           for (unsigned int i = 0; i < type->length; i++) {
-              char *elem_name = ralloc_asprintf(mem_ctx, "%s[%d]", name, i);
-              add_uniform(mem_ctx, uniforms, ht, elem_name, array_elem_type,
-                          shader_type, next_shader_pos, total_uniforms);
-           }
-           return;
-        }
-      }
-
-      /* Fix the storage size of samplers at 1 vec4 each. Be sure to pad out
-       * vectors to vec4 slots.
-       */
-      if (type->is_array()) {
-        if (array_elem_type->is_sampler())
-           vec4_slots = type->length;
-        else
-           vec4_slots = type->length * array_elem_type->matrix_columns;
-      } else if (type->is_sampler()) {
-        vec4_slots = 1;
-      } else {
-        vec4_slots = type->matrix_columns;
-      }
-
-      if (n == NULL) {
-        n = (uniform_node *) calloc(1, sizeof(struct uniform_node));
-        n->u = (gl_uniform *) calloc(1, sizeof(struct gl_uniform));
-        n->slots = vec4_slots;
-
-        n->u->Name = strdup(name);
-        n->u->Type = type;
-        n->u->VertPos = -1;
-        n->u->FragPos = -1;
-        n->u->GeomPos = -1;
-        (*total_uniforms)++;
-
-        hash_table_insert(ht, n, name);
-        uniforms->push_tail(& n->link);
-      }
-
-      switch (shader_type) {
-      case GL_VERTEX_SHADER:
-        n->u->VertPos = *next_shader_pos;
-        break;
-      case GL_FRAGMENT_SHADER:
-        n->u->FragPos = *next_shader_pos;
-        break;
-      case GL_GEOMETRY_SHADER:
-        n->u->GeomPos = *next_shader_pos;
-        break;
-      }
-
-      (*next_shader_pos) += vec4_slots;
-   }
-}
-
-void
-assign_uniform_locations(struct gl_shader_program *prog)
-{
-   /* */
-   exec_list uniforms;
-   unsigned total_uniforms = 0;
-   hash_table *ht = hash_table_ctor(32, hash_table_string_hash,
-                                   hash_table_string_compare);
-   void *mem_ctx = ralloc_context(NULL);
-
-   for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) {
-      if (prog->_LinkedShaders[i] == NULL)
-        continue;
-
-      unsigned next_position = 0;
-
-      foreach_list(node, prog->_LinkedShaders[i]->ir) {
-        ir_variable *const var = ((ir_instruction *) node)->as_variable();
-
-        if ((var == NULL) || (var->mode != ir_var_uniform))
-           continue;
-
-        if (strncmp(var->name, "gl_", 3) == 0) {
-           /* At the moment, we don't allocate uniform locations for
-            * builtin uniforms.  It's permitted by spec, and we'll
-            * likely switch to doing that at some point, but not yet.
-            */
-           continue;
-        }
-
-        var->location = next_position;
-        add_uniform(mem_ctx, &uniforms, ht, var->name, var->type,
-                    prog->_LinkedShaders[i]->Type,
-                    &next_position, &total_uniforms);
-      }
-   }
-
-   ralloc_free(mem_ctx);
-
-   gl_uniform_list *ul = (gl_uniform_list *)
-      calloc(1, sizeof(gl_uniform_list));
-
-   ul->Size = total_uniforms;
-   ul->NumUniforms = total_uniforms;
-   ul->Uniforms = (gl_uniform *) calloc(total_uniforms, sizeof(gl_uniform));
-
-   unsigned idx = 0;
-   uniform_node *next;
-   for (uniform_node *node = (uniform_node *) uniforms.head
-          ; node->link.next != NULL
-          ; node = next) {
-      next = (uniform_node *) node->link.next;
-
-      node->link.remove();
-      memcpy(&ul->Uniforms[idx], node->u, sizeof(gl_uniform));
-      idx++;
-
-      free(node->u);
-      free(node);
-   }
-
-   hash_table_dtor(ht);
-
-   prog->Uniforms = ul;
-}
-
-
 /**
  * Find a contiguous set of available bits in a bitmask.
  *
@@ -1250,12 +1217,6 @@ find_available_slots(unsigned used_mask, unsigned needed_count)
  * \return
  * If locations are successfully assigned, true is returned.  Otherwise an
  * error is emitted to the shader link log and false is returned.
- *
- * \bug
- * Locations set via \c glBindFragDataLocation are not currently supported.
- * Only locations assigned automatically by the linker, explicitly set by a
- * layout qualifier, or explicitly set by a built-in variable (e.g., \c
- * gl_FragColor) are supported for fragment shaders.
  */
 bool
 assign_attribute_or_color_locations(gl_shader_program *prog,
@@ -1279,7 +1240,8 @@ assign_attribute_or_color_locations(gl_shader_program *prog,
     * 1. Invalidate the location assignments for all vertex shader inputs.
     *
     * 2. Assign locations for inputs that have user-defined (via
-    *    glBindVertexAttribLocation) locations.
+    *    glBindVertexAttribLocation) locations and outputs that have
+    *    user-defined locations (via glBindFragDataLocation).
     *
     * 3. Sort the attributes without assigned locations by number of slots
     *    required in decreasing order.  Fragmentation caused by attribute
@@ -1293,10 +1255,9 @@ assign_attribute_or_color_locations(gl_shader_program *prog,
       ? (int) VERT_ATTRIB_GENERIC0 : (int) FRAG_RESULT_DATA0;
 
    const enum ir_variable_mode direction =
-      (target_index == MESA_SHADER_VERTEX) ? ir_var_in : ir_var_out;
-
+      (target_index == MESA_SHADER_VERTEX)
+      ? ir_var_shader_in : ir_var_shader_out;
 
-   invalidate_variable_locations(sh, direction, generic_base);
 
    /* Temporary storage for the set of attributes that need locations assigned.
     */
@@ -1339,14 +1300,31 @@ 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;
+        unsigned index;
+
+        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;
+           }
         }
       }
 
-      /* The location was explicitly assigned, nothing to do here.
+      /* If the variable is not a built-in and has a location statically
+       * assigned in the shader (presumably via a layout qualifier), make sure
+       * that it doesn't collide with other assigned locations.  Otherwise,
+       * add it to the list of variables that need linker-assigned locations.
        */
       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
@@ -1387,10 +1365,12 @@ assign_attribute_or_color_locations(gl_shader_program *prog,
             * attribute overlaps any previously allocated bits.
             */
            if ((~(use_mask << attr) & used_locations) != used_locations) {
+              const char *const string = (target_index == MESA_SHADER_VERTEX)
+                 ? "vertex shader input" : "fragment shader output";
               linker_error(prog,
-                           "insufficient contiguous attribute locations "
-                           "available for vertex shader input `%s'",
-                           var->name);
+                           "insufficient contiguous locations "
+                           "available for %s `%s' %d %d %d", string,
+                           var->name, used_locations, use_mask, attr);
               return false;
            }
 
@@ -1438,13 +1418,14 @@ assign_attribute_or_color_locations(gl_shader_program *prog,
            ? "vertex shader input" : "fragment shader output";
 
         linker_error(prog,
-                     "insufficient contiguous attribute locations "
+                     "insufficient contiguous locations "
                      "available for %s `%s'",
                      string, to_assign[i].var->name);
         return false;
       }
 
       to_assign[i].var->location = generic_base + location;
+      to_assign[i].var->is_unmatched_generic_inout = 0;
       used_locations |= (use_mask << location);
    }
 
@@ -1468,145 +1449,191 @@ 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;
       }
    }
 }
 
 
-bool
-assign_varying_locations(struct gl_context *ctx,
-                        struct gl_shader_program *prog,
-                        gl_shader *producer, gl_shader *consumer)
+/**
+ * Store the gl_FragDepth layout in the gl_shader_program struct.
+ */
+static void
+store_fragdepth_layout(struct gl_shader_program *prog)
 {
-   /* FINISHME: Set dynamically when geometry shader support is added. */
-   unsigned output_index = VERT_RESULT_VAR0;
-   unsigned input_index = FRAG_ATTRIB_VAR0;
+   if (prog->_LinkedShaders[MESA_SHADER_FRAGMENT] == NULL) {
+      return;
+   }
 
-   /* Operate in a total of three passes.
-    *
-    * 1. Assign locations for any matching inputs and outputs.
-    *
-    * 2. Mark output variables in the producer that do not have locations as
-    *    not being outputs.  This lets the optimizer eliminate them.
+   struct exec_list *ir = prog->_LinkedShaders[MESA_SHADER_FRAGMENT]->ir;
+
+   /* We don't look up the gl_FragDepth symbol directly because if
+    * gl_FragDepth is not used in the shader, it's removed from the IR.
+    * However, the symbol won't be removed from the symbol table.
     *
-    * 3. Mark input variables in the consumer that do not have locations as
-    *    not being inputs.  This lets the optimizer eliminate them.
+    * We're only interested in the cases where the variable is NOT removed
+    * from the IR.
     */
+   foreach_list(node, ir) {
+      ir_variable *const var = ((ir_instruction *) node)->as_variable();
 
-   invalidate_variable_locations(producer, ir_var_out, VERT_RESULT_VAR0);
-   invalidate_variable_locations(consumer, ir_var_in, FRAG_ATTRIB_VAR0);
-
-   foreach_list(node, producer->ir) {
-      ir_variable *const output_var = ((ir_instruction *) node)->as_variable();
+      if (var == NULL || var->mode != ir_var_shader_out) {
+         continue;
+      }
 
-      if ((output_var == NULL) || (output_var->mode != ir_var_out)
-         || (output_var->location != -1))
-        continue;
+      if (strcmp(var->name, "gl_FragDepth") == 0) {
+         switch (var->depth_layout) {
+         case ir_depth_layout_none:
+            prog->FragDepthLayout = FRAG_DEPTH_LAYOUT_NONE;
+            return;
+         case ir_depth_layout_any:
+            prog->FragDepthLayout = FRAG_DEPTH_LAYOUT_ANY;
+            return;
+         case ir_depth_layout_greater:
+            prog->FragDepthLayout = FRAG_DEPTH_LAYOUT_GREATER;
+            return;
+         case ir_depth_layout_less:
+            prog->FragDepthLayout = FRAG_DEPTH_LAYOUT_LESS;
+            return;
+         case ir_depth_layout_unchanged:
+            prog->FragDepthLayout = FRAG_DEPTH_LAYOUT_UNCHANGED;
+            return;
+         default:
+            assert(0);
+            return;
+         }
+      }
+   }
+}
 
-      ir_variable *const input_var =
-        consumer->symbols->get_variable(output_var->name);
+/**
+ * Validate the resources used by a program versus the implementation limits
+ */
+static bool
+check_resources(struct gl_context *ctx, struct gl_shader_program *prog)
+{
+   static const char *const shader_names[MESA_SHADER_TYPES] = {
+      "vertex", "fragment", "geometry"
+   };
 
-      if ((input_var == NULL) || (input_var->mode != ir_var_in))
-        continue;
+   const unsigned max_samplers[MESA_SHADER_TYPES] = {
+      ctx->Const.VertexProgram.MaxTextureImageUnits,
+      ctx->Const.FragmentProgram.MaxTextureImageUnits,
+      ctx->Const.GeometryProgram.MaxTextureImageUnits
+   };
 
-      assert(input_var->location == -1);
+   const unsigned max_default_uniform_components[MESA_SHADER_TYPES] = {
+      ctx->Const.VertexProgram.MaxUniformComponents,
+      ctx->Const.FragmentProgram.MaxUniformComponents,
+      ctx->Const.GeometryProgram.MaxUniformComponents
+   };
 
-      output_var->location = output_index;
-      input_var->location = input_index;
+   const unsigned max_combined_uniform_components[MESA_SHADER_TYPES] = {
+      ctx->Const.VertexProgram.MaxCombinedUniformComponents,
+      ctx->Const.FragmentProgram.MaxCombinedUniformComponents,
+      ctx->Const.GeometryProgram.MaxCombinedUniformComponents
+   };
 
-      /* FINISHME: Support for "varying" records in GLSL 1.50. */
-      assert(!output_var->type->is_record());
+   const unsigned max_uniform_blocks[MESA_SHADER_TYPES] = {
+      ctx->Const.VertexProgram.MaxUniformBlocks,
+      ctx->Const.FragmentProgram.MaxUniformBlocks,
+      ctx->Const.GeometryProgram.MaxUniformBlocks,
+   };
 
-      if (output_var->type->is_array()) {
-        const unsigned slots = output_var->type->length
-           * output_var->type->fields.array->matrix_columns;
+   for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) {
+      struct gl_shader *sh = prog->_LinkedShaders[i];
 
-        output_index += slots;
-        input_index += slots;
-      } else {
-        const unsigned slots = output_var->type->matrix_columns;
+      if (sh == NULL)
+        continue;
 
-        output_index += slots;
-        input_index += slots;
+      if (sh->num_samplers > max_samplers[i]) {
+        linker_error(prog, "Too many %s shader texture samplers",
+                     shader_names[i]);
       }
-   }
-
-   unsigned varying_vectors = 0;
 
-   foreach_list(node, consumer->ir) {
-      ir_variable *const var = ((ir_instruction *) node)->as_variable();
+      if (sh->num_uniform_components > max_default_uniform_components[i]) {
+         if (ctx->Const.GLSLSkipStrictMaxUniformLimitCheck) {
+            linker_warning(prog, "Too many %s shader default uniform block "
+                           "components, but the driver will try to optimize "
+                           "them out; this is non-portable out-of-spec "
+                          "behavior\n",
+                           shader_names[i]);
+         } else {
+            linker_error(prog, "Too many %s shader default uniform block "
+                        "components",
+                         shader_names[i]);
+         }
+      }
 
-      if ((var == NULL) || (var->mode != ir_var_in))
-        continue;
+      if (sh->num_combined_uniform_components >
+         max_combined_uniform_components[i]) {
+         if (ctx->Const.GLSLSkipStrictMaxUniformLimitCheck) {
+            linker_warning(prog, "Too many %s shader uniform components, "
+                           "but the driver will try to optimize them out; "
+                           "this is non-portable out-of-spec behavior\n",
+                           shader_names[i]);
+         } else {
+            linker_error(prog, "Too many %s shader uniform components",
+                         shader_names[i]);
+         }
+      }
+   }
 
-      if (var->location == -1) {
-        if (prog->Version <= 120) {
-           /* On page 25 (page 31 of the PDF) of the GLSL 1.20 spec:
-            *
-            *     Only those varying variables used (i.e. read) in
-            *     the fragment shader executable must be written to
-            *     by the vertex shader executable; declaring
-            *     superfluous varying variables in a vertex shader is
-            *     permissible.
-            *
-            * We interpret this text as meaning that the VS must
-            * write the variable for the FS to read it.  See
-            * "glsl1-varying read but not written" in piglit.
-            */
+   unsigned blocks[MESA_SHADER_TYPES] = {0};
+   unsigned total_uniform_blocks = 0;
 
-           linker_error(prog, "fragment shader varying %s not written "
-                        "by vertex shader\n.", var->name);
+   for (unsigned i = 0; i < prog->NumUniformBlocks; i++) {
+      for (unsigned j = 0; j < MESA_SHADER_TYPES; j++) {
+        if (prog->UniformBlockStageIndex[j][i] != -1) {
+           blocks[j]++;
+           total_uniform_blocks++;
         }
-
-        /* An 'in' variable is only really a shader input if its
-         * value is written by the previous stage.
-         */
-        var->mode = ir_var_auto;
-      } else {
-        /* The packing rules are used for vertex shader inputs are also used
-         * for fragment shader inputs.
-         */
-        varying_vectors += count_attribute_slots(var->type);
       }
-   }
 
-   if (ctx->API == API_OPENGLES2 || prog->Version == 100) {
-      if (varying_vectors > ctx->Const.MaxVarying) {
-        linker_error(prog, "shader uses too many varying vectors "
-                     "(%u > %u)\n",
-                     varying_vectors, ctx->Const.MaxVarying);
-        return false;
-      }
-   } else {
-      const unsigned float_components = varying_vectors * 4;
-      if (float_components > ctx->Const.MaxVarying * 4) {
-        linker_error(prog, "shader uses too many varying components "
-                     "(%u > %u)\n",
-                     float_components, ctx->Const.MaxVarying * 4);
-        return false;
+      if (total_uniform_blocks > ctx->Const.MaxCombinedUniformBlocks) {
+        linker_error(prog, "Too many combined uniform blocks (%d/%d)",
+                     prog->NumUniformBlocks,
+                     ctx->Const.MaxCombinedUniformBlocks);
+      } else {
+        for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) {
+           if (blocks[i] > max_uniform_blocks[i]) {
+              linker_error(prog, "Too many %s uniform blocks (%d/%d)",
+                           shader_names[i],
+                           blocks[i],
+                           max_uniform_blocks[i]);
+              break;
+           }
+        }
       }
    }
 
-   return true;
+   return prog->LinkStatus;
 }
 
-
 void
 link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
 {
+   tfeedback_decl *tfeedback_decls = NULL;
+   unsigned num_tfeedback_decls = prog->TransformFeedback.NumVarying;
+
    void *mem_ctx = ralloc_context(NULL); // temporary linker context
 
    prog->LinkStatus = false;
    prog->Validated = false;
    prog->_Used = false;
 
-   if (prog->InfoLog != NULL)
-      ralloc_free(prog->InfoLog);
-
+   ralloc_free(prog->InfoLog);
    prog->InfoLog = ralloc_strdup(NULL, "");
 
+   ralloc_free(prog->UniformBlocks);
+   prog->UniformBlocks = NULL;
+   prog->NumUniformBlocks = 0;
+   for (int i = 0; i < MESA_SHADER_TYPES; i++) {
+      ralloc_free(prog->UniformBlockStageIndex[i]);
+      prog->UniformBlockStageIndex[i] = NULL;
+   }
+
    /* Separate the shaders into groups based on their type.
     */
    struct gl_shader **vert_shader_list;
@@ -1620,10 +1647,18 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
 
    unsigned min_version = UINT_MAX;
    unsigned max_version = 0;
+   const bool is_es_prog =
+      (prog->NumShaders > 0 && prog->Shaders[0]->IsES) ? true : false;
    for (unsigned i = 0; i < prog->NumShaders; i++) {
       min_version = MIN2(min_version, prog->Shaders[i]->Version);
       max_version = MAX2(max_version, prog->Shaders[i]->Version);
 
+      if (prog->Shaders[i]->IsES != is_es_prog) {
+        linker_error(prog, "all shaders must use same shading "
+                     "language version\n");
+        goto done;
+      }
+
       switch (prog->Shaders[i]->Type) {
       case GL_VERTEX_SHADER:
         vert_shader_list[num_vert_shaders] = prog->Shaders[i];
@@ -1643,10 +1678,10 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
    /* Previous to GLSL version 1.30, different compilation units could mix and
     * match shading language versions.  With GLSL 1.30 and later, the versions
     * of all shaders must match.
+    *
+    * GLSL ES has never allowed mixing of shading language versions.
     */
-   assert(min_version >= 100);
-   assert(max_version <= 130);
-   if ((max_version >= 130 || min_version == 100)
+   if ((is_es_prog || max_version >= 130)
        && min_version != max_version) {
       linker_error(prog, "all shaders must use same shading "
                   "language version\n");
@@ -1654,6 +1689,7 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
    }
 
    prog->Version = max_version;
+   prog->IsES = is_es_prog;
 
    for (unsigned int i = 0; i < MESA_SHADER_TYPES; i++) {
       if (prog->_LinkedShaders[i] != NULL)
@@ -1713,6 +1749,12 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
         if (prog->_LinkedShaders[i] == NULL)
            continue;
 
+         if (!validate_interstage_interface_blocks(prog->_LinkedShaders[prev],
+                                                   prog->_LinkedShaders[i])) {
+            linker_error(prog, "interface block mismatch between shader stages\n");
+            goto done;
+         }
+
         if (!cross_validate_outputs_to_inputs(prog,
                                               prog->_LinkedShaders[prev],
                                               prog->_LinkedShaders[i]))
@@ -1724,6 +1766,28 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
       prog->LinkStatus = true;
    }
 
+
+   for (unsigned int i = 0; i < MESA_SHADER_TYPES; i++) {
+      if (prog->_LinkedShaders[i] != NULL)
+         lower_named_interface_blocks(mem_ctx, prog->_LinkedShaders[i]);
+   }
+
+   /* Implement the GLSL 1.30+ rule for discard vs infinite loops Do
+    * it before optimization because we want most of the checks to get
+    * dropped thanks to constant propagation.
+    *
+    * This rule also applies to GLSL ES 3.00.
+    */
+   if (max_version >= (is_es_prog ? 300 : 130)) {
+      struct gl_shader *sh = prog->_LinkedShaders[MESA_SHADER_FRAGMENT];
+      if (sh) {
+        lower_discard_flow(sh->ir);
+      }
+   }
+
+   if (!interstage_cross_validate_uniform_blocks(prog))
+      goto done;
+
    /* Do common optimization before assigning storage for attributes,
     * uniforms, and varyings.  Later optimization could possibly make
     * some of that unused.
@@ -1736,16 +1800,28 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
       if (!prog->LinkStatus)
         goto done;
 
-      if (ctx->ShaderCompilerOptions[i].LowerClipDistance)
-         lower_clip_distance(prog->_LinkedShaders[i]->ir);
+      if (ctx->ShaderCompilerOptions[i].LowerClipDistance) {
+         lower_clip_distance(prog->_LinkedShaders[i]);
+      }
+
+      unsigned max_unroll = ctx->ShaderCompilerOptions[i].MaxUnrollIterations;
 
-      while (do_common_optimization(prog->_LinkedShaders[i]->ir, true, 32))
+      while (do_common_optimization(prog->_LinkedShaders[i]->ir, true, false, max_unroll, &ctx->ShaderCompilerOptions[i]))
         ;
    }
 
-   update_array_sizes(prog);
-
-   assign_uniform_locations(prog);
+   /* Mark all generic shader inputs and outputs as unpaired. */
+   if (prog->_LinkedShaders[MESA_SHADER_VERTEX] != NULL) {
+      link_invalidate_variable_locations(
+            prog->_LinkedShaders[MESA_SHADER_VERTEX],
+            VERT_ATTRIB_GENERIC0, VARYING_SLOT_VAR0);
+   }
+   /* FINISHME: Geometry shaders not implemented yet */
+   if (prog->_LinkedShaders[MESA_SHADER_FRAGMENT] != NULL) {
+      link_invalidate_variable_locations(
+            prog->_LinkedShaders[MESA_SHADER_FRAGMENT],
+            VARYING_SLOT_VAR0, FRAG_RESULT_DATA0);
+   }
 
    /* FINISHME: The value of the max_attribute_index parameter is
     * FINISHME: implementation dependent based on the value of
@@ -1756,7 +1832,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;
    }
 
@@ -1766,43 +1842,104 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
         break;
    }
 
+   if (num_tfeedback_decls != 0) {
+      /* From GL_EXT_transform_feedback:
+       *   A program will fail to link if:
+       *
+       *   * the <count> specified by TransformFeedbackVaryingsEXT is
+       *     non-zero, but the program object has no vertex or geometry
+       *     shader;
+       */
+      if (prev >= MESA_SHADER_FRAGMENT) {
+         linker_error(prog, "Transform feedback varyings specified, but "
+                      "no vertex or geometry shader is present.");
+         goto done;
+      }
+
+      tfeedback_decls = ralloc_array(mem_ctx, tfeedback_decl,
+                                     prog->TransformFeedback.NumVarying);
+      if (!parse_tfeedback_decls(ctx, prog, mem_ctx, num_tfeedback_decls,
+                                 prog->TransformFeedback.VaryingNames,
+                                 tfeedback_decls))
+         goto done;
+   }
+
    for (unsigned i = prev + 1; i < MESA_SHADER_TYPES; i++) {
       if (prog->_LinkedShaders[i] == NULL)
         continue;
 
-      if (!assign_varying_locations(ctx, prog,
-                                   prog->_LinkedShaders[prev],
-                                   prog->_LinkedShaders[i])) {
+      if (!assign_varying_locations(
+                                   ctx, mem_ctx, prog, prog->_LinkedShaders[prev], prog->_LinkedShaders[i],
+             i == MESA_SHADER_FRAGMENT ? num_tfeedback_decls : 0,
+             tfeedback_decls))
         goto done;
-      }
 
       prev = i;
    }
 
+   if (prev != MESA_SHADER_FRAGMENT && num_tfeedback_decls != 0) {
+      /* There was no fragment shader, but we still have to assign varying
+       * locations for use by transform feedback.
+       */
+      if (!assign_varying_locations(
+                                   ctx, mem_ctx, prog, prog->_LinkedShaders[prev], NULL, num_tfeedback_decls,
+             tfeedback_decls))
+         goto done;
+   }
+
+   if (!store_tfeedback_info(ctx, prog, num_tfeedback_decls, tfeedback_decls))
+      goto done;
+
    if (prog->_LinkedShaders[MESA_SHADER_VERTEX] != NULL) {
       demote_shader_inputs_and_outputs(prog->_LinkedShaders[MESA_SHADER_VERTEX],
-                                      ir_var_out);
+                                      ir_var_shader_out);
+
+      /* Eliminate code that is now dead due to unused vertex outputs being
+       * demoted.
+       */
+      while (do_dead_code(prog->_LinkedShaders[MESA_SHADER_VERTEX]->ir, false))
+        ;
    }
 
    if (prog->_LinkedShaders[MESA_SHADER_GEOMETRY] != NULL) {
       gl_shader *const sh = prog->_LinkedShaders[MESA_SHADER_GEOMETRY];
 
-      demote_shader_inputs_and_outputs(sh, ir_var_in);
-      demote_shader_inputs_and_outputs(sh, ir_var_inout);
-      demote_shader_inputs_and_outputs(sh, ir_var_out);
+      demote_shader_inputs_and_outputs(sh, ir_var_shader_in);
+      demote_shader_inputs_and_outputs(sh, ir_var_shader_out);
+
+      /* Eliminate code that is now dead due to unused geometry outputs being
+       * demoted.
+       */
+      while (do_dead_code(prog->_LinkedShaders[MESA_SHADER_GEOMETRY]->ir, false))
+        ;
    }
 
    if (prog->_LinkedShaders[MESA_SHADER_FRAGMENT] != NULL) {
       gl_shader *const sh = prog->_LinkedShaders[MESA_SHADER_FRAGMENT];
 
-      demote_shader_inputs_and_outputs(sh, ir_var_in);
+      demote_shader_inputs_and_outputs(sh, ir_var_shader_in);
+
+      /* Eliminate code that is now dead due to unused fragment inputs being
+       * demoted.  This shouldn't actually do anything other than remove
+       * declarations of the (now unused) global variables.
+       */
+      while (do_dead_code(prog->_LinkedShaders[MESA_SHADER_FRAGMENT]->ir, false))
+        ;
    }
 
+   update_array_sizes(prog);
+   link_assign_uniform_locations(prog);
+   store_fragdepth_layout(prog);
+
+   if (!check_resources(ctx, prog))
+      goto done;
+
    /* OpenGL ES requires that a vertex shader and a fragment shader both be
-    * present in a linked program.  By checking for use of shading language
-    * version 1.00, we also catch the GL_ARB_ES2_compatibility case.
+    * present in a linked program.  By checking prog->IsES, we also
+    * catch the GL_ARB_ES2_compatibility case.
     */
-   if (ctx->API == API_OPENGLES2 || prog->Version == 100) {
+   if (!prog->InternalSeparateShader &&
+       (ctx->API == API_OPENGLES2 || prog->IsES)) {
       if (prog->_LinkedShaders[MESA_SHADER_VERTEX] == NULL) {
         linker_error(prog, "program lacks a vertex shader\n");
       } else if (prog->_LinkedShaders[MESA_SHADER_FRAGMENT] == NULL) {