glsl: move some uniform linking code to new link_setup_uniform_remap_tables()
This makes link_assign_uniform_locations() easier to follow. Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
This commit is contained in:
@@ -997,12 +997,168 @@ find_empty_block(struct gl_shader_program *prog,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
link_setup_uniform_remap_tables(struct gl_context *ctx,
|
||||||
|
struct gl_shader_program *prog,
|
||||||
|
unsigned num_explicit_uniform_locs)
|
||||||
|
{
|
||||||
|
unsigned total_entries = num_explicit_uniform_locs;
|
||||||
|
unsigned empty_locs =
|
||||||
|
prog->NumUniformRemapTable - num_explicit_uniform_locs;
|
||||||
|
|
||||||
|
/* Reserve all the explicit locations of the active uniforms. */
|
||||||
|
for (unsigned i = 0; i < prog->NumUniformStorage; i++) {
|
||||||
|
if (prog->UniformStorage[i].type->is_subroutine() ||
|
||||||
|
prog->UniformStorage[i].is_shader_storage)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (prog->UniformStorage[i].remap_location != UNMAPPED_UNIFORM_LOC) {
|
||||||
|
/* How many new entries for this uniform? */
|
||||||
|
const unsigned entries =
|
||||||
|
MAX2(1, prog->UniformStorage[i].array_elements);
|
||||||
|
|
||||||
|
/* Set remap table entries point to correct gl_uniform_storage. */
|
||||||
|
for (unsigned j = 0; j < entries; j++) {
|
||||||
|
unsigned element_loc = prog->UniformStorage[i].remap_location + j;
|
||||||
|
assert(prog->UniformRemapTable[element_loc] ==
|
||||||
|
INACTIVE_UNIFORM_EXPLICIT_LOCATION);
|
||||||
|
prog->UniformRemapTable[element_loc] = &prog->UniformStorage[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reserve locations for rest of the uniforms. */
|
||||||
|
for (unsigned i = 0; i < prog->NumUniformStorage; i++) {
|
||||||
|
|
||||||
|
if (prog->UniformStorage[i].type->is_subroutine() ||
|
||||||
|
prog->UniformStorage[i].is_shader_storage)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* Built-in uniforms should not get any location. */
|
||||||
|
if (prog->UniformStorage[i].builtin)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* Explicit ones have been set already. */
|
||||||
|
if (prog->UniformStorage[i].remap_location != UNMAPPED_UNIFORM_LOC)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* how many new entries for this uniform? */
|
||||||
|
const unsigned entries = MAX2(1, prog->UniformStorage[i].array_elements);
|
||||||
|
|
||||||
|
/* Find UniformRemapTable for empty blocks where we can fit this uniform. */
|
||||||
|
int chosen_location = -1;
|
||||||
|
|
||||||
|
if (empty_locs)
|
||||||
|
chosen_location = find_empty_block(prog, &prog->UniformStorage[i]);
|
||||||
|
|
||||||
|
/* Add new entries to the total amount of entries. */
|
||||||
|
total_entries += entries;
|
||||||
|
|
||||||
|
if (chosen_location != -1) {
|
||||||
|
empty_locs -= entries;
|
||||||
|
} else {
|
||||||
|
chosen_location = prog->NumUniformRemapTable;
|
||||||
|
|
||||||
|
/* resize remap table to fit new entries */
|
||||||
|
prog->UniformRemapTable =
|
||||||
|
reralloc(prog,
|
||||||
|
prog->UniformRemapTable,
|
||||||
|
gl_uniform_storage *,
|
||||||
|
prog->NumUniformRemapTable + entries);
|
||||||
|
prog->NumUniformRemapTable += entries;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set pointers for this uniform */
|
||||||
|
for (unsigned j = 0; j < entries; j++)
|
||||||
|
prog->UniformRemapTable[chosen_location + j] =
|
||||||
|
&prog->UniformStorage[i];
|
||||||
|
|
||||||
|
/* set the base location in remap table for the uniform */
|
||||||
|
prog->UniformStorage[i].remap_location = chosen_location;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Verify that total amount of entries for explicit and implicit locations
|
||||||
|
* is less than MAX_UNIFORM_LOCATIONS.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (total_entries > ctx->Const.MaxUserAssignableUniformLocations) {
|
||||||
|
linker_error(prog, "count of uniform locations > MAX_UNIFORM_LOCATIONS"
|
||||||
|
"(%u > %u)", total_entries,
|
||||||
|
ctx->Const.MaxUserAssignableUniformLocations);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reserve all the explicit locations of the active subroutine uniforms. */
|
||||||
|
for (unsigned i = 0; i < prog->NumUniformStorage; i++) {
|
||||||
|
if (!prog->UniformStorage[i].type->is_subroutine())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (prog->UniformStorage[i].remap_location == UNMAPPED_UNIFORM_LOC)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for (unsigned j = 0; j < MESA_SHADER_STAGES; j++) {
|
||||||
|
struct gl_linked_shader *sh = prog->_LinkedShaders[j];
|
||||||
|
if (!sh)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!prog->UniformStorage[i].opaque[j].active)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* How many new entries for this uniform? */
|
||||||
|
const unsigned entries =
|
||||||
|
MAX2(1, prog->UniformStorage[i].array_elements);
|
||||||
|
|
||||||
|
/* Set remap table entries point to correct gl_uniform_storage. */
|
||||||
|
for (unsigned k = 0; k < entries; k++) {
|
||||||
|
unsigned element_loc = prog->UniformStorage[i].remap_location + k;
|
||||||
|
assert(sh->SubroutineUniformRemapTable[element_loc] ==
|
||||||
|
INACTIVE_UNIFORM_EXPLICIT_LOCATION);
|
||||||
|
sh->SubroutineUniformRemapTable[element_loc] =
|
||||||
|
&prog->UniformStorage[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* reserve subroutine locations */
|
||||||
|
for (unsigned i = 0; i < prog->NumUniformStorage; i++) {
|
||||||
|
|
||||||
|
if (!prog->UniformStorage[i].type->is_subroutine())
|
||||||
|
continue;
|
||||||
|
const unsigned entries = MAX2(1, prog->UniformStorage[i].array_elements);
|
||||||
|
|
||||||
|
if (prog->UniformStorage[i].remap_location != UNMAPPED_UNIFORM_LOC)
|
||||||
|
continue;
|
||||||
|
for (unsigned j = 0; j < MESA_SHADER_STAGES; j++) {
|
||||||
|
struct gl_linked_shader *sh = prog->_LinkedShaders[j];
|
||||||
|
if (!sh)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!prog->UniformStorage[i].opaque[j].active)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
sh->SubroutineUniformRemapTable =
|
||||||
|
reralloc(sh,
|
||||||
|
sh->SubroutineUniformRemapTable,
|
||||||
|
gl_uniform_storage *,
|
||||||
|
sh->NumSubroutineUniformRemapTable + entries);
|
||||||
|
|
||||||
|
for (unsigned k = 0; k < entries; k++) {
|
||||||
|
sh->SubroutineUniformRemapTable[sh->NumSubroutineUniformRemapTable + k] =
|
||||||
|
&prog->UniformStorage[i];
|
||||||
|
}
|
||||||
|
prog->UniformStorage[i].remap_location =
|
||||||
|
sh->NumSubroutineUniformRemapTable;
|
||||||
|
sh->NumSubroutineUniformRemapTable += entries;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
link_assign_uniform_locations(struct gl_shader_program *prog,
|
link_assign_uniform_locations(struct gl_shader_program *prog,
|
||||||
unsigned int boolean_true,
|
struct gl_context *ctx,
|
||||||
unsigned int num_explicit_uniform_locs,
|
unsigned int num_explicit_uniform_locs)
|
||||||
unsigned int max_uniform_locs)
|
|
||||||
{
|
{
|
||||||
|
unsigned int boolean_true = ctx->Const.UniformBooleanTrue;
|
||||||
|
|
||||||
ralloc_free(prog->UniformStorage);
|
ralloc_free(prog->UniformStorage);
|
||||||
prog->UniformStorage = NULL;
|
prog->UniformStorage = NULL;
|
||||||
prog->NumUniformStorage = 0;
|
prog->NumUniformStorage = 0;
|
||||||
@@ -1067,7 +1223,7 @@ link_assign_uniform_locations(struct gl_shader_program *prog,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const unsigned num_uniforms = uniform_size.num_active_uniforms;
|
prog->NumUniformStorage = uniform_size.num_active_uniforms;
|
||||||
const unsigned num_data_slots = uniform_size.num_values;
|
const unsigned num_data_slots = uniform_size.num_values;
|
||||||
const unsigned hidden_uniforms = uniform_size.num_hidden_uniforms;
|
const unsigned hidden_uniforms = uniform_size.num_hidden_uniforms;
|
||||||
|
|
||||||
@@ -1077,21 +1233,20 @@ link_assign_uniform_locations(struct gl_shader_program *prog,
|
|||||||
|
|
||||||
/* On the outside chance that there were no uniforms, bail out.
|
/* On the outside chance that there were no uniforms, bail out.
|
||||||
*/
|
*/
|
||||||
if (num_uniforms == 0)
|
if (prog->NumUniformStorage == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
struct gl_uniform_storage *uniforms =
|
prog->UniformStorage = rzalloc_array(prog, struct gl_uniform_storage,
|
||||||
rzalloc_array(prog, struct gl_uniform_storage, num_uniforms);
|
prog->NumUniformStorage);
|
||||||
union gl_constant_value *data =
|
union gl_constant_value *data = rzalloc_array(prog->UniformStorage,
|
||||||
rzalloc_array(uniforms, union gl_constant_value, num_data_slots);
|
union gl_constant_value,
|
||||||
|
num_data_slots);
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
union gl_constant_value *data_end = &data[num_data_slots];
|
union gl_constant_value *data_end = &data[num_data_slots];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
parcel_out_uniform_storage parcel(prog, prog->UniformHash, uniforms, data);
|
parcel_out_uniform_storage parcel(prog, prog->UniformHash,
|
||||||
|
prog->UniformStorage, data);
|
||||||
unsigned total_entries = num_explicit_uniform_locs;
|
|
||||||
unsigned empty_locs = prog->NumUniformRemapTable - num_explicit_uniform_locs;
|
|
||||||
|
|
||||||
for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
|
for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
|
||||||
if (prog->_LinkedShaders[i] == NULL)
|
if (prog->_LinkedShaders[i] == NULL)
|
||||||
@@ -1118,156 +1273,19 @@ link_assign_uniform_locations(struct gl_shader_program *prog,
|
|||||||
sizeof(prog->_LinkedShaders[i]->SamplerTargets));
|
sizeof(prog->_LinkedShaders[i]->SamplerTargets));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Reserve all the explicit locations of the active uniforms. */
|
|
||||||
for (unsigned i = 0; i < num_uniforms; i++) {
|
|
||||||
if (uniforms[i].type->is_subroutine() ||
|
|
||||||
uniforms[i].is_shader_storage)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (uniforms[i].remap_location != UNMAPPED_UNIFORM_LOC) {
|
|
||||||
/* How many new entries for this uniform? */
|
|
||||||
const unsigned entries = MAX2(1, uniforms[i].array_elements);
|
|
||||||
|
|
||||||
/* Set remap table entries point to correct gl_uniform_storage. */
|
|
||||||
for (unsigned j = 0; j < entries; j++) {
|
|
||||||
unsigned element_loc = uniforms[i].remap_location + j;
|
|
||||||
assert(prog->UniformRemapTable[element_loc] ==
|
|
||||||
INACTIVE_UNIFORM_EXPLICIT_LOCATION);
|
|
||||||
prog->UniformRemapTable[element_loc] = &uniforms[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Reserve locations for rest of the uniforms. */
|
|
||||||
for (unsigned i = 0; i < num_uniforms; i++) {
|
|
||||||
|
|
||||||
if (uniforms[i].type->is_subroutine() ||
|
|
||||||
uniforms[i].is_shader_storage)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* Built-in uniforms should not get any location. */
|
|
||||||
if (uniforms[i].builtin)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* Explicit ones have been set already. */
|
|
||||||
if (uniforms[i].remap_location != UNMAPPED_UNIFORM_LOC)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* how many new entries for this uniform? */
|
|
||||||
const unsigned entries = MAX2(1, uniforms[i].array_elements);
|
|
||||||
|
|
||||||
/* Find UniformRemapTable for empty blocks where we can fit this uniform. */
|
|
||||||
int chosen_location = -1;
|
|
||||||
|
|
||||||
if (empty_locs)
|
|
||||||
chosen_location = find_empty_block(prog, &uniforms[i]);
|
|
||||||
|
|
||||||
/* Add new entries to the total amount of entries. */
|
|
||||||
total_entries += entries;
|
|
||||||
|
|
||||||
if (chosen_location != -1) {
|
|
||||||
empty_locs -= entries;
|
|
||||||
} else {
|
|
||||||
chosen_location = prog->NumUniformRemapTable;
|
|
||||||
|
|
||||||
/* resize remap table to fit new entries */
|
|
||||||
prog->UniformRemapTable =
|
|
||||||
reralloc(prog,
|
|
||||||
prog->UniformRemapTable,
|
|
||||||
gl_uniform_storage *,
|
|
||||||
prog->NumUniformRemapTable + entries);
|
|
||||||
prog->NumUniformRemapTable += entries;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* set pointers for this uniform */
|
|
||||||
for (unsigned j = 0; j < entries; j++)
|
|
||||||
prog->UniformRemapTable[chosen_location + j] = &uniforms[i];
|
|
||||||
|
|
||||||
/* set the base location in remap table for the uniform */
|
|
||||||
uniforms[i].remap_location = chosen_location;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Verify that total amount of entries for explicit and implicit locations
|
|
||||||
* is less than MAX_UNIFORM_LOCATIONS.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (total_entries > max_uniform_locs) {
|
|
||||||
linker_error(prog, "count of uniform locations > MAX_UNIFORM_LOCATIONS"
|
|
||||||
"(%u > %u)", total_entries, max_uniform_locs);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Reserve all the explicit locations of the active subroutine uniforms. */
|
|
||||||
for (unsigned i = 0; i < num_uniforms; i++) {
|
|
||||||
if (!uniforms[i].type->is_subroutine())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (uniforms[i].remap_location == UNMAPPED_UNIFORM_LOC)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
for (unsigned j = 0; j < MESA_SHADER_STAGES; j++) {
|
|
||||||
struct gl_linked_shader *sh = prog->_LinkedShaders[j];
|
|
||||||
if (!sh)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (!uniforms[i].opaque[j].active)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* How many new entries for this uniform? */
|
|
||||||
const unsigned entries = MAX2(1, uniforms[i].array_elements);
|
|
||||||
|
|
||||||
/* Set remap table entries point to correct gl_uniform_storage. */
|
|
||||||
for (unsigned k = 0; k < entries; k++) {
|
|
||||||
unsigned element_loc = uniforms[i].remap_location + k;
|
|
||||||
assert(sh->SubroutineUniformRemapTable[element_loc] ==
|
|
||||||
INACTIVE_UNIFORM_EXPLICIT_LOCATION);
|
|
||||||
sh->SubroutineUniformRemapTable[element_loc] = &uniforms[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* reserve subroutine locations */
|
|
||||||
for (unsigned i = 0; i < num_uniforms; i++) {
|
|
||||||
|
|
||||||
if (!uniforms[i].type->is_subroutine())
|
|
||||||
continue;
|
|
||||||
const unsigned entries = MAX2(1, uniforms[i].array_elements);
|
|
||||||
|
|
||||||
if (uniforms[i].remap_location != UNMAPPED_UNIFORM_LOC)
|
|
||||||
continue;
|
|
||||||
for (unsigned j = 0; j < MESA_SHADER_STAGES; j++) {
|
|
||||||
struct gl_linked_shader *sh = prog->_LinkedShaders[j];
|
|
||||||
if (!sh)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (!uniforms[i].opaque[j].active)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
sh->SubroutineUniformRemapTable =
|
|
||||||
reralloc(sh,
|
|
||||||
sh->SubroutineUniformRemapTable,
|
|
||||||
gl_uniform_storage *,
|
|
||||||
sh->NumSubroutineUniformRemapTable + entries);
|
|
||||||
|
|
||||||
for (unsigned k = 0; k < entries; k++)
|
|
||||||
sh->SubroutineUniformRemapTable[sh->NumSubroutineUniformRemapTable + k] = &uniforms[i];
|
|
||||||
uniforms[i].remap_location = sh->NumSubroutineUniformRemapTable;
|
|
||||||
sh->NumSubroutineUniformRemapTable += entries;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
for (unsigned i = 0; i < num_uniforms; i++) {
|
for (unsigned i = 0; i < prog->NumUniformStorage; i++) {
|
||||||
assert(uniforms[i].storage != NULL || uniforms[i].builtin ||
|
assert(prog->UniformStorage[i].storage != NULL ||
|
||||||
uniforms[i].is_shader_storage ||
|
prog->UniformStorage[i].builtin ||
|
||||||
uniforms[i].block_index != -1);
|
prog->UniformStorage[i].is_shader_storage ||
|
||||||
|
prog->UniformStorage[i].block_index != -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(parcel.values == data_end);
|
assert(parcel.values == data_end);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
prog->NumUniformStorage = num_uniforms;
|
|
||||||
prog->NumHiddenUniforms = hidden_uniforms;
|
prog->NumHiddenUniforms = hidden_uniforms;
|
||||||
prog->UniformStorage = uniforms;
|
link_setup_uniform_remap_tables(ctx, prog, num_explicit_uniform_locs);
|
||||||
|
|
||||||
link_set_uniform_initializers(prog, boolean_true);
|
link_set_uniform_initializers(prog, boolean_true);
|
||||||
|
|
||||||
|
@@ -4560,9 +4560,7 @@ link_varyings_and_uniforms(unsigned first, unsigned last,
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
update_array_sizes(prog);
|
update_array_sizes(prog);
|
||||||
link_assign_uniform_locations(prog, ctx->Const.UniformBooleanTrue,
|
link_assign_uniform_locations(prog, ctx, num_explicit_uniform_locs);
|
||||||
num_explicit_uniform_locs,
|
|
||||||
ctx->Const.MaxUserAssignableUniformLocations);
|
|
||||||
link_assign_atomic_counter_resources(ctx, prog);
|
link_assign_atomic_counter_resources(ctx, prog);
|
||||||
|
|
||||||
link_calculate_subroutine_compat(prog);
|
link_calculate_subroutine_compat(prog);
|
||||||
|
@@ -35,9 +35,8 @@ link_invalidate_variable_locations(exec_list *ir);
|
|||||||
|
|
||||||
extern void
|
extern void
|
||||||
link_assign_uniform_locations(struct gl_shader_program *prog,
|
link_assign_uniform_locations(struct gl_shader_program *prog,
|
||||||
unsigned int boolean_true,
|
struct gl_context *ctx,
|
||||||
unsigned int num_explicit_uniform_locs,
|
unsigned int num_explicit_uniform_locs);
|
||||||
unsigned int max_uniform_locs);
|
|
||||||
|
|
||||||
extern void
|
extern void
|
||||||
link_set_uniform_initializers(struct gl_shader_program *prog,
|
link_set_uniform_initializers(struct gl_shader_program *prog,
|
||||||
|
Reference in New Issue
Block a user