Mesa (master): freedreno: support GL_EXT_semaphore

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Tue Aug 18 20:57:08 UTC 2020


Module: Mesa
Branch: master
Commit: e0e9712a4d8008328578c0698157924a8aff0970
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=e0e9712a4d8008328578c0698157924a8aff0970

Author: Hyunjun Ko <zzoon at igalia.com>
Date:   Sun Apr 19 17:20:41 2020 +0200

freedreno: support GL_EXT_semaphore

Signed-off-by: Hyunjun Ko <zzoon at igalia.com>
Reviewed-by: Rob Clark <robdclark at chromium.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4565>

---

 src/freedreno/drm/freedreno_device.c              |  8 +++++
 src/freedreno/drm/freedreno_drmif.h               |  2 ++
 src/gallium/drivers/freedreno/freedreno_context.c |  1 +
 src/gallium/drivers/freedreno/freedreno_fence.c   | 41 ++++++++++++++++++++---
 src/gallium/drivers/freedreno/freedreno_fence.h   |  2 ++
 src/gallium/drivers/freedreno/freedreno_screen.c  |  4 +++
 src/gallium/drivers/freedreno/freedreno_screen.h  |  1 +
 7 files changed, 55 insertions(+), 4 deletions(-)

diff --git a/src/freedreno/drm/freedreno_device.c b/src/freedreno/drm/freedreno_device.c
index f0dc53b526d..fbc9bcb0984 100644
--- a/src/freedreno/drm/freedreno_device.c
+++ b/src/freedreno/drm/freedreno_device.c
@@ -153,3 +153,11 @@ bool fd_dbg(void)
 
 	return dbg == 1;
 }
+
+bool fd_has_syncobj(struct fd_device *dev)
+{
+	uint64_t value;
+	if (drmGetCap(dev->fd, DRM_CAP_SYNCOBJ, &value))
+		return false;
+	return value && dev->version >= FD_VERSION_FENCE_FD;
+}
diff --git a/src/freedreno/drm/freedreno_drmif.h b/src/freedreno/drm/freedreno_drmif.h
index 15038475e74..3f7b8294e3c 100644
--- a/src/freedreno/drm/freedreno_drmif.h
+++ b/src/freedreno/drm/freedreno_drmif.h
@@ -98,6 +98,8 @@ enum fd_version {
 };
 enum fd_version fd_device_version(struct fd_device *dev);
 
+bool fd_has_syncobj(struct fd_device *dev);
+
 /* pipe functions:
  */
 
