[Mesa-dev] [PATCH 6/6] gallium: support for native fence fd's

Rob Clark robdclark at gmail.com
Fri Apr 1 20:29:50 UTC 2016


From: Rob Clark <robclark at freedesktop.org>

This enables gallium support for EGL_ANDROID_native_fence_sync, for
drivers which support PIPE_CAP_NATIVE_FENCE_FD.

TODO: add PIPE_CAP_NATIVE_FENCE_FD to every's switch statement returning
false.. but I'll leave that until this patchset is ready to push since
that sort of thing makes a lot of rebase noise.

Signed-off-by: Rob Clark <robclark at freedesktop.org>
---
 src/gallium/include/pipe/p_context.h  | 17 +++++++++++++
 src/gallium/include/pipe/p_defines.h  |  1 +
 src/gallium/include/pipe/p_screen.h   |  8 +++++++
 src/gallium/state_trackers/dri/dri2.c | 45 +++++++++++++++++++++++++++++++++--
 4 files changed, 69 insertions(+), 2 deletions(-)

diff --git a/src/gallium/include/pipe/p_context.h b/src/gallium/include/pipe/p_context.h
index d617ec4..152fb91 100644
--- a/src/gallium/include/pipe/p_context.h
+++ b/src/gallium/include/pipe/p_context.h
@@ -473,6 +473,23 @@ struct pipe_context {
                         struct pipe_fence_handle **fence);
 
    /**
+    * Create a fence from a native sync fd.
+    *
+    * If the fence fd is -1, the driver should insert fence commands
+    * in command-stream, and (after flush) be prepared to return a
+    * valid fd from screen->get_fence_fd().  Otherwise, the driver
+    * should wrap an existing native fence fd (and be prepared for
+    * ctx->fence_server_sync())
+    *
+    * \param fence  if not NULL, an old fence to unref and transfer a
+    *    new fence reference to
+    * \param fd     native fence fd
+    */
+   void (*create_fence_fd)(struct pipe_context *pipe,
+                           struct pipe_fence_handle **fence,
+                           int fd);
+
+   /**
     * Wait for the fence to finish.
     * \param timeout in nanoseconds (may be PIPE_TIMEOUT_INFINITE).
     */
diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h
index 8257b4a..654a576 100644
--- a/src/gallium/include/pipe/p_defines.h
+++ b/src/gallium/include/pipe/p_defines.h
@@ -689,6 +689,7 @@ enum pipe_cap
    PIPE_CAP_PCI_BUS,
    PIPE_CAP_PCI_DEVICE,
    PIPE_CAP_PCI_FUNCTION,
+   PIPE_CAP_NATIVE_FENCE_FD,
 };
 
 #define PIPE_QUIRK_TEXTURE_BORDER_COLOR_SWIZZLE_NV50 (1 << 0)
diff --git a/src/gallium/include/pipe/p_screen.h b/src/gallium/include/pipe/p_screen.h
index 4f30e75..9e8e942 100644
--- a/src/gallium/include/pipe/p_screen.h
+++ b/src/gallium/include/pipe/p_screen.h
@@ -246,6 +246,14 @@ struct pipe_screen {
                             uint64_t timeout );
 
    /**
+    * For fences created via ctx->create_fence_fd(), return the native
+    * fence fd associated with the fence, or -1 if the fence commands
+    * have not been flushed yet.
+    */
+   int (*fence_get_fd)(struct pipe_screen *screen,
+                       struct pipe_fence_handle *fence);
+
+   /**
     * Returns a driver-specific query.
     *
     * If \p info is NULL, the number of available queries is returned.
diff --git a/src/gallium/state_trackers/dri/dri2.c b/src/gallium/state_trackers/dri/dri2.c
index 6c8bb37..1a970c5 100644
--- a/src/gallium/state_trackers/dri/dri2.c
+++ b/src/gallium/state_trackers/dri/dri2.c
@@ -1311,6 +1311,18 @@ struct dri2_fence {
    void *cl_event;
 };
 
+static unsigned dri2_fence_get_caps(__DRIscreen *_screen)
+{
+   struct dri_screen *driscreen = dri_screen(_screen);
+   struct pipe_screen *screen = driscreen->base.screen;
+   unsigned caps = 0;
+
+   if (screen->get_param(screen, PIPE_CAP_NATIVE_FENCE_FD))
+      caps |= __DRI_FENCE_CAP_NATIVE_FD;
+
+   return caps;
+}
+
 static void *
 dri2_create_fence(__DRIcontext *_ctx)
 {
@@ -1337,6 +1349,32 @@ dri2_create_fence(__DRIcontext *_ctx)
 }
 
 static void *
+dri2_create_fence_fd(__DRIcontext *_ctx, int fd)
+{
+   struct pipe_context *ctx = dri_context(_ctx)->st->pipe;
+   struct dri2_fence *fence = CALLOC_STRUCT(dri2_fence);
+
+   ctx->create_fence_fd(ctx, &fence->pipe_fence, fd);
+   if (!fence->pipe_fence) {
+      FREE(fence);
+      return NULL;
+   }
+
+   fence->driscreen = dri_screen(_ctx->driScreenPriv);
+   return fence;
+}
+
+static int
+dri2_get_fence_fd(__DRIscreen *_screen, void *_fence)
+{
+   struct dri_screen *driscreen = dri_screen(_screen);
+   struct pipe_screen *screen = driscreen->base.screen;
+   struct dri2_fence *fence = (struct dri2_fence*)_fence;
+
+   return screen->fence_get_fd(screen, fence->pipe_fence);
+}
+
+static void *
 dri2_get_fence_from_cl_event(__DRIscreen *_screen, intptr_t cl_event)
 {
    struct dri_screen *driscreen = dri_screen(_screen);
@@ -1421,13 +1459,16 @@ dri2_server_wait_sync(__DRIcontext *_ctx, void *_fence, unsigned flags)
 }
 
 static __DRI2fenceExtension dri2FenceExtension = {
-   .base = { __DRI2_FENCE, 1 },
+   .base = { __DRI2_FENCE, 2 },
 
    .create_fence = dri2_create_fence,
    .get_fence_from_cl_event = dri2_get_fence_from_cl_event,
    .destroy_fence = dri2_destroy_fence,
    .client_wait_sync = dri2_client_wait_sync,
-   .server_wait_sync = dri2_server_wait_sync
+   .server_wait_sync = dri2_server_wait_sync,
+   .get_capabilities = dri2_fence_get_caps,
+   .create_fence_fd = dri2_create_fence_fd,
+   .get_fence_fd = dri2_get_fence_fd,
 };
 
 static const __DRIrobustnessExtension dri2Robustness = {
-- 
2.5.5



More information about the mesa-dev mailing list