From: Nicolai Hähnle Date: Sun, 22 Oct 2017 15:38:53 +0000 (+0200) Subject: gallium: add pipe_context::callback X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=14b9fa75e4c35ccccb767004ba19212901aae404;p=mesa.git gallium: add pipe_context::callback For running post-draw operations inside the driver thread. ddebug will use it. Reviewed-by: Marek Olšák --- diff --git a/src/gallium/auxiliary/util/u_threaded_context.c b/src/gallium/auxiliary/util/u_threaded_context.c index 7db9005452f..e1ec47e4e0c 100644 --- a/src/gallium/auxiliary/util/u_threaded_context.c +++ b/src/gallium/auxiliary/util/u_threaded_context.c @@ -169,6 +169,16 @@ tc_add_small_call(struct threaded_context *tc, enum tc_call_id id) return tc_add_sized_call(tc, id, 0); } +static bool +tc_is_sync(struct threaded_context *tc) +{ + struct tc_batch *last = &tc->batch_slots[tc->last]; + struct tc_batch *next = &tc->batch_slots[tc->next]; + + return util_queue_fence_is_signalled(&last->fence) && + !next->num_total_call_slots; +} + static void _tc_sync(struct threaded_context *tc, const char *info, const char *func) { @@ -2373,6 +2383,41 @@ tc_resource_commit(struct pipe_context *_pipe, struct pipe_resource *res, } +/******************************************************************** + * callback + */ + +struct tc_callback_payload { + void (*fn)(void *data); + void *data; +}; + +static void +tc_call_callback(struct pipe_context *pipe, union tc_payload *payload) +{ + struct tc_callback_payload *p = (struct tc_callback_payload *)payload; + + p->fn(p->data); +} + +static void +tc_callback(struct pipe_context *_pipe, void (*fn)(void *), void *data, + bool asap) +{ + struct threaded_context *tc = threaded_context(_pipe); + + if (asap && tc_is_sync(tc)) { + fn(data); + return; + } + + struct tc_callback_payload *p = + tc_add_struct_typed_call(tc, TC_CALL_callback, tc_callback_payload); + p->fn = fn; + p->data = data; +} + + /******************************************************************** * create & destroy */ @@ -2470,6 +2515,7 @@ threaded_context_create(struct pipe_context *pipe, tc->base.priv = pipe; /* priv points to the wrapped driver context */ tc->base.screen = pipe->screen; tc->base.destroy = tc_destroy; + tc->base.callback = tc_callback; tc->base.stream_uploader = u_upload_clone(&tc->base, pipe->stream_uploader); if (pipe->stream_uploader == pipe->const_uploader) diff --git a/src/gallium/auxiliary/util/u_threaded_context_calls.h b/src/gallium/auxiliary/util/u_threaded_context_calls.h index 1356c54baf2..0d2fd183680 100644 --- a/src/gallium/auxiliary/util/u_threaded_context_calls.h +++ b/src/gallium/auxiliary/util/u_threaded_context_calls.h @@ -1,4 +1,5 @@ CALL(flush) +CALL(callback) CALL(destroy_query) CALL(begin_query) CALL(end_query) diff --git a/src/gallium/include/pipe/p_context.h b/src/gallium/include/pipe/p_context.h index d9228e4fc92..0dd4ad12424 100644 --- a/src/gallium/include/pipe/p_context.h +++ b/src/gallium/include/pipe/p_context.h @@ -855,6 +855,17 @@ struct pipe_context { */ void (*make_image_handle_resident)(struct pipe_context *ctx, uint64_t handle, unsigned access, bool resident); + + /** + * Call the given function from the driver thread. + * + * This is set by threaded contexts for use by debugging wrappers. + * + * \param asap if true, run the callback immediately if there are no pending + * commands to be processed by the driver thread + */ + void (*callback)(struct pipe_context *ctx, void (*fn)(void *), void *data, + bool asap); };