[Mesa-dev] [PATCH 67/87] glsl/i965: add shader cache support for geometry shaders
Timothy Arceri
timothy.arceri at collabora.com
Wed Jul 13 02:48:02 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 | 96 ++++++++++++++++++++++++++++
4 files changed, 133 insertions(+), 6 deletions(-)
diff --git a/src/compiler/glsl/shader_cache.cpp b/src/compiler/glsl/shader_cache.cpp
index 13b7d27..3edc577 100644
--- a/src/compiler/glsl/shader_cache.cpp
+++ b/src/compiler/glsl/shader_cache.cpp
@@ -947,6 +947,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;
@@ -996,6 +1003,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;
@@ -1053,8 +1067,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;
@@ -1118,6 +1131,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 73294d1..45c652c 100644
--- a/src/mesa/drivers/dri/i965/brw_compiler.h
+++ b/src/mesa/drivers/dri/i965/brw_compiler.h
@@ -729,6 +729,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 1865ef1..df0b972 100644
--- a/src/mesa/drivers/dri/i965/brw_gs.c
+++ b/src/mesa/drivers/dri/i965/brw_gs.c
@@ -190,6 +190,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;
}
@@ -255,10 +257,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 2893d8d..9e696b2 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)
@@ -307,6 +329,41 @@ 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;
+
+ /* 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,
+ brw->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)
@@ -353,6 +410,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)
@@ -374,6 +432,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;
@@ -407,6 +468,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;
@@ -560,6 +624,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