diff --git a/src/gallium/auxiliary/driver_noop/noop_pipe.c b/src/gallium/auxiliary/driver_noop/noop_pipe.c index 83306ab9538..73d35d003cf 100644 --- a/src/gallium/auxiliary/driver_noop/noop_pipe.c +++ b/src/gallium/auxiliary/driver_noop/noop_pipe.c @@ -457,9 +457,11 @@ static struct pipe_context *noop_create_context(struct pipe_screen *screen, threaded_context_create(ctx, &((struct noop_pipe_screen*)screen)->pool_transfers, noop_replace_buffer_storage, - noop_create_fence, - noop_is_resource_busy, - false, false, NULL); + &(struct threaded_context_options) { + .create_fence = noop_create_fence, + .is_resource_busy = noop_is_resource_busy, + }, + NULL); if (tc && tc != ctx) threaded_context_init_bytes_mapped_limit((struct threaded_context *)tc, 4); diff --git a/src/gallium/auxiliary/driver_trace/tr_context.h b/src/gallium/auxiliary/driver_trace/tr_context.h index 953ccd328c0..f687fa2939d 100644 --- a/src/gallium/auxiliary/driver_trace/tr_context.h +++ b/src/gallium/auxiliary/driver_trace/tr_context.h @@ -86,8 +86,7 @@ trace_context_create(struct trace_screen *tr_scr, struct pipe_context * trace_context_create_threaded(struct pipe_screen *screen, struct pipe_context *pipe, tc_replace_buffer_storage_func *replace_buffer, - tc_create_fence_func *create_fence, - tc_is_resource_busy *is_resource_busy); + struct threaded_context_options *options); #ifdef __cplusplus } #endif diff --git a/src/gallium/auxiliary/driver_trace/tr_screen.c b/src/gallium/auxiliary/driver_trace/tr_screen.c index 02562e565c7..81eaff92f3e 100644 --- a/src/gallium/auxiliary/driver_trace/tr_screen.c +++ b/src/gallium/auxiliary/driver_trace/tr_screen.c @@ -333,8 +333,7 @@ trace_context_is_resource_busy(struct pipe_screen *_screen, struct pipe_context * trace_context_create_threaded(struct pipe_screen *screen, struct pipe_context *pipe, tc_replace_buffer_storage_func *replace_buffer, - tc_create_fence_func *create_fence, - tc_is_resource_busy *is_resource_busy) + struct threaded_context_options *options) { if (!trace_screens) return pipe; @@ -353,14 +352,14 @@ trace_context_create_threaded(struct pipe_screen *screen, struct pipe_context *p struct trace_context *tr_ctx = trace_context(ctx); tr_ctx->replace_buffer_storage = *replace_buffer; - tr_ctx->create_fence = *create_fence; - tr_scr->is_resource_busy = *is_resource_busy; + tr_ctx->create_fence = options->create_fence; + tr_scr->is_resource_busy = options->is_resource_busy; tr_ctx->threaded = true; *replace_buffer = trace_context_replace_buffer_storage; - if (*create_fence) - *create_fence = trace_context_create_fence; - if (*is_resource_busy) - *is_resource_busy = trace_context_is_resource_busy; + if (options->create_fence) + options->create_fence = trace_context_create_fence; + if (options->is_resource_busy) + options->is_resource_busy = trace_context_is_resource_busy; return ctx; } diff --git a/src/gallium/auxiliary/util/u_threaded_context.c b/src/gallium/auxiliary/util/u_threaded_context.c index 8f99fe77ba3..1b4aaf28b48 100644 --- a/src/gallium/auxiliary/util/u_threaded_context.c +++ b/src/gallium/auxiliary/util/u_threaded_context.c @@ -221,7 +221,7 @@ tc_batch_execute(void *job, UNUSED void *gdata, int thread_index) struct util_queue_fence *fence = &tc->buffer_lists[batch->buffer_list_index].driver_flushed_fence; - if (tc->driver_calls_flush_notify) { + if (tc->options.driver_calls_flush_notify) { tc->signal_fences_next_flush[tc->num_signal_fences_next_flush++] = fence; /* Since our buffer lists are chained as a ring, we need to flush @@ -649,7 +649,7 @@ static bool tc_is_buffer_busy(struct threaded_context *tc, struct threaded_resource *tbuf, unsigned map_usage) { - if (!tc->is_resource_busy) + if (!tc->options.is_resource_busy) return true; uint32_t id_hash = tbuf->buffer_id_unique & TC_BUFFER_ID_MASK; @@ -666,7 +666,7 @@ tc_is_buffer_busy(struct threaded_context *tc, struct threaded_resource *tbuf, /* The buffer isn't referenced by any unflushed batch: we can safely ask to the driver whether * this buffer is busy or not. */ - return tc->is_resource_busy(tc->pipe->screen, tbuf->latest, map_usage); + return tc->options.is_resource_busy(tc->pipe->screen, tbuf->latest, map_usage); } void @@ -2613,7 +2613,7 @@ 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) + if (!tc->options.unsynchronized_get_device_reset_status) tc_sync(tc); return pipe->get_device_reset_status(pipe); @@ -2883,7 +2883,7 @@ tc_flush(struct pipe_context *_pipe, struct pipe_fence_handle **fence, struct pipe_screen *screen = pipe->screen; bool async = flags & (PIPE_FLUSH_DEFERRED | PIPE_FLUSH_ASYNC); - if (async && tc->create_fence) { + if (async && tc->options.create_fence) { if (fence) { struct tc_batch *next = &tc->batch_slots[tc->next]; @@ -2896,7 +2896,8 @@ tc_flush(struct pipe_context *_pipe, struct pipe_fence_handle **fence, next->token->tc = tc; } - screen->fence_reference(screen, fence, tc->create_fence(pipe, next->token)); + screen->fence_reference(screen, fence, + tc->options.create_fence(pipe, next->token)); if (!*fence) goto out_of_memory; } @@ -4186,15 +4187,7 @@ void tc_driver_internal_flush_notify(struct threaded_context *tc) * in pipe_screen. * \param replace_buffer callback for replacing a pipe_resource's storage * with another pipe_resource's storage. - * \param create_fence optional callback to create a fence for async flush - * \param is_resource_busy optional callback to tell TC if transfer_map()/etc - * with the given usage would stall - * \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 options optional TC options/callbacks * \param out if successful, the threaded_context will be returned here in * addition to the return value if "out" != NULL */ @@ -4202,10 +4195,7 @@ struct pipe_context * threaded_context_create(struct pipe_context *pipe, struct slab_parent_pool *parent_transfer_pool, tc_replace_buffer_storage_func replace_buffer, - tc_create_fence_func create_fence, - tc_is_resource_busy is_resource_busy, - bool driver_calls_flush_notify, - bool unsynchronized_get_device_reset_status, + const struct threaded_context_options *options, struct threaded_context **out) { struct threaded_context *tc; @@ -4224,17 +4214,16 @@ threaded_context_create(struct pipe_context *pipe, return NULL; } - pipe = trace_context_create_threaded(pipe->screen, pipe, &replace_buffer, &create_fence, &is_resource_busy); + if (options) + tc->options = *options; + + pipe = trace_context_create_threaded(pipe->screen, pipe, &replace_buffer, &tc->options); /* The driver context isn't wrapped, so set its "priv" to NULL. */ pipe->priv = NULL; tc->pipe = pipe; tc->replace_buffer_storage = replace_buffer; - 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 929f3bed1e1..a961a11dbe5 100644 --- a/src/gallium/auxiliary/util/u_threaded_context.h +++ b/src/gallium/auxiliary/util/u_threaded_context.h @@ -408,13 +408,29 @@ struct tc_buffer_list { BITSET_DECLARE(buffer_list, TC_BUFFER_ID_MASK + 1); }; +/** + * Optional TC parameters/callbacks. + */ +struct threaded_context_options { + tc_create_fence_func create_fence; + tc_is_resource_busy is_resource_busy; + bool driver_calls_flush_notify; + + /** + * 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; +}; + struct threaded_context { struct pipe_context base; struct pipe_context *pipe; struct slab_child_pool pool_transfers; tc_replace_buffer_storage_func replace_buffer_storage; - tc_create_fence_func create_fence; - tc_is_resource_busy is_resource_busy; + struct threaded_context_options options; unsigned map_buffer_alignment; unsigned ubo_alignment; @@ -425,19 +441,10 @@ struct threaded_context { unsigned num_direct_slots; unsigned num_syncs; - bool driver_calls_flush_notify; bool use_forced_staging_uploads; 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. */ @@ -505,10 +512,7 @@ struct pipe_context * threaded_context_create(struct pipe_context *pipe, struct slab_parent_pool *parent_transfer_pool, tc_replace_buffer_storage_func replace_buffer, - tc_create_fence_func create_fence, - tc_is_resource_busy is_resource_busy, - bool driver_calls_flush_notify, - bool unsynchronized_get_device_reset_status, + const struct threaded_context_options *options, struct threaded_context **out); void diff --git a/src/gallium/drivers/crocus/crocus_context.c b/src/gallium/drivers/crocus/crocus_context.c index 9bfa5116a6d..ed0a3723007 100644 --- a/src/gallium/drivers/crocus/crocus_context.c +++ b/src/gallium/drivers/crocus/crocus_context.c @@ -325,9 +325,6 @@ crocus_create_context(struct pipe_screen *pscreen, void *priv, unsigned flags) return threaded_context_create(ctx, &screen->transfer_pool, crocus_replace_buffer_storage, 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 43ab14f8a8c..2c2b33de46e 100644 --- a/src/gallium/drivers/freedreno/freedreno_context.c +++ b/src/gallium/drivers/freedreno/freedreno_context.c @@ -691,10 +691,11 @@ fd_context_init_tc(struct pipe_context *pctx, unsigned flags) struct pipe_context *tc = threaded_context_create( pctx, &ctx->screen->transfer_pool, fd_replace_buffer_storage, - fd_fence_create_unflushed, - fd_resource_busy, - false, - true, + &(struct threaded_context_options){ + .create_fence = fd_fence_create_unflushed, + .is_resource_busy = fd_resource_busy, + .unsynchronized_get_device_reset_status = true, + }, &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 8bb0b8d69eb..fa511b3a443 100644 --- a/src/gallium/drivers/iris/iris_context.c +++ b/src/gallium/drivers/iris/iris_context.c @@ -379,8 +379,5 @@ iris_create_context(struct pipe_screen *pscreen, void *priv, unsigned flags) return threaded_context_create(ctx, &screen->transfer_pool, iris_replace_buffer_storage, 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 080e88f8403..77f4c29e1b5 100644 --- a/src/gallium/drivers/radeonsi/si_pipe.c +++ b/src/gallium/drivers/radeonsi/si_pipe.c @@ -862,10 +862,12 @@ static struct pipe_context *si_pipe_create_context(struct pipe_screen *screen, v struct pipe_context *tc = threaded_context_create(ctx, &sscreen->pool_transfers, si_replace_buffer_storage, - sscreen->info.is_amdgpu ? si_create_fence : NULL, - si_is_resource_busy, - true, - false, + &(struct threaded_context_options){ + .create_fence = sscreen->info.is_amdgpu ? + si_create_fence : NULL, + .is_resource_busy = si_is_resource_busy, + .driver_calls_flush_notify = true, + }, &((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 952dd6ea428..10136174cfa 100644 --- a/src/gallium/drivers/zink/zink_context.c +++ b/src/gallium/drivers/zink/zink_context.c @@ -4214,8 +4214,13 @@ 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, true, &ctx->tc); + &(struct threaded_context_options){ + .create_fence = zink_create_tc_fence_for_tc, + .is_resource_busy = zink_context_is_resource_busy, + .driver_calls_flush_notify = true, + .unsynchronized_get_device_reset_status = true, + }, + &ctx->tc); if (tc && (struct zink_context*)tc != ctx) { threaded_context_init_bytes_mapped_limit(tc, 4);