From: Nicolai Hähnle <nicolai.haeh...@amd.com> For running post-draw operations inside the driver thread. ddebug will use it.
Reviewed-by: Marek Olšák <marek.ol...@amd.com> --- src/gallium/auxiliary/util/u_threaded_context.c | 46 ++++++++++++++++++++++ .../auxiliary/util/u_threaded_context_calls.h | 1 + src/gallium/include/pipe/p_context.h | 11 ++++++ 3 files changed, 58 insertions(+) diff --git a/src/gallium/auxiliary/util/u_threaded_context.c b/src/gallium/auxiliary/util/u_threaded_context.c index 1f8a9d5088b..d4ec24e614b 100644 --- a/src/gallium/auxiliary/util/u_threaded_context.c +++ b/src/gallium/auxiliary/util/u_threaded_context.c @@ -162,20 +162,30 @@ tc_add_sized_call(struct threaded_context *tc, enum tc_call_id id, sizeof(struct type) + \ sizeof(((struct type*)NULL)->slot[0]) * \ (num_slots))) static union tc_payload * 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) { struct tc_batch *last = &tc->batch_slots[tc->last]; struct tc_batch *next = &tc->batch_slots[tc->next]; bool synced = false; tc_debug_check(tc); /* Only wait for queued calls... */ @@ -2348,20 +2358,55 @@ tc_resource_commit(struct pipe_context *_pipe, struct pipe_resource *res, tc_set_resource_reference(&p->res, res); p->level = level; p->box = *box; p->commit = commit; return true; /* we don't care about the return value for this call */ } /******************************************************************** + * 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 */ static void tc_destroy(struct pipe_context *_pipe) { struct threaded_context *tc = threaded_context(_pipe); struct pipe_context *pipe = tc->pipe; if (tc->base.const_uploader && @@ -2444,20 +2489,21 @@ threaded_context_create(struct pipe_context *pipe, pipe->priv = NULL; tc->pipe = pipe; tc->replace_buffer_storage = replace_buffer; tc->create_fence = create_fence; tc->map_buffer_alignment = pipe->screen->get_param(pipe->screen, PIPE_CAP_MIN_MAP_BUFFER_ALIGNMENT); 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) tc->base.const_uploader = tc->base.stream_uploader; else tc->base.const_uploader = u_upload_clone(&tc->base, pipe->const_uploader); if (!tc->base.stream_uploader || !tc->base.const_uploader) goto fail; 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,11 +1,12 @@ CALL(flush) +CALL(callback) CALL(destroy_query) CALL(begin_query) CALL(end_query) CALL(get_query_result_resource) CALL(render_condition) CALL(bind_sampler_states) CALL(set_framebuffer_state) CALL(set_tess_state) CALL(set_constant_buffer) CALL(set_scissor_states) 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 @@ -848,18 +848,29 @@ struct pipe_context { /** * Make an image handle resident. * * \param ctx pipe context * \param handle 64-bit image handle * \param access GL_READ_ONLY, GL_WRITE_ONLY or GL_READ_WRITE * \param resident TRUE for resident, FALSE otherwise */ 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); }; #ifdef __cplusplus } #endif #endif /* PIPE_CONTEXT_H */ -- 2.11.0 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev