[Mesa-dev] [PATCH 02/70] mesa/glsl: move subroutine metadata to gl_program

Timothy Arceri timothy.arceri at collabora.com
Tue Dec 20 10:37:12 UTC 2016


This will allow us to store gl_program rather than gl_shader_program
as the current program perstage which allows us to simplify code
that makes use of the CurrentProgram list.
---
 src/compiler/glsl/link_uniforms.cpp |  24 ++++----
 src/compiler/glsl/linker.cpp        |  89 ++++++++++++++---------------
 src/mesa/main/mtypes.h              |  41 +++++++-------
 src/mesa/main/pipelineobj.c         |  10 +++-
 src/mesa/main/shader_query.cpp      |   8 +--
 src/mesa/main/shaderapi.c           | 108 +++++++++++++++++-------------------
 src/mesa/main/shaderapi.h           |   2 +-
 7 files changed, 141 insertions(+), 141 deletions(-)

diff --git a/src/compiler/glsl/link_uniforms.cpp b/src/compiler/glsl/link_uniforms.cpp
index 396b445..256afa3 100644
--- a/src/compiler/glsl/link_uniforms.cpp
+++ b/src/compiler/glsl/link_uniforms.cpp
@@ -624,7 +624,7 @@ private:
          uniform->opaque[shader_type].index = this->next_subroutine;
          uniform->opaque[shader_type].active = true;
 
