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 <robdclark@chromium.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/merge_requests/3503>
diff --git a/src/gallium/drivers/freedreno/freedreno_context.c b/src/gallium/drivers/freedreno/freedreno_context.c
index 96c8384..47b7a27 100644
--- a/src/gallium/drivers/freedreno/freedreno_context.c
+++ b/src/gallium/drivers/freedreno/freedreno_context.c
@@ -202,6 +202,8 @@
 	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 @@
 		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 d10de1a..80f2462 100644
--- a/src/gallium/drivers/freedreno/freedreno_context.h
+++ b/src/gallium/drivers/freedreno/freedreno_context.h
@@ -159,6 +159,16 @@
 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 3a14590..239f4f0 100644
--- a/src/gallium/drivers/freedreno/freedreno_gmem.c
+++ b/src/gallium/drivers/freedreno/freedreno_gmem.c
@@ -460,6 +460,8 @@
 	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 @@
 
 	if (ctx->emit_tile_fini)
 		ctx->emit_tile_fini(batch);
+
+	mtx_unlock(&ctx->gmem_lock);
 }
 
 static void