mesa: use gl_program for CurrentProgram rather than gl_shader_program

This makes much more sense and should be more performant in some
critical paths such as SSO validation which is called at draw time.

Previously the CurrentProgram array could have contained multiple
pointers to the same struct which was confusing and we would often
need to fish out the information we were really after from the
gl_program anyway.

Also it was error prone to depend on the _LinkedShader array for
programs in current use because a failed linking attempt will lose
the infomation about the current program in use which is still
valid.

V2: fix validate_io() to compare linked_stages rather than the
consumer and producer to decide if we are looking at inward
facing shader interfaces which don't need validation.

Acked-by: Edward O'Callaghan <funfunctor@folklore1984.net>

To avoid build regressions the following 2 patches were squashed in to
this commit:

mesa/meta: rewrite _mesa_shader_program_use() and _mesa_program_use()

These are rewritten to do what the function name suggests, that is
_mesa_shader_program_use() sets the use of all stage and
_mesa_program_use() sets the use of a single stage.

Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Acked-by: Edward O'Callaghan <funfunctor@folklore1984.net>

mesa: update active relinked program

This likely fixes a subroutine bug were
_mesa_shader_program_init_subroutine_defaults() would never have been
called for the relinked program as we previously just set
_NEW_PROGRAM as dirty and never called the _mesa_use* functions when
linking.

Acked-by: Edward O'Callaghan <funfunctor@folklore1984.net>
diff --git a/src/mesa/main/api_validate.c b/src/mesa/main/api_validate.c
index 5f051db..6c95701 100644
--- a/src/mesa/main/api_validate.c
+++ b/src/mesa/main/api_validate.c
@@ -191,12 +191,10 @@
 
 #ifdef DEBUG
    if (ctx->_Shader->Flags & GLSL_LOG) {
-      struct gl_shader_program **shProg = ctx->_Shader->CurrentProgram;
-      gl_shader_stage i;
+      struct gl_program **prog = ctx->_Shader->CurrentProgram;
 
-      for (i = 0; i < MESA_SHADER_STAGES; i++) {
-	 if (shProg[i] == NULL || shProg[i]->_LinkedShaders[i] == NULL ||
-             shProg[i]->_LinkedShaders[i]->Program->_Used)
+      for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
+	 if (prog[i] == NULL || prog[i]->_Used)
 	    continue;
 
 	 /* This is the first time this shader is being used.
@@ -208,12 +206,12 @@
 	  * program isn't also bound to the fragment shader target we don't
 	  * want to log its fragment data.
 	  */
-	 _mesa_append_uniforms_to_file(shProg[i]->_LinkedShaders[i]->Program);
+	 _mesa_append_uniforms_to_file(prog[i]);
       }
 
-      for (i = 0; i < MESA_SHADER_STAGES; i++) {
-	 if (shProg[i] != NULL && shProg[i]->_LinkedShaders[i] != NULL)
-	    shProg[i]->_LinkedShaders[i]->Program->_Used = GL_TRUE;
+      for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
+	 if (prog[i] != NULL)
+	    prog[i]->_Used = GL_TRUE;
       }
    }
 #endif
