From: Timothy Arceri Date: Sat, 2 Apr 2016 01:51:12 +0000 (+1100) Subject: glsl: store stage reference in gl_uniform_block X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=1265e1c4e17dec5c9931fda8b6d44a4006ed1a4c;p=mesa.git 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 --- diff --git a/src/compiler/glsl/linker.cpp b/src/compiler/glsl/linker.cpp index f440dbce888..f750f5b7722 100644 --- a/src/compiler/glsl/linker.cpp +++ b/src/compiler/glsl/linker.cpp @@ -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); + + for (unsigned k = 0; k <= i; k++) { + delete[] InterfaceBlockStageIndex[k]; + } + return false; + } - prog->InterfaceBlockStageIndex[i][index] = j; + 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; diff --git a/src/compiler/glsl/standalone_scaffolding.cpp b/src/compiler/glsl/standalone_scaffolding.cpp index e350f702099..49b4a26dc12 100644 --- a/src/compiler/glsl/standalone_scaffolding.cpp +++ b/src/compiler/glsl/standalone_scaffolding.cpp @@ -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; diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index f2cb4cb107b..e579794de3c 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -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 * diff --git a/src/mesa/main/shader_query.cpp b/src/mesa/main/shader_query.cpp index 4650a5c9ef1..4ef6a81204e 100644 --- a/src/mesa/main/shader_query.cpp +++ b/src/mesa/main/shader_query.cpp @@ -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); } diff --git a/src/mesa/main/shaderobj.c b/src/mesa/main/shaderobj.c index 9a4eb6b56fd..8b9166ceecb 100644 --- a/src/mesa/main/shaderobj.c +++ b/src/mesa/main/shaderobj.c @@ -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;