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].index = this->next_subroutine;
uniform->opaque[shader_type].active = true; 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 /* Increment the subroutine index by 1 for non-arrays and by the
* number of array elements for arrays. * 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; unsigned mask = prog->data->linked_stages;
while (mask) { while (mask) {
const int j = u_bit_scan(&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) if (!prog->data->UniformStorage[i].opaque[j].active)
continue; continue;
@@ -1157,9 +1157,9 @@ link_setup_uniform_remap_tables(struct gl_context *ctx,
for (unsigned k = 0; k < entries; k++) { for (unsigned k = 0; k < entries; k++) {
unsigned element_loc = unsigned element_loc =
prog->data->UniformStorage[i].remap_location + k; prog->data->UniformStorage[i].remap_location + k;
assert(sh->SubroutineUniformRemapTable[element_loc] == assert(p->sh.SubroutineUniformRemapTable[element_loc] ==
INACTIVE_UNIFORM_EXPLICIT_LOCATION); INACTIVE_UNIFORM_EXPLICIT_LOCATION);
sh->SubroutineUniformRemapTable[element_loc] = p->sh.SubroutineUniformRemapTable[element_loc] =
&prog->data->UniformStorage[i]; &prog->data->UniformStorage[i];
} }
} }
@@ -1180,24 +1180,24 @@ link_setup_uniform_remap_tables(struct gl_context *ctx,
unsigned mask = prog->data->linked_stages; unsigned mask = prog->data->linked_stages;
while (mask) { while (mask) {
const int j = u_bit_scan(&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) if (!prog->data->UniformStorage[i].opaque[j].active)
continue; continue;
sh->SubroutineUniformRemapTable = p->sh.SubroutineUniformRemapTable =
reralloc(sh, reralloc(p,
sh->SubroutineUniformRemapTable, p->sh.SubroutineUniformRemapTable,
gl_uniform_storage *, gl_uniform_storage *,
sh->NumSubroutineUniformRemapTable + entries); p->sh.NumSubroutineUniformRemapTable + entries);
for (unsigned k = 0; k < entries; k++) { 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];
} }
prog->data->UniformStorage[i].remap_location = prog->data->UniformStorage[i].remap_location =
sh->NumSubroutineUniformRemapTable; p->sh.NumSubroutineUniformRemapTable;
sh->NumSubroutineUniformRemapTable += entries; 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; unsigned mask = prog->data->linked_stages;
while (mask) { while (mask) {
const int i = u_bit_scan(&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++) { for (unsigned j = 0; j < p->sh.NumSubroutineUniformRemapTable; j++) {
if (sh->SubroutineUniformRemapTable[j] == INACTIVE_UNIFORM_EXPLICIT_LOCATION) if (p->sh.SubroutineUniformRemapTable[j] == INACTIVE_UNIFORM_EXPLICIT_LOCATION)
continue; continue;
struct gl_uniform_storage *uni = sh->SubroutineUniformRemapTable[j]; struct gl_uniform_storage *uni = p->sh.SubroutineUniformRemapTable[j];
if (!uni) if (!uni)
continue; continue;
int count = 0; 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); linker_error(prog, "subroutine uniform %s defined but no valid functions found\n", uni->type->name);
continue; continue;
} }
for (unsigned f = 0; f < sh->NumSubroutineFunctions; f++) { for (unsigned f = 0; f < p->sh.NumSubroutineFunctions; f++) {
struct gl_subroutine_function *fn = &sh->SubroutineFunctions[f]; struct gl_subroutine_function *fn = &p->sh.SubroutineFunctions[f];
for (int k = 0; k < fn->num_compat_types; k++) { for (int k = 0; k < fn->num_compat_types; k++) {
if (fn->types[k] == uni->type) { if (fn->types[k] == uni->type) {
count++; count++;
@@ -3191,11 +3191,12 @@ check_subroutine_resources(struct gl_shader_program *prog)
unsigned mask = prog->data->linked_stages; unsigned mask = prog->data->linked_stages;
while (mask) { while (mask) {
const int i = u_bit_scan(&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", linker_error(prog, "Too many %s shader subroutine uniforms\n",
_mesa_shader_stage_to_string(i)); _mesa_shader_stage_to_string(i));
}
} }
} }
/** /**
@@ -3316,36 +3317,36 @@ reserve_explicit_locations(struct gl_shader_program *prog,
static bool static bool
reserve_subroutine_explicit_locations(struct gl_shader_program *prog, reserve_subroutine_explicit_locations(struct gl_shader_program *prog,
struct gl_linked_shader *sh, struct gl_program *p,
ir_variable *var) ir_variable *var)
{ {
unsigned slots = var->type->uniform_locations(); unsigned slots = var->type->uniform_locations();
unsigned max_loc = var->data.location + slots - 1; unsigned max_loc = var->data.location + slots - 1;
/* Resize remap table if locations do not fit in the current one. */ /* Resize remap table if locations do not fit in the current one. */
if (max_loc + 1 > sh->NumSubroutineUniformRemapTable) { if (max_loc + 1 > p->sh.NumSubroutineUniformRemapTable) {
sh->SubroutineUniformRemapTable = p->sh.SubroutineUniformRemapTable =
reralloc(sh, sh->SubroutineUniformRemapTable, reralloc(p, p->sh.SubroutineUniformRemapTable,
gl_uniform_storage *, gl_uniform_storage *,
max_loc + 1); max_loc + 1);
if (!sh->SubroutineUniformRemapTable) { if (!p->sh.SubroutineUniformRemapTable) {
linker_error(prog, "Out of memory during linking.\n"); linker_error(prog, "Out of memory during linking.\n");
return false; return false;
} }
/* Initialize allocated space. */ /* Initialize allocated space. */
for (unsigned i = sh->NumSubroutineUniformRemapTable; i < max_loc + 1; i++) for (unsigned i = p->sh.NumSubroutineUniformRemapTable; i < max_loc + 1; i++)
sh->SubroutineUniformRemapTable[i] = NULL; p->sh.SubroutineUniformRemapTable[i] = NULL;
sh->NumSubroutineUniformRemapTable = max_loc + 1; p->sh.NumSubroutineUniformRemapTable = max_loc + 1;
} }
for (unsigned i = 0; i < slots; i++) { for (unsigned i = 0; i < slots; i++) {
unsigned loc = var->data.location + i; unsigned loc = var->data.location + i;
/* Check if location is already used. */ /* 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: /* ARB_explicit_uniform_location specification states:
* "No two subroutine uniform variables can have the same location * "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 /* Initialize location as inactive before optimization
* rounds and location assignment. * rounds and location assignment.
*/ */
sh->SubroutineUniformRemapTable[loc] = INACTIVE_UNIFORM_EXPLICIT_LOCATION; p->sh.SubroutineUniformRemapTable[loc] = INACTIVE_UNIFORM_EXPLICIT_LOCATION;
} }
return true; return true;
@@ -3393,9 +3394,9 @@ check_explicit_uniform_locations(struct gl_context *ctx,
unsigned mask = prog->data->linked_stages; unsigned mask = prog->data->linked_stages;
while (mask) { while (mask) {
const int i = u_bit_scan(&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(); ir_variable *var = node->as_variable();
if (!var || var->data.mode != ir_var_uniform) if (!var || var->data.mode != ir_var_uniform)
continue; continue;
@@ -3403,7 +3404,7 @@ check_explicit_uniform_locations(struct gl_context *ctx,
if (var->data.explicit_location) { if (var->data.explicit_location) {
bool ret = false; bool ret = false;
if (var->type->without_array()->is_subroutine()) if (var->type->without_array()->is_subroutine())
ret = reserve_subroutine_explicit_locations(prog, sh, var); ret = reserve_subroutine_explicit_locations(prog, p, var);
else { else {
int slots = reserve_explicit_locations(prog, uniform_map, int slots = reserve_explicit_locations(prog, uniform_map,
var); var);
@@ -4341,12 +4342,12 @@ build_program_resource_list(struct gl_context *ctx,
unsigned mask = shProg->data->linked_stages; unsigned mask = shProg->data->linked_stages;
while (mask) { while (mask) {
const int i = u_bit_scan(&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); 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, if (!add_program_resource(shProg, resource_set,
type, &sh->SubroutineFunctions[j], 0)) type, &p->sh.SubroutineFunctions[j], 0))
return; return;
} }
} }
@@ -4396,33 +4397,33 @@ link_assign_subroutine_types(struct gl_shader_program *prog)
unsigned mask = prog->data->linked_stages; unsigned mask = prog->data->linked_stages;
while (mask) { while (mask) {
const int i = u_bit_scan(&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; p->sh.MaxSubroutineFunctionIndex = 0;
foreach_in_list(ir_instruction, node, sh->ir) { foreach_in_list(ir_instruction, node, prog->_LinkedShaders[i]->ir) {
ir_function *fn = node->as_function(); ir_function *fn = node->as_function();
if (!fn) if (!fn)
continue; continue;
if (fn->is_subroutine) if (fn->is_subroutine)
sh->NumSubroutineUniformTypes++; p->sh.NumSubroutineUniformTypes++;
if (!fn->num_subroutine_types) if (!fn->num_subroutine_types)
continue; continue;
/* these should have been calculated earlier. */ /* these should have been calculated earlier. */
assert(fn->subroutine_index != -1); 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"); linker_error(prog, "Too many subroutine functions declared.\n");
return; return;
} }
sh->SubroutineFunctions = reralloc(sh, sh->SubroutineFunctions, p->sh.SubroutineFunctions = reralloc(p, p->sh.SubroutineFunctions,
struct gl_subroutine_function, struct gl_subroutine_function,
sh->NumSubroutineFunctions + 1); p->sh.NumSubroutineFunctions + 1);
sh->SubroutineFunctions[sh->NumSubroutineFunctions].name = ralloc_strdup(sh, fn->name); p->sh.SubroutineFunctions[p->sh.NumSubroutineFunctions].name = ralloc_strdup(p, fn->name);
sh->SubroutineFunctions[sh->NumSubroutineFunctions].num_compat_types = fn->num_subroutine_types; p->sh.SubroutineFunctions[p->sh.NumSubroutineFunctions].num_compat_types = fn->num_subroutine_types;
sh->SubroutineFunctions[sh->NumSubroutineFunctions].types = p->sh.SubroutineFunctions[p->sh.NumSubroutineFunctions].types =
ralloc_array(sh, const struct glsl_type *, ralloc_array(p, const struct glsl_type *,
fn->num_subroutine_types); fn->num_subroutine_types);
/* From Section 4.4.4(Subroutine Function Layout Qualifiers) of the /* 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 * given a unique index, otherwise a compile or link error will be
* generated." * generated."
*/ */
for (unsigned j = 0; j < sh->NumSubroutineFunctions; j++) { for (unsigned j = 0; j < p->sh.NumSubroutineFunctions; j++) {
if (sh->SubroutineFunctions[j].index != -1 && if (p->sh.SubroutineFunctions[j].index != -1 &&
sh->SubroutineFunctions[j].index == fn->subroutine_index) { p->sh.SubroutineFunctions[j].index == fn->subroutine_index) {
linker_error(prog, "each subroutine index qualifier in the " linker_error(prog, "each subroutine index qualifier in the "
"shader must be unique\n"); "shader must be unique\n");
return; return;
} }
} }
sh->SubroutineFunctions[sh->NumSubroutineFunctions].index = p->sh.SubroutineFunctions[p->sh.NumSubroutineFunctions].index =
fn->subroutine_index; fn->subroutine_index;
if (fn->subroutine_index > (int)sh->MaxSubroutineFunctionIndex) if (fn->subroutine_index > (int)p->sh.MaxSubroutineFunctionIndex)
sh->MaxSubroutineFunctionIndex = fn->subroutine_index; p->sh.MaxSubroutineFunctionIndex = fn->subroutine_index;
for (int j = 0; j < fn->num_subroutine_types; j++) for (int j = 0; j < fn->num_subroutine_types; j++)
sh->SubroutineFunctions[sh->NumSubroutineFunctions].types[j] = fn->subroutine_types[j]; p->sh.SubroutineFunctions[p->sh.NumSubroutineFunctions].types[j] = fn->subroutine_types[j];
sh->NumSubroutineFunctions++; p->sh.NumSubroutineFunctions++;
} }
} }
} }

View File

@@ -1947,6 +1947,26 @@ struct gl_program
/** Fields used by GLSL programs */ /** Fields used by GLSL programs */
struct { struct {
struct gl_active_atomic_buffer **AtomicBuffers; 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; } sh;
/** ARB assembly-style program fields */ /** ARB assembly-style program fields */
@@ -2364,27 +2384,6 @@ struct gl_linked_shader
*/ */
GLuint NumImages; 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; struct gl_shader_info info;
}; };

View File

@@ -1248,7 +1248,7 @@ _mesa_program_resource_prop(struct gl_shader_program *shProg,
return 1; return 1;
case GL_COMPATIBLE_SUBROUTINES: { case GL_COMPATIBLE_SUBROUTINES: {
const struct gl_uniform_storage *uni; const struct gl_uniform_storage *uni;
struct gl_linked_shader *sh; struct gl_program *p;
unsigned count, i; unsigned count, i;
int j; int j;
@@ -1261,10 +1261,10 @@ _mesa_program_resource_prop(struct gl_shader_program *shProg,
goto invalid_operation; goto invalid_operation;
uni = RESOURCE_UNI(res); 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; count = 0;
for (i = 0; i < sh->NumSubroutineFunctions; i++) { for (i = 0; i < p->sh.NumSubroutineFunctions; i++) {
struct gl_subroutine_function *fn = &sh->SubroutineFunctions[i]; struct gl_subroutine_function *fn = &p->sh.SubroutineFunctions[i];
for (j = 0; j < fn->num_compat_types; j++) { for (j = 0; j < fn->num_compat_types; j++) {
if (fn->types[j] == uni->type) { if (fn->types[j] == uni->type) {
val[count++] = i; val[count++] = i;

View File

@@ -2441,7 +2441,8 @@ _mesa_GetActiveSubroutineUniformiv(GLuint program, GLenum shadertype,
return; 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); _mesa_error(ctx, GL_INVALID_VALUE, "%s: invalid index greater than GL_ACTIVE_SUBROUTINE_UNIFORMS", api_name);
return; return;
} }
@@ -2460,8 +2461,8 @@ _mesa_GetActiveSubroutineUniformiv(GLuint program, GLenum shadertype,
if (res) { if (res) {
uni = res->Data; uni = res->Data;
count = 0; count = 0;
for (i = 0; i < sh->NumSubroutineFunctions; i++) { for (i = 0; i < p->sh.NumSubroutineFunctions; i++) {
struct gl_subroutine_function *fn = &sh->SubroutineFunctions[i]; struct gl_subroutine_function *fn = &p->sh.SubroutineFunctions[i];
for (j = 0; j < fn->num_compat_types; j++) { for (j = 0; j < fn->num_compat_types; j++) {
if (fn->types[j] == uni->type) { if (fn->types[j] == uni->type) {
values[count++] = i; values[count++] = i;
@@ -2602,14 +2603,15 @@ _mesa_UniformSubroutinesuiv(GLenum shadertype, GLsizei count,
return; 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); _mesa_error(ctx, GL_INVALID_VALUE, "%s", api_name);
return; return;
} }
i = 0; i = 0;
do { do {
struct gl_uniform_storage *uni = sh->SubroutineUniformRemapTable[i]; struct gl_uniform_storage *uni = p->sh.SubroutineUniformRemapTable[i];
if (uni == NULL) { if (uni == NULL) {
i++; i++;
continue; continue;
@@ -2620,14 +2622,14 @@ _mesa_UniformSubroutinesuiv(GLenum shadertype, GLsizei count,
for (j = i; j < i + uni_count; j++) { for (j = i; j < i + uni_count; j++) {
struct gl_subroutine_function *subfn = NULL; 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); _mesa_error(ctx, GL_INVALID_VALUE, "%s", api_name);
return; return;
} }
for (f = 0; f < sh->NumSubroutineFunctions; f++) { for (f = 0; f < p->sh.NumSubroutineFunctions; f++) {
if (sh->SubroutineFunctions[f].index == indices[j]) if (p->sh.SubroutineFunctions[f].index == indices[j])
subfn = &sh->SubroutineFunctions[f]; subfn = &p->sh.SubroutineFunctions[f];
} }
if (!subfn) { if (!subfn) {
@@ -2643,7 +2645,7 @@ _mesa_UniformSubroutinesuiv(GLenum shadertype, GLsizei count,
return; return;
} }
ctx->SubroutineIndex[sh->Stage].IndexPtr[j] = indices[j]; ctx->SubroutineIndex[p->info.stage].IndexPtr[j] = indices[j];
} }
i += uni_count; i += uni_count;
} while(i < count); } while(i < count);
@@ -2685,12 +2687,13 @@ _mesa_GetUniformSubroutineuiv(GLenum shadertype, GLint location,
return; 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); _mesa_error(ctx, GL_INVALID_VALUE, "%s", api_name);
return; 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; return;
} }
struct gl_program *p = sh->Program;
switch (pname) { switch (pname) {
case GL_ACTIVE_SUBROUTINES: case GL_ACTIVE_SUBROUTINES:
values[0] = sh->NumSubroutineFunctions; values[0] = p->sh.NumSubroutineFunctions;
break; break;
case GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS: case GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS:
values[0] = sh->NumSubroutineUniformRemapTable; values[0] = p->sh.NumSubroutineUniformRemapTable;
break; break;
case GL_ACTIVE_SUBROUTINE_UNIFORMS: case GL_ACTIVE_SUBROUTINE_UNIFORMS:
values[0] = sh->NumSubroutineUniforms; values[0] = p->sh.NumSubroutineUniforms;
break; break;
case GL_ACTIVE_SUBROUTINE_MAX_LENGTH: case GL_ACTIVE_SUBROUTINE_MAX_LENGTH:
{ {
@@ -2760,7 +2764,7 @@ _mesa_GetProgramStageiv(GLuint program, GLenum shadertype,
struct gl_program_resource *res; struct gl_program_resource *res;
resource_type = _mesa_shader_stage_to_subroutine(stage); 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); res = _mesa_program_resource_find_index(shProg, resource_type, i);
if (res) { if (res) {
const GLint len = strlen(_mesa_program_resource_name(res)) + 1; 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; struct gl_program_resource *res;
resource_type = _mesa_shader_stage_to_subroutine_uniform(stage); 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); res = _mesa_program_resource_find_index(shProg, resource_type, i);
if (res) { if (res) {
const GLint len = strlen(_mesa_program_resource_name(res)) + 1 const GLint len = strlen(_mesa_program_resource_name(res)) + 1
@@ -2800,13 +2804,12 @@ _mesa_GetProgramStageiv(GLuint program, GLenum shadertype,
} }
static int static int
find_compat_subroutine(struct gl_linked_shader *sh, find_compat_subroutine(struct gl_program *p, const struct glsl_type *type)
const struct glsl_type *type)
{ {
int i, j; int i, j;
for (i = 0; i < sh->NumSubroutineFunctions; i++) { for (i = 0; i < p->sh.NumSubroutineFunctions; i++) {
struct gl_subroutine_function *fn = &sh->SubroutineFunctions[i]; struct gl_subroutine_function *fn = &p->sh.SubroutineFunctions[i];
for (j = 0; j < fn->num_compat_types; j++) { for (j = 0; j < fn->num_compat_types; j++) {
if (fn->types[j] == type) if (fn->types[j] == type)
return i; return i;
@@ -2817,16 +2820,16 @@ find_compat_subroutine(struct gl_linked_shader *sh,
static void static void
_mesa_shader_write_subroutine_index(struct gl_context *ctx, _mesa_shader_write_subroutine_index(struct gl_context *ctx,
struct gl_linked_shader *sh) struct gl_program *p)
{ {
int i, j; int i, j;
if (sh->NumSubroutineUniformRemapTable == 0) if (p->sh.NumSubroutineUniformRemapTable == 0)
return; return;
i = 0; i = 0;
do { do {
struct gl_uniform_storage *uni = sh->SubroutineUniformRemapTable[i]; struct gl_uniform_storage *uni = p->sh.SubroutineUniformRemapTable[i];
int uni_count; int uni_count;
int val; int val;
@@ -2837,13 +2840,13 @@ _mesa_shader_write_subroutine_index(struct gl_context *ctx,
uni_count = uni->array_elements ? uni->array_elements : 1; uni_count = uni->array_elements ? uni->array_elements : 1;
for (j = 0; j < uni_count; j++) { 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)); memcpy(&uni->storage[j], &val, sizeof(int));
} }
_mesa_propagate_uniforms_to_driver_storage(uni, 0, uni_count); _mesa_propagate_uniforms_to_driver_storage(uni, 0, uni_count);
i += uni_count; i += uni_count;
} while(i < sh->NumSubroutineUniformRemapTable); } while(i < p->sh.NumSubroutineUniformRemapTable);
} }
void void
@@ -2853,28 +2856,29 @@ _mesa_shader_write_subroutine_indices(struct gl_context *ctx,
if (ctx->_Shader->CurrentProgram[stage] && if (ctx->_Shader->CurrentProgram[stage] &&
ctx->_Shader->CurrentProgram[stage]->_LinkedShaders[stage]) ctx->_Shader->CurrentProgram[stage]->_LinkedShaders[stage])
_mesa_shader_write_subroutine_index(ctx, _mesa_shader_write_subroutine_index(ctx,
ctx->_Shader->CurrentProgram[stage]->_LinkedShaders[stage]); ctx->_Shader->CurrentProgram[stage]->_LinkedShaders[stage]->Program);
} }
static void static void
_mesa_shader_init_subroutine_defaults(struct gl_context *ctx, _mesa_program_init_subroutine_defaults(struct gl_context *ctx,
struct gl_linked_shader *sh) struct gl_program *p)
{ {
int i; assert(p);
struct gl_subroutine_index_binding *binding = &ctx->SubroutineIndex[sh->Stage];
if (binding->NumIndex != sh->NumSubroutineUniformRemapTable) { struct gl_subroutine_index_binding *binding = &ctx->SubroutineIndex[p->info.stage];
if (binding->NumIndex != p->sh.NumSubroutineUniformRemapTable) {
binding->IndexPtr = realloc(binding->IndexPtr, binding->IndexPtr = realloc(binding->IndexPtr,
sh->NumSubroutineUniformRemapTable * (sizeof(GLuint))); p->sh.NumSubroutineUniformRemapTable * (sizeof(GLuint)));
binding->NumIndex = sh->NumSubroutineUniformRemapTable; binding->NumIndex = p->sh.NumSubroutineUniformRemapTable;
} }
for (i = 0; i < sh->NumSubroutineUniformRemapTable; i++) { for (int i = 0; i < p->sh.NumSubroutineUniformRemapTable; i++) {
struct gl_uniform_storage *uni = sh->SubroutineUniformRemapTable[i]; struct gl_uniform_storage *uni = p->sh.SubroutineUniformRemapTable[i];
if (!uni) if (!uni)
continue; 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]) if (!shProg->_LinkedShaders[i])
continue; continue;
_mesa_shader_init_subroutine_defaults(ctx, shProg->_LinkedShaders[i]); _mesa_program_init_subroutine_defaults(ctx, shProg->_LinkedShaders[i]->Program);
} }
} }