mesa: add 'no_error' parameter to blit_framebuffer()
[mesa.git] / src / mesa / main / shaderapi.c
index f9106140770dd7d0717bdfa72bc1c130c8917919..9f0122ad704ba5ae8678128b3909f81195fd5849 100644 (file)
@@ -77,14 +77,14 @@ _mesa_get_shader_flags(void)
          flags |= GLSL_DUMP;
       if (strstr(env, "log"))
          flags |= GLSL_LOG;
+      if (strstr(env, "cache_fb"))
+         flags |= GLSL_CACHE_FALLBACK;
+      if (strstr(env, "cache_info"))
+         flags |= GLSL_CACHE_INFO;
       if (strstr(env, "nopvert"))
          flags |= GLSL_NOP_VERT;
       if (strstr(env, "nopfrag"))
          flags |= GLSL_NOP_FRAG;
-      if (strstr(env, "nopt"))
-         flags |= GLSL_NO_OPT;
-      else if (strstr(env, "opt"))
-         flags |= GLSL_OPT;
       if (strstr(env, "uniform"))
          flags |= GLSL_UNIFORMS;
       if (strstr(env, "useprog"))
@@ -140,8 +140,6 @@ _mesa_init_shader_state(struct gl_context *ctx)
 
    /* Extended for ARB_separate_shader_objects */
    ctx->Shader.RefCount = 1;
-   mtx_init(&ctx->Shader.Mutex, mtx_plain);
-
    ctx->TessCtrlProgram.patch_vertices = 3;
    for (i = 0; i < 4; ++i)
       ctx->TessCtrlProgram.patch_default_outer_level[i] = 1.0;
@@ -156,20 +154,15 @@ _mesa_init_shader_state(struct gl_context *ctx)
 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_shader_program(ctx, &ctx->Shader._CurrentFragmentProgram,
-                                 NULL);
    _mesa_reference_shader_program(ctx, &ctx->Shader.ActiveProgram, NULL);
 
    /* Extended for ARB_separate_shader_objects */
    _mesa_reference_pipeline_object(ctx, &ctx->_Shader, NULL);
 
    assert(ctx->Shader.RefCount == 1);
-   mtx_destroy(&ctx->Shader.Mutex);
 }
 
 
