From 9eebc55cc206d7400cc33e5faa52b51a1b4b5b8b Mon Sep 17 00:00:00 2001 From: Timothy Arceri Date: Tue, 28 Nov 2017 16:00:50 +1100 Subject: [PATCH] st/glsl_to_tgsi: add (de)serialise program helpers MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit These will be shared between the on-disk shader cache and ARB_get_program_binary. Tested-by: Dieter Nützel Reviewed-by: Nicolai Hähnle --- src/mesa/state_tracker/st_shader_cache.c | 265 ++++++++++++----------- src/mesa/state_tracker/st_shader_cache.h | 8 + 2 files changed, 146 insertions(+), 127 deletions(-) diff --git a/src/mesa/state_tracker/st_shader_cache.c b/src/mesa/state_tracker/st_shader_cache.c index 1d9b1727552..62d62f76117 100644 --- a/src/mesa/state_tracker/st_shader_cache.c +++ b/src/mesa/state_tracker/st_shader_cache.c @@ -50,22 +50,9 @@ write_tgsi_to_cache(struct blob *blob, const struct tgsi_token *tokens, prog->driver_cache_blob_size = blob->size; } -/** - * Store tgsi and any other required state in on-disk shader cache. - */ void -st_store_tgsi_in_disk_cache(struct st_context *st, struct gl_program *prog) +st_serialise_tgsi_program(struct gl_context *ctx, struct gl_program *prog) { - if (!st->ctx->Cache) - return; - - /* Exit early when we are dealing with a ff shader with no source file to - * generate a source from. - */ - static const char zero[sizeof(prog->sh.data->sha1)] = {0}; - if (memcmp(prog->sh.data->sha1, zero, sizeof(prog->sh.data->sha1)) == 0) - return; - struct blob blob; blob_init(&blob); @@ -112,12 +99,31 @@ st_store_tgsi_in_disk_cache(struct st_context *st, struct gl_program *prog) unreachable("Unsupported stage"); } + blob_finish(&blob); +} + +/** + * Store tgsi and any other required state in on-disk shader cache. + */ +void +st_store_tgsi_in_disk_cache(struct st_context *st, struct gl_program *prog) +{ + if (!st->ctx->Cache) + return; + + /* Exit early when we are dealing with a ff shader with no source file to + * generate a source from. + */ + static const char zero[sizeof(prog->sh.data->sha1)] = {0}; + if (memcmp(prog->sh.data->sha1, zero, sizeof(prog->sh.data->sha1)) == 0) + return; + + st_serialise_tgsi_program(st->ctx, prog); + if (st->ctx->_Shader->Flags & GLSL_CACHE_INFO) { fprintf(stderr, "putting %s tgsi_tokens in cache\n", _mesa_shader_stage_to_string(prog->info.stage)); } - - blob_finish(&blob); } static void @@ -138,159 +144,164 @@ read_tgsi_from_cache(struct blob_reader *blob_reader, blob_copy_bytes(blob_reader, (uint8_t *) *tokens, tokens_size); } -bool -st_load_tgsi_from_disk_cache(struct gl_context *ctx, - struct gl_shader_program *prog) +void +st_deserialise_tgsi_program(struct gl_context *ctx, + struct gl_shader_program *shProg, + struct gl_program *prog) { - if (!ctx->Cache) - return false; - - /* If we didn't load the GLSL metadata from cache then we could not have - * loaded the tgsi either. - */ - if (prog->data->LinkStatus != linking_skipped) - return false; - struct st_context *st = st_context(ctx); - for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { - if (prog->_LinkedShaders[i] == NULL) - continue; + size_t size = prog->driver_cache_blob_size; + uint8_t *buffer = (uint8_t *) prog->driver_cache_blob; - struct gl_program *glprog = prog->_LinkedShaders[i]->Program; + struct blob_reader blob_reader; + blob_reader_init(&blob_reader, buffer, size); - size_t size = glprog->driver_cache_blob_size; - uint8_t *buffer = (uint8_t *) glprog->driver_cache_blob; + switch (prog->info.stage) { + case MESA_SHADER_VERTEX: { + struct st_vertex_program *stvp = (struct st_vertex_program *) prog; - struct blob_reader blob_reader; - blob_reader_init(&blob_reader, buffer, size); + st_release_vp_variants(st, stvp); - switch (glprog->info.stage) { - case MESA_SHADER_VERTEX: { - struct st_vertex_program *stvp = (struct st_vertex_program *) glprog; + stvp->num_inputs = blob_read_uint32(&blob_reader); + blob_copy_bytes(&blob_reader, (uint8_t *) stvp->index_to_input, + sizeof(stvp->index_to_input)); + blob_copy_bytes(&blob_reader, (uint8_t *) stvp->result_to_output, + sizeof(stvp->result_to_output)); - st_release_vp_variants(st, stvp); + read_stream_out_from_cache(&blob_reader, &stvp->tgsi); + read_tgsi_from_cache(&blob_reader, &stvp->tgsi.tokens); - stvp->num_inputs = blob_read_uint32(&blob_reader); - blob_copy_bytes(&blob_reader, (uint8_t *) stvp->index_to_input, - sizeof(stvp->index_to_input)); - blob_copy_bytes(&blob_reader, (uint8_t *) stvp->result_to_output, - sizeof(stvp->result_to_output)); + if (st->vp == stvp) + st->dirty |= ST_NEW_VERTEX_PROGRAM(st, stvp); - read_stream_out_from_cache(&blob_reader, &stvp->tgsi); - read_tgsi_from_cache(&blob_reader, &stvp->tgsi.tokens); + break; + } + case MESA_SHADER_TESS_CTRL: { + struct st_common_program *sttcp = st_common_program(prog); - if (st->vp == stvp) - st->dirty |= ST_NEW_VERTEX_PROGRAM(st, stvp); + st_release_basic_variants(st, sttcp->Base.Target, + &sttcp->variants, &sttcp->tgsi); - break; - } - case MESA_SHADER_TESS_CTRL: { - struct st_common_program *sttcp = st_common_program(glprog); + read_stream_out_from_cache(&blob_reader, &sttcp->tgsi); + read_tgsi_from_cache(&blob_reader, &sttcp->tgsi.tokens); - st_release_basic_variants(st, sttcp->Base.Target, - &sttcp->variants, &sttcp->tgsi); + if (st->tcp == sttcp) + st->dirty |= sttcp->affected_states; - read_stream_out_from_cache(&blob_reader, &sttcp->tgsi); - read_tgsi_from_cache(&blob_reader, &sttcp->tgsi.tokens); + break; + } + case MESA_SHADER_TESS_EVAL: { + struct st_common_program *sttep = st_common_program(prog); - if (st->tcp == sttcp) - st->dirty |= sttcp->affected_states; + st_release_basic_variants(st, sttep->Base.Target, + &sttep->variants, &sttep->tgsi); - break; - } - case MESA_SHADER_TESS_EVAL: { - struct st_common_program *sttep = st_common_program(glprog); + read_stream_out_from_cache(&blob_reader, &sttep->tgsi); + read_tgsi_from_cache(&blob_reader, &sttep->tgsi.tokens); - st_release_basic_variants(st, sttep->Base.Target, - &sttep->variants, &sttep->tgsi); + if (st->tep == sttep) + st->dirty |= sttep->affected_states; - read_stream_out_from_cache(&blob_reader, &sttep->tgsi); - read_tgsi_from_cache(&blob_reader, &sttep->tgsi.tokens); + break; + } + case MESA_SHADER_GEOMETRY: { + struct st_common_program *stgp = st_common_program(prog); - if (st->tep == sttep) - st->dirty |= sttep->affected_states; + st_release_basic_variants(st, stgp->Base.Target, &stgp->variants, + &stgp->tgsi); - break; - } - case MESA_SHADER_GEOMETRY: { - struct st_common_program *stgp = st_common_program(glprog); + read_stream_out_from_cache(&blob_reader, &stgp->tgsi); + read_tgsi_from_cache(&blob_reader, &stgp->tgsi.tokens); - st_release_basic_variants(st, stgp->Base.Target, &stgp->variants, - &stgp->tgsi); + if (st->gp == stgp) + st->dirty |= stgp->affected_states; - read_stream_out_from_cache(&blob_reader, &stgp->tgsi); - read_tgsi_from_cache(&blob_reader, &stgp->tgsi.tokens); + break; + } + case MESA_SHADER_FRAGMENT: { + struct st_fragment_program *stfp = (struct st_fragment_program *) prog; - if (st->gp == stgp) - st->dirty |= stgp->affected_states; + st_release_fp_variants(st, stfp); - break; - } - case MESA_SHADER_FRAGMENT: { - struct st_fragment_program *stfp = - (struct st_fragment_program *) glprog; + read_tgsi_from_cache(&blob_reader, &stfp->tgsi.tokens); - st_release_fp_variants(st, stfp); + if (st->fp == stfp) + st->dirty |= stfp->affected_states; - read_tgsi_from_cache(&blob_reader, &stfp->tgsi.tokens); + break; + } + case MESA_SHADER_COMPUTE: { + struct st_compute_program *stcp = (struct st_compute_program *) prog; - if (st->fp == stfp) - st->dirty |= stfp->affected_states; + st_release_cp_variants(st, stcp); - break; - } - case MESA_SHADER_COMPUTE: { - struct st_compute_program *stcp = - (struct st_compute_program *) glprog; + read_tgsi_from_cache(&blob_reader, + (const struct tgsi_token**) &stcp->tgsi.prog); - st_release_cp_variants(st, stcp); + stcp->tgsi.req_local_mem = stcp->Base.info.cs.shared_size; + stcp->tgsi.req_private_mem = 0; + stcp->tgsi.req_input_mem = 0; - read_tgsi_from_cache(&blob_reader, - (const struct tgsi_token**) &stcp->tgsi.prog); + if (st->cp == stcp) + st->dirty |= stcp->affected_states; - stcp->tgsi.req_local_mem = stcp->Base.info.cs.shared_size; - stcp->tgsi.req_private_mem = 0; - stcp->tgsi.req_input_mem = 0; + break; + } + default: + unreachable("Unsupported stage"); + } - if (st->cp == stcp) - st->dirty |= stcp->affected_states; + /* Make sure we don't try to read more data than we wrote. This should + * never happen in release builds but its useful to have this check to + * catch development bugs. + */ + if (blob_reader.current != blob_reader.end || blob_reader.overrun) { + assert(!"Invalid TGSI shader disk cache item!"); - break; - } - default: - unreachable("Unsupported stage"); + if (ctx->_Shader->Flags & GLSL_CACHE_INFO) { + fprintf(stderr, "Error reading program from cache (invalid " + "TGSI cache item)\n"); } + } - /* Make sure we don't try to read more data than we wrote. This should - * never happen in release builds but its useful to have this check to - * catch development bugs. - */ - if (blob_reader.current != blob_reader.end || blob_reader.overrun) { - assert(!"Invalid TGSI shader disk cache item!"); - - if (ctx->_Shader->Flags & GLSL_CACHE_INFO) { - fprintf(stderr, "Error reading program from cache (invalid " - "TGSI cache item)\n"); - } - } + st_set_prog_affected_state_flags(prog); + _mesa_associate_uniform_storage(ctx, shProg, prog, false); - if (ctx->_Shader->Flags & GLSL_CACHE_INFO) { - fprintf(stderr, "%s tgsi_tokens retrieved from cache\n", - _mesa_shader_stage_to_string(i)); - } + /* Create Gallium shaders now instead of on demand. */ + if (ST_DEBUG & DEBUG_PRECOMPILE || + st->shader_has_one_variant[prog->info.stage]) + st_precompile_shader_variant(st, prog); +} + +bool +st_load_tgsi_from_disk_cache(struct gl_context *ctx, + struct gl_shader_program *prog) +{ + if (!ctx->Cache) + return false; + + /* If we didn't load the GLSL metadata from cache then we could not have + * loaded the tgsi either. + */ + if (prog->data->LinkStatus != linking_skipped) + return false; - st_set_prog_affected_state_flags(glprog); - _mesa_associate_uniform_storage(ctx, prog, glprog, false); + for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { + if (prog->_LinkedShaders[i] == NULL) + continue; - /* Create Gallium shaders now instead of on demand. */ - if (ST_DEBUG & DEBUG_PRECOMPILE || - st->shader_has_one_variant[glprog->info.stage]) - st_precompile_shader_variant(st, glprog); + struct gl_program *glprog = prog->_LinkedShaders[i]->Program; + st_deserialise_tgsi_program(ctx, prog, glprog); /* We don't need the cached blob anymore so free it */ ralloc_free(glprog->driver_cache_blob); glprog->driver_cache_blob = NULL; glprog->driver_cache_blob_size = 0; + + if (ctx->_Shader->Flags & GLSL_CACHE_INFO) { + fprintf(stderr, "%s tgsi_tokens retrieved from cache\n", + _mesa_shader_stage_to_string(i)); + } } return true; diff --git a/src/mesa/state_tracker/st_shader_cache.h b/src/mesa/state_tracker/st_shader_cache.h index 81a2935d7ba..358c6ecef88 100644 --- a/src/mesa/state_tracker/st_shader_cache.h +++ b/src/mesa/state_tracker/st_shader_cache.h @@ -32,6 +32,14 @@ extern "C" { #endif +void +st_serialise_tgsi_program(struct gl_context *ctx, struct gl_program *prog); + +void +st_deserialise_tgsi_program(struct gl_context *ctx, + struct gl_shader_program *shProg, + struct gl_program *prog); + bool st_load_tgsi_from_disk_cache(struct gl_context *ctx, struct gl_shader_program *prog); -- 2.30.2