[Mesa-dev] [PATCH 14/87] glsl, i965: make use of on disk shader cache

Timothy Arceri timothy.arceri at collabora.com
Wed Jul 13 02:47:09 UTC 2016


The hash key for glsl metadata is a hash of the hashes of each GLSL
source string.

This commit uses the put_key/get_key support in the cache put the SHA-1
hash of the source string for each successfully compiled shader into the
cache. This allows for early, optimistic returns from glCompileShader
(if the identical source string had been successfully compiled in the pase),
in the hope that the final, linked shader will be found in the cache.

This is based on the intial patch by Carl, the big change is we check the
in memory i965 cache before checking the on-disk cache.
---
 src/compiler/glsl/glsl_parser_extras.cpp     | 16 ++++++++++++++++
 src/compiler/glsl/linker.cpp                 |  8 ++++++++
 src/mesa/drivers/dri/i965/brw_state_upload.c |  4 ++++
 src/mesa/drivers/dri/i965/brw_vs.c           | 21 ++++++++++++++++-----
 src/mesa/drivers/dri/i965/brw_wm.c           | 17 ++++++++++++++---
 src/mesa/program/ir_to_mesa.cpp              | 16 ++++++++++++++++
 6 files changed, 74 insertions(+), 8 deletions(-)

diff --git a/src/compiler/glsl/glsl_parser_extras.cpp b/src/compiler/glsl/glsl_parser_extras.cpp
index 9601424..a9a1a0e 100644
--- a/src/compiler/glsl/glsl_parser_extras.cpp
+++ b/src/compiler/glsl/glsl_parser_extras.cpp
@@ -36,6 +36,8 @@
 #include "glsl_parser.h"
 #include "ir_optimization.h"
 #include "loop_analysis.h"
+#include "cache.h"
+#include "util/mesa-sha1.h"
 
 /**
  * Format a short human-readable description of the given GLSL version.
@@ -1804,6 +1806,20 @@ _mesa_glsl_compile_shader(struct gl_context *ctx, struct gl_shader *shader,
    state->error = glcpp_preprocess(state, &source, &state->info_log,
                              &ctx->Extensions, ctx);
 
+#ifdef ENABLE_SHADER_CACHE
+   char buf[41];
+   _mesa_sha1_compute(source, strlen(source), shader->sha1);
+   if (ctx->Cache && cache_has_key(ctx->Cache, shader->sha1)) {
+      /* We've seen this shader before and know it compiles */
+      if (ctx->_Shader->Flags & GLSL_CACHE_INFO) {
+         fprintf(stderr, "deferring compile of shader: %s\n",
+                 _mesa_sha1_format(buf, shader->sha1));
+      }
+      shader->CompileStatus = true;
+      return;
+   }
+#endif
+
    if (!state->error) {
      _mesa_glsl_lexer_ctor(state, source);
      _mesa_glsl_parse(state);
diff --git a/src/compiler/glsl/linker.cpp b/src/compiler/glsl/linker.cpp
index d963f54..84f64cb 100644
--- a/src/compiler/glsl/linker.cpp
+++ b/src/compiler/glsl/linker.cpp
@@ -78,6 +78,9 @@
 #include "ir_optimization.h"
 #include "ir_rvalue_visitor.h"
 #include "ir_uniform.h"
+#include "util/mesa-sha1.h"
+#include "cache.h"
+#include "shader_cache.h"
 
 #include "main/shaderobj.h"
 #include "main/enums.h"
@@ -4507,6 +4510,11 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
    char **varying_names = NULL;
    tfeedback_decl *tfeedback_decls = NULL;
 
+#ifdef ENABLE_SHADER_CACHE
+   if (shader_cache_read_program_metadata(ctx, prog))
+      return;
+#endif
+
    void *mem_ctx = ralloc_context(NULL); // temporary linker context
 
    prog->ARB_fragment_coord_conventions_enable = false;
diff --git a/src/mesa/drivers/dri/i965/brw_state_upload.c b/src/mesa/drivers/dri/i965/brw_state_upload.c
index 4a20821..9586ea9 100644
--- a/src/mesa/drivers/dri/i965/brw_state_upload.c
+++ b/src/mesa/drivers/dri/i965/brw_state_upload.c
@@ -739,6 +739,10 @@ brw_upload_programs(struct brw_context *brw,
       }
 
       brw_upload_wm_prog(brw);
+
+#ifdef ENABLE_SHADER_CACHE
+      write_cached_program(brw);
+#endif
    } else if (pipeline == BRW_COMPUTE_PIPELINE) {
       brw_upload_cs_prog(brw);
    }
diff --git a/src/mesa/drivers/dri/i965/brw_vs.c b/src/mesa/drivers/dri/i965/brw_vs.c
index e203083..b0a0f23 100644
--- a/src/mesa/drivers/dri/i965/brw_vs.c
+++ b/src/mesa/drivers/dri/i965/brw_vs.c
@@ -362,7 +362,6 @@ brw_upload_vs_prog(struct brw_context *brw)
    struct gl_context *ctx = &brw->ctx;
    struct gl_shader_program **current = ctx->_Shader->CurrentProgram;
    struct brw_vs_prog_key key;
