From 2fad90dc4a83af4317e2cda6c3d7b5aa77dc7c73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Mon, 26 Apr 2021 21:33:24 -0400 Subject: [PATCH] radeonsi: implement threaded context callbacks for resource busy checking Reviewed-by: Pierre-Eric Pelloux-Prayer Part-of: --- src/gallium/drivers/radeonsi/si_fence.c | 2 ++ src/gallium/drivers/radeonsi/si_gfx_cs.c | 6 +++++- src/gallium/drivers/radeonsi/si_pipe.c | 16 ++++++++++++++-- 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/src/gallium/drivers/radeonsi/si_fence.c b/src/gallium/drivers/radeonsi/si_fence.c index ee6f12f855c..7b82aa3abd3 100644 --- a/src/gallium/drivers/radeonsi/si_fence.c +++ b/src/gallium/drivers/radeonsi/si_fence.c @@ -470,6 +470,8 @@ static void si_flush_all_queues(struct pipe_context *ctx, ws->fence_reference(&gfx_fence, sctx->last_gfx_fence); if (!(flags & PIPE_FLUSH_DEFERRED)) ws->cs_sync_flush(&sctx->gfx_cs); + + tc_driver_internal_flush_notify(sctx->tc); } else { /* Instead of flushing, create a deferred fence. Constraints: * - the gallium frontend must allow a deferred flush. diff --git a/src/gallium/drivers/radeonsi/si_gfx_cs.c b/src/gallium/drivers/radeonsi/si_gfx_cs.c index 24c830ab7dc..a925b429eba 100644 --- a/src/gallium/drivers/radeonsi/si_gfx_cs.c +++ b/src/gallium/drivers/radeonsi/si_gfx_cs.c @@ -93,8 +93,10 @@ void si_flush_gfx_cs(struct si_context *ctx, unsigned flags, struct pipe_fence_h /* Drop this flush if it's a no-op. */ if (!radeon_emitted(cs, ctx->initial_gfx_cs_size) && (!wait_flags || !ctx->gfx_last_ib_is_busy) && - !(flags & RADEON_FLUSH_TOGGLE_SECURE_SUBMISSION)) + !(flags & RADEON_FLUSH_TOGGLE_SECURE_SUBMISSION)) { + tc_driver_internal_flush_notify(ctx->tc); return; + } /* Non-aux contexts must set up no-op API dispatch on GPU resets. This is * similar to si_get_reset_status but here we can ignore soft-recoveries, @@ -198,6 +200,8 @@ void si_flush_gfx_cs(struct si_context *ctx, unsigned flags, struct pipe_fence_h /* Flush the CS. */ ws->cs_flush(cs, flags, &ctx->last_gfx_fence); + + tc_driver_internal_flush_notify(ctx->tc); if (fence) ws->fence_reference(fence, ctx->last_gfx_fence); diff --git a/src/gallium/drivers/radeonsi/si_pipe.c b/src/gallium/drivers/radeonsi/si_pipe.c index 32d7cd1b95d..89c11438189 100644 --- a/src/gallium/drivers/radeonsi/si_pipe.c +++ b/src/gallium/drivers/radeonsi/si_pipe.c @@ -761,6 +761,18 @@ fail: return NULL; } +static bool si_is_resource_busy(struct pipe_screen *screen, struct pipe_resource *resource, + unsigned usage) +{ + struct radeon_winsys *ws = ((struct si_screen *)screen)->ws; + + return !ws->buffer_wait(ws, si_resource(resource)->buf, 0, + /* If mapping for write, we need to wait for all reads and writes. + * If mapping for read, we only need to wait for writes. + */ + usage & PIPE_MAP_WRITE ? RADEON_USAGE_READWRITE : RADEON_USAGE_WRITE); +} + static struct pipe_context *si_pipe_create_context(struct pipe_screen *screen, void *priv, unsigned flags) { @@ -798,8 +810,8 @@ static struct pipe_context *si_pipe_create_context(struct pipe_screen *screen, v threaded_context_create(ctx, &sscreen->pool_transfers, si_replace_buffer_storage, sscreen->info.is_amdgpu ? si_create_fence : NULL, - NULL, - false, + si_is_resource_busy, + true, &((struct si_context *)ctx)->tc); if (tc && tc != ctx && os_get_total_physical_memory(&total_ram)) {