Module: Mesa Branch: master Commit: b44d52f62bf2753a9a961632c685852d3179689d URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=b44d52f62bf2753a9a961632c685852d3179689d
Author: Eric Anholt <[email protected]> Date: Thu Mar 18 12:31:34 2021 -0700 freedreno/a3xx: Switch to using ir3_cache for looking up our VS/FS. Saves the lock/unlock to get the variants for VS/BS/FS programs, and gives us a place we could hang future linked program state. Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/9698> --- src/gallium/drivers/freedreno/a3xx/fd3_draw.c | 22 ++++++++----- src/gallium/drivers/freedreno/a3xx/fd3_emit.c | 6 ++-- src/gallium/drivers/freedreno/a3xx/fd3_emit.h | 14 ++++---- src/gallium/drivers/freedreno/a3xx/fd3_gmem.c | 41 ++++++++++++++++++------ src/gallium/drivers/freedreno/a3xx/fd3_program.c | 37 +++++++++++++++++++++ src/gallium/drivers/freedreno/a3xx/fd3_program.h | 14 ++++++++ 6 files changed, 105 insertions(+), 29 deletions(-) diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_draw.c b/src/gallium/drivers/freedreno/a3xx/fd3_draw.c index 5a705c320aa..554e4d4cfec 100644 --- a/src/gallium/drivers/freedreno/a3xx/fd3_draw.c +++ b/src/gallium/drivers/freedreno/a3xx/fd3_draw.c @@ -98,11 +98,13 @@ fd3_draw_vbo(struct fd_context *ctx, const struct pipe_draw_info *info, struct fd3_emit emit = { .debug = &ctx->debug, .vtx = &ctx->vtx, - .prog = &ctx->prog, .info = info, .indirect = indirect, .draw = draw, - .key = { { { 0 } } }, + .key = { + .vs = ctx->prog.vs, + .fs = ctx->prog.fs, + }, .rasterflat = ctx->rasterizer->flatshade, .sprite_coord_enable = ctx->rasterizer->sprite_coord_enable, .sprite_coord_mode = ctx->rasterizer->sprite_coord_mode, @@ -115,19 +117,23 @@ fd3_draw_vbo(struct fd_context *ctx, const struct pipe_draw_info *info, return false; if (fd3_needs_manual_clipping(ir3_get_shader(ctx->prog.vs), ctx->rasterizer)) - emit.key.ucp_enables = ctx->rasterizer->clip_plane_enable; + emit.key.key.ucp_enables = ctx->rasterizer->clip_plane_enable; - ir3_fixup_shader_state(&ctx->base, &emit.key); + ir3_fixup_shader_state(&ctx->base, &emit.key.key); unsigned dirty = ctx->dirty; - const struct ir3_shader_variant *vp = fd3_emit_get_vp(&emit); - const struct ir3_shader_variant *fp = fd3_emit_get_fp(&emit); - /* do regular pass first, since that is more likely to fail compiling: */ + emit.prog = fd3_program_state(ir3_cache_lookup(ctx->shader_cache, &emit.key, &ctx->debug)); - if (!vp || !fp) + /* bail if compile failed: */ + if (!emit.prog) return false; + const struct ir3_shader_variant *vp = fd3_emit_get_vp(&emit); + const struct ir3_shader_variant *fp = fd3_emit_get_fp(&emit); + + /* do regular pass first: */ + if (unlikely(ctx->stats_users > 0)) { ctx->stats.vs_regs += ir3_shader_halfregs(vp); ctx->stats.fs_regs += ir3_shader_halfregs(fp); diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_emit.c b/src/gallium/drivers/freedreno/a3xx/fd3_emit.c index ccd59337249..ba9878cabef 100644 --- a/src/gallium/drivers/freedreno/a3xx/fd3_emit.c +++ b/src/gallium/drivers/freedreno/a3xx/fd3_emit.c @@ -612,7 +612,7 @@ fd3_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring, val |= COND(fp->writes_pos, A3XX_GRAS_CL_CLIP_CNTL_ZCLIP_DISABLE); val |= COND(fp->fragcoord_compmask != 0, A3XX_GRAS_CL_CLIP_CNTL_ZCOORD | A3XX_GRAS_CL_CLIP_CNTL_WCOORD); - if (!emit->key.ucp_enables) + if (!emit->key.key.ucp_enables) val |= A3XX_GRAS_CL_CLIP_CNTL_NUM_USER_CLIP_PLANES( MIN2(util_bitcount(planes), 6)); OUT_PKT0(ring, REG_A3XX_GRAS_CL_CLIP_CNTL, 1); @@ -623,7 +623,7 @@ fd3_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring, uint32_t planes = ctx->rasterizer->clip_plane_enable; int count = 0; - if (emit->key.ucp_enables) + if (emit->key.key.ucp_enables) planes = 0; while (planes && count < 6) { @@ -746,7 +746,7 @@ fd3_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring, OUT_PKT3(ring, CP_EVENT_WRITE, 1); OUT_RING(ring, HLSQ_FLUSH); - if (emit->prog == &ctx->prog) { /* evil hack to deal sanely with clear path */ + if (!emit->skip_consts) { ir3_emit_vs_consts(vp, ring, ctx, emit->info, emit->indirect, emit->draw); if (!emit->binning_pass) ir3_emit_fs_consts(fp, ring, ctx); diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_emit.h b/src/gallium/drivers/freedreno/a3xx/fd3_emit.h index 2dde98b31e5..9672ebf02c6 100644 --- a/src/gallium/drivers/freedreno/a3xx/fd3_emit.h +++ b/src/gallium/drivers/freedreno/a3xx/fd3_emit.h @@ -33,6 +33,7 @@ #include "freedreno_context.h" #include "fd3_format.h" #include "fd3_program.h" +#include "ir3_cache.h" #include "ir3_gallium.h" struct fd_ringbuffer; @@ -44,17 +45,18 @@ void fd3_emit_gmem_restore_tex(struct fd_ringbuffer *ring, struct fd3_emit { struct pipe_debug_callback *debug; const struct fd_vertex_state *vtx; - const struct fd_program_stateobj *prog; + const struct fd3_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; bool sprite_coord_mode; bool rasterflat; + bool skip_consts; /* cached to avoid repeated lookups of same variants: */ const struct ir3_shader_variant *vs, *fs; @@ -64,9 +66,7 @@ static inline const struct ir3_shader_variant * fd3_emit_get_vp(struct fd3_emit *emit) { if (!emit->vs) { - struct ir3_shader *shader = ir3_get_shader(emit->prog->vs); - emit->vs = ir3_shader_variant(shader, emit->key, - emit->binning_pass, emit->debug); + emit->vs = emit->binning_pass ? emit->prog->bs : emit->prog->vs; } return emit->vs; } @@ -80,9 +80,7 @@ fd3_emit_get_fp(struct fd3_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/a3xx/fd3_gmem.c b/src/gallium/drivers/freedreno/a3xx/fd3_gmem.c index cb69ca0949b..cb4440601cf 100644 --- a/src/gallium/drivers/freedreno/a3xx/fd3_gmem.c +++ b/src/gallium/drivers/freedreno/a3xx/fd3_gmem.c @@ -41,6 +41,18 @@ #include "fd3_format.h" #include "fd3_zsa.h" +static void +fd3_gmem_emit_set_prog(struct fd_context *ctx, struct fd3_emit *emit, struct fd_program_stateobj *prog) +{ + emit->skip_consts = true; + emit->key.vs = prog->vs; + emit->key.fs = prog->fs; + emit->prog = fd3_program_state(ir3_cache_lookup(ctx->shader_cache, &emit->key, &ctx->debug)); + /* reset the fd3_emit_get_*p cache */ + emit->vs = NULL; + emit->fs = NULL; +} + static void emit_mrt(struct fd_ringbuffer *ring, unsigned nr_bufs, struct pipe_surface **bufs, const uint32_t *bases, uint32_t bin_w, @@ -167,9 +179,14 @@ emit_binning_workaround(struct fd_batch *batch) struct fd3_emit emit = { .debug = &ctx->debug, .vtx = &ctx->solid_vbuf_state, - .prog = &ctx->solid_prog, + .key = { + .vs = ctx->solid_prog.vs, + .fs = ctx->solid_prog.fs, + }, }; + fd3_gmem_emit_set_prog(ctx, &emit, &ctx->solid_prog); + OUT_PKT0(ring, REG_A3XX_RB_MODE_CONTROL, 2); OUT_RING(ring, A3XX_RB_MODE_CONTROL_RENDER_MODE(RB_RESOLVE_PASS) | A3XX_RB_MODE_CONTROL_MARB_CACHE_SPLIT_MODE | @@ -363,10 +380,15 @@ fd3_emit_tile_gmem2mem(struct fd_batch *batch, const struct fd_tile *tile) struct fd3_emit emit = { .debug = &ctx->debug, .vtx = &ctx->solid_vbuf_state, - .prog = &ctx->solid_prog, + .key = { + .vs = ctx->solid_prog.vs, + .fs = ctx->solid_prog.fs, + } }; int i; + emit.prog = fd3_program_state(ir3_cache_lookup(ctx->shader_cache, &emit.key, &ctx->debug)); + OUT_PKT0(ring, REG_A3XX_RB_DEPTH_CONTROL, 1); OUT_RING(ring, A3XX_RB_DEPTH_CONTROL_ZFUNC(FUNC_NEVER)); @@ -544,9 +566,10 @@ fd3_emit_tile_mem2gmem(struct fd_batch *batch, const struct fd_tile *tile) .debug = &ctx->debug, .vtx = &ctx->blit_vbuf_state, .sprite_coord_enable = 1, - /* NOTE: They all use the same VP, this is for vtx bufs. */ - .prog = &ctx->blit_prog[0], }; + /* NOTE: They all use the same VP, this is for vtx bufs. */ + fd3_gmem_emit_set_prog(ctx, &emit, &ctx->blit_prog[0]); + float x0, y0, x1, y1; unsigned bin_w = tile->bin_w; unsigned bin_h = tile->bin_h; @@ -659,8 +682,7 @@ fd3_emit_tile_mem2gmem(struct fd_batch *batch, const struct fd_tile *tile) bin_h = gmem->bin_h; if (fd_gmem_needs_restore(batch, tile, FD_BUFFER_COLOR)) { - emit.prog = &ctx->blit_prog[pfb->nr_cbufs - 1]; - emit.fs = NULL; /* frag shader changed so clear cache */ + fd3_gmem_emit_set_prog(ctx, &emit, &ctx->blit_prog[pfb->nr_cbufs - 1]); fd3_program_emit(ring, &emit, pfb->nr_cbufs, pfb->cbufs); emit_mem2gmem_surf(batch, gmem->cbuf_base, pfb->cbufs, pfb->nr_cbufs, bin_w); } @@ -671,15 +693,14 @@ fd3_emit_tile_mem2gmem(struct fd_batch *batch, const struct fd_tile *tile) /* Non-float can use a regular color write. It's split over 8-bit * components, so half precision is always sufficient. */ - emit.prog = &ctx->blit_prog[0]; + fd3_gmem_emit_set_prog(ctx, &emit, &ctx->blit_prog[0]); } else { /* Float depth needs special blit shader that writes depth */ if (pfb->zsbuf->format == PIPE_FORMAT_Z32_FLOAT) - emit.prog = &ctx->blit_z; + fd3_gmem_emit_set_prog(ctx, &emit, &ctx->blit_z); else - emit.prog = &ctx->blit_zs; + fd3_gmem_emit_set_prog(ctx, &emit, &ctx->blit_zs); } - emit.fs = NULL; /* frag shader changed so clear cache */ fd3_program_emit(ring, &emit, 1, &pfb->zsbuf); emit_mem2gmem_surf(batch, gmem->zsbuf_base, &pfb->zsbuf, 1, bin_w); } diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_program.c b/src/gallium/drivers/freedreno/a3xx/fd3_program.c index 491083c4867..3d05abf7bb3 100644 --- a/src/gallium/drivers/freedreno/a3xx/fd3_program.c +++ b/src/gallium/drivers/freedreno/a3xx/fd3_program.c @@ -444,9 +444,46 @@ fd3_program_emit(struct fd_ringbuffer *ring, struct fd3_emit *emit, } } +static struct ir3_program_state * +fd3_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 fd3_program_state *state = CALLOC_STRUCT(fd3_program_state); + + tc_assert_driver_thread(ctx->tc); + + state->bs = bs; + state->vs = vs; + state->fs = fs; + + return &state->base; +} + +static void +fd3_program_destroy(void *data, struct ir3_program_state *state) +{ + struct fd3_program_state *so = fd3_program_state(state); + free(so); +} + +static const struct ir3_cache_funcs cache_funcs = { + .create_state = fd3_program_create, + .destroy_state = fd3_program_destroy, +}; + void fd3_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/a3xx/fd3_program.h b/src/gallium/drivers/freedreno/a3xx/fd3_program.h index 533838a9a6d..33933306eb0 100644 --- a/src/gallium/drivers/freedreno/a3xx/fd3_program.h +++ b/src/gallium/drivers/freedreno/a3xx/fd3_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 fd3_emit; +struct fd3_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 fd3_program_state * +fd3_program_state(struct ir3_program_state *state) +{ + return (struct fd3_program_state *)state; +} + void fd3_program_emit(struct fd_ringbuffer *ring, struct fd3_emit *emit, int nr, struct pipe_surface **bufs); _______________________________________________ mesa-commit mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/mesa-commit