@@ -637,7 +630,7 @@ get_programiv(struct gl_context *ctx, GLuint program, GLenum pname,
       *params = shProg->DeletePending;
       return;
    case GL_LINK_STATUS:
-      *params = shProg->data->LinkStatus;
+      *params = shProg->data->LinkStatus ? GL_TRUE : GL_FALSE;
       return;
    case GL_VALIDATE_STATUS:
       *params = shProg->data->Validated;
@@ -722,7 +715,7 @@ get_programiv(struct gl_context *ctx, GLuint program, GLenum pname,
          break;
       if (check_gs_query(ctx, shProg)) {
          *params = shProg->_LinkedShaders[MESA_SHADER_GEOMETRY]->
-            info.Geom.VerticesOut;
+            Program->info.gs.vertices_out;
       }
       return;
    case GL_GEOMETRY_SHADER_INVOCATIONS:
@@ -730,7 +723,7 @@ get_programiv(struct gl_context *ctx, GLuint program, GLenum pname,
          break;
       if (check_gs_query(ctx, shProg)) {
          *params = shProg->_LinkedShaders[MESA_SHADER_GEOMETRY]->
-            info.Geom.Invocations;
+            Program->info.gs.invocations;
       }
       return;
    case GL_GEOMETRY_INPUT_TYPE:
@@ -738,7 +731,7 @@ get_programiv(struct gl_context *ctx, GLuint program, GLenum pname,
          break;
       if (check_gs_query(ctx, shProg)) {
          *params = shProg->_LinkedShaders[MESA_SHADER_GEOMETRY]->
-            info.Geom.InputType;
+            Program->info.gs.input_primitive;
       }
       return;
    case GL_GEOMETRY_OUTPUT_TYPE:
@@ -746,7 +739,7 @@ get_programiv(struct gl_context *ctx, GLuint program, GLenum pname,
          break;
       if (check_gs_query(ctx, shProg)) {
          *params = shProg->_LinkedShaders[MESA_SHADER_GEOMETRY]->
-            info.Geom.OutputType;
+            Program->info.gs.output_primitive;
       }
       return;
    case GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH: {
@@ -810,12 +803,13 @@ get_programiv(struct gl_context *ctx, GLuint program, GLenum pname,
          return;
       }
       for (i = 0; i < 3; i++)
-         params[i] = shProg->Comp.LocalSize[i];
+         params[i] = shProg->_LinkedShaders[MESA_SHADER_COMPUTE]->
+            Program->info.cs.local_size[i];
       return;
    }
    case GL_PROGRAM_SEPARABLE:
       /* If the program has not been linked, return initial value 0. */
-      *params = (shProg->data->LinkStatus == GL_FALSE) ? 0 : shProg->SeparateShader;
+      *params = (shProg->data->LinkStatus == linking_failure) ? 0 : shProg->SeparateShader;
       return;
 
    /* ARB_tessellation_shader */
@@ -824,7 +818,7 @@ get_programiv(struct gl_context *ctx, GLuint program, GLenum pname,
          break;
       if (check_tcs_query(ctx, shProg)) {
          *params = shProg->_LinkedShaders[MESA_SHADER_TESS_CTRL]->
-            info.TessCtrl.VerticesOut;
+            Program->info.tess.tcs_vertices_out;
       }
       return;
    case GL_TESS_GEN_MODE:
@@ -832,15 +826,29 @@ get_programiv(struct gl_context *ctx, GLuint program, GLenum pname,
          break;
       if (check_tes_query(ctx, shProg)) {
          *params = shProg->_LinkedShaders[MESA_SHADER_TESS_EVAL]->
-            info.TessEval.PrimitiveMode;
+            Program->info.tess.primitive_mode;
       }
       return;
    case GL_TESS_GEN_SPACING:
       if (!has_tess)
          break;
       if (check_tes_query(ctx, shProg)) {
-         *params = shProg->_LinkedShaders[MESA_SHADER_TESS_EVAL]->
-            info.TessEval.Spacing;
+         const struct gl_linked_shader *tes =
+            shProg->_LinkedShaders[MESA_SHADER_TESS_EVAL];
+         switch (tes->Program->info.tess.spacing) {
+         case TESS_SPACING_EQUAL:
+            *params = GL_EQUAL;
+            break;
+         case TESS_SPACING_FRACTIONAL_ODD:
+            *params = GL_FRACTIONAL_ODD;
+            break;
+         case TESS_SPACING_FRACTIONAL_EVEN:
+            *params = GL_FRACTIONAL_EVEN;
+            break;
+         case TESS_SPACING_UNSPECIFIED:
+            *params = 0;
+            break;
+         }
       }
       return;
    case GL_TESS_GEN_VERTEX_ORDER:
@@ -848,7 +856,7 @@ get_programiv(struct gl_context *ctx, GLuint program, GLenum pname,
          break;
       if (check_tes_query(ctx, shProg)) {
          *params = shProg->_LinkedShaders[MESA_SHADER_TESS_EVAL]->
-            info.TessEval.VertexOrder;
+            Program->info.tess.ccw ? GL_CCW : GL_CW;
          }
       return;
    case GL_TESS_GEN_POINT_MODE:
@@ -856,7 +864,7 @@ get_programiv(struct gl_context *ctx, GLuint program, GLenum pname,
          break;
       if (check_tes_query(ctx, shProg)) {
          *params = shProg->_LinkedShaders[MESA_SHADER_TESS_EVAL]->
-            info.TessEval.PointMode;
+            Program->info.tess.point_mode ? GL_TRUE : GL_FALSE;
       }
       return;
    default:
@@ -889,7 +897,7 @@ get_shaderiv(struct gl_context *ctx, GLuint name, GLenum pname, GLint *params)
       *params = shader->DeletePending;
       break;
    case GL_COMPILE_STATUS:
-      *params = shader->CompileStatus;
+      *params = shader->CompileStatus ? GL_TRUE : GL_FALSE;
       break;
    case GL_INFO_LOG_LENGTH:
       *params = (shader->InfoLog && shader->InfoLog[0] != '\0') ?
@@ -989,9 +997,18 @@ shader_source(struct gl_shader *sh, const GLchar *source)
 {
    assert(sh);
 
-   /* free old shader source string and install new one */
-   free((void *)sh->Source);
-   sh->Source = source;
+   if (sh->CompileStatus == compile_skipped && !sh->FallbackSource) {
+      /* If shader was previously compiled back-up the source in case of cache
+       * fallback.
+       */
+      sh->FallbackSource = sh->Source;
+      sh->Source = source;
+   } else {
+      /* free old shader source string and install new one */
+      free((void *)sh->Source);
+      sh->Source = source;
+   }
+
 #ifdef DEBUG
    sh->SourceChecksum = util_hash_crc32(sh->Source, strlen(sh->Source));
 #endif
@@ -1011,7 +1028,7 @@ _mesa_compile_shader(struct gl_context *ctx, struct gl_shader *sh)
       /* If the user called glCompileShader without first calling
        * glShaderSource, we should fail to compile, but not raise a GL_ERROR.
        */
-      sh->CompileStatus = GL_FALSE;
+      sh->CompileStatus = compile_failure;
    } else {
       if (ctx->_Shader->Flags & GLSL_DUMP) {
          _mesa_log("GLSL source for %s shader %d:\n",
@@ -1022,7 +1039,7 @@ _mesa_compile_shader(struct gl_context *ctx, struct gl_shader *sh)
       /* this call will set the shader->CompileStatus field to indicate if
        * compilation was successful.
        */
-      _mesa_glsl_compile_shader(ctx, sh, false, false);
+      _mesa_glsl_compile_shader(ctx, sh, false, false, false);
 
       if (ctx->_Shader->Flags & GLSL_LOG) {
          _mesa_write_shader_to_file(sh);
@@ -1084,10 +1101,40 @@ _mesa_link_program(struct gl_context *ctx, struct gl_shader_program *shProg)
       return;
    }
 
-   FLUSH_VERTICES(ctx, _NEW_PROGRAM);
+   unsigned programs_in_use = 0;
+   if (ctx->_Shader)
+      for (unsigned stage = 0; stage < MESA_SHADER_STAGES; stage++) {
+         if (ctx->_Shader->CurrentProgram[stage] &&
+             ctx->_Shader->CurrentProgram[stage]->Id == shProg->Name) {
+            programs_in_use |= 1 << stage;
+         }
+   }
 
+   FLUSH_VERTICES(ctx, 0);
    _mesa_glsl_link_shader(ctx, shProg);
 
+   /* From section 7.3 (Program Objects) of the OpenGL 4.5 spec:
+    *
+    *    "If LinkProgram or ProgramBinary successfully re-links a program
+    *     object that is active for any shader stage, then the newly generated
+    *     executable code will be installed as part of the current rendering
+    *     state for all shader stages where the program is active.
+    *     Additionally, the newly generated executable code is made part of
+    *     the state of any program pipeline for all stages where the program
+    *     is attached."
+    */
+   if (shProg->data->LinkStatus && programs_in_use) {
+      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, shProg, prog, ctx->_Shader);
+      }
+   }
+
    /* Capture .shader_test files. */
    const char *capture_path = _mesa_get_shader_capture_path();
    if (shProg->Name != 0 && shProg->Name != ~0 && capture_path != NULL) {
@@ -1116,7 +1163,7 @@ _mesa_link_program(struct gl_context *ctx, struct gl_shader_program *shProg)
       ralloc_free(filename);
    }
 
-   if (shProg->data->LinkStatus == GL_FALSE &&
+   if (shProg->data->LinkStatus == linking_failure &&
        (ctx->_Shader->Flags & GLSL_REPORT_ERRORS)) {
       _mesa_debug(ctx, "Error linking program %u:\n%s\n",
                   shProg->Name, shProg->data->InfoLog);
@@ -1197,62 +1244,19 @@ _mesa_active_program(struct gl_context *ctx, struct gl_shader_program *shProg,
 }
 
 
-static void
-use_shader_program(struct gl_context *ctx, gl_shader_stage stage,
-                   struct gl_shader_program *shProg,
-                   struct gl_pipeline_object *shTarget)
-{
-   struct gl_shader_program **target;
-
-   target = &shTarget->CurrentProgram[stage];
-   if ((shProg != NULL) && (shProg->_LinkedShaders[stage] == NULL))
-      shProg = NULL;
-
-   if (shProg)
-      _mesa_shader_program_init_subroutine_defaults(ctx, shProg);
-
-   if (*target != shProg) {
-      /* Program is current, flush it */
-      if (shTarget == ctx->_Shader) {
-         FLUSH_VERTICES(ctx, _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS);
-      }
-
-      /* If the shader is also bound as the current rendering shader, unbind
-       * it from that binding point as well.  This ensures that the correct
-       * semantics of glDeleteProgram are maintained.
-       */
-      switch (stage) {
-      case MESA_SHADER_VERTEX:
-      case MESA_SHADER_TESS_CTRL:
-      case MESA_SHADER_TESS_EVAL:
-      case MESA_SHADER_GEOMETRY:
-      case MESA_SHADER_COMPUTE:
-         /* Empty for now. */
-         break;
-      case MESA_SHADER_FRAGMENT:
-         if (*target == ctx->_Shader->_CurrentFragmentProgram) {
-           _mesa_reference_shader_program(ctx,
-                                           &ctx->_Shader->_CurrentFragmentProgram,
-                                          NULL);
-        }
-        break;
-      }
-
-      _mesa_reference_shader_program(ctx, target, shProg);
-      return;
-   }
-}
-
-
 /**
  * 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;
+      _mesa_use_program(ctx, i, shProg, new_prog, &ctx->Shader);
+   }
    _mesa_active_program(ctx, shProg, "glUseProgram");
 }
 
@@ -1596,7 +1600,7 @@ _mesa_LinkProgram(GLuint programObj)
                                                            "glLinkProgram"));
 }
 
-#if defined(HAVE_SHA1)
+#ifdef ENABLE_SHADER_CACHE
 /**
  * Generate a SHA-1 hash value string for given source string.
  */
@@ -1707,7 +1711,8 @@ read_shader(const gl_shader_stage stage, const char *source)
 
    return buffer;
 }
-#endif /* HAVE_SHA1 */
+
+#endif /* ENABLE_SHADER_CACHE */
 
 /**
  * Called via glShaderSource() and glShaderSourceARB() API functions.
@@ -1724,10 +1729,6 @@ _mesa_ShaderSource(GLuint shaderObj, GLsizei count,
    GLcharARB *source;
    struct gl_shader *sh;
 
-#if defined(HAVE_SHA1)
-   GLcharARB *replacement;
-#endif /* HAVE_SHA1 */
-
    sh = _mesa_lookup_shader_err(ctx, shaderObj, "glShaderSourceARB");
    if (!sh)
       return;
@@ -1783,7 +1784,9 @@ _mesa_ShaderSource(GLuint shaderObj, GLsizei count,
    source[totalLength - 1] = '\0';
    source[totalLength - 2] = '\0';
 
-#if defined(HAVE_SHA1)
+#ifdef ENABLE_SHADER_CACHE
+   GLcharARB *replacement;
+
    /* Dump original shader source to MESA_SHADER_DUMP_PATH and replace
     * if corresponding entry found from MESA_SHADER_READ_PATH.
     */
@@ -1794,7 +1797,7 @@ _mesa_ShaderSource(GLuint shaderObj, GLsizei count,
       free(source);
       source = replacement;
    }
-#endif /* HAVE_SHA1 */
+#endif /* ENABLE_SHADER_CACHE */
 
    shader_source(sh, source);
 
@@ -1802,40 +1805,44 @@ _mesa_ShaderSource(GLuint shaderObj, GLsizei count,
 }
 
 
-void GLAPIENTRY
-_mesa_UseProgram(GLuint program)
+static ALWAYS_INLINE void
+use_program(GLuint program, bool no_error)
 {
    GET_CURRENT_CONTEXT(ctx);
-   struct gl_shader_program *shProg;
+   struct gl_shader_program *shProg = NULL;
 
    if (MESA_VERBOSE & VERBOSE_API)
       _mesa_debug(ctx, "glUseProgram %u\n", program);
 
-   if (_mesa_is_xfb_active_and_unpaused(ctx)) {
-      _mesa_error(ctx, GL_INVALID_OPERATION,
-                  "glUseProgram(transform feedback active)");
-      return;
-   }
-
-   if (program) {
-      shProg = _mesa_lookup_shader_program_err(ctx, program, "glUseProgram");
-      if (!shProg) {
-         return;
+   if (no_error) {
+      if (program) {
+         shProg = _mesa_lookup_shader_program(ctx, program);
       }
-      if (!shProg->data->LinkStatus) {
+   } else {
+      if (_mesa_is_xfb_active_and_unpaused(ctx)) {
          _mesa_error(ctx, GL_INVALID_OPERATION,
-                     "glUseProgram(program %u not linked)", program);
+                     "glUseProgram(transform feedback active)");
          return;
       }
 
-      /* debug code */
-      if (ctx->_Shader->Flags & GLSL_USE_PROG) {
-         print_shader_info(shProg);
+      if (program) {
+         shProg =
+            _mesa_lookup_shader_program_err(ctx, program, "glUseProgram");
+         if (!shProg)
+            return;
+
+         if (!shProg->data->LinkStatus) {
+            _mesa_error(ctx, GL_INVALID_OPERATION,
+                        "glUseProgram(program %u not linked)", program);
+            return;
+         }
+
+         /* debug code */
+         if (ctx->_Shader->Flags & GLSL_USE_PROG) {
+            print_shader_info(shProg);
+         }
       }
    }
-   else {
-      shProg = NULL;
-   }
 
    /* The ARB_separate_shader_object spec says:
     *
@@ -1846,24 +1853,42 @@ _mesa_UseProgram(GLuint program)
     *     object (section 2.14.PPO), the program bound to the appropriate
     *     stage of the pipeline object is considered current."
     */
-   if (program) {
+   if (shProg) {
       /* 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);
+      _mesa_reference_pipeline_object(ctx, &ctx->_Shader,
+                                      ctx->Pipeline.Default);
       /* If a pipeline was bound, rebind it */
       if (ctx->Pipeline.Current) {
-         _mesa_BindProgramPipeline(ctx->Pipeline.Current->Name);
+         if (no_error)
+            _mesa_BindProgramPipeline_no_error(ctx->Pipeline.Current->Name);
+         else
+            _mesa_BindProgramPipeline(ctx->Pipeline.Current->Name);
       }
    }
 }
 
 
+void GLAPIENTRY
+_mesa_UseProgram_no_error(GLuint program)
+{
+   use_program(program, true);
+}
+
+
+void GLAPIENTRY
+_mesa_UseProgram(GLuint program)
+{
+   use_program(program, false);
+}
+
+
 void GLAPIENTRY
 _mesa_ValidateProgram(GLuint program)
 {
@@ -2051,7 +2076,7 @@ _mesa_ProgramBinary(GLuint program, GLenum binaryFormat,
     * Since any value of binaryFormat passed "is not one of those specified as
     * allowable for [this] command, an INVALID_ENUM error is generated."
     */
-   shProg->data->LinkStatus = GL_FALSE;
+   shProg->data->LinkStatus = linking_failure;
    _mesa_error(ctx, GL_INVALID_ENUM, "glProgramBinary");
 }
 
@@ -2135,12 +2160,30 @@ invalid_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_shader_program *shProg, 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);
+   struct gl_program **target;
+
+   target = &shTarget->CurrentProgram[stage];
+   if (prog) {
+      _mesa_program_init_subroutine_defaults(ctx, prog);
+   }
+
+   if (*target != prog) {
+      /* Program is current, flush it */
+      if (shTarget == ctx->_Shader) {
+         FLUSH_VERTICES(ctx, _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS);
+      }
+
+      _mesa_reference_shader_program(ctx,
+                                     &shTarget->ReferencedPrograms[stage],
+                                     shProg);
+      _mesa_reference_program(ctx, target, prog);
+      return;
+   }
+
 }
 
 
@@ -2159,51 +2202,21 @@ _mesa_copy_linked_program_data(const struct gl_shader_program *src,
 
    struct gl_program *dst = dst_sh->Program;
 
-   dst->info.num_images = dst_sh->NumImages;
    dst->info.separate_shader = src->SeparateShader;
 
    switch (dst_sh->Stage) {
-   case MESA_SHADER_VERTEX:
-      dst->ClipDistanceArraySize = src->Vert.ClipDistanceArraySize;
-      dst->CullDistanceArraySize = src->Vert.CullDistanceArraySize;
-      break;
-   case MESA_SHADER_TESS_CTRL: {
-      dst->info.tcs.vertices_out = dst_sh->info.TessCtrl.VerticesOut;
-      break;
-   }
-   case MESA_SHADER_TESS_EVAL: {
-      dst->info.tes.primitive_mode = dst_sh->info.TessEval.PrimitiveMode;
-      dst->info.tes.spacing = dst_sh->info.TessEval.Spacing;
-      dst->info.tes.vertex_order = dst_sh->info.TessEval.VertexOrder;
-      dst->info.tes.point_mode = dst_sh->info.TessEval.PointMode;
-      dst->ClipDistanceArraySize = src->TessEval.ClipDistanceArraySize;
-      dst->CullDistanceArraySize = src->TessEval.CullDistanceArraySize;
-      break;
-   }
    case MESA_SHADER_GEOMETRY: {
       dst->info.gs.vertices_in = src->Geom.VerticesIn;
-      dst->info.gs.vertices_out = dst_sh->info.Geom.VerticesOut;
-      dst->info.gs.invocations = dst_sh->info.Geom.Invocations;
-      dst->info.gs.input_primitive = dst_sh->info.Geom.InputType;
-      dst->info.gs.output_primitive = dst_sh->info.Geom.OutputType;
-      dst->ClipDistanceArraySize = src->Geom.ClipDistanceArraySize;
-      dst->CullDistanceArraySize = src->Geom.CullDistanceArraySize;
       dst->info.gs.uses_end_primitive = src->Geom.UsesEndPrimitive;
       dst->info.gs.uses_streams = src->Geom.UsesStreams;
       break;
    }
    case MESA_SHADER_FRAGMENT: {
       dst->info.fs.depth_layout = src->FragDepthLayout;
-      dst->info.fs.early_fragment_tests = dst_sh->info.EarlyFragmentTests;
-      dst->info.fs.inner_coverage = dst_sh->info.InnerCoverage;
-      dst->info.fs.post_depth_coverage = dst_sh->info.PostDepthCoverage;
       break;
    }
    case MESA_SHADER_COMPUTE: {
-      for (int i = 0; i < 3; i++)
-         dst->info.cs.local_size[i] = src->Comp.LocalSize[i];
       dst->info.cs.shared_size = src->Comp.SharedSize;
-      dst->info.cs.local_size_variable = src->Comp.LocalSizeVariable;
       break;
    }
    default:
@@ -2257,7 +2270,7 @@ _mesa_CreateShaderProgramv(GLenum type, GLsizei count,
            /* Possibly... */
            if (active-user-defined-varyings-in-linked-program) {
               append-error-to-info-log;
-               shProg->data->LinkStatus = GL_FALSE;
+               shProg->data->LinkStatus = linking_failure;
            }
 #endif
         }
@@ -2341,11 +2354,6 @@ _mesa_GetSubroutineUniformLocation(GLuint program, GLenum shadertype,
    GLenum resource_type;
    gl_shader_stage stage;
 
-   if (!_mesa_has_ARB_shader_subroutine(ctx)) {
-      _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
-      return -1;
-   }
-
    if (!_mesa_validate_shader_target(ctx, shadertype)) {
       _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
       return -1;
@@ -2376,11 +2384,6 @@ _mesa_GetSubroutineIndex(GLuint program, GLenum shadertype,
    GLenum resource_type;
    gl_shader_stage stage;
 
-   if (!_mesa_has_ARB_shader_subroutine(ctx)) {
-      _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
-      return -1;
-   }
-
    if (!_mesa_validate_shader_target(ctx, shadertype)) {
       _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
       return -1;
@@ -2420,11 +2423,6 @@ _mesa_GetActiveSubroutineUniformiv(GLuint program, GLenum shadertype,
    GLenum resource_type;
    int count, i, j;
 
-   if (!_mesa_has_ARB_shader_subroutine(ctx)) {
-      _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
-      return;
-   }
-
    if (!_mesa_validate_shader_target(ctx, shadertype)) {
       _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
       return;
@@ -2507,11 +2505,6 @@ _mesa_GetActiveSubroutineUniformName(GLuint program, GLenum shadertype,
    GLenum resource_type;
    gl_shader_stage stage;
 
-   if (!_mesa_has_ARB_shader_subroutine(ctx)) {
-      _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
-      return;
-   }
-
    if (!_mesa_validate_shader_target(ctx, shadertype)) {
       _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
       return;
@@ -2546,11 +2539,6 @@ _mesa_GetActiveSubroutineName(GLuint program, GLenum shadertype,
    GLenum resource_type;
    gl_shader_stage stage;
 
-   if (!_mesa_has_ARB_shader_subroutine(ctx)) {
-      _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
-      return;
-   }
-
    if (!_mesa_validate_shader_target(ctx, shadertype)) {
       _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
       return;
@@ -2577,35 +2565,21 @@ _mesa_UniformSubroutinesuiv(GLenum shadertype, GLsizei count,
 {
    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;
 
-   if (!_mesa_has_ARB_shader_subroutine(ctx)) {
-      _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
-      return;
-   }
-
    if (!_mesa_validate_shader_target(ctx, shadertype)) {
       _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
       return;
    }
 
    stage = _mesa_shader_enum_to_shader_stage(shadertype);
-   shProg = ctx->_Shader->CurrentProgram[stage];
-   if (!shProg) {
-      _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
-      return;
-   }
-
-   sh = shProg->_LinkedShaders[stage];
-   if (!sh) {
+   struct gl_program *p = ctx->_Shader->CurrentProgram[stage];
+   if (!p) {
       _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;
@@ -2662,34 +2636,20 @@ _mesa_GetUniformSubroutineuiv(GLenum shadertype, GLint location,
 {
    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)) {
-      _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
-      return;
-   }
-
    if (!_mesa_validate_shader_target(ctx, shadertype)) {
       _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
       return;
    }
 
    stage = _mesa_shader_enum_to_shader_stage(shadertype);
-   shProg = ctx->_Shader->CurrentProgram[stage];
-   if (!shProg) {
-      _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
-      return;
-   }
-
-   sh = shProg->_LinkedShaders[stage];
-   if (!sh) {
+   struct gl_program *p = ctx->_Shader->CurrentProgram[stage];
+   if (!p) {
       _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;
@@ -2709,11 +2669,6 @@ _mesa_GetProgramStageiv(GLuint program, GLenum shadertype,
    struct gl_linked_shader *sh;
    gl_shader_stage stage;
 
-   if (!_mesa_has_ARB_shader_subroutine(ctx)) {
-      _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
-      return;
-   }
-
    if (!_mesa_validate_shader_target(ctx, shadertype)) {
       _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
       return;
@@ -2855,13 +2810,12 @@ void
 _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]);
 }
 
-static void
+void
 _mesa_program_init_subroutine_defaults(struct gl_context *ctx,
                                        struct gl_program *p)
 {
@@ -2883,20 +2837,3 @@ _mesa_program_init_subroutine_defaults(struct gl_context *ctx,
       binding->IndexPtr[i] = find_compat_subroutine(p, uni->type);
    }
 }
-
-void
-_mesa_shader_program_init_subroutine_defaults(struct gl_context *ctx,
-                                              struct gl_shader_program *shProg)
-{
-   int i;
-
-   if (!shProg)
-      return;
-
-   for (i = 0; i < MESA_SHADER_STAGES; i++) {
-      if (!shProg->_LinkedShaders[i])
-         continue;
-
-      _mesa_program_init_subroutine_defaults(ctx, shProg->_LinkedShaders[i]->Program);
-   }
-}