On Tue, Feb 7, 2017 at 4:42 AM, Timothy Arceri <tarc...@itsqueeze.com> wrote: > Implements a tgsi cache for the OpenGL state tracker. > --- > src/mesa/state_tracker/st_glsl_to_tgsi.cpp | 217 > +++++++++++++++++++++++++++++ > src/mesa/state_tracker/st_program.c | 133 +++++++++++++++++- > 2 files changed, 345 insertions(+), 5 deletions(-) > > diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp > b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp > index 5a65f32..452cfdd 100644 > --- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp > +++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp > @@ -32,6 +32,7 @@ > > #include "st_glsl_to_tgsi.h" > > +#include "compiler/glsl/blob.h" > #include "compiler/glsl/glsl_parser_extras.h" > #include "compiler/glsl/ir_optimization.h" > #include "compiler/glsl/program.h" > @@ -47,6 +48,8 @@ > #include "pipe/p_screen.h" > #include "tgsi/tgsi_ureg.h" > #include "tgsi/tgsi_info.h" > +#include "util/disk_cache.h" > +#include "util/mesa-sha1.h" > #include "util/u_math.h" > #include "util/u_memory.h" > #include "st_program.h" > @@ -7001,6 +7004,214 @@ has_unsupported_control_flow(exec_list *ir, > return visitor.unsupported; > } > > +static void > +read_stream_out_from_cache(struct blob_reader *st_blob, > + struct pipe_shader_state *tgsi) > +{ > + blob_copy_bytes(st_blob, (uint8_t *) &tgsi->stream_output, > + sizeof(tgsi->stream_output)); > +} > + > +static void > +read_tgsi_from_cache(struct blob_reader *st_blob, > + struct pipe_shader_state *tgsi)
The "st_" prefix is only used for "st_" types, which blob_reader isn't. > +{ > + uint32_t num_tokens = blob_read_uint32(st_blob); > + unsigned tokens_size = num_tokens * sizeof(struct tgsi_token); > + tgsi->tokens = (const tgsi_token*) MALLOC(tokens_size); > + blob_copy_bytes(st_blob, (uint8_t *) tgsi->tokens, tokens_size); > +} > + > +static void > +load_tgsi_from_disk_cache(struct gl_context *ctx, > + struct gl_shader_program *prog) > +{ > + unsigned char sha1[20]; > + char sha1_buf[41]; > + struct st_context *st = st_context(ctx); > + > + for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { > + if (prog->_LinkedShaders[i] == NULL) > + continue; > + > + char *buf = ralloc_strdup(NULL, "tsgi_tokens "); > + _mesa_sha1_format(sha1_buf, > + prog->_LinkedShaders[i]->Program->sh.data->sha1); > + ralloc_strcat(&buf, sha1_buf); > + > + struct gl_program *glprog = prog->_LinkedShaders[i]->Program; > + switch (glprog->info.stage) { > + case MESA_SHADER_VERTEX: > + ralloc_strcat(&buf, " vs"); > + _mesa_sha1_compute(buf, strlen(buf), sha1); > + break; > + case MESA_SHADER_TESS_EVAL: > + ralloc_strcat(&buf, " tes"); > + _mesa_sha1_compute(buf, strlen(buf), sha1); > + break; > + case MESA_SHADER_TESS_CTRL: > + ralloc_strcat(&buf, " tcs"); > + _mesa_sha1_compute(buf, strlen(buf), sha1); > + break; > + case MESA_SHADER_GEOMETRY: > + ralloc_strcat(&buf, " gs"); > + _mesa_sha1_compute(buf, strlen(buf), sha1); > + break; > + case MESA_SHADER_FRAGMENT: > + ralloc_strcat(&buf, " fs"); > + _mesa_sha1_compute(buf, strlen(buf), sha1); > + break; > + case MESA_SHADER_COMPUTE: > + break; > + > + default: weird indentation > + unreachable("Unsupported stage"); > + } > + > + size_t size; > + const tgsi_token *tgsi_tokens = NULL; > + uint8_t *buffer = (uint8_t *) disk_cache_get(ctx->Cache, sha1, &size); > + if (buffer) { > + struct blob_reader st_blob; > + blob_reader_init(&st_blob, buffer, size); > + > + switch (glprog->info.stage) { > + case MESA_SHADER_VERTEX: { > + struct st_vertex_program *stvp = > + (struct st_vertex_program *) glprog; > + > + st_release_vp_variants(st, stvp); > + > + stvp->num_inputs = blob_read_uint32(&st_blob); > + blob_copy_bytes(&st_blob, (uint8_t *) stvp->index_to_input, > + sizeof(stvp->index_to_input)); > + blob_copy_bytes(&st_blob, (uint8_t *) stvp->result_to_output, > + sizeof(stvp->result_to_output)); > + > + read_stream_out_from_cache(&st_blob, &stvp->tgsi); > + read_tgsi_from_cache(&st_blob, &stvp->tgsi); > + > + if (st->vp == stvp) > + st->dirty |= ST_NEW_VERTEX_PROGRAM(st, stvp); > + > + tgsi_tokens = stvp->tgsi.tokens; > + break; > + } > + case MESA_SHADER_TESS_EVAL: { > + struct st_tesseval_program *sttep = > + (struct st_tesseval_program *) glprog; > + > + st_release_basic_variants(st, sttep->Base.Target, > + &sttep->variants, &sttep->tgsi); > + > + read_stream_out_from_cache(&st_blob, &sttep->tgsi); > + read_tgsi_from_cache(&st_blob, &sttep->tgsi); > + > + if (st->tep == sttep) > + st->dirty |= sttep->affected_states; > + > + tgsi_tokens = sttep->tgsi.tokens; > + break; > + } > + case MESA_SHADER_TESS_CTRL: { > + struct st_tessctrl_program *sttcp = > + (struct st_tessctrl_program *) glprog; > + > + st_release_basic_variants(st, sttcp->Base.Target, > + &sttcp->variants, &sttcp->tgsi); > + > + read_stream_out_from_cache(&st_blob, &sttcp->tgsi); > + read_tgsi_from_cache(&st_blob, &sttcp->tgsi); > + > + if (st->tcp == sttcp) > + st->dirty |= sttcp->affected_states; > + > + tgsi_tokens = sttcp->tgsi.tokens; > + break; > + } > + case MESA_SHADER_GEOMETRY: { > + struct st_geometry_program *stgp = > + (struct st_geometry_program *) glprog; > + > + st_release_basic_variants(st, stgp->Base.Target, &stgp->variants, > + &stgp->tgsi); > + > + read_stream_out_from_cache(&st_blob, &stgp->tgsi); > + read_tgsi_from_cache(&st_blob, &stgp->tgsi); > + > + if (st->gp == stgp) > + st->dirty |= stgp->affected_states; > + > + tgsi_tokens = stgp->tgsi.tokens; > + break; > + } > + case MESA_SHADER_FRAGMENT: { > + struct st_fragment_program *stfp = > + (struct st_fragment_program *) glprog; > + > + st_release_fp_variants(st, stfp); > + > + read_tgsi_from_cache(&st_blob, &stfp->tgsi); > + > + if (st->fp == stfp) > + st->dirty |= stfp->affected_states; > + > + tgsi_tokens = stfp->tgsi.tokens; > + break; weird indentation > + } > + case MESA_SHADER_COMPUTE: > + /* TODO: add compute support. Note: support needs to be added to > + * the GLSL IR cache first. > + */ > + free(buf); > + return; > + > + default: weird indentation Other than those, I'm OK with this patch. Marek _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev