From 75808934f8c6ab4bea4e3d8a8aad8629f14de4eb Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Sun, 3 Oct 2021 09:12:25 -0700 Subject: [PATCH] gallium/u_threaded: Get reset status without sync GPU hangs are asynchronous already, there should not be an expectation that this is synchronized with driver thread. Signed-off-by: Rob Clark Mike Blumenkrantz Part-of: --- src/gallium/auxiliary/driver_noop/noop_pipe.c | 2 +- src/gallium/auxiliary/util/u_threaded_context.c | 18 +++++++++++++++++- src/gallium/auxiliary/util/u_threaded_context.h | 9 +++++++++ src/gallium/drivers/crocus/crocus_context.c | 1 + src/gallium/drivers/freedreno/freedreno_context.c | 1 + src/gallium/drivers/iris/iris_context.c | 1 + src/gallium/drivers/radeonsi/si_pipe.c | 1 + src/gallium/drivers/zink/zink_context.c | 2 +- 8 files changed, 32 insertions(+), 3 deletions(-) diff --git a/src/gallium/auxiliary/driver_noop/noop_pipe.c b/src/gallium/auxiliary/driver_noop/noop_pipe.c index 4f0746e..83306ab 100644 --- a/src/gallium/auxiliary/driver_noop/noop_pipe.c +++ b/src/gallium/auxiliary/driver_noop/noop_pipe.c @@ -459,7 +459,7 @@ static struct pipe_context *noop_create_context(struct pipe_screen *screen, noop_replace_buffer_storage, noop_create_fence, noop_is_resource_busy, - false, NULL); + false, false, NULL); if (tc && tc != ctx) threaded_context_init_bytes_mapped_limit((struct threaded_context *)tc, 4); diff --git a/src/gallium/auxiliary/util/u_threaded_context.c b/src/gallium/auxiliary/util/u_threaded_context.c index 6adb7fb..8f99fe7 100644 --- a/src/gallium/auxiliary/util/u_threaded_context.c +++ b/src/gallium/auxiliary/util/u_threaded_context.c @@ -2592,7 +2592,6 @@ tc_texture_subdata(struct pipe_context *_pipe, return pipe->func(pipe); \ } -TC_FUNC_SYNC_RET0(enum pipe_reset_status, get_device_reset_status) TC_FUNC_SYNC_RET0(uint64_t, get_timestamp) static void @@ -2608,6 +2607,18 @@ tc_get_sample_position(struct pipe_context *_pipe, out_value); } +static enum pipe_reset_status +tc_get_device_reset_status(struct pipe_context *_pipe) +{ + struct threaded_context *tc = threaded_context(_pipe); + struct pipe_context *pipe = tc->pipe; + + if (!tc->unsynchronized_get_device_reset_status) + tc_sync(tc); + + return pipe->get_device_reset_status(pipe); +} + static void tc_set_device_reset_callback(struct pipe_context *_pipe, const struct pipe_device_reset_callback *cb) @@ -4181,6 +4192,9 @@ void tc_driver_internal_flush_notify(struct threaded_context *tc) * \param driver_calls_flush_notify whether the driver calls * tc_driver_internal_flush_notify after every * driver flush + * \param unsynchronized_get_device_reset_status if true, get_device_reset_status() + * calls will not be synchronized with + * driver thread * \param out if successful, the threaded_context will be returned here in * addition to the return value if "out" != NULL */ @@ -4191,6 +4205,7 @@ threaded_context_create(struct pipe_context *pipe, tc_create_fence_func create_fence, tc_is_resource_busy is_resource_busy, bool driver_calls_flush_notify, + bool unsynchronized_get_device_reset_status, struct threaded_context **out) { struct threaded_context *tc; @@ -4219,6 +4234,7 @@ threaded_context_create(struct pipe_context *pipe, tc->create_fence = create_fence; tc->is_resource_busy = is_resource_busy; tc->driver_calls_flush_notify = driver_calls_flush_notify; + tc->unsynchronized_get_device_reset_status = unsynchronized_get_device_reset_status; tc->map_buffer_alignment = pipe->screen->get_param(pipe->screen, PIPE_CAP_MIN_MAP_BUFFER_ALIGNMENT); tc->ubo_alignment = diff --git a/src/gallium/auxiliary/util/u_threaded_context.h b/src/gallium/auxiliary/util/u_threaded_context.h index 2436608..929f3be 100644 --- a/src/gallium/auxiliary/util/u_threaded_context.h +++ b/src/gallium/auxiliary/util/u_threaded_context.h @@ -430,6 +430,14 @@ struct threaded_context { bool add_all_gfx_bindings_to_buffer_list; bool add_all_compute_bindings_to_buffer_list; + /** + * If true, ctx->get_device_reset_status() will be called without + * synchronizing with driver thread. Drivers can enable this to avoid + * TC syncs if their implementation of get_device_reset_status() is + * safe to call without synchronizing with driver thread. + */ + bool unsynchronized_get_device_reset_status; + /* Estimation of how much vram/gtt bytes are mmap'd in * the current tc_batch. */ @@ -500,6 +508,7 @@ threaded_context_create(struct pipe_context *pipe, tc_create_fence_func create_fence, tc_is_resource_busy is_resource_busy, bool driver_calls_flush_notify, + bool unsynchronized_get_device_reset_status, struct threaded_context **out); void diff --git a/src/gallium/drivers/crocus/crocus_context.c b/src/gallium/drivers/crocus/crocus_context.c index 44d947d..9bfa511 100644 --- a/src/gallium/drivers/crocus/crocus_context.c +++ b/src/gallium/drivers/crocus/crocus_context.c @@ -327,6 +327,7 @@ crocus_create_context(struct pipe_screen *pscreen, void *priv, unsigned flags) NULL, /* TODO: asynchronous flushes? */ NULL, false, + false, &ice->thrctx); } diff --git a/src/gallium/drivers/freedreno/freedreno_context.c b/src/gallium/drivers/freedreno/freedreno_context.c index 8bd0f04..5b5776d 100644 --- a/src/gallium/drivers/freedreno/freedreno_context.c +++ b/src/gallium/drivers/freedreno/freedreno_context.c @@ -701,6 +701,7 @@ fd_context_init_tc(struct pipe_context *pctx, unsigned flags) fd_fence_create_unflushed, fd_resource_busy, false, + false, &ctx->tc); if (tc && tc != pctx) diff --git a/src/gallium/drivers/iris/iris_context.c b/src/gallium/drivers/iris/iris_context.c index 70f74d8..8bb0b8d 100644 --- a/src/gallium/drivers/iris/iris_context.c +++ b/src/gallium/drivers/iris/iris_context.c @@ -381,5 +381,6 @@ iris_create_context(struct pipe_screen *pscreen, void *priv, unsigned flags) NULL, /* TODO: asynchronous flushes? */ NULL, false, + false, &ice->thrctx); } diff --git a/src/gallium/drivers/radeonsi/si_pipe.c b/src/gallium/drivers/radeonsi/si_pipe.c index 1883a1f..c9d668e 100644 --- a/src/gallium/drivers/radeonsi/si_pipe.c +++ b/src/gallium/drivers/radeonsi/si_pipe.c @@ -839,6 +839,7 @@ static struct pipe_context *si_pipe_create_context(struct pipe_screen *screen, v sscreen->info.is_amdgpu ? si_create_fence : NULL, si_is_resource_busy, true, + false, &((struct si_context *)ctx)->tc); if (tc && tc != ctx) diff --git a/src/gallium/drivers/zink/zink_context.c b/src/gallium/drivers/zink/zink_context.c index 1d8f3b3..efa1e37 100644 --- a/src/gallium/drivers/zink/zink_context.c +++ b/src/gallium/drivers/zink/zink_context.c @@ -4215,7 +4215,7 @@ zink_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags) struct threaded_context *tc = (struct threaded_context*)threaded_context_create(&ctx->base, &screen->transfer_pool, zink_context_replace_buffer_storage, zink_create_tc_fence_for_tc, - zink_context_is_resource_busy, true, &ctx->tc); + zink_context_is_resource_busy, true, false, &ctx->tc); if (tc && (struct zink_context*)tc != ctx) { threaded_context_init_bytes_mapped_limit(tc, 4); -- 2.7.4