--- 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 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev