freedreno: threaded_context support
authorRob Clark <robdclark@chromium.org>
Thu, 4 Mar 2021 20:46:34 +0000 (12:46 -0800)
committerMarge Bot <eric+marge@anholt.net>
Thu, 11 Mar 2021 04:42:16 +0000 (04:42 +0000)
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@chromium.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/9323>

src/gallium/drivers/freedreno/a6xx/fd6_context.c
src/gallium/drivers/freedreno/a6xx/fd6_program.c
src/gallium/drivers/freedreno/a6xx/fd6_resource.c
src/gallium/drivers/freedreno/a6xx/fd6_texture.c
src/gallium/drivers/freedreno/freedreno_context.c
src/gallium/drivers/freedreno/freedreno_context.h
src/gallium/drivers/freedreno/freedreno_query_acc.c
src/gallium/drivers/freedreno/freedreno_query_hw.c
src/gallium/drivers/freedreno/freedreno_resource.c

index 4dcaf03..69de576 100644 (file)
@@ -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);
 }
index 125da7d..f9c4009 100644 (file)
@@ -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:
index 951f8a2..a0cf5ec 100644 (file)
@@ -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;
 
index 614e04b..b922766 100644 (file)
@@ -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)
index 93c57e4..49520e9 100644 (file)
@@ -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;
+}
index 4917465..06ae46b 100644 (file)
@@ -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;
 
index 5603a6c..6fb0816 100644 (file)
@@ -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@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);
index 6fbe365..9eb0259 100644 (file)
@@ -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@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);
index 2c0a7c0..b8c89b2 100644 (file)
@@ -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