summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolai Hähnle <nicolai.haehnle@amd.com>2017-10-22 17:38:53 +0200
committerNicolai Hähnle <nicolai.haehnle@amd.com>2017-11-06 11:09:47 +0100
commit9321ee345d0594e7f6f30ae47bb2255c0045a96c (patch)
tree3879872ea3861fb6372e00c6732d483d096445e3
parent3f625ea6732295bcc804219d9999638548f75239 (diff)
gallium: add pipe_context::callback
For running post-draw operations inside the driver thread. ddebug will use it. Reviewed-by: Marek Olšák <marek.olsak@amd.com>
-rw-r--r--src/gallium/auxiliary/util/u_threaded_context.c46
-rw-r--r--src/gallium/auxiliary/util/u_threaded_context_calls.h1
-rw-r--r--src/gallium/include/pipe/p_context.h11
3 files changed, 58 insertions, 0 deletions
diff --git a/src/gallium/auxiliary/util/u_threaded_context.c b/src/gallium/auxiliary/util/u_threaded_context.c
index 1f8a9d5088..d4ec24e614 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)
{
@@ -2355,6 +2365,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
*/
@@ -2451,6 +2496,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 1356c54baf..0d2fd18368 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 d9228e4fc9..0dd4ad1242 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);
};