@@ -394,17 +392,15 @@
    if (ctx->_Shader->CurrentProgram[MESA_SHADER_GEOMETRY]) {
       const GLenum geom_mode =
          ctx->_Shader->CurrentProgram[MESA_SHADER_GEOMETRY]->
-            _LinkedShaders[MESA_SHADER_GEOMETRY]->info.Geom.InputType;
-      struct gl_shader_program *tes =
+            info.gs.input_primitive;
+      struct gl_program *tes =
          ctx->_Shader->CurrentProgram[MESA_SHADER_TESS_EVAL];
       GLenum mode_before_gs = mode;
 
       if (tes) {
-         struct gl_linked_shader *tes_sh =
-            tes->_LinkedShaders[MESA_SHADER_TESS_EVAL];
-         if (tes_sh->info.TessEval.PointMode)
+         if (tes->info.tess.point_mode)
             mode_before_gs = GL_POINTS;
-         else if (tes_sh->info.TessEval.PrimitiveMode == GL_ISOLINES)
+         else if (tes->info.tess.primitive_mode == GL_ISOLINES)
             mode_before_gs = GL_LINES;
          else
             /* the GL_QUADS mode generates triangles too */
@@ -501,8 +497,7 @@
 
       if(ctx->_Shader->CurrentProgram[MESA_SHADER_GEOMETRY]) {
          switch (ctx->_Shader->CurrentProgram[MESA_SHADER_GEOMETRY]->
-                    _LinkedShaders[MESA_SHADER_GEOMETRY]->
-                    info.Geom.OutputType) {
+                    info.gs.output_primitive) {
          case GL_POINTS:
             pass = ctx->TransformFeedback.Mode == GL_POINTS;
             break;
@@ -517,13 +512,11 @@
          }
       }
       else if (ctx->_Shader->CurrentProgram[MESA_SHADER_TESS_EVAL]) {
-         struct gl_shader_program *tes =
+         struct gl_program *tes =
             ctx->_Shader->CurrentProgram[MESA_SHADER_TESS_EVAL];
-         struct gl_linked_shader *tes_sh =
-            tes->_LinkedShaders[MESA_SHADER_TESS_EVAL];
-         if (tes_sh->info.TessEval.PointMode)
+         if (tes->info.tess.point_mode)
             pass = ctx->TransformFeedback.Mode == GL_POINTS;
-         else if (tes_sh->info.TessEval.PrimitiveMode == GL_ISOLINES)
+         else if (tes->info.tess.primitive_mode == GL_ISOLINES)
             pass = ctx->TransformFeedback.Mode == GL_LINES;
          else
             pass = ctx->TransformFeedback.Mode == GL_TRIANGLES;
@@ -1296,8 +1289,6 @@
 static bool
 check_valid_to_compute(struct gl_context *ctx, const char *function)
 {
-   struct gl_shader_program *prog;
-
    if (!_mesa_has_compute_shaders(ctx)) {
       _mesa_error(ctx, GL_INVALID_OPERATION,
                   "unsupported function (%s) called",
@@ -1310,8 +1301,7 @@
     * "An INVALID_OPERATION error is generated if there is no active program
     *  for the compute shader stage."
     */
-   prog = ctx->_Shader->CurrentProgram[MESA_SHADER_COMPUTE];
-   if (prog == NULL || prog->_LinkedShaders[MESA_SHADER_COMPUTE] == NULL) {
+   if (ctx->_Shader->CurrentProgram[MESA_SHADER_COMPUTE] == NULL) {
       _mesa_error(ctx, GL_INVALID_OPERATION,
                   "%s(no active compute shader)",
                   function);
@@ -1325,7 +1315,6 @@
 _mesa_validate_DispatchCompute(struct gl_context *ctx,
                                const GLuint *num_groups)
 {
-   struct gl_shader_program *prog;
    int i;
    FLUSH_CURRENT(ctx, 0);
 
@@ -1363,8 +1352,8 @@
     * "An INVALID_OPERATION error is generated by DispatchCompute if the active
     *  program for the compute shader stage has a variable work group size."
     */
-   prog = ctx->_Shader->CurrentProgram[MESA_SHADER_COMPUTE];
-   if (prog->Comp.LocalSizeVariable) {
+   struct gl_program *prog = ctx->_Shader->CurrentProgram[MESA_SHADER_COMPUTE];
+   if (prog->info.cs.local_size_variable) {
       _mesa_error(ctx, GL_INVALID_OPERATION,
                   "glDispatchCompute(variable work group size forbidden)");
       return GL_FALSE;
@@ -1378,7 +1367,6 @@
                                            const GLuint *num_groups,
                                            const GLuint *group_size)
 {
-   struct gl_shader_program *prog;
    GLuint total_invocations = 1;
    int i;
 
@@ -1393,8 +1381,8 @@
     *  DispatchComputeGroupSizeARB if the active program for the compute
     *  shader stage has a fixed work group size."
     */
-   prog = ctx->_Shader->CurrentProgram[MESA_SHADER_COMPUTE];
-   if (!prog->Comp.LocalSizeVariable) {
+   struct gl_program *prog = ctx->_Shader->CurrentProgram[MESA_SHADER_COMPUTE];
+   if (!prog->info.cs.local_size_variable) {
       _mesa_error(ctx, GL_INVALID_OPERATION,
                   "glDispatchComputeGroupSizeARB(fixed work group size "
                   "forbidden)");
@@ -1462,7 +1450,6 @@
                         GLsizei size, const char *name)
 {
    const uint64_t end = (uint64_t) indirect + size;
-   struct gl_shader_program *prog;
 
    if (!check_valid_to_compute(ctx, name))
       return GL_FALSE;
@@ -1513,8 +1500,8 @@
     * "An INVALID_OPERATION error is generated if the active program for the
     *  compute shader stage has a variable work group size."
     */
-   prog = ctx->_Shader->CurrentProgram[MESA_SHADER_COMPUTE];
-   if (prog->Comp.LocalSizeVariable) {
+   struct gl_program *prog = ctx->_Shader->CurrentProgram[MESA_SHADER_COMPUTE];
+   if (prog->info.cs.local_size_variable) {
       _mesa_error(ctx, GL_INVALID_OPERATION,
                   "%s(variable work group size forbidden)", name);
       return GL_FALSE;
diff --git a/src/mesa/main/ff_fragment_shader.cpp b/src/mesa/main/ff_fragment_shader.cpp
index 6261b9c..b2942f1 100644
--- a/src/mesa/main/ff_fragment_shader.cpp
+++ b/src/mesa/main/ff_fragment_shader.cpp
@@ -300,9 +300,7 @@
 {
    /* _NEW_PROGRAM */
    const GLboolean vertexShader =
-      (ctx->_Shader->CurrentProgram[MESA_SHADER_VERTEX] &&
-       ctx->_Shader->CurrentProgram[MESA_SHADER_VERTEX]->data->LinkStatus &&
-       ctx->_Shader->CurrentProgram[MESA_SHADER_VERTEX]->_LinkedShaders[MESA_SHADER_VERTEX]);
+      ctx->_Shader->CurrentProgram[MESA_SHADER_VERTEX] != NULL;
    const GLboolean vertexProgram = ctx->VertexProgram._Enabled;
    GLbitfield fp_inputs = 0x0;
 
@@ -366,7 +364,7 @@
        * validation (see additional comments in state.c).
        */
       if (vertexShader)
-         vprog = ctx->_Shader->CurrentProgram[MESA_SHADER_VERTEX]->_LinkedShaders[MESA_SHADER_VERTEX]->Program;
+         vprog = ctx->_Shader->CurrentProgram[MESA_SHADER_VERTEX];
       else
          vprog = ctx->VertexProgram.Current;
 
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index 7784d25..c733911 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -2907,7 +2907,7 @@
     *
     * There is a separate program set for each shader stage.
     */
-   struct gl_shader_program *CurrentProgram[MESA_SHADER_STAGES];
+   struct gl_program *CurrentProgram[MESA_SHADER_STAGES];
 
    struct gl_program *_CurrentFragmentProgram;
 
diff --git a/src/mesa/main/pipelineobj.c b/src/mesa/main/pipelineobj.c
index e777f99..ec5df89 100644
--- a/src/mesa/main/pipelineobj.c
+++ b/src/mesa/main/pipelineobj.c
@@ -61,7 +61,7 @@
    _mesa_reference_program(ctx, &obj->_CurrentFragmentProgram, NULL);
 
    for (i = 0; i < MESA_SHADER_STAGES; i++)
-      _mesa_reference_shader_program(ctx, &obj->CurrentProgram[i], NULL);
+      _mesa_reference_program(ctx, &obj->CurrentProgram[i], NULL);
 
    _mesa_reference_shader_program(ctx, &obj->ActiveProgram, NULL);
    mtx_destroy(&obj->Mutex);
@@ -218,6 +218,18 @@
    }
 }
 
+static void
+use_program_stage(struct gl_context *ctx, GLenum type,
+                  struct gl_shader_program *shProg,
+                  struct gl_pipeline_object *pipe) {
+   gl_shader_stage stage = _mesa_shader_enum_to_shader_stage(type);
+   struct gl_program *prog = NULL;
+   if (shProg && shProg->_LinkedShaders[stage])
+      prog = shProg->_LinkedShaders[stage]->Program;
+
+   _mesa_use_program(ctx, stage, prog, pipe);
+}
+
 /**
  * Bound program to severals stages of the pipeline
  */
@@ -325,22 +337,22 @@
     *     configured for the indicated shader stages."
     */
    if ((stages & GL_VERTEX_SHADER_BIT) != 0)
-      _mesa_use_shader_program(ctx, GL_VERTEX_SHADER, shProg, pipe);
+      use_program_stage(ctx, GL_VERTEX_SHADER, shProg, pipe);
 
    if ((stages & GL_FRAGMENT_SHADER_BIT) != 0)
-      _mesa_use_shader_program(ctx, GL_FRAGMENT_SHADER, shProg, pipe);
+      use_program_stage(ctx, GL_FRAGMENT_SHADER, shProg, pipe);
 
    if ((stages & GL_GEOMETRY_SHADER_BIT) != 0)
-      _mesa_use_shader_program(ctx, GL_GEOMETRY_SHADER, shProg, pipe);
+      use_program_stage(ctx, GL_GEOMETRY_SHADER, shProg, pipe);
 
    if ((stages & GL_TESS_CONTROL_SHADER_BIT) != 0)
-      _mesa_use_shader_program(ctx, GL_TESS_CONTROL_SHADER, shProg, pipe);
+      use_program_stage(ctx, GL_TESS_CONTROL_SHADER, shProg, pipe);
 
    if ((stages & GL_TESS_EVALUATION_SHADER_BIT) != 0)
-      _mesa_use_shader_program(ctx, GL_TESS_EVALUATION_SHADER, shProg, pipe);
+      use_program_stage(ctx, GL_TESS_EVALUATION_SHADER, shProg, pipe);
 
    if ((stages & GL_COMPUTE_SHADER_BIT) != 0)
-      _mesa_use_shader_program(ctx, GL_COMPUTE_SHADER, shProg, pipe);
+      use_program_stage(ctx, GL_COMPUTE_SHADER, shProg, pipe);
 
    pipe->Validated = false;
 }
@@ -469,11 +481,9 @@
       FLUSH_VERTICES(ctx, _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS);
 
       for (i = 0; i < MESA_SHADER_STAGES; i++) {
-         if (ctx->_Shader->CurrentProgram[i]) {
-            struct gl_linked_shader *sh =
-               ctx->_Shader->CurrentProgram[i]->_LinkedShaders[i];
-            if (sh)
-               _mesa_program_init_subroutine_defaults(ctx, sh->Program);
+         struct gl_program *prog = ctx->_Shader->CurrentProgram[i];
+         if (prog) {
+            _mesa_program_init_subroutine_defaults(ctx, prog);
          }
       }
    }
@@ -659,35 +669,35 @@
       return;
    case GL_VERTEX_SHADER:
       *params = pipe->CurrentProgram[MESA_SHADER_VERTEX]
-         ? pipe->CurrentProgram[MESA_SHADER_VERTEX]->Name : 0;
+         ? pipe->CurrentProgram[MESA_SHADER_VERTEX]->Id : 0;
       return;
    case GL_TESS_EVALUATION_SHADER:
       if (!has_tess)
          break;
       *params = pipe->CurrentProgram[MESA_SHADER_TESS_EVAL]
-         ? pipe->CurrentProgram[MESA_SHADER_TESS_EVAL]->Name : 0;
+         ? pipe->CurrentProgram[MESA_SHADER_TESS_EVAL]->Id : 0;
       return;
    case GL_TESS_CONTROL_SHADER:
       if (!has_tess)
          break;
       *params = pipe->CurrentProgram[MESA_SHADER_TESS_CTRL]
-         ? pipe->CurrentProgram[MESA_SHADER_TESS_CTRL]->Name : 0;
+         ? pipe->CurrentProgram[MESA_SHADER_TESS_CTRL]->Id : 0;
       return;
    case GL_GEOMETRY_SHADER:
       if (!has_gs)
          break;
       *params = pipe->CurrentProgram[MESA_SHADER_GEOMETRY]
-         ? pipe->CurrentProgram[MESA_SHADER_GEOMETRY]->Name : 0;
+         ? pipe->CurrentProgram[MESA_SHADER_GEOMETRY]->Id : 0;
       return;
    case GL_FRAGMENT_SHADER:
       *params = pipe->CurrentProgram[MESA_SHADER_FRAGMENT]
-         ? pipe->CurrentProgram[MESA_SHADER_FRAGMENT]->Name : 0;
+         ? pipe->CurrentProgram[MESA_SHADER_FRAGMENT]->Id : 0;
       return;
    case GL_COMPUTE_SHADER:
       if (!_mesa_has_compute_shaders(ctx))
          break;
       *params = pipe->CurrentProgram[MESA_SHADER_COMPUTE]
-         ? pipe->CurrentProgram[MESA_SHADER_COMPUTE]->Name : 0;
+         ? pipe->CurrentProgram[MESA_SHADER_COMPUTE]->Id : 0;
       return;
    default:
       break;
@@ -703,23 +713,22 @@
  */
 static bool
 program_stages_all_active(struct gl_pipeline_object *pipe,
-                          const struct gl_shader_program *prog)
+                          const struct gl_program *prog)
 {
-   unsigned i;
    bool status = true;
 
    if (!prog)
       return true;
 
-   for (i = 0; i < MESA_SHADER_STAGES; i++) {
-      if (prog->_LinkedShaders[i]) {
-         if (pipe->CurrentProgram[i]) {
-            if (prog->Name != pipe->CurrentProgram[i]->Name) {
-               status = false;
-            }
-         } else {
+   unsigned mask = prog->sh.data->linked_stages;
+   while (mask) {
+      const int i = u_bit_scan(&mask);
+      if (pipe->CurrentProgram[i]) {
+         if (prog->Id != pipe->CurrentProgram[i]->Id) {
             status = false;
          }
+      } else {
+         status = false;
       }
    }
 
@@ -727,7 +736,7 @@
       pipe->InfoLog = ralloc_asprintf(pipe,
                                       "Program %d is not active for all "
                                       "shaders that was linked",
-                                      prog->Name);
+                                      prog->Id);
    }
 
    return status;
@@ -742,7 +751,7 @@
     * sequence of unrelated programs or empty stages.
     */
    for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
-      struct gl_shader_program *cur = pipe->CurrentProgram[i];
+      struct gl_program *cur = pipe->CurrentProgram[i];
 
       /* Empty stages anywhere in the pipe are OK.  Also we can be confident
        * that if the linked_stages mask matches we are looking at the same
@@ -751,7 +760,7 @@
        * programs with the sames stages linked are not active for all linked
        * stages.
        */
-      if (!cur || cur->data->linked_stages == prev_linked_stages)
+      if (!cur || cur->sh.data->linked_stages == prev_linked_stages)
          continue;
 
       if (prev_linked_stages) {
@@ -762,7 +771,7 @@
             return true;
       }
 
-      prev_linked_stages = cur->data->linked_stages;
+      prev_linked_stages = cur->sh.data->linked_stages;
    }
 
    return false;
@@ -861,11 +870,12 @@
     *           PROGRAM_SEPARABLE parameter set to FALSE.
     */
    for (i = 0; i < MESA_SHADER_STAGES; i++) {
-      if (pipe->CurrentProgram[i] && !pipe->CurrentProgram[i]->SeparateShader) {
+      if (pipe->CurrentProgram[i] &&
+          !pipe->CurrentProgram[i]->info.separate_shader) {
          pipe->InfoLog = ralloc_asprintf(pipe,
                                          "Program %d was relinked without "
                                          "PROGRAM_SEPARABLE state",
-                                         pipe->CurrentProgram[i]->Name);
+                                         pipe->CurrentProgram[i]->Id);
          return GL_FALSE;
       }
    }
diff --git a/src/mesa/main/shader_query.cpp b/src/mesa/main/shader_query.cpp
index 4010737..f465b39 100644
--- a/src/mesa/main/shader_query.cpp
+++ b/src/mesa/main/shader_query.cpp
@@ -1373,24 +1373,21 @@
 }
 
 static bool
-validate_io(struct gl_shader_program *producer,
-            struct gl_shader_program *consumer,
-            gl_shader_stage producer_stage,
-            gl_shader_stage consumer_stage)
+validate_io(struct gl_program *producer, struct gl_program *consumer)
 {
-   if (producer == consumer)
+   if (producer->sh.data->linked_stages == consumer->sh.data->linked_stages)
       return true;
 
    const bool nonarray_stage_to_array_stage =
-      producer_stage != MESA_SHADER_TESS_CTRL &&
-      (consumer_stage == MESA_SHADER_GEOMETRY ||
-       consumer_stage == MESA_SHADER_TESS_CTRL ||
-       consumer_stage == MESA_SHADER_TESS_EVAL);
+      producer->info.stage != MESA_SHADER_TESS_CTRL &&
+      (consumer->info.stage == MESA_SHADER_GEOMETRY ||
+       consumer->info.stage == MESA_SHADER_TESS_CTRL ||
+       consumer->info.stage == MESA_SHADER_TESS_EVAL);
 
    bool valid = true;
 
    gl_shader_variable const **outputs =
-      (gl_shader_variable const **) calloc(producer->data->NumProgramResourceList,
+      (gl_shader_variable const **) calloc(producer->sh.data->NumProgramResourceList,
                                            sizeof(gl_shader_variable *));
    if (outputs == NULL)
       return false;
@@ -1413,9 +1410,9 @@
     * some output that did not have an input.
     */
    unsigned num_outputs = 0;
-   for (unsigned i = 0; i < producer->data->NumProgramResourceList; i++) {
+   for (unsigned i = 0; i < producer->sh.data->NumProgramResourceList; i++) {
       struct gl_program_resource *res =
-         &producer->data->ProgramResourceList[i];
+         &producer->sh.data->ProgramResourceList[i];
 
       if (res->Type != GL_PROGRAM_OUTPUT)
          continue;
@@ -1434,9 +1431,9 @@
    }
 
    unsigned match_index = 0;
-   for (unsigned i = 0; i < consumer->data->NumProgramResourceList; i++) {
+   for (unsigned i = 0; i < consumer->sh.data->NumProgramResourceList; i++) {
       struct gl_program_resource *res =
-         &consumer->data->ProgramResourceList[i];
+         &consumer->sh.data->ProgramResourceList[i];
 
       if (res->Type != GL_PROGRAM_INPUT)
          continue;
@@ -1592,30 +1589,27 @@
 extern "C" bool
 _mesa_validate_pipeline_io(struct gl_pipeline_object *pipeline)
 {
-   struct gl_shader_program **shProg =
-      (struct gl_shader_program **) pipeline->CurrentProgram;
+   struct gl_program **prog = (struct gl_program **) pipeline->CurrentProgram;
 
    /* Find first active stage in pipeline. */
    unsigned idx, prev = 0;
    for (idx = 0; idx < ARRAY_SIZE(pipeline->CurrentProgram); idx++) {
-      if (shProg[idx]) {
+      if (prog[idx]) {
          prev = idx;
          break;
       }
    }
 
    for (idx = prev + 1; idx < ARRAY_SIZE(pipeline->CurrentProgram); idx++) {
-      if (shProg[idx]) {
+      if (prog[idx]) {
          /* Pipeline might include both non-compute and a compute program, do
           * not attempt to validate varyings between non-compute and compute
           * stage.
           */
-         if (shProg[idx]->_LinkedShaders[idx]->Stage == MESA_SHADER_COMPUTE)
+         if (prog[idx]->info.stage == MESA_SHADER_COMPUTE)
             break;
 
-         if (!validate_io(shProg[prev], shProg[idx],
-                          shProg[prev]->_LinkedShaders[prev]->Stage,
-                          shProg[idx]->_LinkedShaders[idx]->Stage))
+         if (!validate_io(prog[prev], prog[idx]))
             return false;
 
          prev = idx;
diff --git a/src/mesa/main/shaderapi.c b/src/mesa/main/shaderapi.c
index c87ba09..8ad4e36 100644
--- a/src/mesa/main/shaderapi.c
+++ b/src/mesa/main/shaderapi.c
@@ -156,10 +156,8 @@
 void
 _mesa_free_shader_state(struct gl_context *ctx)
 {
-   int i;
-   for (i = 0; i < MESA_SHADER_STAGES; i++) {
-      _mesa_reference_shader_program(ctx, &ctx->Shader.CurrentProgram[i],
-                                     NULL);
+   for (int i = 0; i < MESA_SHADER_STAGES; i++) {
+      _mesa_reference_program(ctx, &ctx->Shader.CurrentProgram[i], NULL);
    }
    _mesa_reference_program(ctx, &ctx->Shader._CurrentFragmentProgram, NULL);
    _mesa_reference_shader_program(ctx, &ctx->Shader.ActiveProgram, NULL);
@@ -1100,7 +1098,8 @@
    unsigned programs_in_use = 0;
    if (ctx->_Shader)
       for (unsigned stage = 0; stage < MESA_SHADER_STAGES; stage++) {
-         if (ctx->_Shader->CurrentProgram[stage] == shProg) {
+         if (ctx->_Shader->CurrentProgram[stage] &&
+             ctx->_Shader->CurrentProgram[stage]->Id == shProg->Name) {
             programs_in_use |= 1 << stage;
          }
    }
@@ -1119,7 +1118,15 @@
     *     is attached."
     */
    if (shProg->data->LinkStatus && programs_in_use) {
-      ctx->NewState |= _NEW_PROGRAM;
+      while (programs_in_use) {
+         const int stage = u_bit_scan(&programs_in_use);
+
+         struct gl_program *prog = NULL;
+         if (shProg->_LinkedShaders[stage])
+            prog = shProg->_LinkedShaders[stage]->Program;
+
+         _mesa_use_program(ctx, stage, prog, ctx->_Shader);
+      }
    }
 
    /* Capture .shader_test files. */
@@ -1232,27 +1239,17 @@
 
 
 static void
-use_shader_program(struct gl_context *ctx, gl_shader_stage stage,
-                   struct gl_shader_program *shProg,
-                   struct gl_pipeline_object *shTarget)
+use_program(struct gl_context *ctx, gl_shader_stage stage,
+            struct gl_program *new_prog, struct gl_pipeline_object *shTarget)
 {
-   struct gl_shader_program **target;
+   struct gl_program **target;
 
    target = &shTarget->CurrentProgram[stage];
-   if ((shProg != NULL) && (shProg->_LinkedShaders[stage] == NULL))
-      shProg = NULL;
-
-   if (shProg) {
-      for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
-         struct gl_linked_shader *sh = shProg->_LinkedShaders[i];
-         if (!sh)
-            continue;
-
-         _mesa_program_init_subroutine_defaults(ctx, sh->Program);
-      }
+   if (new_prog) {
+      _mesa_program_init_subroutine_defaults(ctx, new_prog);
    }
 
-   if (*target != shProg) {
+   if (*target != new_prog) {
       /* Program is current, flush it */
       if (shTarget == ctx->_Shader) {
          FLUSH_VERTICES(ctx, _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS);
@@ -1271,10 +1268,7 @@
          /* Empty for now. */
          break;
       case MESA_SHADER_FRAGMENT:
-         if (*target != NULL &&
-             ((*target)->_LinkedShaders[MESA_SHADER_FRAGMENT] &&
-              (*target)->_LinkedShaders[MESA_SHADER_FRAGMENT]->Program ==
-              ctx->_Shader->_CurrentFragmentProgram)) {
+         if (*target == ctx->_Shader->_CurrentFragmentProgram) {
 	    _mesa_reference_program(ctx,
                                     &ctx->_Shader->_CurrentFragmentProgram,
                                     NULL);
@@ -1282,7 +1276,7 @@
 	 break;
       }
 
-      _mesa_reference_shader_program(ctx, target, shProg);
+      _mesa_reference_program(ctx, target, new_prog);
       return;
    }
 }
@@ -1292,11 +1286,15 @@
  * Use the named shader program for subsequent rendering.
  */
 void
-_mesa_use_program(struct gl_context *ctx, struct gl_shader_program *shProg)
+_mesa_use_shader_program(struct gl_context *ctx,
+                         struct gl_shader_program *shProg)
 {
-   int i;
-   for (i = 0; i < MESA_SHADER_STAGES; i++)
-      use_shader_program(ctx, i, shProg, &ctx->Shader);
+   for (int i = 0; i < MESA_SHADER_STAGES; i++) {
+      struct gl_program *new_prog = NULL;
+      if (shProg && shProg->_LinkedShaders[i])
+         new_prog = shProg->_LinkedShaders[i]->Program;
+      use_program(ctx, i, new_prog, &ctx->Shader);
+   }
    _mesa_active_program(ctx, shProg, "glUseProgram");
 }
 
@@ -1893,10 +1891,10 @@
       /* Attach shader state to the binding point */
       _mesa_reference_pipeline_object(ctx, &ctx->_Shader, &ctx->Shader);
       /* Update the program */
-      _mesa_use_program(ctx, shProg);
+      _mesa_use_shader_program(ctx, shProg);
    } else {
       /* Must be done first: detach the progam */
-      _mesa_use_program(ctx, shProg);
+      _mesa_use_shader_program(ctx, shProg);
       /* Unattach shader_state binding point */
       _mesa_reference_pipeline_object(ctx, &ctx->_Shader, ctx->Pipeline.Default);
       /* If a pipeline was bound, rebind it */
@@ -2178,12 +2176,11 @@
 
 
 void
-_mesa_use_shader_program(struct gl_context *ctx, GLenum type,
-                         struct gl_shader_program *shProg,
-                         struct gl_pipeline_object *shTarget)
+_mesa_use_program(struct gl_context *ctx, gl_shader_stage stage,
+                  struct gl_program *prog,
+                  struct gl_pipeline_object *shTarget)
 {
-   gl_shader_stage stage = _mesa_shader_enum_to_shader_stage(type);
-   use_shader_program(ctx, stage, shProg, shTarget);
+   use_program(ctx, stage, prog, shTarget);
 }
 
 
@@ -2612,8 +2609,6 @@
 {
    GET_CURRENT_CONTEXT(ctx);
    const char *api_name = "glUniformSubroutinesuiv";
-   struct gl_shader_program *shProg;
-   struct gl_linked_shader *sh;
    gl_shader_stage stage;
    int i;
 
@@ -2628,19 +2623,12 @@
    }
 
    stage = _mesa_shader_enum_to_shader_stage(shadertype);
-   shProg = ctx->_Shader->CurrentProgram[stage];
-   if (!shProg) {
+   struct gl_program *p = ctx->_Shader->CurrentProgram[stage];
+   if (!p) {
       _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
       return;
    }
 
-   sh = shProg->_LinkedShaders[stage];
-   if (!sh) {
-      _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
-      return;
-   }
-
-   struct gl_program *p = shProg->_LinkedShaders[stage]->Program;
    if (count != p->sh.NumSubroutineUniformRemapTable) {
       _mesa_error(ctx, GL_INVALID_VALUE, "%s", api_name);
       return;
@@ -2697,8 +2685,6 @@
 {
    GET_CURRENT_CONTEXT(ctx);
    const char *api_name = "glGetUniformSubroutineuiv";
-   struct gl_shader_program *shProg;
-   struct gl_linked_shader *sh;
    gl_shader_stage stage;
 
    if (!_mesa_has_ARB_shader_subroutine(ctx)) {
@@ -2712,19 +2698,12 @@
    }
 
    stage = _mesa_shader_enum_to_shader_stage(shadertype);
-   shProg = ctx->_Shader->CurrentProgram[stage];
-   if (!shProg) {
+   struct gl_program *p = ctx->_Shader->CurrentProgram[stage];
+   if (!p) {
       _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
       return;
    }
 
-   sh = shProg->_LinkedShaders[stage];
-   if (!sh) {
-      _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
-      return;
-   }
-
-   struct gl_program *p = sh->Program;
    if (location >= p->sh.NumSubroutineUniformRemapTable) {
       _mesa_error(ctx, GL_INVALID_VALUE, "%s", api_name);
       return;
@@ -2890,10 +2869,9 @@
 _mesa_shader_write_subroutine_indices(struct gl_context *ctx,
                                       gl_shader_stage stage)
 {
-   if (ctx->_Shader->CurrentProgram[stage] &&
-       ctx->_Shader->CurrentProgram[stage]->_LinkedShaders[stage])
+   if (ctx->_Shader->CurrentProgram[stage])
       _mesa_shader_write_subroutine_index(ctx,
-                                          ctx->_Shader->CurrentProgram[stage]->_LinkedShaders[stage]->Program);
+                                          ctx->_Shader->CurrentProgram[stage]);
 }
 
 void
diff --git a/src/mesa/main/shaderapi.h b/src/mesa/main/shaderapi.h
index 06de11f..a89dbfb 100644
--- a/src/mesa/main/shaderapi.h
+++ b/src/mesa/main/shaderapi.h
@@ -51,7 +51,8 @@
                   GLsizei *length, const GLchar *src);
 
 extern void
-_mesa_use_program(struct gl_context *ctx, struct gl_shader_program *shProg);
+_mesa_use_shader_program(struct gl_context *ctx,
+                         struct gl_shader_program *shProg);
 
 extern void
 _mesa_active_program(struct gl_context *ctx, struct gl_shader_program *shProg,
@@ -213,9 +214,9 @@
 _mesa_ProgramParameteri(GLuint program, GLenum pname, GLint value);
 
 void
-_mesa_use_shader_program(struct gl_context *ctx, GLenum type,
-                         struct gl_shader_program *shProg,
-                         struct gl_pipeline_object *shTarget);
+_mesa_use_program(struct gl_context *ctx, gl_shader_stage stage,
+                  struct gl_program *prog,
+                  struct gl_pipeline_object *shTarget);
 
 extern void
 _mesa_copy_linked_program_data(const struct gl_shader_program *src,
diff --git a/src/mesa/main/state.c b/src/mesa/main/state.c
index 2a926a1..5cb58a4 100644
--- a/src/mesa/main/state.c
+++ b/src/mesa/main/state.c
@@ -95,17 +95,17 @@
 static GLbitfield
 update_program(struct gl_context *ctx)
 {
-   const struct gl_shader_program *vsProg =
+   struct gl_program *vsProg =
       ctx->_Shader->CurrentProgram[MESA_SHADER_VERTEX];
-   const struct gl_shader_program *tcsProg =
+   struct gl_program *tcsProg =
       ctx->_Shader->CurrentProgram[MESA_SHADER_TESS_CTRL];
-   const struct gl_shader_program *tesProg =
+   struct gl_program *tesProg =
       ctx->_Shader->CurrentProgram[MESA_SHADER_TESS_EVAL];
-   const struct gl_shader_program *gsProg =
+   struct gl_program *gsProg =
       ctx->_Shader->CurrentProgram[MESA_SHADER_GEOMETRY];
-   struct gl_shader_program *fsProg =
+   struct gl_program *fsProg =
       ctx->_Shader->CurrentProgram[MESA_SHADER_FRAGMENT];
-   const struct gl_shader_program *csProg =
+   struct gl_program *csProg =
       ctx->_Shader->CurrentProgram[MESA_SHADER_COMPUTE];
    const struct gl_program *prevVP = ctx->VertexProgram._Current;
    const struct gl_program *prevFP = ctx->FragmentProgram._Current;
@@ -132,13 +132,11 @@
     * come up, or matter.
     */
 
-   if (fsProg && fsProg->data->LinkStatus
-       && fsProg->_LinkedShaders[MESA_SHADER_FRAGMENT]) {
+   if (fsProg) {
       /* Use GLSL fragment shader */
       _mesa_reference_program(ctx, &ctx->_Shader->_CurrentFragmentProgram,
-                              fsProg->_LinkedShaders[MESA_SHADER_FRAGMENT]->Program);
-      _mesa_reference_program(ctx, &ctx->FragmentProgram._Current,
-                              fsProg->_LinkedShaders[MESA_SHADER_FRAGMENT]->Program);
+                              fsProg);
+      _mesa_reference_program(ctx, &ctx->FragmentProgram._Current, fsProg);
       _mesa_reference_program(ctx, &ctx->FragmentProgram._TexEnvProgram,
                               NULL);
    }
@@ -179,32 +177,26 @@
 			      NULL);
    }
 
-   if (gsProg && gsProg->data->LinkStatus
-       && gsProg->_LinkedShaders[MESA_SHADER_GEOMETRY]) {
+   if (gsProg) {
       /* Use GLSL geometry shader */
-      _mesa_reference_program(ctx, &ctx->GeometryProgram._Current,
-                              gsProg->_LinkedShaders[MESA_SHADER_GEOMETRY]->Program);
+      _mesa_reference_program(ctx, &ctx->GeometryProgram._Current, gsProg);
    } else {
       /* No geometry program */
       _mesa_reference_program(ctx, &ctx->GeometryProgram._Current, NULL);
    }
 
-   if (tesProg && tesProg->data->LinkStatus
-       && tesProg->_LinkedShaders[MESA_SHADER_TESS_EVAL]) {
+   if (tesProg) {
       /* Use GLSL tessellation evaluation shader */
-      _mesa_reference_program(ctx, &ctx->TessEvalProgram._Current,
-         tesProg->_LinkedShaders[MESA_SHADER_TESS_EVAL]->Program);
+      _mesa_reference_program(ctx, &ctx->TessEvalProgram._Current, tesProg);
    }
    else {
       /* No tessellation evaluation program */
       _mesa_reference_program(ctx, &ctx->TessEvalProgram._Current, NULL);
    }
 
-   if (tcsProg && tcsProg->data->LinkStatus
-       && tcsProg->_LinkedShaders[MESA_SHADER_TESS_CTRL]) {
+   if (tcsProg) {
       /* Use GLSL tessellation control shader */
-      _mesa_reference_program(ctx, &ctx->TessCtrlProgram._Current,
-          tcsProg->_LinkedShaders[MESA_SHADER_TESS_CTRL]->Program);
+      _mesa_reference_program(ctx, &ctx->TessCtrlProgram._Current, tcsProg);
    }
    else {
       /* No tessellation control program */
@@ -215,11 +207,9 @@
     * _mesa_get_fixed_func_vertex_program() needs to know active
     * fragprog inputs.
     */
-   if (vsProg && vsProg->data->LinkStatus
-       && vsProg->_LinkedShaders[MESA_SHADER_VERTEX]) {
+   if (vsProg) {
       /* Use GLSL vertex shader */
-      _mesa_reference_program(ctx, &ctx->VertexProgram._Current,
-                              vsProg->_LinkedShaders[MESA_SHADER_VERTEX]->Program);
+      _mesa_reference_program(ctx, &ctx->VertexProgram._Current, vsProg);
    }
    else if (ctx->VertexProgram._Enabled) {
       /* Use user-defined vertex program */
@@ -238,11 +228,9 @@
       _mesa_reference_program(ctx, &ctx->VertexProgram._Current, NULL);
    }
 
-   if (csProg && csProg->data->LinkStatus
-       && csProg->_LinkedShaders[MESA_SHADER_COMPUTE]) {
+   if (csProg) {
       /* Use GLSL compute shader */
-      _mesa_reference_program(ctx, &ctx->ComputeProgram._Current,
-                              csProg->_LinkedShaders[MESA_SHADER_COMPUTE]->Program);
+      _mesa_reference_program(ctx, &ctx->ComputeProgram._Current, csProg);
    } else {
       /* no compute program */
       _mesa_reference_program(ctx, &ctx->ComputeProgram._Current, NULL);
diff --git a/src/mesa/main/texstate.c b/src/mesa/main/texstate.c
index 4676d4a..be73fc3 100644
--- a/src/mesa/main/texstate.c
+++ b/src/mesa/main/texstate.c
@@ -700,9 +700,8 @@
    BITSET_DECLARE(enabled_texture_units, MAX_COMBINED_TEXTURE_IMAGE_UNITS);
 
    for (i = 0; i < MESA_SHADER_STAGES; i++) {
-      if (ctx->_Shader->CurrentProgram[i] &&
-          ctx->_Shader->CurrentProgram[i]->data->LinkStatus) {
-         prog[i] = ctx->_Shader->CurrentProgram[i]->_LinkedShaders[i]->Program;
+      if (ctx->_Shader->CurrentProgram[i]) {
+         prog[i] = ctx->_Shader->CurrentProgram[i];
       } else {
          if (i == MESA_SHADER_FRAGMENT && ctx->FragmentProgram._Enabled)
             prog[i] = ctx->FragmentProgram.Current;
diff --git a/src/mesa/main/transformfeedback.c b/src/mesa/main/transformfeedback.c
index 771223a..06fa56a 100644
--- a/src/mesa/main/transformfeedback.c
+++ b/src/mesa/main/transformfeedback.c
@@ -390,7 +390,7 @@
    int i;
    for (i = MESA_SHADER_GEOMETRY; i >= MESA_SHADER_VERTEX; i--) {
       if (ctx->_Shader->CurrentProgram[i] != NULL)
-         return ctx->_Shader->CurrentProgram[i]->_LinkedShaders[i]->Program;
+         return ctx->_Shader->CurrentProgram[i];
    }
    return NULL;
 }
diff --git a/src/mesa/main/uniform_query.cpp b/src/mesa/main/uniform_query.cpp
index f505986..d5a2d0f 100644
--- a/src/mesa/main/uniform_query.cpp
+++ b/src/mesa/main/uniform_query.cpp
@@ -1163,27 +1163,22 @@
 
    GLbitfield mask;
    GLbitfield TexturesUsed[MAX_COMBINED_TEXTURE_IMAGE_UNITS];
-   struct gl_linked_shader *shader;
    unsigned active_samplers = 0;
-   const struct gl_shader_program **shProg =
-      (const struct gl_shader_program **) pipeline->CurrentProgram;
+   const struct gl_program **prog =
+      (const struct gl_program **) pipeline->CurrentProgram;
 
 
    memset(TexturesUsed, 0, sizeof(TexturesUsed));
 
    for (unsigned idx = 0; idx < ARRAY_SIZE(pipeline->CurrentProgram); idx++) {
-      if (!shProg[idx])
+      if (!prog[idx])
          continue;
 
-      shader = shProg[idx]->_LinkedShaders[idx];
-      if (!shader || !shader->Program)
-         continue;
-
-      mask = shader->Program->SamplersUsed;
+      mask = prog[idx]->SamplersUsed;
       while (mask) {
          const int s = u_bit_scan(&mask);
-         GLuint unit = shader->Program->SamplerUnits[s];
-         GLuint tgt = shader->Program->sh.SamplerTargets[s];
+         GLuint unit = prog[idx]->SamplerUnits[s];
+         GLuint tgt = prog[idx]->sh.SamplerTargets[s];
 
          /* FIXME: Samplers are initialized to 0 and Mesa doesn't do a
           * great job of eliminating unused uniforms currently so for now
@@ -1197,14 +1192,14 @@
                ralloc_asprintf(pipeline,
                      "Program %d: "
                      "Texture unit %d is accessed with 2 different types",
-                     shProg[idx]->Name, unit);
+                     prog[idx]->Id, unit);
             return false;
          }
 
          TexturesUsed[unit] |= (1 << tgt);
       }
 
-      active_samplers += shader->Program->info.num_textures;
+      active_samplers += prog[idx]->info.num_textures;
    }
 
    if (active_samplers > MAX_COMBINED_TEXTURE_IMAGE_UNITS) {