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

Reply via email to