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.
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;
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];
}
}
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;
}
}
}
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++;
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));
+ }
}
}
/**
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
/* 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;
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;
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);
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;
}
}
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
* 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++;
}
}
}
/** 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 */
*/
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;
};
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;
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;
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;
}
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;
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;
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) {
return;
}
- ctx->SubroutineIndex[sh->Stage].IndexPtr[j] = indices[j];
+ ctx->SubroutineIndex[p->info.stage].IndexPtr[j] = indices[j];
}
i += uni_count;
} while(i < count);
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];
}
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:
{
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;
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
}
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;
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;
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
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);
}
}
if (!shProg->_LinkedShaders[i])
continue;
- _mesa_shader_init_subroutine_defaults(ctx, shProg->_LinkedShaders[i]);
+ _mesa_program_init_subroutine_defaults(ctx, shProg->_LinkedShaders[i]->Program);
}
}