From 1265e1c4e17dec5c9931fda8b6d44a4006ed1a4c Mon Sep 17 00:00:00 2001 From: Timothy Arceri Date: Sat, 2 Apr 2016 12:51:12 +1100 Subject: [PATCH] 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 --- src/compiler/glsl/linker.cpp | 37 +++++++++++++++++----------- src/compiler/glsl/standalone_scaffolding.cpp | 7 ------ src/mesa/main/mtypes.h | 13 +++------- src/mesa/main/shader_query.cpp | 2 +- src/mesa/main/shaderobj.c | 4 --- 5 files changed, 26 insertions(+), 37 deletions(-) diff --git a/src/compiler/glsl/linker.cpp b/src/compiler/glsl/linker.cpp index f440dbc..f750f5b 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 e350f70..49b4a26 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 f2cb4cb..e579794 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 * @@ -2830,16 +2833,6 @@ struct gl_shader_program 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 * * Maps any active uniform that is not an array element to a location. diff --git a/src/mesa/main/shader_query.cpp b/src/mesa/main/shader_query.cpp index 4650a5c..4ef6a81 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 9a4eb6b..8b9166c 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; -- 2.7.4