Here we skip the recreation of uniform storage if we are relinking after a cache miss. --- src/compiler/glsl/link_uniforms.cpp | 32 +++++++++++++++++++++------- src/compiler/glsl/linker.cpp | 3 ++- src/compiler/glsl/linker.h | 2 +- src/compiler/glsl/main.cpp | 2 +- src/compiler/glsl/standalone_scaffolding.cpp | 3 ++- src/compiler/glsl/standalone_scaffolding.h | 2 +- src/mesa/main/shaderobj.c | 9 ++++---- src/mesa/main/shaderobj.h | 3 ++- src/mesa/program/ir_to_mesa.cpp | 2 +- 9 files changed, 39 insertions(+), 19 deletions(-)
diff --git a/src/compiler/glsl/link_uniforms.cpp b/src/compiler/glsl/link_uniforms.cpp index 8c27030..fc566ac 100644 --- a/src/compiler/glsl/link_uniforms.cpp +++ b/src/compiler/glsl/link_uniforms.cpp @@ -995,11 +995,13 @@ void link_assign_uniform_locations(struct gl_shader_program *prog, unsigned int boolean_true, unsigned int num_explicit_uniform_locs, - unsigned int max_uniform_locs) + unsigned int max_uniform_locs, bool skip_cache) { - ralloc_free(prog->UniformStorage); - prog->UniformStorage = NULL; - prog->NumUniformStorage = 0; + if (!skip_cache) { + ralloc_free(prog->UniformStorage); + prog->UniformStorage = NULL; + prog->NumUniformStorage = 0; + } if (prog->UniformHash != NULL) { prog->UniformHash->clear(); @@ -1074,10 +1076,17 @@ link_assign_uniform_locations(struct gl_shader_program *prog, if (num_uniforms == 0) return; - struct gl_uniform_storage *uniforms = - rzalloc_array(prog, struct gl_uniform_storage, num_uniforms); - union gl_constant_value *data = - rzalloc_array(uniforms, union gl_constant_value, num_data_slots); + struct gl_uniform_storage *uniforms; + union gl_constant_value *data; + + if (prog->UniformStorage == NULL) { + uniforms = rzalloc_array(prog, struct gl_uniform_storage, num_uniforms); + data = rzalloc_array(uniforms, union gl_constant_value, num_data_slots); + } else { + uniforms = prog->UniformStorage; + data = prog->UniformDataSlots; + } + #ifndef NDEBUG union gl_constant_value *data_end = &data[num_data_slots]; #endif @@ -1112,6 +1121,13 @@ link_assign_uniform_locations(struct gl_shader_program *prog, sizeof(prog->_LinkedShaders[i]->SamplerTargets)); } + /* If this is a fallback compile for a cache miss we already have the + * correct uniform mappings and we don't want to reinitialise uniforms so + * just return now. + */ + if (skip_cache && prog->UniformStorage) + return; + /* Reserve all the explicit locations of the active uniforms. */ for (unsigned i = 0; i < num_uniforms; i++) { if (uniforms[i].type->is_subroutine() || diff --git a/src/compiler/glsl/linker.cpp b/src/compiler/glsl/linker.cpp index c493de2..45b8e46 100644 --- a/src/compiler/glsl/linker.cpp +++ b/src/compiler/glsl/linker.cpp @@ -4773,7 +4773,8 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog, update_array_sizes(prog); link_assign_uniform_locations(prog, ctx->Const.UniformBooleanTrue, num_explicit_uniform_locs, - ctx->Const.MaxUserAssignableUniformLocations); + ctx->Const.MaxUserAssignableUniformLocations, + skip_cache); link_assign_atomic_counter_resources(ctx, prog); store_fragdepth_layout(prog); diff --git a/src/compiler/glsl/linker.h b/src/compiler/glsl/linker.h index f026732..6b68c41 100644 --- a/src/compiler/glsl/linker.h +++ b/src/compiler/glsl/linker.h @@ -37,7 +37,7 @@ extern void link_assign_uniform_locations(struct gl_shader_program *prog, unsigned int boolean_true, unsigned int num_explicit_uniform_locs, - unsigned int max_uniform_locs); + unsigned int max_uniform_locs, bool skip_cache); extern void link_set_uniform_initializers(struct gl_shader_program *prog, diff --git a/src/compiler/glsl/main.cpp b/src/compiler/glsl/main.cpp index 97cedb5..1d3c5a3 100644 --- a/src/compiler/glsl/main.cpp +++ b/src/compiler/glsl/main.cpp @@ -424,7 +424,7 @@ main(int argc, char **argv) } if ((status == EXIT_SUCCESS) && do_link) { - _mesa_clear_shader_program_data(whole_program); + _mesa_clear_shader_program_data(whole_program, false); link_shaders(ctx, whole_program, true); status = (whole_program->LinkStatus) ? EXIT_SUCCESS : EXIT_FAILURE; diff --git a/src/compiler/glsl/standalone_scaffolding.cpp b/src/compiler/glsl/standalone_scaffolding.cpp index fffe6cc..886a1bb 100644 --- a/src/compiler/glsl/standalone_scaffolding.cpp +++ b/src/compiler/glsl/standalone_scaffolding.cpp @@ -114,7 +114,8 @@ _mesa_delete_shader(struct gl_context *ctx, struct gl_shader *sh) } void -_mesa_clear_shader_program_data(struct gl_shader_program *shProg) +_mesa_clear_shader_program_data(struct gl_shader_program *shProg, + bool skip_cache) { shProg->NumUniformStorage = 0; shProg->UniformStorage = NULL; diff --git a/src/compiler/glsl/standalone_scaffolding.h b/src/compiler/glsl/standalone_scaffolding.h index 38bd76a..5c6e72c 100644 --- a/src/compiler/glsl/standalone_scaffolding.h +++ b/src/compiler/glsl/standalone_scaffolding.h @@ -53,7 +53,7 @@ extern "C" void _mesa_delete_shader(struct gl_context *ctx, struct gl_shader *sh); extern "C" void -_mesa_clear_shader_program_data(struct gl_shader_program *); +_mesa_clear_shader_program_data(struct gl_shader_program *, bool skip_cache); extern "C" void _mesa_shader_debug(struct gl_context *ctx, GLenum type, GLuint *id, diff --git a/src/mesa/main/shaderobj.c b/src/mesa/main/shaderobj.c index 274cb12..49a155c 100644 --- a/src/mesa/main/shaderobj.c +++ b/src/mesa/main/shaderobj.c @@ -265,11 +265,12 @@ _mesa_new_shader_program(GLuint name) * Clear (free) the shader program state that gets produced by linking. */ void -_mesa_clear_shader_program_data(struct gl_shader_program *shProg) +_mesa_clear_shader_program_data(struct gl_shader_program *shProg, + bool skip_cache) { unsigned i; - if (shProg->UniformStorage) { + if (shProg->UniformStorage && !skip_cache) { for (i = 0; i < shProg->NumUniformStorage; ++i) _mesa_uniform_detach_all_driver_storage(&shProg->UniformStorage[i]); ralloc_free(shProg->UniformStorage); @@ -277,7 +278,7 @@ _mesa_clear_shader_program_data(struct gl_shader_program *shProg) shProg->UniformStorage = NULL; } - if (shProg->UniformRemapTable) { + if (shProg->UniformRemapTable && !skip_cache) { ralloc_free(shProg->UniformRemapTable); shProg->NumUniformRemapTable = 0; shProg->UniformRemapTable = NULL; @@ -325,7 +326,7 @@ _mesa_free_shader_program_data(struct gl_context *ctx, assert(shProg->Type == GL_SHADER_PROGRAM_MESA); - _mesa_clear_shader_program_data(shProg); + _mesa_clear_shader_program_data(shProg, false); if (shProg->AttributeBindings) { string_to_uint_map_dtor(shProg->AttributeBindings); diff --git a/src/mesa/main/shaderobj.h b/src/mesa/main/shaderobj.h index 53836f1..388de39 100644 --- a/src/mesa/main/shaderobj.h +++ b/src/mesa/main/shaderobj.h @@ -96,7 +96,8 @@ extern struct gl_shader_program * _mesa_new_shader_program(GLuint name); extern void -_mesa_clear_shader_program_data(struct gl_shader_program *shProg); +_mesa_clear_shader_program_data(struct gl_shader_program *shProg, + bool skip_cache); extern void _mesa_free_shader_program_data(struct gl_context *ctx, diff --git a/src/mesa/program/ir_to_mesa.cpp b/src/mesa/program/ir_to_mesa.cpp index fa034ab..4f4cbaf 100644 --- a/src/mesa/program/ir_to_mesa.cpp +++ b/src/mesa/program/ir_to_mesa.cpp @@ -2992,7 +2992,7 @@ _mesa_glsl_link_shader(struct gl_context *ctx, struct gl_shader_program *prog, { unsigned int i; - _mesa_clear_shader_program_data(prog); + _mesa_clear_shader_program_data(prog, skip_cache); prog->LinkStatus = GL_TRUE; -- 2.5.5 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev