[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