mesa/glsl: move subroutine metadata to gl_program

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.

Reviewed-by: Eric Anholt <eric@anholt.net>
This commit is contained in:
Timothy Arceri
2016-12-29 08:56:43 +11:00
parent 0de6f6223a
commit 41dd6c3539
5 changed files with 123 additions and 119 deletions

View File

@@ -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;
}
}
}

View File

@@ -3155,24 +3155,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++;
@@ -3191,13 +3191,14 @@ 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));
}
}
}
/**
* Validate shader image resources.
*/
@@ -3316,36 +3317,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
@@ -3362,7 +3363,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;
@@ -3393,9 +3394,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;
@@ -3403,7 +3404,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);
@@ -4341,12 +4342,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;
}
}
@@ -4396,33 +4397,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
@@ -4432,23 +4433,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++;
}
}
}

View File

@@ -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;
};

View File

@@ -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;

View File

@@ -2441,7 +2441,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 +2461,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 +2603,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 +2622,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 +2645,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 +2687,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 +2745,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 +2764,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 +2783,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 +2804,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 +2820,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 +2840,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,28 +2856,29 @@ _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)
_mesa_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);
binding->IndexPtr[i] = find_compat_subroutine(p, uni->type);
}
}
@@ -2891,6 +2895,6 @@ _mesa_shader_program_init_subroutine_defaults(struct gl_context *ctx,
if (!shProg->_LinkedShaders[i])
continue;
_mesa_shader_init_subroutine_defaults(ctx, shProg->_LinkedShaders[i]);
_mesa_program_init_subroutine_defaults(ctx, shProg->_LinkedShaders[i]->Program);
}
}