[Mesa-dev] [PATCH 12/88] i965: add initial implementation of on disk shader cache

Timothy Arceri timothy.arceri at collabora.com
Mon Sep 26 03:28:35 UTC 2016


On Sun, 2016-09-25 at 19:43 -0700, Kenneth Graunke wrote:
> On Saturday, September 24, 2016 3:24:53 PM PDT Timothy Arceri wrote:
> > 
> > This uses the recently-added cache.c to write out the final linked
> > binary for vertex and fragment shader programs.
> > 
> > This is based off the initial implementation done by Carl.
> > ---
> >  src/mesa/drivers/dri/i965/Makefile.sources   |   1 +
> >  src/mesa/drivers/dri/i965/brw_shader_cache.c | 390
> > +++++++++++++++++++++++++++
> >  src/mesa/drivers/dri/i965/brw_state.h        |   7 +
> >  3 files changed, 398 insertions(+)
> >  create mode 100644 src/mesa/drivers/dri/i965/brw_shader_cache.c
> > 
> > diff --git a/src/mesa/drivers/dri/i965/Makefile.sources
> > b/src/mesa/drivers/dri/i965/Makefile.sources
> > index df90cb4..bd2bd37 100644
> > --- a/src/mesa/drivers/dri/i965/Makefile.sources
> > +++ b/src/mesa/drivers/dri/i965/Makefile.sources
> > @@ -147,6 +147,7 @@ i965_FILES = \
> >  	brw_sf_emit.c \
> >  	brw_sf.h \
> >  	brw_sf_state.c \
> > +	brw_shader_cache.cpp \
> >  	brw_state_batch.c \
> >  	brw_state_cache.c \
> >  	brw_state_dump.c \
> > diff --git a/src/mesa/drivers/dri/i965/brw_shader_cache.c
> > b/src/mesa/drivers/dri/i965/brw_shader_cache.c
> > new file mode 100644
> > index 0000000..aba45b6
> > --- /dev/null
> > +++ b/src/mesa/drivers/dri/i965/brw_shader_cache.c
> > @@ -0,0 +1,390 @@
> > +/*
> > + * Copyright © 2014 Intel Corporation
> > + *
> > + * Permission is hereby granted, free of charge, to any person
> > obtaining a
> > + * copy of this software and associated documentation files (the
> > "Software"),
> > + * to deal in the Software without restriction, including without
> > limitation
> > + * the rights to use, copy, modify, merge, publish, distribute,
> > sublicense,
> > + * and/or sell copies of the Software, and to permit persons to
> > whom the
> > + * Software is furnished to do so, subject to the following
> > conditions:
> > + *
> > + * The above copyright notice and this permission notice
> > (including the next
> > + * paragraph) shall be included in all copies or substantial
> > portions of the
> > + * Software.
> > + *
> > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
> > EXPRESS OR
> > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
> > MERCHANTABILITY,
> > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO
> > EVENT SHALL
> > + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
> > DAMAGES OR OTHER
> > + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
> > ARISING
> > + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
> > OTHER DEALINGS
> > + * IN THE SOFTWARE.
> > + */
> > +
> > +#include <util/macros.h>
> > +#include <util/mesa-sha1.h>
> > +#include <main/mtypes.h>
> > +#include <compiler/glsl/glsl_parser_extras.h>
> > +#include <compiler/glsl/ir_uniform.h>
> > +#include <compiler/glsl/cache.h>
> > +#include <compiler/glsl/blob.h>
> > +
> > +#include "brw_state.h"
> > +#include "brw_wm.h"
> > +#include "brw_vs.h"
> > +#include "brw_context.h"
> > +
> > +static void
> > +gen_vs_sha1(struct brw_context *brw, struct gl_shader_program
> > *prog,
> > +            struct brw_vs_prog_key *vs_key, unsigned char
> > *vs_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));
> > +
> > +   _mesa_sha1_compute(vs_key, sizeof *vs_key, sha1);
> > +   offset += snprintf(manifest + offset, sizeof(manifest) -
> > offset,
> > +                      "vs_key: %s\n", _mesa_sha1_format(sha1_buf,
> > sha1));
> > +
> > +   _mesa_sha1_compute(manifest, strlen(manifest), vs_sha1);
> > +}
> 
> The VS/TCS/TES/GS code is basically identical...you could avoid a lot
> of
> duplication by doing...
> 
> static void
> gen_shader_sha1(struct brw_context *brw, struct gl_shader_program
> *prog,
>                 unsigned stage, void *key, unsigned char *out_sha1)
> {
>    char sha1_buf[41];
>    unsigned char sha1[20];
>    char manifest[256];
>    int offset = 0;
> 
>    format_program_sha1(prog, manifest, sizeof(manifest), &offset);
> 
>    _mesa_sha1_compute(key, key_size(stage), sha1);
>    offset += snprintf(manifest + offset, sizeof(manifest) - offset,
>                       "%s_key: %s\n",
>                       _mesa_shader_stage_to_abbrev(stage),
>                       _mesa_sha1_format(sha1_buf, sha1));
> 
>    _mesa_sha1_compute(manifest, strlen(manifest), tcs_sha1)
> }
> 
> assuming you move the key initialization for TCS/TES/GS to the
> caller,
> which would make it more consistent with the VS anyway.  (Here,
> key_size
> is a helper function that returns sizeof(brw_vs_prog) etc.)
> 
> (Also assuming you're OK with using "VS_key" rather than "vs_key"...)
> 
> > 
> > +
> > +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)
> > +{
> > +   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_wm_populate_key(brw, wm_key);
> > +   _mesa_sha1_compute(wm_key, sizeof *wm_key, sha1);
> > +   offset += snprintf(manifest + offset, sizeof(manifest) -
> > offset,
> > +                      "wm_key: %s\n", _mesa_sha1_format(sha1_buf,
> > sha1));
> > +
> > +   _mesa_sha1_compute(manifest, strlen(manifest), wm_sha1);
> > +
> > +}
> 
> I don't know why this function is (eventually) monkeying around with
> the
> vue map coming out of the GS stage based on VS outputs written.  I
> can't
> imagine it works once you're caching TES/GS...

It's been a while since I worked on this but I believe this is meant to
handle the effects of the following code in brw_state_upload()

   /* Update the VUE map for data exiting the GS stage of the pipeline.
    * This comes from the last enabled shader stage.
    */
   GLbitfield64 old_slots = brw->vue_map_geom_out.slots_valid;
   bool old_separate = brw->vue_map_geom_out.separate;
   if (brw->geometry_program)
      brw->vue_map_geom_out = brw->gs.prog_data->base.vue_map;
   else if (brw->tess_eval_program)
      brw->vue_map_geom_out = brw->tes.prog_data->base.vue_map;
   else
      brw->vue_map_geom_out = brw->vs.prog_data->base.vue_map;




More information about the mesa-dev mailing list