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