diff options
Diffstat (limited to 'src/glsl')
-rw-r--r-- | src/glsl/ir_uniform.h | 6 | ||||
-rw-r--r-- | src/glsl/link_uniforms.cpp | 35 |
2 files changed, 30 insertions, 11 deletions
diff --git a/src/glsl/ir_uniform.h b/src/glsl/ir_uniform.h index 7508f795d08..3508509d4d0 100644 --- a/src/glsl/ir_uniform.h +++ b/src/glsl/ir_uniform.h @@ -178,6 +178,12 @@ struct gl_uniform_storage { * an atomic counter. */ int atomic_buffer_index; + + /** + * The 'base location' for this uniform in the uniform remap table. For + * arrays this is the first element in the array. + */ + unsigned remap_location; }; #ifdef __cplusplus diff --git a/src/glsl/link_uniforms.cpp b/src/glsl/link_uniforms.cpp index 1c451e7f51c..3fedf313cbd 100644 --- a/src/glsl/link_uniforms.cpp +++ b/src/glsl/link_uniforms.cpp @@ -799,6 +799,10 @@ link_assign_uniform_locations(struct gl_shader_program *prog) prog->UniformStorage = NULL; prog->NumUserUniformStorage = 0; + ralloc_free(prog->UniformRemapTable); + prog->UniformRemapTable = NULL; + prog->NumUniformRemapTable = 0; + if (prog->UniformHash != NULL) { prog->UniformHash->clear(); } else { @@ -911,19 +915,28 @@ link_assign_uniform_locations(struct gl_shader_program *prog) sizeof(prog->_LinkedShaders[i]->SamplerTargets)); } - /* Determine the size of the largest uniform array queryable via - * glGetUniformLocation. Using this as the location scale guarantees that - * there is enough "room" for the array index to be stored in the low order - * part of the uniform location. It also makes the locations be more - * tightly packed. - */ - unsigned max_array_size = 1; + /* Build the uniform remap table that is used to set/get uniform locations */ for (unsigned i = 0; i < num_user_uniforms; i++) { - if (uniforms[i].array_elements > max_array_size) - max_array_size = uniforms[i].array_elements; - } - prog->UniformLocationBaseScale = max_array_size; + /* how many new entries for this uniform? */ + const unsigned entries = MAX2(1, uniforms[i].array_elements); + + /* resize remap table to fit new entries */ + prog->UniformRemapTable = + reralloc(prog, + prog->UniformRemapTable, + gl_uniform_storage *, + prog->NumUniformRemapTable + entries); + + /* set pointers for this uniform */ + for (unsigned j = 0; j < entries; j++) + prog->UniformRemapTable[prog->NumUniformRemapTable+j] = &uniforms[i]; + + /* set the base location in remap table for the uniform */ + uniforms[i].remap_location = prog->NumUniformRemapTable; + + prog->NumUniformRemapTable += entries; + } #ifndef NDEBUG for (unsigned i = 0; i < num_user_uniforms; i++) { |