freedreno: support GL_EXT_semaphore
authorHyunjun Ko <zzoon@igalia.com>
Sun, 19 Apr 2020 15:20:41 +0000 (17:20 +0200)
committerMarge Bot <eric+marge@anholt.net>
Tue, 18 Aug 2020 20:40:40 +0000 (20:40 +0000)
Signed-off-by: Hyunjun Ko <zzoon@igalia.com>
Reviewed-by: Rob Clark <robdclark@chromium.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4565>

src/freedreno/drm/freedreno_device.c
src/freedreno/drm/freedreno_drmif.h
src/gallium/drivers/freedreno/freedreno_context.c
src/gallium/drivers/freedreno/freedreno_fence.c
src/gallium/drivers/freedreno/freedreno_fence.h
src/gallium/drivers/freedreno/freedreno_screen.c
src/gallium/drivers/freedreno/freedreno_screen.h

index f0dc53b526d4c06d011bad156fadcf6659249b0d..fbc9bcb09845b1db5bc379fa53ebca5d8e93a842 100644 (file)
@@ -153,3 +153,11 @@ bool fd_dbg(void)
 
        return dbg == 1;
 }
 
        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;
+}
index 15038475e7427afc7e8dd088d46921e0f35b2cdf..3f7b8294e3ce6b74eb9df73dfe785c79a9976b31 100644 (file)
@@ -98,6 +98,8 @@ enum fd_version {
 };
 enum fd_version fd_device_version(struct fd_device *dev);
 
 };
 enum fd_version fd_device_version(struct fd_device *dev);
 
+bool fd_has_syncobj(struct fd_device *dev);
+
 /* pipe functions:
  */
 
 /* pipe functions:
  */
 
index 4ebb279bc3b80487edebc1dcfec4dea1ccac14a4..e783a8ac71599a29de7d4a072c395a94afd02800 100644 (file)
@@ -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->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;
 
        pctx->texture_barrier = fd_texture_barrier;
        pctx->memory_barrier = fd_memory_barrier;
 
index 3477d9835c5757a0a6e609f7464597abe722f47e..9f0f6ee531d54f615694eed5577195e835593183 100644 (file)
@@ -32,6 +32,8 @@
 #include "freedreno_fence.h"
 #include "freedreno_context.h"
 #include "freedreno_util.h"
 #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;
 
 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;
        struct fd_screen *screen;
        int fence_fd;
        uint32_t timestamp;
+       uint32_t syncobj;
 };
 
 static void fence_flush(struct pipe_fence_handle *fence)
 };
 
 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,
 }
 
 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;
 
 {
        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->screen = ctx->screen;
        fence->timestamp = timestamp;
        fence->fence_fd = fence_fd;
+       fence->syncobj = syncobj;
 
        return fence;
 }
 
        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)
 {
                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,
 }
 
 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)
 {
 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)
 {
 
 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);
 }
 }
index efb9aaee166a56a2c8439a13aa777fd8a885aac8..0d17e1edebee5ee98d81ee3e9659250da2e4711e 100644 (file)
@@ -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);
                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);
 int fd_fence_get_fd(struct pipe_screen *pscreen,
                struct pipe_fence_handle *pfence);
 bool fd_fence_is_fd(struct pipe_fence_handle *fence);
index 9f0867ba83af6119a950515d9f70e9ee984b2d39..f7c8cf9e04e9c035bd3055d2f2c82460573dba5f 100644 (file)
@@ -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;
                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);
        }
        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;
 
        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;
        struct sysinfo si;
        sysinfo(&si);
        screen->ram_size = si.totalram;
index c2a13f51f8c3e338e9b84b22350526886e4e2266..4707496ef06ad3da6d7e331d930b9c9f38f0c541 100644 (file)
@@ -76,6 +76,7 @@ struct fd_screen {
        uint32_t priority_mask;
        bool has_timestamp;
        bool has_robustness;
        uint32_t priority_mask;
        bool has_timestamp;
        bool has_robustness;
+       bool has_syncobj;
 
        unsigned num_perfcntr_groups;
        const struct fd_perfcntr_group *perfcntr_groups;
 
        unsigned num_perfcntr_groups;
        const struct fd_perfcntr_group *perfcntr_groups;