freedreno: add gmem_lock
authorRob Clark <robdclark@chromium.org>
Tue, 21 Jan 2020 23:59:22 +0000 (15:59 -0800)
committerMarge Bot <eric+marge@anholt.net>
Wed, 29 Jan 2020 21:19:41 +0000 (21:19 +0000)
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 <robdclark@chromium.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/merge_requests/3503>

src/gallium/drivers/freedreno/freedreno_context.c
src/gallium/drivers/freedreno/freedreno_context.h
src/gallium/drivers/freedreno/freedreno_gmem.c

index 96c83844193104129128d5d3b685c89aa15a90b4..47b7a27ad1f6e847f332dbeb5bb87b68a490b3b2 100644 (file)
@@ -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:
         */
index d10de1a850462190a7be26cff3574e615459a7a4..80f2462fdd97952baf1cc53e4356b153fc3b297e 100644 (file)
@@ -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;
index 3a14590dff5ba49c9025b89c573f3f9ff4b48026..239f4f0e9555ce14c3e463c0adc2a3b7ff7d3ba4 100644 (file)
@@ -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