glsl: store stage reference in gl_uniform_block
This allows us to simplify the code and drop InterfaceBlockStageIndex which is a per stage array of integers the size of all blocks in the program combined including duplicates across stages. Adding a stage ref per block will use less memory. Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
This commit is contained in:
@@ -1171,6 +1171,8 @@ cross_validate_uniforms(struct gl_shader_program *prog)
|
||||
static bool
|
||||
interstage_cross_validate_uniform_blocks(struct gl_shader_program *prog)
|
||||
{
|
||||
int *InterfaceBlockStageIndex[MESA_SHADER_STAGES];
|
||||
|
||||
unsigned max_num_uniform_blocks = 0;
|
||||
for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
|
||||
if (prog->_LinkedShaders[i])
|
||||
@@ -1180,10 +1182,9 @@ interstage_cross_validate_uniform_blocks(struct gl_shader_program *prog)
|
||||
for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
|
||||
struct gl_shader *sh = prog->_LinkedShaders[i];
|
||||
|
||||
prog->InterfaceBlockStageIndex[i] = ralloc_array(prog, int,
|
||||
max_num_uniform_blocks);
|
||||
InterfaceBlockStageIndex[i] = new int[max_num_uniform_blocks];
|
||||
for (unsigned int j = 0; j < max_num_uniform_blocks; j++)
|
||||
prog->InterfaceBlockStageIndex[i][j] = -1;
|
||||
InterfaceBlockStageIndex[i][j] = -1;
|
||||
|
||||
if (sh == NULL)
|
||||
continue;
|
||||
@@ -1194,13 +1195,17 @@ interstage_cross_validate_uniform_blocks(struct gl_shader_program *prog)
|
||||
&prog->NumBufferInterfaceBlocks,
|
||||
sh->BufferInterfaceBlocks[j]);
|
||||
|
||||
if (index == -1) {
|
||||
linker_error(prog, "uniform block `%s' has mismatching definitions\n",
|
||||
sh->BufferInterfaceBlocks[j]->Name);
|
||||
return false;
|
||||
}
|
||||
if (index == -1) {
|
||||
linker_error(prog, "uniform block `%s' has mismatching definitions\n",
|
||||
sh->BufferInterfaceBlocks[j]->Name);
|
||||
|
||||
prog->InterfaceBlockStageIndex[i][index] = j;
|
||||
for (unsigned k = 0; k <= i; k++) {
|
||||
delete[] InterfaceBlockStageIndex[k];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
InterfaceBlockStageIndex[i][index] = j;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1209,18 +1214,23 @@ interstage_cross_validate_uniform_blocks(struct gl_shader_program *prog)
|
||||
*/
|
||||
for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
|
||||
for (unsigned j = 0; j < prog->NumBufferInterfaceBlocks; j++) {
|
||||
int stage_index =
|
||||
prog->InterfaceBlockStageIndex[i][j];
|
||||
int stage_index = InterfaceBlockStageIndex[i][j];
|
||||
|
||||
if (stage_index != -1) {
|
||||
struct gl_shader *sh = prog->_LinkedShaders[i];
|
||||
|
||||
prog->BufferInterfaceBlocks[j].stageref |= (1 << i);
|
||||
|
||||
sh->BufferInterfaceBlocks[stage_index] =
|
||||
&prog->BufferInterfaceBlocks[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
|
||||
delete[] InterfaceBlockStageIndex[i];
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -3933,10 +3943,7 @@ build_program_resource_list(struct gl_context *ctx,
|
||||
/* Add stagereferences for uniforms in a uniform block. */
|
||||
int block_index = shProg->UniformStorage[i].block_index;
|
||||
if (block_index != -1) {
|
||||
for (unsigned j = 0; j < MESA_SHADER_STAGES; j++) {
|
||||
if (shProg->InterfaceBlockStageIndex[j][block_index] != -1)
|
||||
stageref |= (1 << j);
|
||||
}
|
||||
stageref |= shProg->BufferInterfaceBlocks[block_index].stageref;
|
||||
}
|
||||
|
||||
bool is_shader_storage = shProg->UniformStorage[i].is_shader_storage;
|
||||
|
@@ -96,8 +96,6 @@ _mesa_delete_shader(struct gl_context *ctx, struct gl_shader *sh)
|
||||
void
|
||||
_mesa_clear_shader_program_data(struct gl_shader_program *shProg)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
shProg->NumUniformStorage = 0;
|
||||
shProg->UniformStorage = NULL;
|
||||
shProg->NumUniformRemapTable = 0;
|
||||
@@ -119,11 +117,6 @@ _mesa_clear_shader_program_data(struct gl_shader_program *shProg)
|
||||
shProg->ShaderStorageBlocks = NULL;
|
||||
shProg->NumShaderStorageBlocks = 0;
|
||||
|
||||
for (i = 0; i < MESA_SHADER_STAGES; i++) {
|
||||
ralloc_free(shProg->InterfaceBlockStageIndex[i]);
|
||||
shProg->InterfaceBlockStageIndex[i] = NULL;
|
||||
}
|
||||
|
||||
ralloc_free(shProg->AtomicBuffers);
|
||||
shProg->AtomicBuffers = NULL;
|
||||
shProg->NumAtomicBuffers = 0;
|
||||
|
@@ -2529,6 +2529,9 @@ struct gl_uniform_block
|
||||
*/
|
||||
bool IsShaderStorage;
|
||||
|
||||
/** Stages that reference this block */
|
||||
uint8_t stageref;
|
||||
|
||||
/**
|
||||
* Layout specified in the shader
|
||||
*
|
||||
@@ -2829,16 +2832,6 @@ struct gl_shader_program
|
||||
unsigned NumShaderStorageBlocks;
|
||||
struct gl_uniform_block **ShaderStorageBlocks;
|
||||
|
||||
/**
|
||||
* Indices into the BufferInterfaceBlocks[] array for each stage they're
|
||||
* used in, or -1.
|
||||
*
|
||||
* This is used to maintain the Binding values of the stage's
|
||||
* BufferInterfaceBlocks[] and to answer the
|
||||
* GL_UNIFORM_BLOCK_REFERENCED_BY_*_SHADER queries.
|
||||
*/
|
||||
int *InterfaceBlockStageIndex[MESA_SHADER_STAGES];
|
||||
|
||||
/**
|
||||
* Map of active uniform names to locations
|
||||
*
|
||||
|
@@ -926,7 +926,7 @@ is_resource_referenced(struct gl_shader_program *shProg,
|
||||
return RESOURCE_ATC(res)->StageReferences[stage];
|
||||
|
||||
if (res->Type == GL_UNIFORM_BLOCK || res->Type == GL_SHADER_STORAGE_BLOCK)
|
||||
return shProg->InterfaceBlockStageIndex[stage][index] != -1;
|
||||
return shProg->BufferInterfaceBlocks[index].stageref & (1 << stage);
|
||||
|
||||
return res->StageReferences & (1 << stage);
|
||||
}
|
||||
|
@@ -295,10 +295,6 @@ _mesa_clear_shader_program_data(struct gl_shader_program *shProg)
|
||||
ralloc_free(shProg->BufferInterfaceBlocks);
|
||||
shProg->BufferInterfaceBlocks = NULL;
|
||||
shProg->NumBufferInterfaceBlocks = 0;
|
||||
for (i = 0; i < MESA_SHADER_STAGES; i++) {
|
||||
ralloc_free(shProg->InterfaceBlockStageIndex[i]);
|
||||
shProg->InterfaceBlockStageIndex[i] = NULL;
|
||||
}
|
||||
|
||||
ralloc_free(shProg->AtomicBuffers);
|
||||
shProg->AtomicBuffers = NULL;
|
||||
|
Reference in New Issue
Block a user