From b3b1fa5e2bc4a7df3c68bb0b234d4bcf68ffaa84 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Tue, 21 Jan 2020 15:59:22 -0800 Subject: [PATCH] freedreno: add gmem_lock The gmem state is split out now, so it does not require synchronization. But gmem rendering still accesses vsc state from the context. TODO maybe there is a better way? For gen's that don't do vsc resizing, this is probably easier.. but for a6xx there isn't really a great position for more fine grained locking. Maybe it doesn't matter since in practice the lock shouldn't be contended. Signed-off-by: Rob Clark Part-of: --- src/gallium/drivers/freedreno/freedreno_context.c | 4 ++++ src/gallium/drivers/freedreno/freedreno_context.h | 10 ++++++++++ src/gallium/drivers/freedreno/freedreno_gmem.c | 4 ++++ 3 files changed, 18 insertions(+) diff --git a/src/gallium/drivers/freedreno/freedreno_context.c b/src/gallium/drivers/freedreno/freedreno_context.c index 96c83844193..47b7a27ad1f 100644 --- a/src/gallium/drivers/freedreno/freedreno_context.c +++ b/src/gallium/drivers/freedreno/freedreno_context.c @@ -202,6 +202,8 @@ fd_context_destroy(struct pipe_context *pctx) fd_device_del(ctx->dev); fd_pipe_del(ctx->pipe); + mtx_destroy(&ctx->gmem_lock); + if (fd_mesa_debug & (FD_DBG_BSTAT | FD_DBG_MSGS)) { printf("batch_total=%u, batch_sysmem=%u, batch_gmem=%u, batch_nondraw=%u, batch_restore=%u\n", (uint32_t)ctx->stats.batch_total, (uint32_t)ctx->stats.batch_sysmem, @@ -362,6 +364,8 @@ fd_context_init(struct fd_context *ctx, struct pipe_screen *pscreen, if (primtypes[i]) ctx->primtype_mask |= (1 << i); + (void) mtx_init(&ctx->gmem_lock, mtx_plain); + /* need some sane default in case state tracker doesn't * set some state: */ diff --git a/src/gallium/drivers/freedreno/freedreno_context.h b/src/gallium/drivers/freedreno/freedreno_context.h index d10de1a8504..80f2462fdd9 100644 --- a/src/gallium/drivers/freedreno/freedreno_context.h +++ b/src/gallium/drivers/freedreno/freedreno_context.h @@ -159,6 +159,16 @@ enum fd_dirty_shader_state { struct fd_context { struct pipe_context base; + /* We currently need to serialize emitting GMEM batches, because of + * VSC state access in the context. + * + * In practice this lock should not be contended, since pipe_context + * use should be single threaded. But it is needed to protect the + * case, with batch reordering where a ctxB batch triggers flushing + * a ctxA batch + */ + mtx_t gmem_lock; + struct fd_device *dev; struct fd_screen *screen; struct fd_pipe *pipe; diff --git a/src/gallium/drivers/freedreno/freedreno_gmem.c b/src/gallium/drivers/freedreno/freedreno_gmem.c index 3a14590dff5..239f4f0e955 100644 --- a/src/gallium/drivers/freedreno/freedreno_gmem.c +++ b/src/gallium/drivers/freedreno/freedreno_gmem.c @@ -460,6 +460,8 @@ render_tiles(struct fd_batch *batch, struct fd_gmem_stateobj *gmem) struct fd_context *ctx = batch->ctx; int i; + mtx_lock(&ctx->gmem_lock); + ctx->emit_tile_init(batch); if (batch->restore) @@ -496,6 +498,8 @@ render_tiles(struct fd_batch *batch, struct fd_gmem_stateobj *gmem) if (ctx->emit_tile_fini) ctx->emit_tile_fini(batch); + + mtx_unlock(&ctx->gmem_lock); } static void -- 2.30.2