Syncobj based waits or signals only happen at submission boundaries. In
order to guarantee that the requested signal event will occur when the
state tracker requested it, we must issue a flush.

Signed-off-by: Andres Rodriguez <andre...@gmail.com>
---
 src/gallium/drivers/radeonsi/si_fence.c | 37 +++++++++++++++++++++++++++++++++
 1 file changed, 37 insertions(+)

diff --git a/src/gallium/drivers/radeonsi/si_fence.c 
b/src/gallium/drivers/radeonsi/si_fence.c
index 086d45c..7d898d1 100644
--- a/src/gallium/drivers/radeonsi/si_fence.c
+++ b/src/gallium/drivers/radeonsi/si_fence.c
@@ -63,6 +63,14 @@ static void si_add_fence_dependency(struct 
r600_common_context *rctx,
        ws->cs_add_fence_dependency(rctx->gfx.cs, fence);
 }
 
+static void si_add_syncobj_signal(struct r600_common_context *rctx,
+                                 struct pipe_semaphore_handle *semaphore)
+{
+       struct radeon_winsys *ws = rctx->ws;
+
+       ws->cs_add_syncobj_signal(rctx->gfx.cs, semaphore);
+}
+
 static void si_semaphore_reference(struct pipe_screen *screen,
                               struct pipe_semaphore_handle **dst,
                               struct pipe_semaphore_handle *src)
@@ -478,11 +486,40 @@ finish:
        }
 }
 
+static void si_semaphore_server_signal(struct pipe_context *ctx,
+                                      struct pipe_semaphore_handle *semaphore)
+{
+       struct r600_common_context *rctx = (struct r600_common_context *)ctx;
+       struct si_multi_fence *rfence = (struct si_multi_fence *)semaphore;
+
+       /* We should have at least one syncobj to signal */
+       assert(rfence->sdma || rfence->gfx);
+
+       if (rfence->sdma)
+               si_add_syncobj_signal(rctx, rfence->sdma);
+       if (rfence->gfx)
+               si_add_syncobj_signal(rctx, rfence->gfx);
+
+       /**
+        * The spec does not require a flush here. We insert a flush
+        * because syncobj based signals are not directly placed into
+        * the command stream. Instead the signal happens when the
+        * submission associated with the syncobj finishes execution.
+        *
+        * Therefore, we must make sure that we flush the pipe to avoid
+        * new work being emitted and getting executed before the signal
+        * operation.
+        */
+       si_flush_from_st(ctx, NULL, PIPE_FLUSH_ASYNC);
+}
+
+
 void si_init_fence_functions(struct si_context *ctx)
 {
        ctx->b.b.flush = si_flush_from_st;
        ctx->b.b.create_semaphore_fd = si_create_semaphore_fd;
        ctx->b.b.semaphore_server_sync = si_semaphore_server_sync;
+       ctx->b.b.semaphore_server_signal = si_semaphore_server_signal;
 }
 
 void si_init_screen_fence_functions(struct si_screen *screen)
-- 
2.9.3

_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to