[17/22] radeonsi: implement semaphore_server_signal

Submitted by Andres Rodriguez on Dec. 22, 2017, 12:41 a.m.

Details

Message ID 20171222004157.28106-18-andresx7@gmail.com
State New
Headers show
Series "Add support for GL_EXT_semaphore" ( rev: 2 ) in Mesa

Not browsing as part of any series.

Commit Message

Andres Rodriguez Dec. 22, 2017, 12:41 a.m.
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 <andresx7@gmail.com>
---
 src/gallium/drivers/radeonsi/si_fence.c | 37 +++++++++++++++++++++++++++++++++
 1 file changed, 37 insertions(+)

Patch hide | download patch | download mbox

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)