[Mesa-dev] [PATCH 1/4] u_threaded_gallium: remove synchronization in fence_server_sync

Nicolai Hähnle nhaehnle at gmail.com
Thu Nov 9 13:45:56 UTC 2017


From: Nicolai Hähnle <nicolai.haehnle at amd.com>

The whole point of fence_server_sync is that it can be used to
avoid waiting in the application thread.
---
 src/gallium/auxiliary/util/u_threaded_context.c       | 14 +++++++++++---
 src/gallium/auxiliary/util/u_threaded_context.h       |  1 +
 src/gallium/auxiliary/util/u_threaded_context_calls.h |  1 +
 3 files changed, 13 insertions(+), 3 deletions(-)

diff --git a/src/gallium/auxiliary/util/u_threaded_context.c b/src/gallium/auxiliary/util/u_threaded_context.c
index e1ec47e4e0c..341d70a48fc 100644
--- a/src/gallium/auxiliary/util/u_threaded_context.c
+++ b/src/gallium/auxiliary/util/u_threaded_context.c
@@ -1829,28 +1829,36 @@ tc_create_fence_fd(struct pipe_context *_pipe,
                    struct pipe_fence_handle **fence, int fd)
 {
    struct threaded_context *tc = threaded_context(_pipe);
    struct pipe_context *pipe = tc->pipe;
 
    tc_sync(tc);
    pipe->create_fence_fd(pipe, fence, fd);
 }
 
 static void
+tc_call_fence_server_sync(struct pipe_context *pipe, union tc_payload *payload)
+{
+   pipe->fence_server_sync(pipe, payload->fence);
+   pipe->screen->fence_reference(pipe->screen, &payload->fence, NULL);
+}
+
+static void
 tc_fence_server_sync(struct pipe_context *_pipe,
                      struct pipe_fence_handle *fence)
 {
    struct threaded_context *tc = threaded_context(_pipe);
-   struct pipe_context *pipe = tc->pipe;
+   struct pipe_screen *screen = tc->pipe->screen;
+   union tc_payload *payload = tc_add_small_call(tc, TC_CALL_fence_server_sync);
 
-   tc_sync(tc);
-   pipe->fence_server_sync(pipe, fence);
+   payload->fence = NULL;
+   screen->fence_reference(screen, &payload->fence, fence);
 }
 
 static struct pipe_video_codec *
 tc_create_video_codec(struct pipe_context *_pipe,
                       const struct pipe_video_codec *templ)
 {
    unreachable("Threaded context should not be enabled for video APIs");
    return NULL;
 }
 
diff --git a/src/gallium/auxiliary/util/u_threaded_context.h b/src/gallium/auxiliary/util/u_threaded_context.h
index ea815ed5e03..b2d904569e1 100644
--- a/src/gallium/auxiliary/util/u_threaded_context.h
+++ b/src/gallium/auxiliary/util/u_threaded_context.h
@@ -302,20 +302,21 @@ struct threaded_query {
 };
 
 /* This is the second half of tc_call containing call data.
  * Most calls will typecast this to the type they need, typically larger
  * than 8 bytes.
  */
 union tc_payload {
    struct pipe_query *query;
    struct pipe_resource *resource;
    struct pipe_transfer *transfer;
+   struct pipe_fence_handle *fence;
    uint64_t handle;
 };
 
 #ifdef _MSC_VER
 #define ALIGN16 __declspec(align(16))
 #else
 #define ALIGN16 __attribute__((aligned(16)))
 #endif
 
 /* Each call slot should be aligned to its own size for optimal cache usage. */
diff --git a/src/gallium/auxiliary/util/u_threaded_context_calls.h b/src/gallium/auxiliary/util/u_threaded_context_calls.h
index 0d2fd183680..675deaabd92 100644
--- a/src/gallium/auxiliary/util/u_threaded_context_calls.h
+++ b/src/gallium/auxiliary/util/u_threaded_context_calls.h
@@ -1,12 +1,13 @@
 CALL(flush)
 CALL(callback)
+CALL(fence_server_sync)
 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)
-- 
2.11.0



More information about the mesa-dev mailing list