[Mesa-dev] [PATCH 2/3] st: add nir shader disk cache support
Marek Olšák
maraeo at gmail.com
Mon Jan 29 21:58:26 UTC 2018
Reviewed-by: Marek Olšák <marek.olsak at amd.com>
Marek
On Wed, Jan 24, 2018 at 1:41 AM, Timothy Arceri <tarceri at itsqueeze.com> wrote:
> ---
> src/mesa/state_tracker/st_glsl_to_tgsi.cpp | 2 +-
> src/mesa/state_tracker/st_program.c | 6 +-
> src/mesa/state_tracker/st_shader_cache.c | 133 +++++++++++++++++++++++------
> src/mesa/state_tracker/st_shader_cache.h | 8 +-
> 4 files changed, 115 insertions(+), 34 deletions(-)
>
> diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
> index f496bcfe59..e42405f2fa 100644
> --- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
> +++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
> @@ -6946,7 +6946,7 @@ st_link_shader(struct gl_context *ctx, struct gl_shader_program *prog)
> }
>
> /* Return early if we are loading the shader from on-disk cache */
> - if (st_load_tgsi_from_disk_cache(ctx, prog)) {
> + if (st_load_ir_from_disk_cache(ctx, prog, use_nir)) {
> return GL_TRUE;
> }
>
> diff --git a/src/mesa/state_tracker/st_program.c b/src/mesa/state_tracker/st_program.c
> index 1116b5afbc..de9c5d1654 100644
> --- a/src/mesa/state_tracker/st_program.c
> +++ b/src/mesa/state_tracker/st_program.c
> @@ -539,7 +539,7 @@ st_translate_vertex_program(struct st_context *st,
>
> if (stvp->glsl_to_tgsi) {
> stvp->glsl_to_tgsi = NULL;
> - st_store_tgsi_in_disk_cache(st, &stvp->Base);
> + st_store_ir_in_disk_cache(st, &stvp->Base, false);
> }
>
> return stvp->tgsi.tokens != NULL;
> @@ -996,7 +996,7 @@ st_translate_fragment_program(struct st_context *st,
>
> if (stfp->glsl_to_tgsi) {
> stfp->glsl_to_tgsi = NULL;
> - st_store_tgsi_in_disk_cache(st, &stfp->Base);
> + st_store_ir_in_disk_cache(st, &stfp->Base, false);
> }
>
> return stfp->tgsi.tokens != NULL;
> @@ -1412,7 +1412,7 @@ st_translate_program_common(struct st_context *st,
> outputMapping,
> &out_state->stream_output);
>
> - st_store_tgsi_in_disk_cache(st, prog);
> + st_store_ir_in_disk_cache(st, prog, false);
>
> if ((ST_DEBUG & DEBUG_TGSI) && (ST_DEBUG & DEBUG_MESA)) {
> _mesa_print_program(prog);
> diff --git a/src/mesa/state_tracker/st_shader_cache.c b/src/mesa/state_tracker/st_shader_cache.c
> index a971b0d7ee..0f79a410a1 100644
> --- a/src/mesa/state_tracker/st_shader_cache.c
> +++ b/src/mesa/state_tracker/st_shader_cache.c
> @@ -26,6 +26,8 @@
> #include "st_program.h"
> #include "st_shader_cache.h"
> #include "compiler/glsl/program.h"
> +#include "compiler/nir/nir.h"
> +#include "compiler/nir/nir_serialize.h"
> #include "pipe/p_shader_tokens.h"
> #include "program/ir_to_mesa.h"
> #include "util/u_memory.h"
> @@ -44,20 +46,33 @@ write_stream_out_to_cache(struct blob *blob,
> sizeof(tgsi->stream_output));
> }
>
> +static void
> +copy_blob_to_driver_cache_blob(struct blob *blob, struct gl_program *prog)
> +{
> + prog->driver_cache_blob = ralloc_size(NULL, blob->size);
> + memcpy(prog->driver_cache_blob, blob->data, blob->size);
> + prog->driver_cache_blob_size = blob->size;
> +}
> +
> static void
> write_tgsi_to_cache(struct blob *blob, const struct tgsi_token *tokens,
> struct gl_program *prog, unsigned num_tokens)
> {
> blob_write_uint32(blob, num_tokens);
> blob_write_bytes(blob, tokens, num_tokens * sizeof(struct tgsi_token));
> + copy_blob_to_driver_cache_blob(blob, prog);
> +}
>
> - prog->driver_cache_blob = ralloc_size(NULL, blob->size);
> - memcpy(prog->driver_cache_blob, blob->data, blob->size);
> - prog->driver_cache_blob_size = blob->size;
> +static void
> +write_nir_to_cache(struct blob *blob, struct gl_program *prog)
> +{
> + nir_serialize(blob, prog->nir);
> + copy_blob_to_driver_cache_blob(blob, prog);
> }
>
> -void
> -st_serialise_tgsi_program(struct gl_context *ctx, struct gl_program *prog)
> +static void
> +st_serialise_ir_program(struct gl_context *ctx, struct gl_program *prog,
> + bool nir)
> {
> struct blob blob;
> blob_init(&blob);
> @@ -73,8 +88,12 @@ st_serialise_tgsi_program(struct gl_context *ctx, struct gl_program *prog)
> sizeof(stvp->result_to_output));
>
> write_stream_out_to_cache(&blob, &stvp->tgsi);
> - write_tgsi_to_cache(&blob, stvp->tgsi.tokens, prog,
> - stvp->num_tgsi_tokens);
> +
> + if (nir)
> + write_nir_to_cache(&blob, prog);
> + else
> + write_tgsi_to_cache(&blob, stvp->tgsi.tokens, prog,
> + stvp->num_tgsi_tokens);
> break;
> }
> case MESA_SHADER_TESS_CTRL:
> @@ -83,20 +102,29 @@ st_serialise_tgsi_program(struct gl_context *ctx, struct gl_program *prog)
> struct st_common_program *stcp = (struct st_common_program *) prog;
>
> write_stream_out_to_cache(&blob, &stcp->tgsi);
> - write_tgsi_to_cache(&blob, stcp->tgsi.tokens, prog,
> - stcp->num_tgsi_tokens);
> +
> + if (nir)
> + write_nir_to_cache(&blob, prog);
> + else
> + write_tgsi_to_cache(&blob, stcp->tgsi.tokens, prog,
> + stcp->num_tgsi_tokens);
> break;
> }
> case MESA_SHADER_FRAGMENT: {
> struct st_fragment_program *stfp = (struct st_fragment_program *) prog;
>
> - write_tgsi_to_cache(&blob, stfp->tgsi.tokens, prog,
> - stfp->num_tgsi_tokens);
> + if (nir)
> + write_nir_to_cache(&blob, prog);
> + else
> + write_tgsi_to_cache(&blob, stfp->tgsi.tokens, prog,
> + stfp->num_tgsi_tokens);
> break;
> }
> case MESA_SHADER_COMPUTE: {
> struct st_compute_program *stcp = (struct st_compute_program *) prog;
>
> + assert(!nir);
> +
> write_tgsi_to_cache(&blob, stcp->tgsi.prog, prog,
> stcp->num_tgsi_tokens);
> break;
> @@ -112,7 +140,8 @@ st_serialise_tgsi_program(struct gl_context *ctx, struct gl_program *prog)
> * 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_store_ir_in_disk_cache(struct st_context *st, struct gl_program *prog,
> + bool nir)
> {
> if (!st->ctx->Cache)
> return;
> @@ -124,10 +153,10 @@ st_store_tgsi_in_disk_cache(struct st_context *st, struct gl_program *prog)
> if (memcmp(prog->sh.data->sha1, zero, sizeof(prog->sh.data->sha1)) == 0)
> return;
>
> - st_serialise_tgsi_program(st->ctx, prog);
> + st_serialise_ir_program(st->ctx, prog, nir);
>
> if (st->ctx->_Shader->Flags & GLSL_CACHE_INFO) {
> - fprintf(stderr, "putting %s tgsi_tokens in cache\n",
> + fprintf(stderr, "putting %s state tracker IR in cache\n",
> _mesa_shader_stage_to_string(prog->info.stage));
> }
> }
> @@ -150,14 +179,18 @@ read_tgsi_from_cache(struct blob_reader *blob_reader,
> blob_copy_bytes(blob_reader, (uint8_t *) *tokens, tokens_size);
> }
>
> -void
> -st_deserialise_tgsi_program(struct gl_context *ctx,
> - struct gl_shader_program *shProg,
> - struct gl_program *prog)
> +static void
> +st_deserialise_ir_program(struct gl_context *ctx,
> + struct gl_shader_program *shProg,
> + struct gl_program *prog, bool nir)
> {
> struct st_context *st = st_context(ctx);
> size_t size = prog->driver_cache_blob_size;
> uint8_t *buffer = (uint8_t *) prog->driver_cache_blob;
> + const struct nir_shader_compiler_options *options =
> + ctx->Const.ShaderCompilerOptions[prog->info.stage].NirOptions;
> +
> + assert(prog->driver_cache_blob && prog->driver_cache_blob_size > 0);
>
> struct blob_reader blob_reader;
> blob_reader_init(&blob_reader, buffer, size);
> @@ -175,7 +208,13 @@ st_deserialise_tgsi_program(struct gl_context *ctx,
> sizeof(stvp->result_to_output));
>
> read_stream_out_from_cache(&blob_reader, &stvp->tgsi);
> - read_tgsi_from_cache(&blob_reader, &stvp->tgsi.tokens);
> +
> + if (nir) {
> + stvp->tgsi.type = PIPE_SHADER_IR_NIR;
> + stvp->shader_program = shProg;
> + stvp->tgsi.ir.nir = nir_deserialize(NULL, options, &blob_reader);
> + } else
> + read_tgsi_from_cache(&blob_reader, &stvp->tgsi.tokens);
>
> if (st->vp == stvp)
> st->dirty |= ST_NEW_VERTEX_PROGRAM(st, stvp);
> @@ -189,7 +228,13 @@ st_deserialise_tgsi_program(struct gl_context *ctx,
> &sttcp->variants, &sttcp->tgsi);
>
> read_stream_out_from_cache(&blob_reader, &sttcp->tgsi);
> - read_tgsi_from_cache(&blob_reader, &sttcp->tgsi.tokens);
> +
> + if (nir) {
> + sttcp->tgsi.type = PIPE_SHADER_IR_NIR;
> + sttcp->shader_program = shProg;
> + sttcp->tgsi.ir.nir = nir_deserialize(NULL, options, &blob_reader);
> + } else
> + read_tgsi_from_cache(&blob_reader, &sttcp->tgsi.tokens);
>
> if (st->tcp == sttcp)
> st->dirty |= sttcp->affected_states;
> @@ -203,7 +248,13 @@ st_deserialise_tgsi_program(struct gl_context *ctx,
> &sttep->variants, &sttep->tgsi);
>
> read_stream_out_from_cache(&blob_reader, &sttep->tgsi);
> - read_tgsi_from_cache(&blob_reader, &sttep->tgsi.tokens);
> +
> + if (nir) {
> + sttep->tgsi.type = PIPE_SHADER_IR_NIR;
> + sttep->shader_program = shProg;
> + sttep->tgsi.ir.nir = nir_deserialize(NULL, options, &blob_reader);
> + } else
> + read_tgsi_from_cache(&blob_reader, &sttep->tgsi.tokens);
>
> if (st->tep == sttep)
> st->dirty |= sttep->affected_states;
> @@ -217,7 +268,13 @@ st_deserialise_tgsi_program(struct gl_context *ctx,
> &stgp->tgsi);
>
> read_stream_out_from_cache(&blob_reader, &stgp->tgsi);
> - read_tgsi_from_cache(&blob_reader, &stgp->tgsi.tokens);
> +
> + if (nir) {
> + stgp->tgsi.type = PIPE_SHADER_IR_NIR;
> + stgp->shader_program = shProg;
> + stgp->tgsi.ir.nir = nir_deserialize(NULL, options, &blob_reader);
> + } else
> + read_tgsi_from_cache(&blob_reader, &stgp->tgsi.tokens);
>
> if (st->gp == stgp)
> st->dirty |= stgp->affected_states;
> @@ -229,7 +286,12 @@ st_deserialise_tgsi_program(struct gl_context *ctx,
>
> st_release_fp_variants(st, stfp);
>
> - read_tgsi_from_cache(&blob_reader, &stfp->tgsi.tokens);
> + if (nir) {
> + stfp->tgsi.type = PIPE_SHADER_IR_NIR;
> + stfp->shader_program = shProg;
> + stfp->tgsi.ir.nir = nir_deserialize(NULL, options, &blob_reader);
> + } else
> + read_tgsi_from_cache(&blob_reader, &stfp->tgsi.tokens);
>
> if (st->fp == stfp)
> st->dirty |= stfp->affected_states;
> @@ -239,6 +301,8 @@ st_deserialise_tgsi_program(struct gl_context *ctx,
> case MESA_SHADER_COMPUTE: {
> struct st_compute_program *stcp = (struct st_compute_program *) prog;
>
> + assert(!nir);
> +
> st_release_cp_variants(st, stcp);
>
> read_tgsi_from_cache(&blob_reader,
> @@ -280,8 +344,9 @@ st_deserialise_tgsi_program(struct gl_context *ctx,
> }
>
> bool
> -st_load_tgsi_from_disk_cache(struct gl_context *ctx,
> - struct gl_shader_program *prog)
> +st_load_ir_from_disk_cache(struct gl_context *ctx,
> + struct gl_shader_program *prog,
> + bool nir)
> {
> if (!ctx->Cache)
> return false;
> @@ -297,7 +362,7 @@ st_load_tgsi_from_disk_cache(struct gl_context *ctx,
> continue;
>
> struct gl_program *glprog = prog->_LinkedShaders[i]->Program;
> - st_deserialise_tgsi_program(ctx, prog, glprog);
> + st_deserialise_ir_program(ctx, prog, glprog, nir);
>
> /* We don't need the cached blob anymore so free it */
> ralloc_free(glprog->driver_cache_blob);
> @@ -305,10 +370,24 @@ st_load_tgsi_from_disk_cache(struct gl_context *ctx,
> glprog->driver_cache_blob_size = 0;
>
> if (ctx->_Shader->Flags & GLSL_CACHE_INFO) {
> - fprintf(stderr, "%s tgsi_tokens retrieved from cache\n",
> + fprintf(stderr, "%s state tracker IR retrieved from cache\n",
> _mesa_shader_stage_to_string(i));
> }
> }
>
> return true;
> }
> +
> +void
> +st_serialise_tgsi_program(struct gl_context *ctx, struct gl_program *prog)
> +{
> + st_serialise_ir_program(ctx, prog, false);
> +}
> +
> +void
> +st_deserialise_tgsi_program(struct gl_context *ctx,
> + struct gl_shader_program *shProg,
> + struct gl_program *prog)
> +{
> + st_deserialise_ir_program(ctx, shProg, prog, false);
> +}
> diff --git a/src/mesa/state_tracker/st_shader_cache.h b/src/mesa/state_tracker/st_shader_cache.h
> index 488035c7ed..4457047e83 100644
> --- a/src/mesa/state_tracker/st_shader_cache.h
> +++ b/src/mesa/state_tracker/st_shader_cache.h
> @@ -44,11 +44,13 @@ st_deserialise_tgsi_program(struct gl_context *ctx,
> struct gl_program *prog);
>
> bool
> -st_load_tgsi_from_disk_cache(struct gl_context *ctx,
> - struct gl_shader_program *prog);
> +st_load_ir_from_disk_cache(struct gl_context *ctx,
> + struct gl_shader_program *prog,
> + bool nir);
>
> void
> -st_store_tgsi_in_disk_cache(struct st_context *st, struct gl_program *prog);
> +st_store_ir_in_disk_cache(struct st_context *st, struct gl_program *prog,
> + bool nir);
>
> #ifdef __cplusplus
> }
> --
> 2.14.3
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/mesa-dev
More information about the mesa-dev
mailing list