[Mesa-dev] [PATCH 48/88] glsl: don't lose uniform values when falling back to full compile

Timothy Arceri timothy.arceri at collabora.com
Sat Sep 24 05:25:29 UTC 2016


Here we skip the recreation of uniform storage if we are relinking
after a cache miss.
---
 src/compiler/glsl/link_uniforms.cpp          | 33 +++++++++++++++++++++-------
 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, 45 insertions(+), 22 deletions(-)

diff --git a/src/compiler/glsl/link_uniforms.cpp b/src/compiler/glsl/link_uniforms.cpp
index c847ceb..799bcb2 100644
--- a/src/compiler/glsl/link_uniforms.cpp
+++ b/src/compiler/glsl/link_uniforms.cpp
@@ -1001,11 +1001,14 @@ 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 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();
@@ -1080,10 +1083,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
@@ -1118,6 +1128,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 (is_cache_fallback && 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 3362bce..d492997 100644
--- a/src/compiler/glsl/linker.cpp
+++ b/src/compiler/glsl/linker.cpp
@@ -4382,7 +4382,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;
@@ -4565,7 +4565,8 @@ link_varyings_and_uniforms(unsigned first, unsigned last,
    update_array_sizes(prog);
    link_assign_uniform_locations(prog, ctx->Const.UniformBooleanTrue,
                                  num_explicit_uniform_locs,
-                                 ctx->Const.MaxUserAssignableUniformLocations);
+                                 ctx->Const.MaxUserAssignableUniformLocations,
+                                 is_cache_fallback);
    link_assign_atomic_counter_resources(ctx, prog);
 
    link_calculate_subroutine_compat(prog);
@@ -4940,8 +4941,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 302a574..4e36d0b 100644
--- a/src/compiler/glsl/linker.h
+++ b/src/compiler/glsl/linker.h
@@ -37,7 +37,8 @@ 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 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 793edbf..d219ff4 100644
--- a/src/compiler/glsl/standalone.cpp
+++ b/src/compiler/glsl/standalone.cpp
@@ -402,7 +402,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 e62a823..0859dd2 100644
--- a/src/mesa/program/ir_to_mesa.cpp
+++ b/src/mesa/program/ir_to_mesa.cpp
@@ -3054,7 +3054,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



More information about the mesa-dev mailing list