[Mesa-dev] [PATCH 67/88] glsl/i965: add shader cache support for geometry shaders

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


---
 src/compiler/glsl/shader_cache.cpp           | 18 +++++-
 src/mesa/drivers/dri/i965/brw_compiler.h     |  2 +
 src/mesa/drivers/dri/i965/brw_gs.c           | 23 +++++--
 src/mesa/drivers/dri/i965/brw_shader_cache.c | 97 ++++++++++++++++++++++++++++
 4 files changed, 134 insertions(+), 6 deletions(-)

diff --git a/src/compiler/glsl/shader_cache.cpp b/src/compiler/glsl/shader_cache.cpp
index 3121658..4d0b711 100644
--- a/src/compiler/glsl/shader_cache.cpp
+++ b/src/compiler/glsl/shader_cache.cpp
@@ -1023,6 +1023,13 @@ write_shader_metadata(struct blob *metadata, gl_linked_shader *shader)
       blob_write_bytes(metadata, shader->ImageUnits,
                        sizeof(shader->ImageUnits));
 
+      if (shader->Stage == MESA_SHADER_GEOMETRY) {
+         blob_write_uint32(metadata, shader->info.Geom.VerticesOut);
+         blob_write_uint32(metadata, shader->info.Geom.Invocations);
+         blob_write_uint32(metadata, shader->info.Geom.InputType);
+         blob_write_uint32(metadata, shader->info.Geom.OutputType);
+      }
+
       if (shader->Stage == MESA_SHADER_FRAGMENT) {
          struct gl_fragment_program *fprog =
             (struct gl_fragment_program *) glprog;
@@ -1072,6 +1079,13 @@ read_shader_metadata(struct blob_reader *metadata,
       blob_copy_bytes(metadata, (uint8_t *) linked->ImageUnits,
                       sizeof(linked->ImageUnits));
 
+      if (linked->Stage == MESA_SHADER_GEOMETRY) {
+         linked->info.Geom.VerticesOut = blob_read_uint32(metadata);
+         linked->info.Geom.Invocations = blob_read_uint32(metadata);
+         linked->info.Geom.InputType = blob_read_uint32(metadata);
+         linked->info.Geom.OutputType = blob_read_uint32(metadata);
+      }
+
       if (linked->Stage == MESA_SHADER_FRAGMENT) {
          struct gl_fragment_program *fprog =
             (struct gl_fragment_program *) glprog;
@@ -1129,8 +1143,7 @@ shader_cache_write_program_metadata(struct gl_context *ctx,
    /* We should be able to serialize any valid combinations of shaders, but
     * for now we only support vs and fs.
     */
-   if (prog->_LinkedShaders[MESA_SHADER_GEOMETRY] ||
-       prog->_LinkedShaders[MESA_SHADER_TESS_EVAL] ||
+   if (prog->_LinkedShaders[MESA_SHADER_TESS_EVAL] ||
        prog->_LinkedShaders[MESA_SHADER_TESS_CTRL] ||
        prog->_LinkedShaders[MESA_SHADER_COMPUTE])
       return;
@@ -1196,6 +1209,7 @@ shader_cache_read_program_metadata(struct gl_context *ctx,
 
    for (unsigned i = 0; i < prog->NumShaders; i++) {
       if (prog->Shaders[i]->Stage != MESA_SHADER_VERTEX &&
+          prog->Shaders[i]->Stage != MESA_SHADER_GEOMETRY &&
           prog->Shaders[i]->Stage != MESA_SHADER_FRAGMENT) {
          compile_shaders(ctx, prog);
          return false;
diff --git a/src/mesa/drivers/dri/i965/brw_compiler.h b/src/mesa/drivers/dri/i965/brw_compiler.h
index 183f7e6..e67db0c 100644
--- a/src/mesa/drivers/dri/i965/brw_compiler.h
+++ b/src/mesa/drivers/dri/i965/brw_compiler.h
@@ -733,6 +733,8 @@ struct brw_gs_prog_data
     * binding table entry.
     */
    unsigned char transform_feedback_swizzles[64 /* BRW_MAX_SOL_BINDINGS */];
+
+   GLuint program_size;
 };
 
 
diff --git a/src/mesa/drivers/dri/i965/brw_gs.c b/src/mesa/drivers/dri/i965/brw_gs.c
index 7b668ba..464b27e 100644
--- a/src/mesa/drivers/dri/i965/brw_gs.c
+++ b/src/mesa/drivers/dri/i965/brw_gs.c
@@ -194,6 +194,8 @@ brw_codegen_gs_prog(struct brw_context *brw,
                     &stage_state->prog_offset, &brw->gs.prog_data, gp);
    ralloc_free(mem_ctx);
 
+   brw->gs.prog_data->program_size = program_size;
+
    return true;
 }
 
@@ -259,10 +261,23 @@ brw_upload_gs_prog(struct brw_context *brw)
    if (!brw_search_cache(&brw->cache, BRW_CACHE_GS_PROG,
                          &key, sizeof(key),
                          &stage_state->prog_offset, &brw->gs.prog_data)) {
-      bool success = brw_codegen_gs_prog(brw, current[MESA_SHADER_GEOMETRY],
-                                         gp, &key);
-      assert(success);
-      (void)success;
+#ifdef ENABLE_SHADER_CACHE
+      upload_cached_program(brw, MESA_SHADER_GEOMETRY);
+
+      /* If upload from disk cache failed call codegen */
+      if (!current[MESA_SHADER_GEOMETRY] ||
+          !current[MESA_SHADER_GEOMETRY]->program_written_to_cache) {
+         gp = (struct brw_geometry_program *) brw->geometry_program;
+         gp->id = key.program_string_id;
+#endif
+         bool success = brw_codegen_gs_prog(brw,
+                                            current[MESA_SHADER_GEOMETRY], gp,
+                                            &key);
+         assert(success);
+         (void)success;
+#ifdef ENABLE_SHADER_CACHE
+      }
+#endif
    }
    brw->gs.base.prog_data = &brw->gs.prog_data->base.base;
 }
diff --git a/src/mesa/drivers/dri/i965/brw_shader_cache.c b/src/mesa/drivers/dri/i965/brw_shader_cache.c
index 19bd45e..5243725 100644
--- a/src/mesa/drivers/dri/i965/brw_shader_cache.c
+++ b/src/mesa/drivers/dri/i965/brw_shader_cache.c
@@ -36,6 +36,7 @@
 #include "brw_state.h"
 #include "brw_wm.h"
 #include "brw_vs.h"
+#include "brw_gs.h"
 #include "brw_context.h"
 
 static void
@@ -59,6 +60,27 @@ gen_vs_sha1(struct brw_context *brw, struct gl_shader_program *prog,
 }
 
 static void
+gen_gs_sha1(struct brw_context *brw, struct gl_shader_program *prog,
+            struct brw_gs_prog_key *gs_key, unsigned char *gs_sha1)
+{
+   char sha1_buf[41];
+   unsigned char sha1[20];
+   char manifest[256];
+   int offset = 0;
+
+   offset += snprintf(manifest, sizeof(manifest), "program: %s\n",
+                      _mesa_sha1_format(sha1_buf, prog->sha1));
+
+   brw_gs_populate_key(brw, gs_key);
+   gs_key->program_string_id = 0;
+   _mesa_sha1_compute(gs_key, sizeof *gs_key, sha1);
+   offset += snprintf(manifest + offset, sizeof(manifest) - offset,
+                      "gs_key: %s\n", _mesa_sha1_format(sha1_buf, sha1));
+
+   _mesa_sha1_compute(manifest, strlen(manifest), gs_sha1);
+}
+
+static void
 gen_wm_sha1(struct brw_context *brw, struct gl_shader_program *prog,
             struct brw_vs_prog_key *vs_key, struct brw_wm_prog_key *wm_key,
             unsigned char *wm_sha1)
@@ -308,6 +330,42 @@ upload_cached_vs(struct brw_context *brw, struct blob_reader *binary,
 }
 
 static void
+upload_cached_gs(struct brw_context *brw, struct blob_reader *binary,
+                 struct gl_shader_program *prog,
+                 struct brw_gs_prog_key *gs_key)
+{
+   struct brw_gs_prog_data *gs_prog_data;
+   struct brw_stage_prog_data *prog_data;
+   const struct gen_device_info *devinfo = &brw->screen->devinfo;
+
+   /* Read GS program from blob. */
+   size_t gs_program_size = blob_read_uint32(binary);
+   uint8_t *gs_program = blob_read_bytes(binary, gs_program_size);
+
+   /* Read GS program_data from blob and fixup params pointers. */
+   size_t gs_prog_data_size = blob_read_uint32(binary);
+   assert(gs_prog_data_size == sizeof *gs_prog_data);
+
+   gs_prog_data = blob_read_bytes(binary, gs_prog_data_size);
+   prog_data = &gs_prog_data->base.base;
+   load_program_data(prog, binary, prog_data, MESA_SHADER_GEOMETRY, &brw->ctx,
+                     NULL);
+
+   struct brw_geometry_program *gp =
+      (struct brw_geometry_program *)brw->geometry_program;
+   gs_key->program_string_id = gp->id;
+
+   brw_alloc_stage_scratch(brw, &brw->gs.base, prog_data->total_scratch,
+                           devinfo->max_gs_threads);
+
+   brw_upload_cache(&brw->cache, BRW_CACHE_GS_PROG,
+                    gs_key, sizeof(struct brw_gs_prog_key),
+                    gs_program, gs_program_size,
+                    gs_prog_data, gs_prog_data_size,
+                    &brw->gs.base.prog_offset, &brw->gs.prog_data, gp);
+}
+
+static void
 upload_cached_wm(struct brw_context *brw, struct blob_reader *binary,
                  struct gl_shader_program *prog,
                  struct brw_wm_prog_key *wm_key)
@@ -355,6 +413,7 @@ upload_cached_program(struct brw_context *brw, gl_shader_stage stage)
    struct gl_shader_program *prog;
    struct brw_wm_prog_key wm_key;
    struct brw_vs_prog_key vs_key;
+   struct brw_gs_prog_key gs_key;
 
    struct program_cache *cache = brw->ctx.Cache;
    if (cache == NULL)
@@ -376,6 +435,9 @@ upload_cached_program(struct brw_context *brw, gl_shader_stage stage)
    case MESA_SHADER_VERTEX:
       gen_vs_sha1(brw, prog, &vs_key, binary_sha1);
       break;
+   case MESA_SHADER_GEOMETRY:
+      gen_gs_sha1(brw, prog, &gs_key, binary_sha1);
+      break;
    case MESA_SHADER_FRAGMENT:
       gen_wm_sha1(brw, prog, &vs_key, &wm_key, binary_sha1);
       break;
@@ -409,6 +471,9 @@ upload_cached_program(struct brw_context *brw, gl_shader_stage stage)
    case MESA_SHADER_VERTEX:
       upload_cached_vs(brw, &binary, prog, &vs_key);
       break;
+   case MESA_SHADER_GEOMETRY:
+      upload_cached_gs(brw, &binary, prog, &gs_key);
+      break;
    case MESA_SHADER_FRAGMENT:
       upload_cached_wm(brw, &binary, prog, &wm_key);
       break;
@@ -562,6 +627,38 @@ write_cached_program(struct brw_context *brw)
       ralloc_free (binary);
    }
 
+   if (prog->_LinkedShaders[MESA_SHADER_GEOMETRY]) {
+      struct brw_gs_prog_key gs_key;
+      unsigned char gs_sha1[20];
+
+      binary = blob_create (NULL);
+      if (binary == NULL)
+         return;
+
+      blob_write_string(binary, brw->ctx.VersionString);
+
+      gen_gs_sha1(brw, prog, &gs_key, gs_sha1);
+
+      /* Write GS program to blob. */
+      program_size = brw->gs.prog_data->program_size;
+
+      blob_write_uint32(binary, program_size);
+
+      blob_cursor = blob_reserve_bytes(binary, program_size);
+      drm_intel_bo_get_subdata(brw->cache.bo, brw->gs.base.prog_offset,
+                               program_size, blob_cursor);
+
+      /* Write GS program_data to blob. */
+      blob_write_uint32(binary, sizeof *brw->gs.prog_data);
+      blob_write_bytes(binary, brw->gs.prog_data, sizeof *brw->gs.prog_data);
+
+      write_program_data(prog, binary, &brw->gs.prog_data->base.base,
+                         MESA_SHADER_GEOMETRY);
+
+      cache_binary(brw, binary, cache, gs_sha1);
+      ralloc_free (binary);
+   }
+
    if (prog->_LinkedShaders[MESA_SHADER_FRAGMENT]) {
       struct brw_wm_prog_key wm_key;
       unsigned char wm_sha1[20];
-- 
2.7.4



More information about the mesa-dev mailing list