[Mesa-dev] [PATCH 42/56] i965: add cache fallback support

Timothy Arceri timothy.arceri at collabora.com
Tue Nov 29 03:58:41 UTC 2016


This is fairly simple, if we have no IR we compile the fallback
shaders then copy the other fallback data such as attibute bindings
to a temp shader program struct, then we link the program and clean
up the mess. The IR will be attached to the existing gl_program.
---
 src/mesa/drivers/dri/i965/brw_shader_cache.c | 84 +++++++++++++++++++++++++++-
 src/mesa/main/shaderobj.c                    |  3 +-
 src/mesa/program/program.c                   |  5 +-
 3 files changed, 88 insertions(+), 4 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_shader_cache.c b/src/mesa/drivers/dri/i965/brw_shader_cache.c
index 7345242..755e63d 100644
--- a/src/mesa/drivers/dri/i965/brw_shader_cache.c
+++ b/src/mesa/drivers/dri/i965/brw_shader_cache.c
@@ -23,12 +23,16 @@
 
 #include "compiler/glsl/blob.h"
 #include "compiler/glsl/ir_uniform.h"
+#include "compiler/glsl/program.h"
 #include "compiler/glsl/shader_cache.h"
 #include "compiler/nir_types.h"
 #include "main/mtypes.h"
+#include "main/shaderobj.h"
+#include "program/program.h"
 #include "util/disk_cache.h"
 #include "util/macros.h"
 #include "util/mesa-sha1.h"
+#include "util/string_to_uint_map.h"
 
 #include "brw_context.h"
 #include "brw_state.h"
@@ -78,6 +82,84 @@ gen_shader_sha1(struct brw_context *brw, struct gl_program *prog,
 }
 
 static void
+fallback_to_full_recompile(struct brw_context *brw,
+                           struct gl_program *prog)
+{
+   prog->program_written_to_cache = false;
+   if (brw->ctx._Shader->Flags & GLSL_CACHE_INFO) {
+      fprintf(stderr, "Falling back to compile %s from source.\n",
+              _mesa_shader_stage_to_abbrev(prog->info.stage));
+   }
+
+   /* Cached program not found. Fall back to linking shaders but first
+    * compile any shaders we didn't compile earlier.
+    */
+   if (!prog->nir) {
+      prog->sh.data->cache_fallback = true;
+
+      for (unsigned i = 0; i < prog->sh.data->NumFallbackShaders; i++) {
+         _mesa_glsl_compile_shader(&brw->ctx, prog->sh.data->FallbackShaders[i],
+                                   false, false, true);
+      }
+
+      /* Create a temp shader program to be used for linking */
+      struct gl_shader_program *shProg = _mesa_new_shader_program(prog->Id);
+      ralloc_free(shProg->data);
+      shProg->data = prog->sh.data;
+
+      shProg->NumShaders = prog->sh.data->NumFallbackShaders;
+      shProg->Shaders = prog->sh.data->FallbackShaders;
+
+      string_to_uint_map_dtor(shProg->AttributeBindings);
+      shProg->AttributeBindings = prog->sh.data->FallbackAttributeBindings;
+      string_to_uint_map_dtor(shProg->FragDataBindings);
+      shProg->FragDataBindings = prog->sh.data->FallbackFragDataBindings;
+      string_to_uint_map_dtor(shProg->FragDataIndexBindings);
+      shProg->FragDataIndexBindings =
+         prog->sh.data->FallbackFragDataIndexBindings;
+      shProg->SeparateShader = prog->info.separate_shader;
+
+      for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
+         struct gl_program *curr_prog = brw->ctx._Shader->CurrentProgram[i];
+         if (!curr_prog)
+            continue;
+
+         shProg->cache_progs[i] = curr_prog;
+      }
+
+      _mesa_glsl_link_shader(&brw->ctx, shProg);
+
+      /* We should never get here again so free the fallback data */
+      prog->sh.data->NumFallbackShaders = 0;
+      ralloc_free(prog->sh.data->FallbackShaders);
+      prog->sh.data->FallbackShaders = NULL;
+
+      string_to_uint_map_dtor(shProg->AttributeBindings);
+      prog->sh.data->FallbackAttributeBindings = NULL;
+      shProg->AttributeBindings = NULL;
+
+      string_to_uint_map_dtor(shProg->FragDataBindings);
+      prog->sh.data->FallbackFragDataBindings = NULL;
+      shProg->FragDataBindings = NULL;
+
+      string_to_uint_map_dtor(shProg->FragDataIndexBindings);
+      prog->sh.data->FallbackFragDataIndexBindings = NULL;
+      shProg->FragDataIndexBindings = NULL;
+
+      /* Since we don't bother referencing these we need to reset them so the
+       * delete shader program call doesn't try to remove a reference that
+       * doesn't exist.
+       */
+      shProg->NumShaders = 0;
+      shProg->Shaders = NULL;
+
+      _mesa_delete_shader_program(&brw->ctx, shProg);
+
+      prog->sh.data->cache_fallback = false;
+   }
+}
+
+static void
 load_program_data(struct gl_program *glprog, struct blob_reader *binary,
                   struct brw_stage_prog_data *prog_data,
                   gl_shader_stage stage, struct gl_context *ctx)
@@ -327,7 +409,7 @@ upload_cached_program(struct brw_context *brw, gl_shader_stage stage)
    return true;
 
 FAIL:
-   /*FIXME: Fall back and compile from source here. */
+   fallback_to_full_recompile(brw, prog);
    return false;
 }
 
diff --git a/src/mesa/main/shaderobj.c b/src/mesa/main/shaderobj.c
index 728ff43..95432c6 100644
--- a/src/mesa/main/shaderobj.c
+++ b/src/mesa/main/shaderobj.c
@@ -137,7 +137,8 @@ void
 _mesa_delete_linked_shader(struct gl_context *ctx,
                            struct gl_linked_shader *sh)
 {
-   _mesa_reference_program(ctx, &sh->Program, NULL);
+   if (sh->Program && !sh->Program->sh.data->cache_fallback)
+      _mesa_reference_program(ctx, &sh->Program, NULL);
    ralloc_free(sh);
 }
 
diff --git a/src/mesa/program/program.c b/src/mesa/program/program.c
index 39aef5c..710d5ff 100644
--- a/src/mesa/program/program.c
+++ b/src/mesa/program/program.c
@@ -266,7 +266,7 @@ _mesa_delete_program(struct gl_context *ctx, struct gl_program *prog)
       _mesa_free_parameter_list(prog->Parameters);
    }
 
-   if (prog->nir) {
+   if (prog->nir && (prog->is_arb_asm || !prog->sh.data->cache_fallback)) {
       ralloc_free(prog->nir);
    }
 
@@ -327,8 +327,9 @@ _mesa_reference_program_(struct gl_context *ctx,
 
       if (deleteFlag) {
          assert(ctx);
-         _mesa_reference_shader_program_data(ctx, &oldProg->sh.data, NULL);
+         struct gl_shader_program_data *data = oldProg->sh.data;
          ctx->Driver.DeleteProgram(ctx, oldProg);
+         _mesa_reference_shader_program_data(ctx, &data, NULL);
       }
 
       *ptr = NULL;
-- 
2.7.4



More information about the mesa-dev mailing list