Here we skip the recreation of uniform storage if we are relinking after a cache miss. --- src/compiler/glsl/link_uniforms.cpp | 38 ++++++++++++++++++++-------- src/compiler/glsl/linker.cpp | 9 ++++--- src/compiler/glsl/linker.h | 3 ++- src/compiler/glsl/standalone.cpp | 2 +- src/compiler/glsl/standalone_scaffolding.cpp | 3 ++- src/compiler/glsl/standalone_scaffolding.h | 3 ++- src/mesa/main/shaderobj.c | 9 ++++--- src/mesa/main/shaderobj.h | 3 ++- src/mesa/program/ir_to_mesa.cpp | 2 +- 9 files changed, 47 insertions(+), 25 deletions(-)
diff --git a/src/compiler/glsl/link_uniforms.cpp b/src/compiler/glsl/link_uniforms.cpp index 067db8d..ad7e8b7 100644 --- a/src/compiler/glsl/link_uniforms.cpp +++ b/src/compiler/glsl/link_uniforms.cpp @@ -1156,7 +1156,8 @@ static void link_assign_uniform_storage(struct gl_context *ctx, struct gl_shader_program *prog, const unsigned num_data_slots, - unsigned num_explicit_uniform_locs) + unsigned num_explicit_uniform_locs, + bool is_cache_fallback) { /* On the outside chance that there were no uniforms, bail out. */ @@ -1165,11 +1166,16 @@ link_assign_uniform_storage(struct gl_context *ctx, unsigned int boolean_true = ctx->Const.UniformBooleanTrue; - prog->UniformStorage = rzalloc_array(prog, struct gl_uniform_storage, - prog->NumUniformStorage); - union gl_constant_value *data = rzalloc_array(prog->UniformStorage, - union gl_constant_value, - num_data_slots); + union gl_constant_value *data; + if (prog->UniformStorage == NULL) { + prog->UniformStorage = rzalloc_array(prog, struct gl_uniform_storage, + prog->NumUniformStorage); + data = rzalloc_array(prog->UniformStorage, union gl_constant_value, + num_data_slots); + } else { + data = prog->UniformDataSlots; + } + #ifndef NDEBUG union gl_constant_value *data_end = &data[num_data_slots]; #endif @@ -1202,6 +1208,13 @@ link_assign_uniform_storage(struct gl_context *ctx, 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 (is_cache_fallback) + return; + #ifndef NDEBUG for (unsigned i = 0; i < prog->NumUniformStorage; i++) { assert(prog->UniformStorage[i].storage != NULL || @@ -1225,11 +1238,14 @@ link_assign_uniform_storage(struct gl_context *ctx, void link_assign_uniform_locations(struct gl_shader_program *prog, struct gl_context *ctx, - unsigned int num_explicit_uniform_locs) + unsigned int num_explicit_uniform_locs, + bool is_cache_fallback) { - ralloc_free(prog->UniformStorage); - prog->UniformStorage = NULL; - prog->NumUniformStorage = 0; + if (!is_cache_fallback) { + ralloc_free(prog->UniformStorage); + prog->UniformStorage = NULL; + prog->NumUniformStorage = 0; + } if (prog->UniformHash != NULL) { prog->UniformHash->clear(); @@ -1299,5 +1315,5 @@ link_assign_uniform_locations(struct gl_shader_program *prog, delete hiddenUniforms; link_assign_uniform_storage(ctx, prog, uniform_size.num_values, - num_explicit_uniform_locs); + num_explicit_uniform_locs, is_cache_fallback); } diff --git a/src/compiler/glsl/linker.cpp b/src/compiler/glsl/linker.cpp index 56df085..fb0b076 100644 --- a/src/compiler/glsl/linker.cpp +++ b/src/compiler/glsl/linker.cpp @@ -4381,7 +4381,7 @@ disable_varying_optimizations_for_sso(struct gl_shader_program *prog) static bool link_varyings_and_uniforms(unsigned first, unsigned last, unsigned num_explicit_uniform_locs, - struct gl_context *ctx, + bool is_cache_fallback, struct gl_context *ctx, struct gl_shader_program *prog, void *mem_ctx) { bool has_xfb_qualifiers = false; @@ -4562,7 +4562,8 @@ link_varyings_and_uniforms(unsigned first, unsigned last, return false; update_array_sizes(prog); - link_assign_uniform_locations(prog, ctx, num_explicit_uniform_locs); + link_assign_uniform_locations(prog, ctx, num_explicit_uniform_locs, + is_cache_fallback); link_assign_atomic_counter_resources(ctx, prog); link_calculate_subroutine_compat(prog); @@ -4937,8 +4938,8 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog, store_fragdepth_layout(prog); - if(!link_varyings_and_uniforms(first, last, num_explicit_uniform_locs, ctx, - prog, mem_ctx)) + if(!link_varyings_and_uniforms(first, last, num_explicit_uniform_locs, + is_cache_fallback, ctx, prog, mem_ctx)) goto done; /* OpenGL ES < 3.1 requires that a vertex shader and a fragment shader both diff --git a/src/compiler/glsl/linker.h b/src/compiler/glsl/linker.h index b503fd5..e8ff0a2 100644 --- a/src/compiler/glsl/linker.h +++ b/src/compiler/glsl/linker.h @@ -36,7 +36,8 @@ link_invalidate_variable_locations(exec_list *ir); extern void link_assign_uniform_locations(struct gl_shader_program *prog, struct gl_context *ctx, - unsigned int num_explicit_uniform_locs); + unsigned int num_explicit_uniform_locs, + bool is_cache_fallback); extern void link_set_uniform_initializers(struct gl_shader_program *prog, diff --git a/src/compiler/glsl/standalone.cpp b/src/compiler/glsl/standalone.cpp index e57da69..089b16e 100644 --- a/src/compiler/glsl/standalone.cpp +++ b/src/compiler/glsl/standalone.cpp @@ -418,7 +418,7 @@ standalone_compile_shader(const struct standalone_options *_options, } if ((status == EXIT_SUCCESS) && options->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 956be6d..c16790f 100644 --- a/src/compiler/glsl/standalone_scaffolding.cpp +++ b/src/compiler/glsl/standalone_scaffolding.cpp @@ -131,7 +131,8 @@ _mesa_delete_linked_shader(struct gl_context *ctx, } void -_mesa_clear_shader_program_data(struct gl_shader_program *shProg) +_mesa_clear_shader_program_data(struct gl_shader_program *shProg, + bool is_cache_fallback) { shProg->NumUniformStorage = 0; shProg->UniformStorage = NULL; diff --git a/src/compiler/glsl/standalone_scaffolding.h b/src/compiler/glsl/standalone_scaffolding.h index 7d2ef24..683675f 100644 --- a/src/compiler/glsl/standalone_scaffolding.h +++ b/src/compiler/glsl/standalone_scaffolding.h @@ -60,7 +60,8 @@ _mesa_delete_linked_shader(struct gl_context *ctx, struct gl_linked_shader *sh); extern "C" void -_mesa_clear_shader_program_data(struct gl_shader_program *); +_mesa_clear_shader_program_data(struct gl_shader_program *, + bool is_cache_fallback); 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 350b677..b6b6c99 100644 --- a/src/mesa/main/shaderobj.c +++ b/src/mesa/main/shaderobj.c @@ -289,11 +289,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 is_cache_fallback) { unsigned i; - if (shProg->UniformStorage) { + if (shProg->UniformStorage && !is_cache_fallback) { for (i = 0; i < shProg->NumUniformStorage; ++i) _mesa_uniform_detach_all_driver_storage(&shProg->UniformStorage[i]); ralloc_free(shProg->UniformStorage); @@ -301,7 +302,7 @@ _mesa_clear_shader_program_data(struct gl_shader_program *shProg) shProg->UniformStorage = NULL; } - if (shProg->UniformRemapTable) { + if (shProg->UniformRemapTable && !is_cache_fallback) { ralloc_free(shProg->UniformRemapTable); shProg->NumUniformRemapTable = 0; shProg->UniformRemapTable = NULL; @@ -349,7 +350,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 814a7f1..354ac8c 100644 --- a/src/mesa/main/shaderobj.h +++ b/src/mesa/main/shaderobj.h @@ -99,7 +99,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 is_cache_fallback); 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 f595e61..9d4b20b 100644 --- a/src/mesa/program/ir_to_mesa.cpp +++ b/src/mesa/program/ir_to_mesa.cpp @@ -3055,7 +3055,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, is_cache_fallback); prog->LinkStatus = GL_TRUE; -- 2.7.4 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev