Mesa (master): freedreno: threaded_context support

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Thu Mar 11 05:04:27 UTC 2021


Module: Mesa
Branch: master
Commit: 9dbe2405a3a697fed589b04a6ccb9e18a3d502a8
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=9dbe2405a3a697fed589b04a6ccb9e18a3d502a8

Author: Rob Clark <robdclark at chromium.org>
Date:   Thu Mar  4 12:46:34 2021 -0800

freedreno: threaded_context support

Currently only initialized for a6xx, mostly because that is the easiest
setup for me to test and debug at the moment.  But the couple a6xx changes
should not require counterparts in older gens.

Signed-off-by: Rob Clark <robdclark at chromium.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/9323>

---

 src/gallium/drivers/freedreno/a6xx/fd6_context.c   |  4 ++--
 src/gallium/drivers/freedreno/a6xx/fd6_program.c   |  2 ++
 src/gallium/drivers/freedreno/a6xx/fd6_resource.c  |  2 ++
 src/gallium/drivers/freedreno/a6xx/fd6_texture.c   |  3 +++
 src/gallium/drivers/freedreno/freedreno_context.c  | 28 ++++++++++++++++++++++
 src/gallium/drivers/freedreno/freedreno_context.h  |  3 +++
 .../drivers/freedreno/freedreno_query_acc.c        |  4 ++++
 src/gallium/drivers/freedreno/freedreno_query_hw.c |  4 ++++
 src/gallium/drivers/freedreno/freedreno_resource.c |  4 ++++
 9 files changed, 52 insertions(+), 2 deletions(-)

diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_context.c b/src/gallium/drivers/freedreno/a6xx/fd6_context.c
index 4dcaf03b156..69de576b848 100644
--- a/src/gallium/drivers/freedreno/a6xx/fd6_context.c
+++ b/src/gallium/drivers/freedreno/a6xx/fd6_context.c
@@ -192,7 +192,7 @@ fd6_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags)
 	fd6_blitter_init(pctx);
 
 	fd6_ctx->border_color_uploader = u_upload_create(pctx, 4096, 0,
-                                                         PIPE_USAGE_STREAM, 0);
+			PIPE_USAGE_STREAM, 0);
 
-	return pctx;
+	return fd_context_init_tc(pctx, flags);
 }
diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_program.c b/src/gallium/drivers/freedreno/a6xx/fd6_program.c
index 125da7daebe..f9c400914a1 100644
--- a/src/gallium/drivers/freedreno/a6xx/fd6_program.c
+++ b/src/gallium/drivers/freedreno/a6xx/fd6_program.c
@@ -1072,6 +1072,8 @@ fd6_program_create(void *data, struct ir3_shader_variant *bs,
 	struct fd_context *ctx = fd_context(data);
 	struct fd6_program_state *state = CALLOC_STRUCT(fd6_program_state);
 
+	tc_assert_driver_thread(ctx->tc);
+
 	/* if we have streamout, use full VS in binning pass, as the
 	 * binning pass VS will have outputs on other than position/psize
 	 * stripped out:
diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_resource.c b/src/gallium/drivers/freedreno/a6xx/fd6_resource.c
index 951f8a261fd..a0cf5ec2adb 100644
--- a/src/gallium/drivers/freedreno/a6xx/fd6_resource.c
+++ b/src/gallium/drivers/freedreno/a6xx/fd6_resource.c
@@ -112,6 +112,8 @@ void
 fd6_validate_format(struct fd_context *ctx, struct fd_resource *rsc,
 		enum pipe_format format)
 {
+	tc_assert_driver_thread(ctx->tc);
+
 	if (!rsc->layout.ubwc)
 		return;
 
diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_texture.c b/src/gallium/drivers/freedreno/a6xx/fd6_texture.c
index 614e04b5357..b922766b28c 100644
--- a/src/gallium/drivers/freedreno/a6xx/fd6_texture.c
+++ b/src/gallium/drivers/freedreno/a6xx/fd6_texture.c
@@ -339,6 +339,9 @@ fd6_sampler_view_update(struct fd_context *ctx, struct fd6_pipe_sampler_view *so
 	}
 }
 
+/* NOTE this can be called in either driver thread or frontend thread
+ * depending on where the last unref comes from
+ */
 static void
 fd6_sampler_view_destroy(struct pipe_context *pctx,
 		struct pipe_sampler_view *_view)
diff --git a/src/gallium/drivers/freedreno/freedreno_context.c b/src/gallium/drivers/freedreno/freedreno_context.c
index 93c57e4a6b0..49520e969d3 100644
--- a/src/gallium/drivers/freedreno/freedreno_context.c
+++ b/src/gallium/drivers/freedreno/freedreno_context.c
@@ -249,6 +249,8 @@ fd_context_batch(struct fd_context *ctx)
 {
 	struct fd_batch *batch = NULL;
 
+	tc_assert_driver_thread(ctx->tc);
+
 	fd_batch_reference(&batch, ctx->batch);
 
 	if (unlikely(!batch)) {
@@ -613,3 +615,29 @@ fail:
 	pctx->destroy(pctx);
 	return NULL;
 }
+
+struct pipe_context *
+fd_context_init_tc(struct pipe_context *pctx, unsigned flags)
+{
+	struct fd_context *ctx = fd_context(pctx);
+
+	if (!(flags & PIPE_CONTEXT_PREFER_THREADED))
+		return pctx;
+
+	/* Clover (compute-only) is unsupported. */
+	if (flags & PIPE_CONTEXT_COMPUTE_ONLY)
+		return pctx;
+
+	struct pipe_context *tc = threaded_context_create(pctx,
+			&ctx->screen->transfer_pool,
+			fd_replace_buffer_storage,
+			NULL, // TODO fd_create_fence for async flush
+			&ctx->tc);
+
+	uint64_t total_ram;
+	if (tc && tc != pctx && os_get_total_physical_memory(&total_ram)) {
+		((struct threaded_context *) tc)->bytes_mapped_limit = total_ram / 16;
+	}
+
+	return tc;
+}
diff --git a/src/gallium/drivers/freedreno/freedreno_context.h b/src/gallium/drivers/freedreno/freedreno_context.h
index 491746590c4..06ae46b5af3 100644
--- a/src/gallium/drivers/freedreno/freedreno_context.h
+++ b/src/gallium/drivers/freedreno/freedreno_context.h
@@ -182,6 +182,8 @@ struct ir3_shader_key;
 struct fd_context {
 	struct pipe_context base;
 
+	struct threaded_context *tc;
+
 	struct list_head node;   /* node in screen->context_list */
 
 	/* We currently need to serialize emitting GMEM batches, because of
@@ -549,6 +551,7 @@ void fd_emit_string5(struct fd_ringbuffer *ring, const char *string, int len);
 struct pipe_context * fd_context_init(struct fd_context *ctx,
 		struct pipe_screen *pscreen, const uint8_t *primtypes,
 		void *priv, unsigned flags);
+struct pipe_context * fd_context_init_tc(struct pipe_context *pctx, unsigned flags);
 
 void fd_context_destroy(struct pipe_context *pctx) assert_dt;
 
diff --git a/src/gallium/drivers/freedreno/freedreno_query_acc.c b/src/gallium/drivers/freedreno/freedreno_query_acc.c
index 5603a6cf83a..6fb0816ac3e 100644
--- a/src/gallium/drivers/freedreno/freedreno_query_acc.c
+++ b/src/gallium/drivers/freedreno/freedreno_query_acc.c
@@ -157,6 +157,9 @@ fd_acc_get_query_result(struct fd_context *ctx, struct fd_query *q,
 		int ret;
 
 		if (pending(rsc, false)) {
+			assert(!q->base.flushed);
+			tc_assert_driver_thread(ctx->tc);
+
 			/* piglit spec at arb_occlusion_query@occlusion_query_conform
 			 * test, and silly apps perhaps, get stuck in a loop trying
 			 * to get  query result forever with wait==false..  we don't
@@ -180,6 +183,7 @@ fd_acc_get_query_result(struct fd_context *ctx, struct fd_query *q,
 	}
 
 	if (rsc->track->write_batch) {
+		tc_assert_driver_thread(ctx->tc);
 		fd_context_access_begin(ctx);
 		fd_batch_flush(rsc->track->write_batch);
 		fd_context_access_end(ctx);
diff --git a/src/gallium/drivers/freedreno/freedreno_query_hw.c b/src/gallium/drivers/freedreno/freedreno_query_hw.c
index 6fbe365a93b..9eb025954a5 100644
--- a/src/gallium/drivers/freedreno/freedreno_query_hw.c
+++ b/src/gallium/drivers/freedreno/freedreno_query_hw.c
@@ -213,6 +213,9 @@ fd_hw_get_query_result(struct fd_context *ctx, struct fd_query *q,
 		struct fd_resource *rsc = fd_resource(period->end->prsc);
 
 		if (pending(rsc, false)) {
+			assert(!q->base.flushed);
+			tc_assert_driver_thread(ctx->tc);
+
 			/* piglit spec at arb_occlusion_query@occlusion_query_conform
 			 * test, and silly apps perhaps, get stuck in a loop trying
 			 * to get  query result forever with wait==false..  we don't
@@ -251,6 +254,7 @@ fd_hw_get_query_result(struct fd_context *ctx, struct fd_query *q,
 		struct fd_resource *rsc = fd_resource(start->prsc);
 
 		if (rsc->track->write_batch) {
+			tc_assert_driver_thread(ctx->tc);
 			fd_context_access_begin(ctx);
 			fd_batch_flush(rsc->track->write_batch);
 			fd_context_access_end(ctx);
diff --git a/src/gallium/drivers/freedreno/freedreno_resource.c b/src/gallium/drivers/freedreno/freedreno_resource.c
index 2c0a7c089eb..b8c89b223ef 100644
--- a/src/gallium/drivers/freedreno/freedreno_resource.c
+++ b/src/gallium/drivers/freedreno/freedreno_resource.c
@@ -487,6 +487,8 @@ fd_try_shadow_resource(struct fd_context *ctx, struct fd_resource *rsc,
 void
 fd_resource_uncompress(struct fd_context *ctx, struct fd_resource *rsc)
 {
+	tc_assert_driver_thread(ctx->tc);
+
 	bool success =
 		fd_try_shadow_resource(ctx, rsc, 0, NULL, FD_FORMAT_MOD_QCOM_TILED);
 
@@ -744,6 +746,8 @@ resource_transfer_map(struct pipe_context *pctx,
 	char *buf;
 	int ret = 0;
 
+	tc_assert_driver_thread(ctx->tc);
+
 	/* we always need a staging texture for tiled buffers:
 	 *
 	 * TODO we might sometimes want to *also* shadow the resource to avoid



More information about the mesa-commit mailing list