-   /* BRW_NEW_VERTEX_PROGRAM */
    struct brw_vertex_program *vp =
       (struct brw_vertex_program *)brw->vertex_program;
 
@@ -374,10 +373,22 @@ brw_upload_vs_prog(struct brw_context *brw)
    if (!brw_search_cache(&brw->cache, BRW_CACHE_VS_PROG,
 			 &key, sizeof(key),
 			 &brw->vs.base.prog_offset, &brw->vs.prog_data)) {
-      bool success = brw_codegen_vs_prog(brw, current[MESA_SHADER_VERTEX],
-                                         vp, &key);
-      (void) success;
-      assert(success);
+#ifdef ENABLE_SHADER_CACHE
+      upload_cached_program(brw, MESA_SHADER_VERTEX);
+
+      /* If upload from disk cache failed call codegen */
+      if (!current[MESA_SHADER_VERTEX] ||
+          !current[MESA_SHADER_VERTEX]->program_written_to_cache) {
+         vp = (struct brw_vertex_program *) brw->vertex_program;
+         vp->id = key.program_string_id;
+#endif
+         bool success = brw_codegen_vs_prog(brw, current[MESA_SHADER_VERTEX],
+                                            vp, &key);
+         (void) success;
+         assert(success);
+#ifdef ENABLE_SHADER_CACHE
+      }
+#endif
    }
    brw->vs.base.prog_data = &brw->vs.prog_data->base.base;
 }
diff --git a/src/mesa/drivers/dri/i965/brw_wm.c b/src/mesa/drivers/dri/i965/brw_wm.c
index 539926d..29b027d 100644
--- a/src/mesa/drivers/dri/i965/brw_wm.c
+++ b/src/mesa/drivers/dri/i965/brw_wm.c
@@ -570,9 +570,20 @@ brw_upload_wm_prog(struct brw_context *brw)
    if (!brw_search_cache(&brw->cache, BRW_CACHE_FS_PROG,
 			 &key, sizeof(key),
 			 &brw->wm.base.prog_offset, &brw->wm.prog_data)) {
-      bool success = brw_codegen_wm_prog(brw, current, fp, &key);
-      (void) success;
-      assert(success);
+#ifdef ENABLE_SHADER_CACHE
+      upload_cached_program(brw, MESA_SHADER_FRAGMENT);
+
+      /* If upload from disk cache failed call codegen */
+      if (!current || !current->program_written_to_cache) {
+         fp = (struct brw_fragment_program *) brw->fragment_program;
+         fp->id = key.program_string_id;
+#endif
+         bool success = brw_codegen_wm_prog(brw, current, fp, &key);
+         (void) success;
+         assert(success);
+#ifdef ENABLE_SHADER_CACHE
+      }
+#endif
    }
    brw->wm.base.prog_data = &brw->wm.prog_data->base;
 }
diff --git a/src/mesa/program/ir_to_mesa.cpp b/src/mesa/program/ir_to_mesa.cpp
index e74d94f..69f2ef2 100644
--- a/src/mesa/program/ir_to_mesa.cpp
+++ b/src/mesa/program/ir_to_mesa.cpp
@@ -46,6 +46,9 @@
 #include "compiler/glsl_types.h"
 #include "compiler/glsl/linker.h"
 #include "compiler/glsl/program.h"
+#include "compiler/glsl/shader_cache.h"
+#include "program/hash_table.h"
+
 #include "program/hash_table.h"
 #include "program/prog_instruction.h"
 #include "program/prog_optimize.h"
@@ -3066,6 +3069,14 @@ _mesa_glsl_link_shader(struct gl_context *ctx, struct gl_shader_program *prog)
       link_shaders(ctx, prog);
    }
 
+   /* FIXME: We look at prog->Version to determine whether we actually linked
+    * the program or just loaded the uniform meta data from cache.  We
+    * probably want to turn prog->LinkStatus into an enum that captures the
+    * different states.
+    */
+   if (prog->LinkStatus && prog->Version == 0)
+      return;
+
    if (prog->LinkStatus) {
       if (!ctx->Driver.LinkShader(ctx, prog)) {
 	 prog->LinkStatus = GL_FALSE;
@@ -3082,6 +3093,11 @@ _mesa_glsl_link_shader(struct gl_context *ctx, struct gl_shader_program *prog)
 	 fprintf(stderr, "%s\n", prog->InfoLog);
       }
    }
+
+#ifdef ENABLE_SHADER_CACHE
+   if (prog->LinkStatus)
+      shader_cache_write_program_metadata(ctx, prog);
+#endif
 }
 
 } /* extern "C" */
-- 
2.7.4



More information about the mesa-dev mailing list