-         prog->_LinkedShaders[shader_type]->NumSubroutineUniforms++;
+         prog->_LinkedShaders[shader_type]->Program->sh.NumSubroutineUniforms++;
 
          /* Increment the subroutine index by 1 for non-arrays and by the
           * number of array elements for arrays.
@@ -1148,7 +1148,7 @@ link_setup_uniform_remap_tables(struct gl_context *ctx,
       unsigned mask = prog->data->linked_stages;
       while (mask) {
          const int j = u_bit_scan(&mask);
-         struct gl_linked_shader *sh = prog->_LinkedShaders[j];
+         struct gl_program *p = prog->_LinkedShaders[j]->Program;
 
          if (!prog->data->UniformStorage[i].opaque[j].active)
             continue;
@@ -1157,9 +1157,9 @@ link_setup_uniform_remap_tables(struct gl_context *ctx,
          for (unsigned k = 0; k < entries; k++) {
             unsigned element_loc =
                prog->data->UniformStorage[i].remap_location + k;
-            assert(sh->SubroutineUniformRemapTable[element_loc] ==
+            assert(p->sh.SubroutineUniformRemapTable[element_loc] ==
                    INACTIVE_UNIFORM_EXPLICIT_LOCATION);
-            sh->SubroutineUniformRemapTable[element_loc] =
+            p->sh.SubroutineUniformRemapTable[element_loc] =
                &prog->data->UniformStorage[i];
          }
       }
@@ -1180,24 +1180,24 @@ link_setup_uniform_remap_tables(struct gl_context *ctx,
       unsigned mask = prog->data->linked_stages;
       while (mask) {
          const int j = u_bit_scan(&mask);
-         struct gl_linked_shader *sh = prog->_LinkedShaders[j];
+         struct gl_program *p = prog->_LinkedShaders[j]->Program;
 
          if (!prog->data->UniformStorage[i].opaque[j].active)
             continue;
 
-         sh->SubroutineUniformRemapTable =
-            reralloc(sh,
-                     sh->SubroutineUniformRemapTable,
+         p->sh.SubroutineUniformRemapTable =
+            reralloc(p,
+                     p->sh.SubroutineUniformRemapTable,
                      gl_uniform_storage *,
-                     sh->NumSubroutineUniformRemapTable + entries);
+                     p->sh.NumSubroutineUniformRemapTable + entries);
 
          for (unsigned k = 0; k < entries; k++) {
-            sh->SubroutineUniformRemapTable[sh->NumSubroutineUniformRemapTable + k] =
+            p->sh.SubroutineUniformRemapTable[p->sh.NumSubroutineUniformRemapTable + k] =
                &prog->data->UniformStorage[i];
          }
          prog->data->UniformStorage[i].remap_location =
-            sh->NumSubroutineUniformRemapTable;
-         sh->NumSubroutineUniformRemapTable += entries;
+            p->sh.NumSubroutineUniformRemapTable;
+         p->sh.NumSubroutineUniformRemapTable += entries;
       }
    }
 }
diff --git a/src/compiler/glsl/linker.cpp b/src/compiler/glsl/linker.cpp
index 05f8ddb..efc2760 100644
--- a/src/compiler/glsl/linker.cpp
+++ b/src/compiler/glsl/linker.cpp
@@ -3157,24 +3157,24 @@ link_calculate_subroutine_compat(struct gl_shader_program *prog)
    unsigned mask = prog->data->linked_stages;
    while (mask) {
       const int i = u_bit_scan(&mask);
-      struct gl_linked_shader *sh = prog->_LinkedShaders[i];
+      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;
 
          int count = 0;
-         if (sh->NumSubroutineFunctions == 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++;
@@ -3193,11 +3193,12 @@ check_subroutine_resources(struct gl_shader_program *prog)
    unsigned mask = prog->data->linked_stages;
    while (mask) {
       const int i = u_bit_scan(&mask);
-      struct gl_linked_shader *sh = prog->_LinkedShaders[i];
+      struct gl_program *p = prog->_LinkedShaders[i]->Program;
 
-      if (sh->NumSubroutineUniformRemapTable > MAX_SUBROUTINE_UNIFORM_LOCATIONS)
+      if (p->sh.NumSubroutineUniformRemapTable > MAX_SUBROUTINE_UNIFORM_LOCATIONS) {
          linker_error(prog, "Too many %s shader subroutine uniforms\n",
                       _mesa_shader_stage_to_string(i));
+      }
    }
 }
 /**
@@ -3318,36 +3319,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
@@ -3364,7 +3365,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;
@@ -3395,9 +3396,9 @@ check_explicit_uniform_locations(struct gl_context *ctx,
    unsigned mask = prog->data->linked_stages;
    while (mask) {
       const int i = u_bit_scan(&mask);
-      struct gl_linked_shader *sh = prog->_LinkedShaders[i];
+      struct gl_program *p = prog->_LinkedShaders[i]->Program;
 
-      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;
@@ -3405,7 +3406,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);
@@ -4343,12 +4344,12 @@ build_program_resource_list(struct gl_context *ctx,
    unsigned mask = shProg->data->linked_stages;
    while (mask) {
       const int i = u_bit_scan(&mask);
-      struct gl_linked_shader *sh = shProg->_LinkedShaders[i];
+      struct gl_program *p = shProg->_LinkedShaders[i]->Program;
 
       GLuint type = _mesa_shader_stage_to_subroutine((gl_shader_stage)i);
-      for (unsigned j = 0; j < sh->NumSubroutineFunctions; j++) {
+      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;
       }
    }
@@ -4398,33 +4399,33 @@ link_assign_subroutine_types(struct gl_shader_program *prog)
    unsigned mask = prog->data->linked_stages;
    while (mask) {
       const int i = u_bit_scan(&mask);
-      gl_linked_shader *sh = prog->_LinkedShaders[i];
+      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
@@ -4434,23 +4435,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++;
       }
    }
 }
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index ac4cac0..1da76b8 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -1947,6 +1947,26 @@ struct gl_program
       /** Fields used by GLSL programs */
       struct {
          struct gl_active_atomic_buffer **AtomicBuffers;
+
+         /**
+          * Number of types for subroutine uniforms.
+          */
+         GLuint NumSubroutineUniformTypes;
+
+         /**
+          * Subroutine uniform remap table
+          * based on the program level uniform remap table.
+          */
+         GLuint NumSubroutineUniforms; /* non-sparse total */
+         GLuint NumSubroutineUniformRemapTable;
+         struct gl_uniform_storage **SubroutineUniformRemapTable;
+
+         /**
+          * Num of subroutine functions for this stage and storage for them.
+          */
+         GLuint NumSubroutineFunctions;
+         GLuint MaxSubroutineFunctionIndex;
+         struct gl_subroutine_function *SubroutineFunctions;
       } sh;
 
       /** ARB assembly-style program fields */