diff --git a/src/gallium/drivers/freedreno/freedreno_context.c b/src/gallium/drivers/freedreno/freedreno_context.c
index 4ebb279bc3b..e783a8ac715 100644
--- a/src/gallium/drivers/freedreno/freedreno_context.c
+++ b/src/gallium/drivers/freedreno/freedreno_context.c
@@ -428,6 +428,7 @@ fd_context_init(struct fd_context *ctx, struct pipe_screen *pscreen,
 	pctx->get_device_reset_status = fd_get_device_reset_status;
 	pctx->create_fence_fd = fd_create_fence_fd;
 	pctx->fence_server_sync = fd_fence_server_sync;
+	pctx->fence_server_signal = fd_fence_server_signal;
 	pctx->texture_barrier = fd_texture_barrier;
 	pctx->memory_barrier = fd_memory_barrier;
 
diff --git a/src/gallium/drivers/freedreno/freedreno_fence.c b/src/gallium/drivers/freedreno/freedreno_fence.c
index 3477d9835c5..9f0f6ee531d 100644
--- a/src/gallium/drivers/freedreno/freedreno_fence.c
+++ b/src/gallium/drivers/freedreno/freedreno_fence.c
@@ -32,6 +32,8 @@
 #include "freedreno_fence.h"
 #include "freedreno_context.h"
 #include "freedreno_util.h"
+/* TODO: Use the interface drm/freedreno_drmif.h instead of calling directly */
+#include <xf86drm.h>
 
 struct pipe_fence_handle {
 	struct pipe_reference reference;
@@ -44,6 +46,7 @@ struct pipe_fence_handle {
 	struct fd_screen *screen;
 	int fence_fd;
 	uint32_t timestamp;
+	uint32_t syncobj;
 };
 
 static void fence_flush(struct pipe_fence_handle *fence)
@@ -99,7 +102,7 @@ bool fd_fence_finish(struct pipe_screen *pscreen,
 }
 
 static struct pipe_fence_handle * fence_create(struct fd_context *ctx,
-		struct fd_batch *batch, uint32_t timestamp, int fence_fd)
+		struct fd_batch *batch, uint32_t timestamp, int fence_fd, int syncobj)
 {
 	struct pipe_fence_handle *fence;
 
@@ -114,6 +117,7 @@ static struct pipe_fence_handle * fence_create(struct fd_context *ctx,
 	fence->screen = ctx->screen;
 	fence->timestamp = timestamp;
 	fence->fence_fd = fence_fd;
+	fence->syncobj = syncobj;
 
 	return fence;
 }
@@ -122,8 +126,27 @@ void fd_create_fence_fd(struct pipe_context *pctx,
 		struct pipe_fence_handle **pfence, int fd,
 		enum pipe_fd_type type)
 {
-	assert(type == PIPE_FD_TYPE_NATIVE_SYNC);
-	*pfence = fence_create(fd_context(pctx), NULL, 0, os_dupfd_cloexec(fd));
+	struct fd_context *ctx = fd_context(pctx);
+
+	switch (type) {
+	case PIPE_FD_TYPE_NATIVE_SYNC:
+		*pfence = fence_create(fd_context(pctx), NULL, 0, os_dupfd_cloexec(fd), 0);
+		break;
+	case PIPE_FD_TYPE_SYNCOBJ: {
+		int ret;
+		uint32_t syncobj;
+
+		assert(ctx->screen->has_syncobj);
+		ret = drmSyncobjFDToHandle(fd_device_fd(ctx->screen->dev), fd, &syncobj);
+		if (!ret)
+			close(fd);
+
+		*pfence = fence_create(fd_context(pctx), NULL, 0, -1, syncobj);
+		break;
+	}
+	default:
+		unreachable("Unhandled fence type");
+	}
 }
 
 void fd_fence_server_sync(struct pipe_context *pctx,
@@ -143,6 +166,16 @@ void fd_fence_server_sync(struct pipe_context *pctx,
 	}
 }
 
+void fd_fence_server_signal(struct pipe_context *pctx,
+		struct pipe_fence_handle *fence)
+{
+	struct fd_context *ctx = fd_context(pctx);
+
+	if (fence->syncobj) {
+		drmSyncobjSignal(fd_device_fd(ctx->screen->dev), &fence->syncobj, 1);
+	}
+}
+
 int fd_fence_get_fd(struct pipe_screen *pscreen,
 		struct pipe_fence_handle *fence)
 {
@@ -157,5 +190,5 @@ bool fd_fence_is_fd(struct pipe_fence_handle *fence)
 
 struct pipe_fence_handle * fd_fence_create(struct fd_batch *batch)
 {
-	return fence_create(batch->ctx, batch, 0, -1);
+	return fence_create(batch->ctx, batch, 0, -1, 0);
 }
diff --git a/src/gallium/drivers/freedreno/freedreno_fence.h b/src/gallium/drivers/freedreno/freedreno_fence.h
index efb9aaee166..0d17e1edebe 100644
--- a/src/gallium/drivers/freedreno/freedreno_fence.h
+++ b/src/gallium/drivers/freedreno/freedreno_fence.h
@@ -42,6 +42,8 @@ void fd_create_fence_fd(struct pipe_context *pctx,
 		enum pipe_fd_type type);
 void fd_fence_server_sync(struct pipe_context *pctx,
 		struct pipe_fence_handle *fence);
+void fd_fence_server_signal(struct pipe_context *ctx,
+		struct pipe_fence_handle *fence);
 int fd_fence_get_fd(struct pipe_screen *pscreen,
 		struct pipe_fence_handle *pfence);
 bool fd_fence_is_fd(struct pipe_fence_handle *fence);
diff --git a/src/gallium/drivers/freedreno/freedreno_screen.c b/src/gallium/drivers/freedreno/freedreno_screen.c
index 9f0867ba83a..f7c8cf9e04e 100644
--- a/src/gallium/drivers/freedreno/freedreno_screen.c
+++ b/src/gallium/drivers/freedreno/freedreno_screen.c
@@ -457,6 +457,8 @@ fd_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
 		return fd_device_version(screen->dev) >= FD_VERSION_MEMORY_FD;
 	case PIPE_CAP_NATIVE_FENCE_FD:
 		return fd_device_version(screen->dev) >= FD_VERSION_FENCE_FD;
+	case PIPE_CAP_FENCE_SIGNAL:
+		return screen->has_syncobj;
 	default:
 		return u_pipe_screen_get_param_defaults(pscreen, param);
 	}
@@ -930,6 +932,8 @@ fd_screen_create(struct fd_device *dev, struct renderonly *ro)
 	if (fd_device_version(dev) >= FD_VERSION_ROBUSTNESS)
 		screen->has_robustness = true;
 
+	screen->has_syncobj = fd_has_syncobj(screen->dev);
+
 	struct sysinfo si;
 	sysinfo(&si);
 	screen->ram_size = si.totalram;
diff --git a/src/gallium/drivers/freedreno/freedreno_screen.h b/src/gallium/drivers/freedreno/freedreno_screen.h
index c2a13f51f8c..4707496ef06 100644
--- a/src/gallium/drivers/freedreno/freedreno_screen.h
+++ b/src/gallium/drivers/freedreno/freedreno_screen.h
@@ -76,6 +76,7 @@ struct fd_screen {
 	uint32_t priority_mask;
 	bool has_timestamp;
 	bool has_robustness;
+	bool has_syncobj;
 
 	unsigned num_perfcntr_groups;
 	const struct fd_perfcntr_group *perfcntr_groups;



More information about the mesa-commit mailing list