From 8120871b8dbcbe60248967b210ce7fb71d877e58 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 18 Mar 2021 13:25:45 -0700 Subject: [PATCH] freedreno/a5xx: Switch to using ir3_cache for looking up our VS/FS Saves the lock/unlock to get the variants for VS/BS/FS programs, gives us a place we could hang future linked program state, and gives us safe constlen handling that fixes a couple of our piglits. Part-of: --- src/gallium/drivers/freedreno/a5xx/fd5_draw.c | 29 ++++++++------ src/gallium/drivers/freedreno/a5xx/fd5_emit.h | 15 ++++--- .../drivers/freedreno/a5xx/fd5_program.c | 39 ++++++++++++++++++- .../drivers/freedreno/a5xx/fd5_program.h | 14 +++++++ .../ci/piglit-freedreno-a530-fails.txt | 2 - 5 files changed, 77 insertions(+), 22 deletions(-) diff --git a/src/gallium/drivers/freedreno/a5xx/fd5_draw.c b/src/gallium/drivers/freedreno/a5xx/fd5_draw.c index 620e2bf312f..d7ded0b5249 100644 --- a/src/gallium/drivers/freedreno/a5xx/fd5_draw.c +++ b/src/gallium/drivers/freedreno/a5xx/fd5_draw.c @@ -78,16 +78,19 @@ fd5_draw_vbo(struct fd_context *ctx, const struct pipe_draw_info *info, struct fd5_emit emit = { .debug = &ctx->debug, .vtx = &ctx->vtx, - .prog = &ctx->prog, .info = info, .indirect = indirect, .draw = draw, .key = { - .rasterflat = ctx->rasterizer->flatshade, - .ucp_enables = ctx->rasterizer->clip_plane_enable, - .has_per_samp = fd5_ctx->fastc_srgb || fd5_ctx->vastc_srgb, - .vastc_srgb = fd5_ctx->vastc_srgb, - .fastc_srgb = fd5_ctx->fastc_srgb, + .vs = ctx->prog.vs, + .fs = ctx->prog.fs, + .key = { + .rasterflat = ctx->rasterizer->flatshade, + .ucp_enables = ctx->rasterizer->clip_plane_enable, + .has_per_samp = fd5_ctx->fastc_srgb || fd5_ctx->vastc_srgb, + .vastc_srgb = fd5_ctx->vastc_srgb, + .fastc_srgb = fd5_ctx->fastc_srgb, + }, }, .rasterflat = ctx->rasterizer->flatshade, .sprite_coord_enable = ctx->rasterizer->sprite_coord_enable, @@ -106,16 +109,20 @@ fd5_draw_vbo(struct fd_context *ctx, const struct pipe_draw_info *info, !u_trim_pipe_prim(info->mode, (unsigned*)&draw->count)) return false; - ir3_fixup_shader_state(&ctx->base, &emit.key); + ir3_fixup_shader_state(&ctx->base, &emit.key.key); unsigned dirty = ctx->dirty; + + emit.prog = fd5_program_state(ir3_cache_lookup(ctx->shader_cache, &emit.key, &ctx->debug)); + + /* bail if compile failed: */ + if (!emit.prog) + return false; + const struct ir3_shader_variant *vp = fd5_emit_get_vp(&emit); const struct ir3_shader_variant *fp = fd5_emit_get_fp(&emit); - /* do regular pass first, since that is more likely to fail compiling: */ - - if (!vp || !fp) - return false; + /* do regular pass first: */ if (unlikely(ctx->stats_users > 0)) { ctx->stats.vs_regs += ir3_shader_halfregs(vp); diff --git a/src/gallium/drivers/freedreno/a5xx/fd5_emit.h b/src/gallium/drivers/freedreno/a5xx/fd5_emit.h index 43b079a6de7..024e5a5160b 100644 --- a/src/gallium/drivers/freedreno/a5xx/fd5_emit.h +++ b/src/gallium/drivers/freedreno/a5xx/fd5_emit.h @@ -43,12 +43,12 @@ struct fd_ringbuffer; struct fd5_emit { struct pipe_debug_callback *debug; const struct fd_vertex_state *vtx; - const struct fd_program_stateobj *prog; + const struct fd5_program_state *prog; const struct pipe_draw_info *info; const struct pipe_draw_indirect_info *indirect; const struct pipe_draw_start_count *draw; bool binning_pass; - struct ir3_shader_key key; + struct ir3_cache_key key; enum fd_dirty_3d_state dirty; uint32_t sprite_coord_enable; /* bitmask */ @@ -82,9 +82,10 @@ fd5_emit_get_vp(struct fd5_emit *emit) /* We use nonbinning VS during binning when TFB is enabled because that * is what has all the outputs that might be involved in TFB. */ - struct ir3_shader *shader = ir3_get_shader(emit->prog->vs); - emit->vs = ir3_shader_variant(shader, emit->key, - emit->binning_pass && !shader->stream_output.num_outputs, emit->debug); + if (emit->binning_pass && !emit->prog->vs->shader->stream_output.num_outputs) + emit->vs = emit->prog->bs; + else + emit->vs = emit->prog->vs; } return emit->vs; } @@ -98,9 +99,7 @@ fd5_emit_get_fp(struct fd5_emit *emit) static const struct ir3_shader_variant binning_fs = {}; emit->fs = &binning_fs; } else { - struct ir3_shader *shader = ir3_get_shader(emit->prog->fs); - emit->fs = ir3_shader_variant(shader, emit->key, - false, emit->debug); + emit->fs = emit->prog->fs; } } return emit->fs; diff --git a/src/gallium/drivers/freedreno/a5xx/fd5_program.c b/src/gallium/drivers/freedreno/a5xx/fd5_program.c index 5399e0e3e7e..cc70f7b9014 100644 --- a/src/gallium/drivers/freedreno/a5xx/fd5_program.c +++ b/src/gallium/drivers/freedreno/a5xx/fd5_program.c @@ -374,7 +374,7 @@ fd5_program_emit(struct fd_context *ctx, struct fd_ringbuffer *ring, */ const struct ir3_shader_variant *link_fs = s[FS].v; if (do_streamout && emit->binning_pass) - link_fs = ir3_shader_variant(ir3_get_shader(emit->prog->fs), emit->key, false, emit->debug); + link_fs = emit->prog->fs; struct ir3_shader_linkage l = {0}; ir3_link_shaders(&l, s[VS].v, link_fs, true); @@ -638,9 +638,46 @@ fd5_program_emit(struct fd_context *ctx, struct fd_ringbuffer *ring, OUT_RING(ring, 0x00000000); /* VFD_CONTROL_5 */ } +static struct ir3_program_state * +fd5_program_create(void *data, struct ir3_shader_variant *bs, + struct ir3_shader_variant *vs, + struct ir3_shader_variant *hs, + struct ir3_shader_variant *ds, + struct ir3_shader_variant *gs, + struct ir3_shader_variant *fs, + const struct ir3_shader_key *key) + in_dt +{ + struct fd_context *ctx = fd_context(data); + struct fd5_program_state *state = CALLOC_STRUCT(fd5_program_state); + + tc_assert_driver_thread(ctx->tc); + + state->bs = bs; + state->vs = vs; + state->fs = fs; + + return &state->base; +} + +static void +fd5_program_destroy(void *data, struct ir3_program_state *state) +{ + struct fd5_program_state *so = fd5_program_state(state); + free(so); +} + +static const struct ir3_cache_funcs cache_funcs = { + .create_state = fd5_program_create, + .destroy_state = fd5_program_destroy, +}; + void fd5_prog_init(struct pipe_context *pctx) { + struct fd_context *ctx = fd_context(pctx); + + ctx->shader_cache = ir3_cache_create(&cache_funcs, ctx); ir3_prog_init(pctx); fd_prog_init(pctx); } diff --git a/src/gallium/drivers/freedreno/a5xx/fd5_program.h b/src/gallium/drivers/freedreno/a5xx/fd5_program.h index cdb31c62b63..d0fff12d582 100644 --- a/src/gallium/drivers/freedreno/a5xx/fd5_program.h +++ b/src/gallium/drivers/freedreno/a5xx/fd5_program.h @@ -30,10 +30,24 @@ #include "pipe/p_context.h" #include "freedreno_context.h" +#include "ir3/ir3_cache.h" #include "ir3/ir3_shader.h" struct fd5_emit; +struct fd5_program_state { + struct ir3_program_state base; + struct ir3_shader_variant *bs; /* VS for when emit->binning */ + struct ir3_shader_variant *vs; + struct ir3_shader_variant *fs; /* FS for when !emit->binning */ +}; + +static inline struct fd5_program_state * +fd5_program_state(struct ir3_program_state *state) +{ + return (struct fd5_program_state *)state; +} + void fd5_emit_shader(struct fd_ringbuffer *ring, const struct ir3_shader_variant *so); void fd5_program_emit(struct fd_context *ctx, struct fd_ringbuffer *ring, diff --git a/src/gallium/drivers/freedreno/ci/piglit-freedreno-a530-fails.txt b/src/gallium/drivers/freedreno/ci/piglit-freedreno-a530-fails.txt index 02f5bb1fc88..09a26449cc4 100644 --- a/src/gallium/drivers/freedreno/ci/piglit-freedreno-a530-fails.txt +++ b/src/gallium/drivers/freedreno/ci/piglit-freedreno-a530-fails.txt @@ -35,9 +35,7 @@ glx@glx_ext_import_context@query context info,Fail shaders@glsl-bug-110796,Fail shaders@glsl-kwin-blur-1,Fail shaders@glsl-kwin-blur-2,Fail -shaders@glsl-uniform-interstage-limits@300 vs- 300 fs,Fail shaders@glsl-uniform-interstage-limits@350 vs- 350 fs,Fail -shaders@glsl-uniform-interstage-limits@400 vs- 400 fs,Fail shaders@point-vertex-id divisor,Crash shaders@point-vertex-id gl_instanceid,Crash shaders@point-vertex-id gl_instanceid divisor,Crash