@@ -2364,27 +2384,6 @@ struct gl_linked_shader
     */
    GLuint NumImages;
 
-   /**
-     * Number of types for subroutine uniforms.
-     */
-   GLuint NumSubroutineUniformTypes;
-
-   /**
-     * Subroutine uniform remap table
-     * based on the program level uniform remap table.
-     */
-   GLuint NumSubroutineUniforms; /* non-sparse total */
-   GLuint NumSubroutineUniformRemapTable;
-   struct gl_uniform_storage **SubroutineUniformRemapTable;
-
-   /**
-    * Num of subroutine functions for this stage
-    * and storage for them.
-    */
-   GLuint NumSubroutineFunctions;
-   GLuint MaxSubroutineFunctionIndex;
-   struct gl_subroutine_function *SubroutineFunctions;
-
    struct gl_shader_info info;
 };
 
diff --git a/src/mesa/main/pipelineobj.c b/src/mesa/main/pipelineobj.c
index 5fc2808..282071a 100644
--- a/src/mesa/main/pipelineobj.c
+++ b/src/mesa/main/pipelineobj.c
@@ -468,8 +468,14 @@ _mesa_bind_pipeline(struct gl_context *ctx,
 
       FLUSH_VERTICES(ctx, _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS);
 
-      for (i = 0; i < MESA_SHADER_STAGES; i++)
-         _mesa_shader_program_init_subroutine_defaults(ctx, ctx->_Shader->CurrentProgram[i]);
+      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_shader_program_init_subroutine_defaults(ctx, sh->Program);
+         }
+      }
    }
 }
 
