[Mesa-dev] [v2 4/4] glsl: use gl_shader_cache when compiling (WIP)

Tapani Pälli tapani.palli at intel.com
Sun Sep 29 23:14:59 PDT 2013


Patch takes gl_shader_cache in to use if Mesa is compiled with
additional option '--enable-shadercache'. When compiling a shader,
compiler first checks the cache if shader exists already or does
it need to be compiled. Compiler also attempts to cache all
compiled shaders.

Signed-off-by: Tapani Pälli <tapani.palli at intel.com>
---
 configure.ac                    | 19 ++++++++++++++++++
 src/glsl/glsl_parser_extras.cpp | 44 +++++++++++++++++++++++++++++++++++++++++
 src/mesa/main/context.c         |  4 ++++
 src/mesa/main/mtypes.h          |  6 ++++++
 4 files changed, 73 insertions(+)

diff --git a/configure.ac b/configure.ac
index 1f0a646..d72142e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -892,6 +892,19 @@ AS_IF([test "x$GLX_USE_TLS" = xyes -a "x$ax_pthread_ok" = xyes],
       [DEFINES="${DEFINES} -DGLX_USE_TLS -DHAVE_PTHREAD"])
 
 dnl
+dnl Shadercache
+dnl
+AC_ARG_ENABLE([shadercache],
+    [AS_HELP_STRING([--enable-shadercache],
+        [enable compiler shader cache @<:@default=disabled@:>@])],
+    [USE_SHADERCACHE="$enableval"],
+    [USE_SHADERCACHE=no])
+AC_SUBST(SHADERCACHE, ${USE_SHADERCACHE})
+
+AS_IF([test "x$USE_SHADERCACHE" = xyes],
+      [DEFINES="${DEFINES} -DUSE_SHADERCACHE"])
+
+dnl
 dnl More DRI setup
 dnl
 dnl Directory for DRI drivers
@@ -2221,6 +2234,12 @@ else
     echo "        Gallium:         no"
 fi
 
+echo ""
+if test "x$USE_SHADERCACHE" = xyes; then
+    echo "        Shadercache:     yes"
+else
+    echo "        Shadercache:     no"
+fi
 
 dnl Libraries
 echo ""
diff --git a/src/glsl/glsl_parser_extras.cpp b/src/glsl/glsl_parser_extras.cpp
index e9922fc..14545a8 100644
--- a/src/glsl/glsl_parser_extras.cpp
+++ b/src/glsl/glsl_parser_extras.cpp
@@ -30,6 +30,7 @@ extern "C" {
 #include "main/context.h"
 #include "main/shaderobj.h"
 }
+#include "main/shadercache.h"
 
 #include "ralloc.h"
 #include "ast.h"
@@ -37,6 +38,7 @@ extern "C" {
 #include "glsl_parser.h"
 #include "ir_optimization.h"
 #include "loop_analysis.h"
+#include "linker.h"
 
 /**
  * Format a short human-readable description of the given GLSL version.
@@ -1448,6 +1450,42 @@ _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 USE_SHADERCACHE
+   /* if no preprocessing errors, check if we have the same shader cached */
+   if (!state->error) {
+      struct gl_shader *existing =
+         ctx->VertexProgram.ShaderCache->find(shader, source, state);
+      if (existing) {
+         /* use cached shader, clone ir list, populate symbol table */
+         shader->CompileStatus = GL_TRUE;
+         shader->InfoLog = state->info_log;
+         shader->Version = existing->Version;
+         shader->Type = existing->Type;
+         shader->IsES = existing->IsES;
+
+         /**
+          * NOTE - following should not be needed and should be removed
+          * as takes a lot of time. Problem with this is that we might currently
+          * bail out while reading cache and decide to use the original. This
+          * should be decided/known already when writing cache.
+          */
+         ralloc_free(shader->ir);
+         shader->ir = new(shader) exec_list;
+         clone_ir_list(shader, shader->ir, existing->ir);
+         ralloc_free(existing->ir);
+         ralloc_free(existing);
+
+         populate_symbol_table(shader);
+
+         memcpy(shader->builtins_to_link, state->builtins_to_link,
+            sizeof(shader->builtins_to_link[0]) * state->num_builtins_to_link);
+         shader->num_builtins_to_link = state->num_builtins_to_link;
+
+         return;
+      }
+   }
+#endif
+
    if (!state->error) {
      _mesa_glsl_lexer_ctor(state, source);
      _mesa_glsl_parse(state);
@@ -1516,6 +1554,12 @@ _mesa_glsl_compile_shader(struct gl_context *ctx, struct gl_shader *shader,
    /* Retain any live IR, but trash the rest. */
    reparent_ir(shader->ir, shader->ir);
 
+#ifdef USE_SHADERCACHE
+   /* shader compiled fine, attempt to cache this shader */
+   if (shader->CompileStatus == GL_TRUE)
+      ctx->VertexProgram.ShaderCache->cache(shader, source, state);
+#endif
+
    ralloc_free(state);
 }
 
diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c
index 310518c..3a2be05 100644
--- a/src/mesa/main/context.c
+++ b/src/mesa/main/context.c
@@ -132,6 +132,7 @@
 #include "program/prog_print.h"
 #include "math/m_matrix.h"
 #include "main/dispatch.h" /* for _gloffset_COUNT */
+#include "shadercache.h"
 
 #ifdef USE_SPARC_ASM
 #include "sparc/sparc.h"
@@ -776,6 +777,9 @@ init_attrib_groups(struct gl_context *ctx)
    _mesa_init_rastpos( ctx );
    _mesa_init_scissor( ctx );
    _mesa_init_shader_state( ctx );
+#ifdef USE_SHADERCACHE
+   _mesa_init_shader_cache( ctx );
+#endif
    _mesa_init_stencil( ctx );
    _mesa_init_transform( ctx );
    _mesa_init_transform_feedback( ctx );
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index d82672d..5844dc9 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -74,6 +74,7 @@ struct gl_attrib_node;
 struct gl_list_extensions;
 struct gl_meta_state;
 struct gl_program_cache;
+struct gl_shader_cache;
 struct gl_texture_object;
 struct gl_context;
 struct st_context;
@@ -2091,6 +2092,11 @@ struct gl_vertex_program_state
    /** Cache of fixed-function programs */
    struct gl_program_cache *Cache;
 
+#ifdef USE_SHADERCACHE
+   /** Cache of GLSL shaders */
+   struct gl_shader_cache *ShaderCache;
+#endif
+
    GLboolean _Overriden;
 };
 
-- 
1.8.1.4



More information about the mesa-dev mailing list