glsl: set InnerCoverage directly in gl_program
[mesa.git] / src / compiler / glsl / linker.cpp
index 6f54f75ae1e1a581db47bcedcc71e77e9b76be5f..35f1d8b6a8e8d78db97cc2985bf8d2f85ef72f24 100644 (file)
@@ -553,7 +553,7 @@ analyze_clip_cull_usage(struct gl_shader_program *prog,
    *clip_distance_array_size = 0;
    *cull_distance_array_size = 0;
 
-   if (prog->Version >= (prog->IsES ? 300 : 130)) {
+   if (prog->data->Version >= (prog->IsES ? 300 : 130)) {
       /* From section 7.1 (Vertex Shader Special Variables) of the
        * GLSL 1.30 spec:
        *
@@ -672,7 +672,7 @@ validate_vertex_shader_executable(struct gl_shader_program *prog,
     * All GLSL ES Versions are similar to GLSL 1.40--failing to write to
     * gl_Position is not an error.
     */
-   if (prog->Version < (prog->IsES ? 300 : 140)) {
+   if (prog->data->Version < (prog->IsES ? 300 : 140)) {
       find_assignment_visitor find("gl_Position");
       find.run(shader->ir);
       if (!find.variable_found()) {
@@ -1089,7 +1089,8 @@ cross_validate_globals(struct gl_shader_program *prog,
           * In GLSL ES 3.00 and ES 3.20, precision qualifier for each block
           * member should match.
           */
-         if (prog->IsES && (prog->Version != 310 || !var->get_interface_type()) &&
+         if (prog->IsES && (prog->data->Version != 310 ||
+                            !var->get_interface_type()) &&
              existing->data.precision != var->data.precision) {
             linker_error(prog, "declarations for %s `%s` have "
                          "mismatching precision qualifiers\n",
@@ -1136,10 +1137,10 @@ interstage_cross_validate_uniform_blocks(struct gl_shader_program *prog,
       if (prog->_LinkedShaders[i]) {
          if (validate_ssbo) {
             max_num_buffer_blocks +=
-               prog->_LinkedShaders[i]->NumShaderStorageBlocks;
+               prog->_LinkedShaders[i]->Program->info.num_ssbos;
          } else {
             max_num_buffer_blocks +=
-               prog->_LinkedShaders[i]->NumUniformBlocks;
+               prog->_LinkedShaders[i]->Program->info.num_ubos;
          }
       }
    }
@@ -1157,11 +1158,11 @@ interstage_cross_validate_uniform_blocks(struct gl_shader_program *prog,
       unsigned sh_num_blocks;
       struct gl_uniform_block **sh_blks;
       if (validate_ssbo) {
-         sh_num_blocks = prog->_LinkedShaders[i]->NumShaderStorageBlocks;
-         sh_blks = sh->ShaderStorageBlocks;
+         sh_num_blocks = prog->_LinkedShaders[i]->Program->info.num_ssbos;
+         sh_blks = sh->Program->sh.ShaderStorageBlocks;
       } else {
-         sh_num_blocks = prog->_LinkedShaders[i]->NumUniformBlocks;
-         sh_blks = sh->UniformBlocks;
+         sh_num_blocks = prog->_LinkedShaders[i]->Program->info.num_ubos;
+         sh_blks = sh->Program->sh.UniformBlocks;
       }
 
       for (unsigned int j = 0; j < sh_num_blocks; j++) {
@@ -1193,7 +1194,8 @@ interstage_cross_validate_uniform_blocks(struct gl_shader_program *prog,
             struct gl_linked_shader *sh = prog->_LinkedShaders[i];
 
             struct gl_uniform_block **sh_blks = validate_ssbo ?
-               sh->ShaderStorageBlocks : sh->UniformBlocks;
+               sh->Program->sh.ShaderStorageBlocks :
+               sh->Program->sh.UniformBlocks;
 
             blks[j].stageref |= sh_blks[stage_index]->stageref;
             sh_blks[stage_index] = &blks[j];
@@ -1657,15 +1659,15 @@ link_xfb_stride_layout_qualifiers(struct gl_context *ctx,
  */
 static void
 link_tcs_out_layout_qualifiers(struct gl_shader_program *prog,
-                               struct gl_linked_shader *linked_shader,
+                               struct gl_program *gl_prog,
                                struct gl_shader **shader_list,
                                unsigned num_shaders)
 {
-   linked_shader->info.TessCtrl.VerticesOut = 0;
-
-   if (linked_shader->Stage != MESA_SHADER_TESS_CTRL)
+   if (gl_prog->info.stage != MESA_SHADER_TESS_CTRL)
       return;
 
+   gl_prog->info.tess.tcs_vertices_out = 0;
+
    /* From the GLSL 4.0 spec (chapter 4.3.8.2):
     *
     *     "All tessellation control shader layout declarations in a program
@@ -1680,16 +1682,16 @@ link_tcs_out_layout_qualifiers(struct gl_shader_program *prog,
       struct gl_shader *shader = shader_list[i];
 
       if (shader->info.TessCtrl.VerticesOut != 0) {
-         if (linked_shader->info.TessCtrl.VerticesOut != 0 &&
-             linked_shader->info.TessCtrl.VerticesOut !=
-             shader->info.TessCtrl.VerticesOut) {
+         if (gl_prog->info.tess.tcs_vertices_out != 0 &&
+             gl_prog->info.tess.tcs_vertices_out !=
+             (unsigned) shader->info.TessCtrl.VerticesOut) {
             linker_error(prog, "tessellation control shader defined with "
                          "conflicting output vertex count (%d and %d)\n",
-                         linked_shader->info.TessCtrl.VerticesOut,
+                         gl_prog->info.tess.tcs_vertices_out,
                          shader->info.TessCtrl.VerticesOut);
             return;
          }
-         linked_shader->info.TessCtrl.VerticesOut =
+         gl_prog->info.tess.tcs_vertices_out =
             shader->info.TessCtrl.VerticesOut;
       }
    }
@@ -1698,7 +1700,7 @@ link_tcs_out_layout_qualifiers(struct gl_shader_program *prog,
     * since we already know we're in the right type of shader program
     * for doing it.
     */
-   if (linked_shader->info.TessCtrl.VerticesOut == 0) {
+   if (gl_prog->info.tess.tcs_vertices_out == 0) {
       linker_error(prog, "tessellation control shader didn't declare "
                    "vertices out layout qualifier\n");
       return;
@@ -1719,7 +1721,7 @@ link_tes_in_layout_qualifiers(struct gl_shader_program *prog,
                               unsigned num_shaders)
 {
    linked_shader->info.TessEval.PrimitiveMode = PRIM_UNKNOWN;
-   linked_shader->info.TessEval.Spacing = 0;
+   linked_shader->info.TessEval.Spacing = TESS_SPACING_UNSPECIFIED;
    linked_shader->info.TessEval.VertexOrder = 0;
    linked_shader->info.TessEval.PointMode = -1;
 
@@ -1802,8 +1804,8 @@ link_tes_in_layout_qualifiers(struct gl_shader_program *prog,
       return;
    }
 
-   if (linked_shader->info.TessEval.Spacing == 0)
-      linked_shader->info.TessEval.Spacing = GL_EQUAL;
+   if (linked_shader->info.TessEval.Spacing == TESS_SPACING_UNSPECIFIED)
+      linked_shader->info.TessEval.Spacing = TESS_SPACING_EQUAL;
 
    if (linked_shader->info.TessEval.VertexOrder == 0)
       linked_shader->info.TessEval.VertexOrder = GL_CCW;
@@ -1824,14 +1826,14 @@ link_fs_inout_layout_qualifiers(struct gl_shader_program *prog,
                                 struct gl_shader **shader_list,
                                 unsigned num_shaders)
 {
-   linked_shader->info.redeclares_gl_fragcoord = false;
-   linked_shader->info.uses_gl_fragcoord = false;
-   linked_shader->info.origin_upper_left = false;
-   linked_shader->info.pixel_center_integer = false;
-   linked_shader->info.BlendSupport = 0;
+   bool redeclares_gl_fragcoord = false;
+   bool uses_gl_fragcoord = false;
+   bool origin_upper_left = false;
+   bool pixel_center_integer = false;
 
    if (linked_shader->Stage != MESA_SHADER_FRAGMENT ||
-       (prog->Version < 150 && !prog->ARB_fragment_coord_conventions_enable))
+       (prog->data->Version < 150 &&
+        !prog->ARB_fragment_coord_conventions_enable))
       return;
 
    for (unsigned i = 0; i < num_shaders; i++) {
@@ -1842,12 +1844,10 @@ link_fs_inout_layout_qualifiers(struct gl_shader_program *prog,
        *    it must be redeclared in all the fragment shaders in that program
        *    that have a static use gl_FragCoord."
        */
-      if ((linked_shader->info.redeclares_gl_fragcoord
-           && !shader->info.redeclares_gl_fragcoord
-           && shader->info.uses_gl_fragcoord)
-          || (shader->info.redeclares_gl_fragcoord
-              && !linked_shader->info.redeclares_gl_fragcoord
-              && linked_shader->info.uses_gl_fragcoord)) {
+      if ((redeclares_gl_fragcoord && !shader->redeclares_gl_fragcoord &&
+           shader->uses_gl_fragcoord)
+          || (shader->redeclares_gl_fragcoord && !redeclares_gl_fragcoord &&
+              uses_gl_fragcoord)) {
              linker_error(prog, "fragment shader defined with conflicting "
                          "layout qualifiers for gl_FragCoord\n");
       }
@@ -1857,12 +1857,9 @@ link_fs_inout_layout_qualifiers(struct gl_shader_program *prog,
        *   "All redeclarations of gl_FragCoord in all fragment shaders in a
        *    single program must have the same set of qualifiers."
        */
-      if (linked_shader->info.redeclares_gl_fragcoord &&
-          shader->info.redeclares_gl_fragcoord &&
-          (shader->info.origin_upper_left !=
-           linked_shader->info.origin_upper_left ||
-           shader->info.pixel_center_integer !=
-           linked_shader->info.pixel_center_integer)) {
+      if (redeclares_gl_fragcoord && shader->redeclares_gl_fragcoord &&
+          (shader->origin_upper_left != origin_upper_left ||
+           shader->pixel_center_integer != pixel_center_integer)) {
          linker_error(prog, "fragment shader defined with conflicting "
                       "layout qualifiers for gl_FragCoord\n");
       }
@@ -1872,22 +1869,20 @@ link_fs_inout_layout_qualifiers(struct gl_shader_program *prog,
        * are multiple redeclarations, all the fields except uses_gl_fragcoord
        * are already known to be the same.
        */
-      if (shader->info.redeclares_gl_fragcoord ||
-          shader->info.uses_gl_fragcoord) {
-         linked_shader->info.redeclares_gl_fragcoord =
-            shader->info.redeclares_gl_fragcoord;
-         linked_shader->info.uses_gl_fragcoord =
-            linked_shader->info.uses_gl_fragcoord ||
-            shader->info.uses_gl_fragcoord;
-         linked_shader->info.origin_upper_left =
-            shader->info.origin_upper_left;
-         linked_shader->info.pixel_center_integer =
-            shader->info.pixel_center_integer;
+      if (shader->redeclares_gl_fragcoord || shader->uses_gl_fragcoord) {
+         redeclares_gl_fragcoord = shader->redeclares_gl_fragcoord;
+         uses_gl_fragcoord |= shader->uses_gl_fragcoord;
+         origin_upper_left = shader->origin_upper_left;
+         pixel_center_integer = shader->pixel_center_integer;
       }
 
-      linked_shader->info.EarlyFragmentTests |=
-         shader->info.EarlyFragmentTests;
-      linked_shader->info.BlendSupport |= shader->info.BlendSupport;
+      linked_shader->Program->info.fs.early_fragment_tests |=
+         shader->EarlyFragmentTests;
+      linked_shader->Program->info.fs.inner_coverage |= shader->InnerCoverage;
+      linked_shader->Program->info.fs.post_depth_coverage |=
+         shader->PostDepthCoverage;
+
+      linked_shader->Program->sh.fs.BlendSupport |= shader->BlendSupport;
    }
 }
 
@@ -1910,7 +1905,8 @@ link_gs_inout_layout_qualifiers(struct gl_shader_program *prog,
    /* No in/out qualifiers defined for anything but GLSL 1.50+
     * geometry shaders so far.
     */
-   if (linked_shader->Stage != MESA_SHADER_GEOMETRY || prog->Version < 150)
+   if (linked_shader->Stage != MESA_SHADER_GEOMETRY ||
+       prog->data->Version < 150)
       return;
 
    /* From the GLSL 1.50 spec, page 46:
@@ -2187,19 +2183,22 @@ link_intrastage_shaders(void *mem_ctx,
       return NULL;
    }
 
-   gl_linked_shader *linked = ctx->Driver.NewShader(shader_list[0]->Stage);
+   gl_linked_shader *linked = rzalloc(NULL, struct gl_linked_shader);
+   linked->Stage = shader_list[0]->Stage;
 
    /* Create program and attach it to the linked shader */
    struct gl_program *gl_prog =
       ctx->Driver.NewProgram(ctx,
                              _mesa_shader_stage_to_program(shader_list[0]->Stage),
-                             prog->Name);
+                             prog->Name, false);
    if (!gl_prog) {
       prog->data->LinkStatus = false;
       _mesa_delete_linked_shader(ctx, linked);
       return NULL;
    }
 
+   _mesa_reference_shader_program_data(ctx, &gl_prog->sh.data, prog->data);
+
    /* Don't use _mesa_reference_program() just take ownership */
    linked->Program = gl_prog;
 
@@ -2207,7 +2206,7 @@ link_intrastage_shaders(void *mem_ctx,
    clone_ir_list(mem_ctx, linked->ir, main->ir);
 
    link_fs_inout_layout_qualifiers(prog, linked, shader_list, num_shaders);
-   link_tcs_out_layout_qualifiers(prog, linked, shader_list, num_shaders);
+   link_tcs_out_layout_qualifiers(prog, gl_prog, shader_list, num_shaders);
    link_tes_in_layout_qualifiers(prog, linked, shader_list, num_shaders);
    link_gs_inout_layout_qualifiers(prog, linked, shader_list, num_shaders);
    link_cs_input_layout_qualifiers(prog, linked, shader_list, num_shaders);
@@ -2262,22 +2261,22 @@ link_intrastage_shaders(void *mem_ctx,
    }
 
    /* Copy ubo blocks to linked shader list */
-   linked->UniformBlocks =
+   linked->Program->sh.UniformBlocks =
       ralloc_array(linked, gl_uniform_block *, num_ubo_blocks);
    ralloc_steal(linked, ubo_blocks);
    for (unsigned i = 0; i < num_ubo_blocks; i++) {
-      linked->UniformBlocks[i] = &ubo_blocks[i];
+      linked->Program->sh.UniformBlocks[i] = &ubo_blocks[i];
    }
-   linked->NumUniformBlocks = num_ubo_blocks;
+   linked->Program->info.num_ubos = num_ubo_blocks;
 
    /* Copy ssbo blocks to linked shader list */
-   linked->ShaderStorageBlocks =
+   linked->Program->sh.ShaderStorageBlocks =
       ralloc_array(linked, gl_uniform_block *, num_ssbo_blocks);
    ralloc_steal(linked, ssbo_blocks);
    for (unsigned i = 0; i < num_ssbo_blocks; i++) {
-      linked->ShaderStorageBlocks[i] = &ssbo_blocks[i];
+      linked->Program->sh.ShaderStorageBlocks[i] = &ssbo_blocks[i];
    }
-   linked->NumShaderStorageBlocks = num_ssbo_blocks;
+   linked->Program->info.num_ssbos = num_ssbo_blocks;
 
    /* At this point linked should contain all of the linked IR, so
     * validate it to make sure nothing went wrong.
@@ -2420,7 +2419,7 @@ resize_tes_inputs(struct gl_context *ctx,
     * known until draw time.
     */
    const int num_vertices = tcs
-      ? tcs->info.TessCtrl.VerticesOut
+      ? tcs->Program->info.tess.tcs_vertices_out
       : ctx->Const.MaxPatchVertices;
 
    array_resize_visitor input_resize_visitor(num_vertices, prog,
@@ -2806,7 +2805,7 @@ assign_attribute_or_color_locations(void *mem_ctx,
                      }
                   }
                } else if (target_index == MESA_SHADER_FRAGMENT ||
-                          (prog->IsES && prog->Version >= 300)) {
+                          (prog->IsES && prog->data->Version >= 300)) {
                   linker_error(prog, "overlapping location is assigned "
                                "to %s `%s' %d %d %d\n", string, var->name,
                                used_locations, use_mask, attr);
@@ -3056,7 +3055,8 @@ check_resources(struct gl_context *ctx, struct gl_shader_program *prog)
       if (sh == NULL)
          continue;
 
-      if (sh->num_samplers > ctx->Const.Program[i].MaxTextureImageUnits) {
+      if (sh->Program->info.num_textures >
+          ctx->Const.Program[i].MaxTextureImageUnits) {
          linker_error(prog, "Too many %s shader texture samplers\n",
                       _mesa_shader_stage_to_string(i));
       }
@@ -3089,23 +3089,23 @@ check_resources(struct gl_context *ctx, struct gl_shader_program *prog)
          }
       }
 
-      total_shader_storage_blocks += sh->NumShaderStorageBlocks;
-      total_uniform_blocks += sh->NumUniformBlocks;
+      total_shader_storage_blocks += sh->Program->info.num_ssbos;
+      total_uniform_blocks += sh->Program->info.num_ubos;
 
       const unsigned max_uniform_blocks =
          ctx->Const.Program[i].MaxUniformBlocks;
-      if (max_uniform_blocks < sh->NumUniformBlocks) {
+      if (max_uniform_blocks < sh->Program->info.num_ubos) {
          linker_error(prog, "Too many %s uniform blocks (%d/%d)\n",
-                      _mesa_shader_stage_to_string(i), sh->NumUniformBlocks,
-                      max_uniform_blocks);
+                      _mesa_shader_stage_to_string(i),
+                      sh->Program->info.num_ubos, max_uniform_blocks);
       }
 
       const unsigned max_shader_storage_blocks =
          ctx->Const.Program[i].MaxShaderStorageBlocks;
-      if (max_shader_storage_blocks < sh->NumShaderStorageBlocks) {
+      if (max_shader_storage_blocks < sh->Program->info.num_ssbos) {
          linker_error(prog, "Too many %s shader storage blocks (%d/%d)\n",
                       _mesa_shader_stage_to_string(i),
-                      sh->NumShaderStorageBlocks, max_shader_storage_blocks);
+                      sh->Program->info.num_ssbos, max_shader_storage_blocks);
       }
    }
 
@@ -3144,28 +3144,27 @@ check_resources(struct gl_context *ctx, struct gl_shader_program *prog)
 static void
 link_calculate_subroutine_compat(struct gl_shader_program *prog)
 {
-   for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
-      struct gl_linked_shader *sh = prog->_LinkedShaders[i];
-      int count;
-      if (!sh)
-         continue;
+   unsigned mask = prog->data->linked_stages;
+   while (mask) {
+      const int i = u_bit_scan(&mask);
+      struct gl_program *p = prog->_LinkedShaders[i]->Program;
 
-      for (unsigned j = 0; j < sh->NumSubroutineUniformRemapTable; j++) {
-         if (sh->SubroutineUniformRemapTable[j] == INACTIVE_UNIFORM_EXPLICIT_LOCATION)
+      for (unsigned j = 0; j < p->sh.NumSubroutineUniformRemapTable; j++) {
+         if (p->sh.SubroutineUniformRemapTable[j] == INACTIVE_UNIFORM_EXPLICIT_LOCATION)
             continue;
 
-         struct gl_uniform_storage *uni = sh->SubroutineUniformRemapTable[j];
+         struct gl_uniform_storage *uni = p->sh.SubroutineUniformRemapTable[j];
 
          if (!uni)
             continue;
 
-         count = 0;
-         if (sh->NumSubroutineFunctions == 0) {
+         int count = 0;
+         if (p->sh.NumSubroutineFunctions == 0) {
             linker_error(prog, "subroutine uniform %s defined but no valid functions found\n", uni->type->name);
             continue;
          }
-         for (unsigned f = 0; f < sh->NumSubroutineFunctions; f++) {
-            struct gl_subroutine_function *fn = &sh->SubroutineFunctions[f];
+         for (unsigned f = 0; f < p->sh.NumSubroutineFunctions; f++) {
+            struct gl_subroutine_function *fn = &p->sh.SubroutineFunctions[f];
             for (int k = 0; k < fn->num_compat_types; k++) {
                if (fn->types[k] == uni->type) {
                   count++;
@@ -3181,13 +3180,14 @@ link_calculate_subroutine_compat(struct gl_shader_program *prog)
 static void
 check_subroutine_resources(struct gl_shader_program *prog)
 {
-   for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
-      struct gl_linked_shader *sh = prog->_LinkedShaders[i];
+   unsigned mask = prog->data->linked_stages;
+   while (mask) {
+      const int i = u_bit_scan(&mask);
+      struct gl_program *p = prog->_LinkedShaders[i]->Program;
 
-      if (sh) {
-         if (sh->NumSubroutineUniformRemapTable > MAX_SUBROUTINE_UNIFORM_LOCATIONS)
-            linker_error(prog, "Too many %s shader subroutine uniforms\n",
-                         _mesa_shader_stage_to_string(i));
+      if (p->sh.NumSubroutineUniformRemapTable > MAX_SUBROUTINE_UNIFORM_LOCATIONS) {
+         linker_error(prog, "Too many %s shader subroutine uniforms\n",
+                      _mesa_shader_stage_to_string(i));
       }
    }
 }
@@ -3208,13 +3208,14 @@ check_image_resources(struct gl_context *ctx, struct gl_shader_program *prog)
       struct gl_linked_shader *sh = prog->_LinkedShaders[i];
 
       if (sh) {
-         if (sh->NumImages > ctx->Const.Program[i].MaxImageUniforms)
+         if (sh->Program->info.num_images > ctx->Const.Program[i].MaxImageUniforms)
             linker_error(prog, "Too many %s shader image uniforms (%u > %u)\n",
-                         _mesa_shader_stage_to_string(i), sh->NumImages,
+                         _mesa_shader_stage_to_string(i),
+                         sh->Program->info.num_images,
                          ctx->Const.Program[i].MaxImageUniforms);
 
-         total_image_units += sh->NumImages;
-         total_shader_storage_blocks += sh->NumShaderStorageBlocks;
+         total_image_units += sh->Program->info.num_images;
+         total_shader_storage_blocks += sh->Program->info.num_ssbos;
 
          if (i == MESA_SHADER_FRAGMENT) {
             foreach_in_list(ir_instruction, node, sh->ir) {
@@ -3309,36 +3310,36 @@ reserve_explicit_locations(struct gl_shader_program *prog,
 
 static bool
 reserve_subroutine_explicit_locations(struct gl_shader_program *prog,
-                                      struct gl_linked_shader *sh,
+                                      struct gl_program *p,
                                       ir_variable *var)
 {
    unsigned slots = var->type->uniform_locations();
    unsigned max_loc = var->data.location + slots - 1;
 
    /* Resize remap table if locations do not fit in the current one. */
-   if (max_loc + 1 > sh->NumSubroutineUniformRemapTable) {
-      sh->SubroutineUniformRemapTable =
-         reralloc(sh, sh->SubroutineUniformRemapTable,
+   if (max_loc + 1 > p->sh.NumSubroutineUniformRemapTable) {
+      p->sh.SubroutineUniformRemapTable =
+         reralloc(p, p->sh.SubroutineUniformRemapTable,
                   gl_uniform_storage *,
                   max_loc + 1);
 
-      if (!sh->SubroutineUniformRemapTable) {
+      if (!p->sh.SubroutineUniformRemapTable) {
          linker_error(prog, "Out of memory during linking.\n");
          return false;
       }
 
       /* Initialize allocated space. */
-      for (unsigned i = sh->NumSubroutineUniformRemapTable; i < max_loc + 1; i++)
-         sh->SubroutineUniformRemapTable[i] = NULL;
+      for (unsigned i = p->sh.NumSubroutineUniformRemapTable; i < max_loc + 1; i++)
+         p->sh.SubroutineUniformRemapTable[i] = NULL;
 
-      sh->NumSubroutineUniformRemapTable = max_loc + 1;
+      p->sh.NumSubroutineUniformRemapTable = max_loc + 1;
    }
 
    for (unsigned i = 0; i < slots; i++) {
       unsigned loc = var->data.location + i;
 
       /* Check if location is already used. */
-      if (sh->SubroutineUniformRemapTable[loc] == INACTIVE_UNIFORM_EXPLICIT_LOCATION) {
+      if (p->sh.SubroutineUniformRemapTable[loc] == INACTIVE_UNIFORM_EXPLICIT_LOCATION) {
 
          /* ARB_explicit_uniform_location specification states:
           *     "No two subroutine uniform variables can have the same location
@@ -3355,7 +3356,7 @@ reserve_subroutine_explicit_locations(struct gl_shader_program *prog,
       /* Initialize location as inactive before optimization
        * rounds and location assignment.
        */
-      sh->SubroutineUniformRemapTable[loc] = INACTIVE_UNIFORM_EXPLICIT_LOCATION;
+      p->sh.SubroutineUniformRemapTable[loc] = INACTIVE_UNIFORM_EXPLICIT_LOCATION;
    }
 
    return true;
@@ -3365,12 +3366,14 @@ reserve_subroutine_explicit_locations(struct gl_shader_program *prog,
  * any optimizations happen to handle also inactive uniforms and
  * inactive array elements that may get trimmed away.
  */
-static unsigned
+static void
 check_explicit_uniform_locations(struct gl_context *ctx,
                                  struct gl_shader_program *prog)
 {
+   prog->NumExplicitUniformLocations = 0;
+
    if (!ctx->Extensions.ARB_explicit_uniform_location)
-      return 0;
+      return;
 
    /* This map is used to detect if overlapping explicit locations
     * occur with the same uniform (from different stage) or a different one.
@@ -3379,17 +3382,16 @@ check_explicit_uniform_locations(struct gl_context *ctx,
 
    if (!uniform_map) {
       linker_error(prog, "Out of memory during linking.\n");
-      return 0;
+      return;
    }
 
    unsigned entries_total = 0;
-   for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
-      struct gl_linked_shader *sh = prog->_LinkedShaders[i];
+   unsigned mask = prog->data->linked_stages;
+   while (mask) {
+      const int i = u_bit_scan(&mask);
+      struct gl_program *p = prog->_LinkedShaders[i]->Program;
 
-      if (!sh)
-         continue;
-
-      foreach_in_list(ir_instruction, node, sh->ir) {
+      foreach_in_list(ir_instruction, node, prog->_LinkedShaders[i]->ir) {
          ir_variable *var = node->as_variable();
          if (!var || var->data.mode != ir_var_uniform)
             continue;
@@ -3397,7 +3399,7 @@ check_explicit_uniform_locations(struct gl_context *ctx,
          if (var->data.explicit_location) {
             bool ret = false;
             if (var->type->without_array()->is_subroutine())
-               ret = reserve_subroutine_explicit_locations(prog, sh, var);
+               ret = reserve_subroutine_explicit_locations(prog, p, var);
             else {
                int slots = reserve_explicit_locations(prog, uniform_map,
                                                       var);
@@ -3408,7 +3410,7 @@ check_explicit_uniform_locations(struct gl_context *ctx,
             }
             if (!ret) {
                delete uniform_map;
-               return 0;
+               return;
             }
          }
       }
@@ -3433,7 +3435,7 @@ check_explicit_uniform_locations(struct gl_context *ctx,
    }
 
    delete uniform_map;
-   return entries_total;
+   prog->NumExplicitUniformLocations = entries_total;
 }
 
 static bool
@@ -3522,25 +3524,25 @@ add_program_resource(struct gl_shader_program *prog,
    if (_mesa_set_search(resource_set, data))
       return true;
 
-   prog->ProgramResourceList =
+   prog->data->ProgramResourceList =
       reralloc(prog,
-               prog->ProgramResourceList,
+               prog->data->ProgramResourceList,
                gl_program_resource,
-               prog->NumProgramResourceList + 1);
+               prog->data->NumProgramResourceList + 1);
 
-   if (!prog->ProgramResourceList) {
+   if (!prog->data->ProgramResourceList) {
       linker_error(prog, "Out of memory during linking.\n");
       return false;
    }
 
    struct gl_program_resource *res =
-      &prog->ProgramResourceList[prog->NumProgramResourceList];
+      &prog->data->ProgramResourceList[prog->data->NumProgramResourceList];
 
    res->Type = type;
    res->Data = data;
    res->StageReferences = stages;
 
-   prog->NumProgramResourceList++;
+   prog->data->NumProgramResourceList++;
 
    _mesa_set_add(resource_set, data);
 
@@ -3729,9 +3731,64 @@ add_shader_variable(const struct gl_context *ctx,
                     bool use_implicit_location, int location,
                     const glsl_type *outermost_struct_type = NULL)
 {
-   const bool is_vertex_input =
-      programInterface == GL_PROGRAM_INPUT &&
-      stage_mask == MESA_SHADER_VERTEX;
+   const glsl_type *interface_type = var->get_interface_type();
+
+   if (outermost_struct_type == NULL) {
+      /* Unsized (non-patch) TCS output/TES input arrays are implicitly
+       * sized to gl_MaxPatchVertices.  Internally, we shrink them to a
+       * smaller size.
+       *
+       * This can cause trouble with SSO programs.  Since the TCS declares
+       * the number of output vertices, we can always shrink TCS output
+       * arrays.  However, the TES might not be linked with a TCS, in
+       * which case it won't know the size of the patch.  In other words,
+       * the TCS and TES may disagree on the (smaller) array sizes.  This
+       * can result in the resource names differing across stages, causing
+       * SSO validation failures and other cascading issues.
+       *
+       * Expanding the array size to the full gl_MaxPatchVertices fixes
+       * these issues.  It's also what program interface queries expect,
+       * as that is the official size of the array.
+       */
+      if (var->data.tess_varying_implicit_sized_array) {
+         type = resize_to_max_patch_vertices(ctx, type);
+         interface_type = resize_to_max_patch_vertices(ctx, interface_type);
+      }
+
+      if (var->data.from_named_ifc_block) {
+         const char *interface_name = interface_type->name;
+
+         if (interface_type->is_array()) {
+            /* Issue #16 of the ARB_program_interface_query spec says:
+             *
+             * "* If a variable is a member of an interface block without an
+             *    instance name, it is enumerated using just the variable name.
+             *
+             *  * If a variable is a member of an interface block with an
+             *    instance name, it is enumerated as "BlockName.Member", where
+             *    "BlockName" is the name of the interface block (not the
+             *    instance name) and "Member" is the name of the variable."
+             *
+             * In particular, it indicates that it should be "BlockName",
+             * not "BlockName[array length]".  The conformance suite and
+             * dEQP both require this behavior.
+             *
+             * Here, we unwrap the extra array level added by named interface
+             * block array lowering so we have the correct variable type.  We
+             * also unwrap the interface type when constructing the name.
+             *
+             * We leave interface_type the same so that ES 3.x SSO pipeline
+             * validation can enforce the rules requiring array length to
+             * match on interface blocks.
+             */
+            type = type->fields.array;
+
+            interface_name = interface_type->fields.array->name;
+         }
+
+         name = ralloc_asprintf(shProg, "%s.%s", interface_name, name);
+      }
+   }
 
    switch (type->base_type) {
    case GLSL_TYPE_STRUCT: {
@@ -3758,51 +3815,12 @@ add_shader_variable(const struct gl_context *ctx,
                                   outermost_struct_type))
             return false;
 
-         field_location +=
-            field->type->count_attribute_slots(is_vertex_input);
+         field_location += field->type->count_attribute_slots(false);
       }
       return true;
    }
 
    default: {
-      const glsl_type *interface_type = var->get_interface_type();
-
-      /* Unsized (non-patch) TCS output/TES input arrays are implicitly
-       * sized to gl_MaxPatchVertices.  Internally, we shrink them to a
-       * smaller size.
-       *
-       * This can cause trouble with SSO programs.  Since the TCS declares
-       * the number of output vertices, we can always shrink TCS output
-       * arrays.  However, the TES might not be linked with a TCS, in
-       * which case it won't know the size of the patch.  In other words,
-       * the TCS and TES may disagree on the (smaller) array sizes.  This
-       * can result in the resource names differing across stages, causing
-       * SSO validation failures and other cascading issues.
-       *
-       * Expanding the array size to the full gl_MaxPatchVertices fixes
-       * these issues.  It's also what program interface queries expect,
-       * as that is the official size of the array.
-       */
-      if (var->data.tess_varying_implicit_sized_array) {
-         type = resize_to_max_patch_vertices(ctx, type);
-         interface_type = resize_to_max_patch_vertices(ctx, interface_type);
-      }
-
-      /* Issue #16 of the ARB_program_interface_query spec says:
-       *
-       * "* If a variable is a member of an interface block without an
-       *    instance name, it is enumerated using just the variable name.
-       *
-       *  * If a variable is a member of an interface block with an instance
-       *    name, it is enumerated as "BlockName.Member", where "BlockName" is
-       *    the name of the interface block (not the instance name) and
-       *    "Member" is the name of the variable."
-       */
-      const char *prefixed_name = (var->data.from_named_ifc_block &&
-                                   !is_gl_identifier(var->name))
-         ? ralloc_asprintf(shProg, "%s.%s", interface_type->name, name)
-         : name;
-
       /* The ARB_program_interface_query spec says:
        *
        *     "For an active variable declared as a single instance of a basic
@@ -3810,8 +3828,7 @@ add_shader_variable(const struct gl_context *ctx,
        *     from the shader source."
        */
       gl_shader_variable *sha_v =
-         create_shader_variable(shProg, var, prefixed_name, type,
-                                interface_type,
+         create_shader_variable(shProg, var, name, type, interface_type,
                                 use_implicit_location, location,
                                 outermost_struct_type);
       if (!sha_v)
@@ -4169,10 +4186,10 @@ build_program_resource_list(struct gl_context *ctx,
                             struct gl_shader_program *shProg)
 {
    /* Rebuild resource list. */
-   if (shProg->ProgramResourceList) {
-      ralloc_free(shProg->ProgramResourceList);
-      shProg->ProgramResourceList = NULL;
-      shProg->NumProgramResourceList = 0;
+   if (shProg->data->ProgramResourceList) {
+      ralloc_free(shProg->data->ProgramResourceList);
+      shProg->data->ProgramResourceList = NULL;
+      shProg->data->NumProgramResourceList = 0;
    }
 
    int input_stage = MESA_SHADER_STAGES, output_stage = 0;
@@ -4220,25 +4237,26 @@ build_program_resource_list(struct gl_context *ctx,
                                 output_stage, GL_PROGRAM_OUTPUT))
       return;
 
+   struct gl_transform_feedback_info *linked_xfb =
+      shProg->xfb_program->sh.LinkedTransformFeedback;
+
    /* Add transform feedback varyings. */
-   if (shProg->LinkedTransformFeedback.NumVarying > 0) {
-      for (int i = 0; i < shProg->LinkedTransformFeedback.NumVarying; i++) {
+   if (linked_xfb->NumVarying > 0) {
+      for (int i = 0; i < linked_xfb->NumVarying; i++) {
          if (!add_program_resource(shProg, resource_set,
                                    GL_TRANSFORM_FEEDBACK_VARYING,
-                                   &shProg->LinkedTransformFeedback.Varyings[i],
-                                   0))
+                                   &linked_xfb->Varyings[i], 0))
          return;
       }
    }
 
    /* Add transform feedback buffers. */
    for (unsigned i = 0; i < ctx->Const.MaxTransformFeedbackBuffers; i++) {
-      if ((shProg->LinkedTransformFeedback.ActiveBuffers >> i) & 1) {
-         shProg->LinkedTransformFeedback.Buffers[i].Binding = i;
+      if ((linked_xfb->ActiveBuffers >> i) & 1) {
+         linked_xfb->Buffers[i].Binding = i;
          if (!add_program_resource(shProg, resource_set,
                                    GL_TRANSFORM_FEEDBACK_BUFFER,
-                                   &shProg->LinkedTransformFeedback.Buffers[i],
-                                   0))
+                                   &linked_xfb->Buffers[i], 0))
          return;
       }
    }
@@ -4317,17 +4335,15 @@ build_program_resource_list(struct gl_context *ctx,
       }
    }
 
-   for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
-      struct gl_linked_shader *sh = shProg->_LinkedShaders[i];
-      GLuint type;
+   unsigned mask = shProg->data->linked_stages;
+   while (mask) {
+      const int i = u_bit_scan(&mask);
+      struct gl_program *p = shProg->_LinkedShaders[i]->Program;
 
-      if (!sh)
-         continue;
-
-      type = _mesa_shader_stage_to_subroutine((gl_shader_stage)i);
-      for (unsigned j = 0; j < sh->NumSubroutineFunctions; j++) {
+      GLuint type = _mesa_shader_stage_to_subroutine((gl_shader_stage)i);
+      for (unsigned j = 0; j < p->sh.NumSubroutineFunctions; j++) {
          if (!add_program_resource(shProg, resource_set,
-                                   type, &sh->SubroutineFunctions[j], 0))
+                                   type, &p->sh.SubroutineFunctions[j], 0))
             return;
       }
    }
@@ -4359,10 +4375,12 @@ validate_sampler_array_indexing(struct gl_context *ctx,
                            "expressions is forbidden in GLSL %s %u";
          /* Backend has indicated that it has no dynamic indexing support. */
          if (no_dynamic_indexing) {
-            linker_error(prog, msg, prog->IsES ? "ES" : "", prog->Version);
+            linker_error(prog, msg, prog->IsES ? "ES" : "",
+                         prog->data->Version);
             return false;
          } else {
-            linker_warning(prog, msg, prog->IsES ? "ES" : "", prog->Version);
+            linker_warning(prog, msg, prog->IsES ? "ES" : "",
+                           prog->data->Version);
          }
       }
    }
@@ -4372,37 +4390,36 @@ validate_sampler_array_indexing(struct gl_context *ctx,
 static void
 link_assign_subroutine_types(struct gl_shader_program *prog)
 {
-   for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
-      gl_linked_shader *sh = prog->_LinkedShaders[i];
-
-      if (sh == NULL)
-         continue;
+   unsigned mask = prog->data->linked_stages;
+   while (mask) {
+      const int i = u_bit_scan(&mask);
+      gl_program *p = prog->_LinkedShaders[i]->Program;
 
-      sh->MaxSubroutineFunctionIndex = 0;
-      foreach_in_list(ir_instruction, node, sh->ir) {
+      p->sh.MaxSubroutineFunctionIndex = 0;
+      foreach_in_list(ir_instruction, node, prog->_LinkedShaders[i]->ir) {
          ir_function *fn = node->as_function();
          if (!fn)
             continue;
 
          if (fn->is_subroutine)
-            sh->NumSubroutineUniformTypes++;
+            p->sh.NumSubroutineUniformTypes++;
 
          if (!fn->num_subroutine_types)
             continue;
 
          /* these should have been calculated earlier. */
          assert(fn->subroutine_index != -1);
-         if (sh->NumSubroutineFunctions + 1 > MAX_SUBROUTINES) {
+         if (p->sh.NumSubroutineFunctions + 1 > MAX_SUBROUTINES) {
             linker_error(prog, "Too many subroutine functions declared.\n");
             return;
          }
-         sh->SubroutineFunctions = reralloc(sh, sh->SubroutineFunctions,
+         p->sh.SubroutineFunctions = reralloc(p, p->sh.SubroutineFunctions,
                                             struct gl_subroutine_function,
-                                            sh->NumSubroutineFunctions + 1);
-         sh->SubroutineFunctions[sh->NumSubroutineFunctions].name = ralloc_strdup(sh, fn->name);
-         sh->SubroutineFunctions[sh->NumSubroutineFunctions].num_compat_types = fn->num_subroutine_types;
-         sh->SubroutineFunctions[sh->NumSubroutineFunctions].types =
-            ralloc_array(sh, const struct glsl_type *,
+                                            p->sh.NumSubroutineFunctions + 1);
+         p->sh.SubroutineFunctions[p->sh.NumSubroutineFunctions].name = ralloc_strdup(p, fn->name);
+         p->sh.SubroutineFunctions[p->sh.NumSubroutineFunctions].num_compat_types = fn->num_subroutine_types;
+         p->sh.SubroutineFunctions[p->sh.NumSubroutineFunctions].types =
+            ralloc_array(p, const struct glsl_type *,
                          fn->num_subroutine_types);
 
          /* From Section 4.4.4(Subroutine Function Layout Qualifiers) of the
@@ -4412,23 +4429,23 @@ link_assign_subroutine_types(struct gl_shader_program *prog)
           *    given a unique index, otherwise a compile or link error will be
           *    generated."
           */
-         for (unsigned j = 0; j < sh->NumSubroutineFunctions; j++) {
-            if (sh->SubroutineFunctions[j].index != -1 &&
-                sh->SubroutineFunctions[j].index == fn->subroutine_index) {
+         for (unsigned j = 0; j < p->sh.NumSubroutineFunctions; j++) {
+            if (p->sh.SubroutineFunctions[j].index != -1 &&
+                p->sh.SubroutineFunctions[j].index == fn->subroutine_index) {
                linker_error(prog, "each subroutine index qualifier in the "
                             "shader must be unique\n");
                return;
             }
          }
-         sh->SubroutineFunctions[sh->NumSubroutineFunctions].index =
+         p->sh.SubroutineFunctions[p->sh.NumSubroutineFunctions].index =
             fn->subroutine_index;
 
-         if (fn->subroutine_index > (int)sh->MaxSubroutineFunctionIndex)
-            sh->MaxSubroutineFunctionIndex = fn->subroutine_index;
+         if (fn->subroutine_index > (int)p->sh.MaxSubroutineFunctionIndex)
+            p->sh.MaxSubroutineFunctionIndex = fn->subroutine_index;
 
          for (int j = 0; j < fn->num_subroutine_types; j++)
-            sh->SubroutineFunctions[sh->NumSubroutineFunctions].types[j] = fn->subroutine_types[j];
-         sh->NumSubroutineFunctions++;
+            p->sh.SubroutineFunctions[p->sh.NumSubroutineFunctions].types[j] = fn->subroutine_types[j];
+         p->sh.NumSubroutineFunctions++;
       }
    }
 }
@@ -4504,17 +4521,26 @@ disable_varying_optimizations_for_sso(struct gl_shader_program *prog)
    }
 }
 
+static void
+link_and_validate_uniforms(struct gl_context *ctx,
+                           struct gl_shader_program *prog)
+{
+   update_array_sizes(prog);
+   link_assign_uniform_locations(prog, ctx);
+
+   link_assign_atomic_counter_resources(ctx, prog);
+   link_calculate_subroutine_compat(prog);
+   check_resources(ctx, prog);
+   check_subroutine_resources(prog);
+   check_image_resources(ctx, prog);
+   link_check_atomic_counter_resources(ctx, prog);
+}
+
 static bool
 link_varyings_and_uniforms(unsigned first, unsigned last,
-                           unsigned num_explicit_uniform_locs,
                            struct gl_context *ctx,
                            struct gl_shader_program *prog, void *mem_ctx)
 {
-   bool has_xfb_qualifiers = false;
-   unsigned num_tfeedback_decls = 0;
-   char **varying_names = NULL;
-   tfeedback_decl *tfeedback_decls = NULL;
-
    /* Mark all generic shader inputs and outputs as unpaired. */
    for (unsigned i = MESA_SHADER_VERTEX; i <= MESA_SHADER_FRAGMENT; i++) {
       if (prog->_LinkedShaders[i] != NULL) {
@@ -4542,160 +4568,22 @@ link_varyings_and_uniforms(unsigned first, unsigned last,
       return false;
    }
 
-   /* From the ARB_enhanced_layouts spec:
-    *
-    *    "If the shader used to record output variables for transform feedback
-    *    varyings uses the "xfb_buffer", "xfb_offset", or "xfb_stride" layout
-    *    qualifiers, the values specified by TransformFeedbackVaryings are
-    *    ignored, and the set of variables captured for transform feedback is
-    *    instead derived from the specified layout qualifiers."
+   /* Find the program used for xfb. Even if we don't use xfb we still want to
+    * set this so we can fill the default values for program interface query.
     */
-   for (int i = MESA_SHADER_FRAGMENT - 1; i >= 0; i--) {
-      /* Find last stage before fragment shader */
-      if (prog->_LinkedShaders[i]) {
-         has_xfb_qualifiers =
-            process_xfb_layout_qualifiers(mem_ctx, prog->_LinkedShaders[i],
-                                          &num_tfeedback_decls,
-                                          &varying_names);
-         break;
-      }
-   }
-
-   if (!has_xfb_qualifiers) {
-      num_tfeedback_decls = prog->TransformFeedback.NumVarying;
-      varying_names = prog->TransformFeedback.VaryingNames;
-   }
-
-   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 (first >= MESA_SHADER_FRAGMENT) {
-         linker_error(prog, "Transform feedback varyings specified, but "
-                      "no vertex, tessellation, or geometry shader is "
-                      "present.\n");
-         return false;
-      }
-
-      tfeedback_decls = rzalloc_array(mem_ctx, tfeedback_decl,
-                                      num_tfeedback_decls);
-      if (!parse_tfeedback_decls(ctx, prog, mem_ctx, num_tfeedback_decls,
-                                 varying_names, tfeedback_decls))
-         return false;
-   }
-
-   /* If there is no fragment shader we need to set transform feedback.
-    *
-    * For SSO we also need to assign output locations.  We assign them here
-    * because we need to do it for both single stage programs and multi stage
-    * programs.
-    */
-   if (last < MESA_SHADER_FRAGMENT &&
-       (num_tfeedback_decls != 0 || prog->SeparateShader)) {
-      const uint64_t reserved_out_slots =
-         reserved_varying_slot(prog->_LinkedShaders[last], ir_var_shader_out);
-      if (!assign_varying_locations(ctx, mem_ctx, prog,
-                                    prog->_LinkedShaders[last], NULL,
-                                    num_tfeedback_decls, tfeedback_decls,
-                                    reserved_out_slots))
-         return false;
-   }
-
-   if (last <= MESA_SHADER_FRAGMENT) {
-      /* Remove unused varyings from the first/last stage unless SSO */
-      remove_unused_shader_inputs_and_outputs(prog->SeparateShader,
-                                              prog->_LinkedShaders[first],
-                                              ir_var_shader_in);
-      remove_unused_shader_inputs_and_outputs(prog->SeparateShader,
-                                              prog->_LinkedShaders[last],
-                                              ir_var_shader_out);
-
-      /* If the program is made up of only a single stage */
-      if (first == last) {
-         gl_linked_shader *const sh = prog->_LinkedShaders[last];
-
-         do_dead_builtin_varyings(ctx, NULL, sh, 0, NULL);
-         do_dead_builtin_varyings(ctx, sh, NULL, num_tfeedback_decls,
-                                  tfeedback_decls);
-
-         if (prog->SeparateShader) {
-            const uint64_t reserved_slots =
-               reserved_varying_slot(sh, ir_var_shader_in);
-
-            /* Assign input locations for SSO, output locations are already
-             * assigned.
-             */
-            if (!assign_varying_locations(ctx, mem_ctx, prog,
-                                          NULL /* producer */,
-                                          sh /* consumer */,
-                                          0 /* num_tfeedback_decls */,
-                                          NULL /* tfeedback_decls */,
-                                          reserved_slots))
-               return false;
-         }
-      } else {
-         /* Linking the stages in the opposite order (from fragment to vertex)
-          * ensures that inter-shader outputs written to in an earlier stage
-          * are eliminated if they are (transitively) not used in a later
-          * stage.
-          */
-         int next = last;
-         for (int i = next - 1; i >= 0; i--) {
-            if (prog->_LinkedShaders[i] == NULL && i != 0)
-               continue;
-
-            gl_linked_shader *const sh_i = prog->_LinkedShaders[i];
-            gl_linked_shader *const sh_next = prog->_LinkedShaders[next];
-
-            const uint64_t reserved_out_slots =
-               reserved_varying_slot(sh_i, ir_var_shader_out);
-            const uint64_t reserved_in_slots =
-               reserved_varying_slot(sh_next, ir_var_shader_in);
-
-            do_dead_builtin_varyings(ctx, sh_i, sh_next,
-                      next == MESA_SHADER_FRAGMENT ? num_tfeedback_decls : 0,
-                      tfeedback_decls);
-
-            if (!assign_varying_locations(ctx, mem_ctx, prog, sh_i, sh_next,
-                      next == MESA_SHADER_FRAGMENT ? num_tfeedback_decls : 0,
-                      tfeedback_decls,
-                      reserved_out_slots | reserved_in_slots))
-               return false;
-
-            /* This must be done after all dead varyings are eliminated. */
-            if (sh_i != NULL) {
-               unsigned slots_used = _mesa_bitcount_64(reserved_out_slots);
-               if (!check_against_output_limit(ctx, prog, sh_i, slots_used)) {
-                  return false;
-               }
-            }
-
-            unsigned slots_used = _mesa_bitcount_64(reserved_in_slots);
-            if (!check_against_input_limit(ctx, prog, sh_next, slots_used))
-               return false;
+   prog->xfb_program = prog->_LinkedShaders[last]->Program;
+   for (int i = MESA_SHADER_GEOMETRY; i >= MESA_SHADER_VERTEX; i--) {
+      if (prog->_LinkedShaders[i] == NULL)
+         continue;
 
-            next = i;
-         }
-      }
+      prog->xfb_program = prog->_LinkedShaders[i]->Program;
+      break;
    }
 
-   if (!store_tfeedback_info(ctx, prog, num_tfeedback_decls, tfeedback_decls,
-                             has_xfb_qualifiers))
+   if (!link_varyings(prog, first, last, ctx, mem_ctx))
       return false;
 
-   update_array_sizes(prog);
-   link_assign_uniform_locations(prog, ctx, num_explicit_uniform_locs);
-   link_assign_atomic_counter_resources(ctx, prog);
-
-   link_calculate_subroutine_compat(prog);
-   check_resources(ctx, prog);
-   check_subroutine_resources(prog);
-   check_image_resources(ctx, prog);
-   link_check_atomic_counter_resources(ctx, prog);
+   link_and_validate_uniforms(ctx, prog);
 
    if (!prog->data->LinkStatus)
       return false;
@@ -4727,7 +4615,6 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
 {
    prog->data->LinkStatus = true; /* All error paths will set this to false */
    prog->data->Validated = false;
-   prog->_Used = false;
 
    /* Section 7.3 (Program Objects) of the OpenGL 4.5 Core Profile spec says:
     *
@@ -4748,8 +4635,6 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
       return;
    }
 
-   unsigned int num_explicit_uniform_locs = 0;
-
    void *mem_ctx = ralloc_context(NULL); // temporary linker context
 
    prog->ARB_fragment_coord_conventions_enable = false;
@@ -4777,7 +4662,7 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
          goto done;
       }
 
-      if (prog->Shaders[i]->info.ARB_fragment_coord_conventions_enable) {
+      if (prog->Shaders[i]->ARB_fragment_coord_conventions_enable) {
          prog->ARB_fragment_coord_conventions_enable = true;
       }
 
@@ -4795,7 +4680,7 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
       goto done;
    }
 
-   prog->Version = max_version;
+   prog->data->Version = max_version;
    prog->IsES = prog->Shaders[0]->IsES;
 
    /* Some shaders have to be linked with some other shaders present.
@@ -4889,6 +4774,7 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
          }
 
          prog->_LinkedShaders[stage] = sh;
+         prog->data->linked_stages |= 1 << stage;
       }
    }
 
@@ -4928,7 +4814,7 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
       last = i;
    }
 
-   num_explicit_uniform_locs = check_explicit_uniform_locations(ctx, prog);
+   check_explicit_uniform_locations(ctx, prog);
    link_assign_subroutine_types(prog);
 
    if (!prog->data->LinkStatus)
@@ -5012,10 +4898,18 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
          lower_tess_level(prog->_LinkedShaders[i]);
       }
 
-      while (do_common_optimization(prog->_LinkedShaders[i]->ir, true, false,
-                                    &ctx->Const.ShaderCompilerOptions[i],
-                                    ctx->Const.NativeIntegers))
-         ;
+      if (ctx->Const.GLSLOptimizeConservatively) {
+         /* Run it just once. */
+         do_common_optimization(prog->_LinkedShaders[i]->ir, true, false,
+                                &ctx->Const.ShaderCompilerOptions[i],
+                                ctx->Const.NativeIntegers);
+      } else {
+         /* Repeat it until it stops making changes. */
+         while (do_common_optimization(prog->_LinkedShaders[i]->ir, true, false,
+                                       &ctx->Const.ShaderCompilerOptions[i],
+                                       ctx->Const.NativeIntegers))
+            ;
+      }
 
       lower_const_arrays_to_uniforms(prog->_LinkedShaders[i]->ir, i);
       propagate_invariance(prog->_LinkedShaders[i]->ir);
@@ -5025,8 +4919,8 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
     * with loop induction variable. This check emits a warning or error
     * depending if backend can handle dynamic indexing.
     */
-   if ((!prog->IsES && prog->Version < 130) ||
-       (prog->IsES && prog->Version < 300)) {
+   if ((!prog->IsES && prog->data->Version < 130) ||
+       (prog->IsES && prog->data->Version < 300)) {
       if (!validate_sampler_array_indexing(ctx, prog))
          goto done;
    }
@@ -5036,8 +4930,7 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
 
    store_fragdepth_layout(prog);
 
-   if(!link_varyings_and_uniforms(first, last, num_explicit_uniform_locs, ctx,
-                                  prog, mem_ctx))
+   if(!link_varyings_and_uniforms(first, last, ctx, prog, mem_ctx))
       goto done;
 
    /* OpenGL ES < 3.1 requires that a vertex shader and a fragment shader both