[Mesa-dev] [PATCH 3/5] st/mesa: use asynchronous flushes

Nicolai Hähnle nhaehnle at gmail.com
Sun Oct 22 19:18:10 UTC 2017


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

---
 src/mesa/state_tracker/st_cb_flush.c   |  4 ++--
 src/mesa/state_tracker/st_cb_syncobj.c | 26 ++++++++++++++++++++++++--
 2 files changed, 26 insertions(+), 4 deletions(-)

diff --git a/src/mesa/state_tracker/st_cb_flush.c b/src/mesa/state_tracker/st_cb_flush.c
index c8452d0e6f7..5f4e2ac3cc1 100644
--- a/src/mesa/state_tracker/st_cb_flush.c
+++ b/src/mesa/state_tracker/st_cb_flush.c
@@ -56,21 +56,21 @@ void st_flush(struct st_context *st,
 }
 
 
 /**
  * Flush, and wait for completion.
  */
 void st_finish( struct st_context *st )
 {
    struct pipe_fence_handle *fence = NULL;
 
-   st_flush(st, &fence, 0);
+   st_flush(st, &fence, PIPE_FLUSH_ASYNC | PIPE_FLUSH_HINT_FINISH);
 
    if(fence) {
       st->pipe->screen->fence_finish(st->pipe->screen, NULL, fence,
                                      PIPE_TIMEOUT_INFINITE);
       st->pipe->screen->fence_reference(st->pipe->screen, &fence, NULL);
    }
 
    st_manager_flush_swapbuffers();
 }
 
@@ -81,21 +81,21 @@ void st_finish( struct st_context *st )
  */
 static void st_glFlush(struct gl_context *ctx)
 {
    struct st_context *st = st_context(ctx);
 
    /* Don't call st_finish() here.  It is not the state tracker's
     * responsibilty to inject sleeps in the hope of avoiding buffer
     * synchronization issues.  Calling finish() here will just hide
     * problems that need to be fixed elsewhere.
     */
-   st_flush(st, NULL, 0);
+   st_flush(st, NULL, PIPE_FLUSH_ASYNC);
 
    st_manager_flush_frontbuffer(st);
 }
 
 
 /**
  * Called via ctx->Driver.Finish()
  */
 static void st_glFinish(struct gl_context *ctx)
 {
diff --git a/src/mesa/state_tracker/st_cb_syncobj.c b/src/mesa/state_tracker/st_cb_syncobj.c
index 637fbe3b73a..44323b4750a 100644
--- a/src/mesa/state_tracker/st_cb_syncobj.c
+++ b/src/mesa/state_tracker/st_cb_syncobj.c
@@ -123,22 +123,44 @@ static void st_client_wait_sync(struct gl_context *ctx,
 
 static void st_check_sync(struct gl_context *ctx, struct gl_sync_object *obj)
 {
    st_client_wait_sync(ctx, obj, 0, 0);
 }
 
 static void st_server_wait_sync(struct gl_context *ctx,
                                 struct gl_sync_object *obj,
                                 GLbitfield flags, GLuint64 timeout)
 {
-   /* NO-OP.
-    * Neither Gallium nor DRM interfaces support blocking on the GPU. */
+   struct pipe_context *pipe = st_context(ctx)->pipe;
+   struct pipe_screen *screen = pipe->screen;
+   struct st_sync_object *so = (struct st_sync_object*)obj;
+   struct pipe_fence_handle *fence = NULL;
+
+   /* Nothing needs to be done here if the driver does not support async
+    * flushes. */
+   if (!pipe->fence_server_sync)
+      return;
+
+   /* If the fence doesn't exist, assume it's signalled. */
+   mtx_lock(&so->mutex);
+   if (!so->fence) {
+      mtx_unlock(&so->mutex);
+      so->b.StatusFlag = GL_TRUE;
+      return;
+   }
+
+   /* We need a local copy of the fence pointer. */
+   screen->fence_reference(screen, &fence, so->fence);
+   mtx_unlock(&so->mutex);
+
+   pipe->fence_server_sync(pipe, fence);
+   screen->fence_reference(screen, &fence, NULL);
 }
 
 void st_init_syncobj_functions(struct dd_function_table *functions)
 {
    functions->NewSyncObject = st_new_sync_object;
    functions->FenceSync = st_fence_sync;
    functions->DeleteSyncObject = st_delete_sync_object;
    functions->CheckSync = st_check_sync;
    functions->ClientWaitSync = st_client_wait_sync;
    functions->ServerWaitSync = st_server_wait_sync;
-- 
2.11.0



More information about the mesa-dev mailing list