diff --git a/src/mesa/main/shader_query.cpp b/src/mesa/main/shader_query.cpp
index 1d1616b..2f15773 100644
--- a/src/mesa/main/shader_query.cpp
+++ b/src/mesa/main/shader_query.cpp
@@ -1248,7 +1248,7 @@ _mesa_program_resource_prop(struct gl_shader_program *shProg,
       return 1;
    case GL_COMPATIBLE_SUBROUTINES: {
       const struct gl_uniform_storage *uni;
-      struct gl_linked_shader *sh;
+      struct gl_program *p;
       unsigned count, i;
       int j;
 
@@ -1261,10 +1261,10 @@ _mesa_program_resource_prop(struct gl_shader_program *shProg,
          goto invalid_operation;
       uni = RESOURCE_UNI(res);
 
-      sh = shProg->_LinkedShaders[_mesa_shader_stage_from_subroutine_uniform(res->Type)];
+      p = shProg->_LinkedShaders[_mesa_shader_stage_from_subroutine_uniform(res->Type)]->Program;
       count = 0;
-      for (i = 0; i < sh->NumSubroutineFunctions; i++) {
-         struct gl_subroutine_function *fn = &sh->SubroutineFunctions[i];
+      for (i = 0; i < p->sh.NumSubroutineFunctions; i++) {
+         struct gl_subroutine_function *fn = &p->sh.SubroutineFunctions[i];
          for (j = 0; j < fn->num_compat_types; j++) {
             if (fn->types[j] == uni->type) {
                val[count++] = i;
diff --git a/src/mesa/main/shaderapi.c b/src/mesa/main/shaderapi.c
index 10cee7b..4fe26fd 100644
--- a/src/mesa/main/shaderapi.c
+++ b/src/mesa/main/shaderapi.c
@@ -1208,8 +1208,15 @@ use_shader_program(struct gl_context *ctx, gl_shader_stage stage,
    if ((shProg != NULL) && (shProg->_LinkedShaders[stage] == NULL))
       shProg = NULL;
 
-   if (shProg)
-      _mesa_shader_program_init_subroutine_defaults(ctx, shProg);
+   if (shProg) {
+      for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
+         struct gl_linked_shader *sh = shProg->_LinkedShaders[i];
+         if (!sh)
+            continue;
+
+         _mesa_shader_program_init_subroutine_defaults(ctx, sh->Program);
+      }
+   }
 
    if (*target != shProg) {
       /* Program is current, flush it */
@@ -2441,7 +2448,8 @@ _mesa_GetActiveSubroutineUniformiv(GLuint program, GLenum shadertype,
       return;
    }
 
-   if (index >= sh->NumSubroutineUniforms) {
+   struct gl_program *p = shProg->_LinkedShaders[stage]->Program;
+   if (index >= p->sh.NumSubroutineUniforms) {
       _mesa_error(ctx, GL_INVALID_VALUE, "%s: invalid index greater than GL_ACTIVE_SUBROUTINE_UNIFORMS", api_name);
       return;
    }
@@ -2460,8 +2468,8 @@ _mesa_GetActiveSubroutineUniformiv(GLuint program, GLenum shadertype,
       if (res) {
          uni = res->Data;
          count = 0;
-         for (i = 0; i < sh->NumSubroutineFunctions; i++) {
-            struct gl_subroutine_function *fn = &sh->SubroutineFunctions[i];
+         for (i = 0; i < p->sh.NumSubroutineFunctions; i++) {
+            struct gl_subroutine_function *fn = &p->sh.SubroutineFunctions[i];
             for (j = 0; j < fn->num_compat_types; j++) {
                if (fn->types[j] == uni->type) {
                   values[count++] = i;
@@ -2602,14 +2610,15 @@ _mesa_UniformSubroutinesuiv(GLenum shadertype, GLsizei count,
       return;
    }
 
-   if (count != sh->NumSubroutineUniformRemapTable) {
+   struct gl_program *p = shProg->_LinkedShaders[stage]->Program;
+   if (count != p->sh.NumSubroutineUniformRemapTable) {
       _mesa_error(ctx, GL_INVALID_VALUE, "%s", api_name);
       return;
    }
 
    i = 0;
    do {
-      struct gl_uniform_storage *uni = sh->SubroutineUniformRemapTable[i];
+      struct gl_uniform_storage *uni = p->sh.SubroutineUniformRemapTable[i];
       if (uni == NULL) {
          i++;
          continue;
@@ -2620,14 +2629,14 @@ _mesa_UniformSubroutinesuiv(GLenum shadertype, GLsizei count,
 
       for (j = i; j < i + uni_count; j++) {
          struct gl_subroutine_function *subfn = NULL;
-         if (indices[j] > sh->MaxSubroutineFunctionIndex) {
+         if (indices[j] > p->sh.MaxSubroutineFunctionIndex) {
             _mesa_error(ctx, GL_INVALID_VALUE, "%s", api_name);
             return;
          }
 
-         for (f = 0; f < sh->NumSubroutineFunctions; f++) {
-            if (sh->SubroutineFunctions[f].index == indices[j])
-               subfn = &sh->SubroutineFunctions[f];
+         for (f = 0; f < p->sh.NumSubroutineFunctions; f++) {
+            if (p->sh.SubroutineFunctions[f].index == indices[j])
+               subfn = &p->sh.SubroutineFunctions[f];
          }
 
          if (!subfn) {
@@ -2643,7 +2652,7 @@ _mesa_UniformSubroutinesuiv(GLenum shadertype, GLsizei count,
             return;
          }
 
-         ctx->SubroutineIndex[sh->Stage].IndexPtr[j] = indices[j];
+         ctx->SubroutineIndex[p->info.stage].IndexPtr[j] = indices[j];
       }
       i += uni_count;
    } while(i < count);
@@ -2685,12 +2694,13 @@ _mesa_GetUniformSubroutineuiv(GLenum shadertype, GLint location,
       return;
    }
 
-   if (location >= sh->NumSubroutineUniformRemapTable) {
+   struct gl_program *p = sh->Program;
+   if (location >= p->sh.NumSubroutineUniformRemapTable) {
       _mesa_error(ctx, GL_INVALID_VALUE, "%s", api_name);
       return;
    }
 
-   *params = ctx->SubroutineIndex[sh->Stage].IndexPtr[location];
+   *params = ctx->SubroutineIndex[p->info.stage].IndexPtr[location];
 }
 
 
@@ -2742,15 +2752,16 @@ _mesa_GetProgramStageiv(GLuint program, GLenum shadertype,
       return;
    }
 
+   struct gl_program *p = sh->Program;
    switch (pname) {
    case GL_ACTIVE_SUBROUTINES:
-      values[0] = sh->NumSubroutineFunctions;
+      values[0] = p->sh.NumSubroutineFunctions;
       break;
    case GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS:
-      values[0] = sh->NumSubroutineUniformRemapTable;
+      values[0] = p->sh.NumSubroutineUniformRemapTable;
       break;
    case GL_ACTIVE_SUBROUTINE_UNIFORMS:
-      values[0] = sh->NumSubroutineUniforms;
+      values[0] = p->sh.NumSubroutineUniforms;
       break;
    case GL_ACTIVE_SUBROUTINE_MAX_LENGTH:
    {
@@ -2760,7 +2771,7 @@ _mesa_GetProgramStageiv(GLuint program, GLenum shadertype,
       struct gl_program_resource *res;
 
       resource_type = _mesa_shader_stage_to_subroutine(stage);
-      for (i = 0; i < sh->NumSubroutineFunctions; i++) {
+      for (i = 0; i < p->sh.NumSubroutineFunctions; i++) {
          res = _mesa_program_resource_find_index(shProg, resource_type, i);
          if (res) {
             const GLint len = strlen(_mesa_program_resource_name(res)) + 1;
@@ -2779,7 +2790,7 @@ _mesa_GetProgramStageiv(GLuint program, GLenum shadertype,
       struct gl_program_resource *res;
 
       resource_type = _mesa_shader_stage_to_subroutine_uniform(stage);
-      for (i = 0; i < sh->NumSubroutineUniformRemapTable; i++) {
+      for (i = 0; i < p->sh.NumSubroutineUniformRemapTable; i++) {
          res = _mesa_program_resource_find_index(shProg, resource_type, i);
          if (res) {
             const GLint len = strlen(_mesa_program_resource_name(res)) + 1
@@ -2800,13 +2811,12 @@ _mesa_GetProgramStageiv(GLuint program, GLenum shadertype,
 }
 
 static int
-find_compat_subroutine(struct gl_linked_shader *sh,
-                       const struct glsl_type *type)
+find_compat_subroutine(struct gl_program *p, const struct glsl_type *type)
 {
    int i, j;
 
-   for (i = 0; i < sh->NumSubroutineFunctions; i++) {
-      struct gl_subroutine_function *fn = &sh->SubroutineFunctions[i];
+   for (i = 0; i < p->sh.NumSubroutineFunctions; i++) {
+      struct gl_subroutine_function *fn = &p->sh.SubroutineFunctions[i];
       for (j = 0; j < fn->num_compat_types; j++) {
          if (fn->types[j] == type)
             return i;
@@ -2817,16 +2827,16 @@ find_compat_subroutine(struct gl_linked_shader *sh,
 
 static void
 _mesa_shader_write_subroutine_index(struct gl_context *ctx,
-                                    struct gl_linked_shader *sh)
+                                    struct gl_program *p)
 {
    int i, j;
 
-   if (sh->NumSubroutineUniformRemapTable == 0)
+   if (p->sh.NumSubroutineUniformRemapTable == 0)
       return;
 
    i = 0;
    do {
-      struct gl_uniform_storage *uni = sh->SubroutineUniformRemapTable[i];
+      struct gl_uniform_storage *uni = p->sh.SubroutineUniformRemapTable[i];
       int uni_count;
       int val;
 
@@ -2837,13 +2847,13 @@ _mesa_shader_write_subroutine_index(struct gl_context *ctx,
 
       uni_count = uni->array_elements ? uni->array_elements : 1;
       for (j = 0; j < uni_count; j++) {
-         val = ctx->SubroutineIndex[sh->Stage].IndexPtr[i + j];
+         val = ctx->SubroutineIndex[p->info.stage].IndexPtr[i + j];
          memcpy(&uni->storage[j], &val, sizeof(int));
       }
 
       _mesa_propagate_uniforms_to_driver_storage(uni, 0, uni_count);
       i += uni_count;
-   } while(i < sh->NumSubroutineUniformRemapTable);
+   } while(i < p->sh.NumSubroutineUniformRemapTable);
 }
 
 void
@@ -2853,44 +2863,28 @@ _mesa_shader_write_subroutine_indices(struct gl_context *ctx,
    if (ctx->_Shader->CurrentProgram[stage] &&
        ctx->_Shader->CurrentProgram[stage]->_LinkedShaders[stage])
       _mesa_shader_write_subroutine_index(ctx,
-                                          ctx->_Shader->CurrentProgram[stage]->_LinkedShaders[stage]);
+                                          ctx->_Shader->CurrentProgram[stage]->_LinkedShaders[stage]->Program);
 }
 
-static void
-_mesa_shader_init_subroutine_defaults(struct gl_context *ctx,
-                                      struct gl_linked_shader *sh)
+void
+_mesa_shader_program_init_subroutine_defaults(struct gl_context *ctx,
+                                              struct gl_program *p)
 {
-   int i;
-   struct gl_subroutine_index_binding *binding = &ctx->SubroutineIndex[sh->Stage];
-   if (binding->NumIndex != sh->NumSubroutineUniformRemapTable) {
+   assert(p);
+
+   struct gl_subroutine_index_binding *binding = &ctx->SubroutineIndex[p->info.stage];
+   if (binding->NumIndex != p->sh.NumSubroutineUniformRemapTable) {
       binding->IndexPtr = realloc(binding->IndexPtr,
-                                  sh->NumSubroutineUniformRemapTable * (sizeof(GLuint)));
-      binding->NumIndex = sh->NumSubroutineUniformRemapTable;
+                                  p->sh.NumSubroutineUniformRemapTable * (sizeof(GLuint)));
+      binding->NumIndex = p->sh.NumSubroutineUniformRemapTable;
    }
 
-   for (i = 0; i < sh->NumSubroutineUniformRemapTable; i++) {
-      struct gl_uniform_storage *uni = sh->SubroutineUniformRemapTable[i];
+   for (int i = 0; i < p->sh.NumSubroutineUniformRemapTable; i++) {
+      struct gl_uniform_storage *uni = p->sh.SubroutineUniformRemapTable[i];
 
       if (!uni)
          continue;
 
-      binding->IndexPtr[i] = find_compat_subroutine(sh, 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_shader_init_subroutine_defaults(ctx, shProg->_LinkedShaders[i]);
+      binding->IndexPtr[i] = find_compat_subroutine(p, uni->type);
    }
 }
diff --git a/src/mesa/main/shaderapi.h b/src/mesa/main/shaderapi.h
index 50929f4..62c756d 100644
--- a/src/mesa/main/shaderapi.h
+++ b/src/mesa/main/shaderapi.h
@@ -289,7 +289,7 @@ _mesa_PatchParameterfv(GLenum pname, const GLfloat *values);
 /* GL_ARB_shader_subroutine */
 void
 _mesa_shader_program_init_subroutine_defaults(struct gl_context *ctx,
-                                              struct gl_shader_program *shProg);
+                                              struct gl_program *prog);
 
 extern GLint GLAPIENTRY
 _mesa_GetSubroutineUniformLocation(GLuint program, GLenum shadertype,
-- 
2.9.3



More information about the mesa-dev mailing list