[RFC v2 04/12] sync: Add support for DMA fences

Louis-Francis Ratté-Boulianne lfrb at collabora.com
Wed Sep 27 05:19:55 UTC 2017


Functions are available to create a SyncFence from a DMA fence
fd and to retrieve the file descriptor from a SyncFence.

DMA fences can't be triggered/reset externally.

Signed-off-by: Louis-Francis Ratté-Boulianne <lfrb at collabora.com>
---
 Xext/sync.c            |  34 +++++++++++-
 Xext/syncsrv.h         |   6 ++
 hw/xfree86/sdksyms.sh  |   1 +
 miext/sync/Makefile.am |   5 +-
 miext/sync/meson.build |   1 +
 miext/sync/misync.h    |  16 ++++++
 miext/sync/misyncdma.c | 145 +++++++++++++++++++++++++++++++++++++++++++++++++
 miext/sync/misyncdma.h |  28 ++++++++++
 miext/sync/misyncshm.c |   1 +
 miext/sync/misyncstr.h |   1 +
 10 files changed, 235 insertions(+), 3 deletions(-)
 create mode 100644 miext/sync/misyncdma.c
 create mode 100644 miext/sync/misyncdma.h

diff --git a/Xext/sync.c b/Xext/sync.c
index 822c205a7..5c79d9e67 100644
--- a/Xext/sync.c
+++ b/Xext/sync.c
@@ -946,6 +946,34 @@ SyncFDFromFence(ClientPtr client, DrawablePtr pDraw, SyncFence *pFence)
 #endif
 }
 
+int
+SyncCreateFenceFromDMAFenceFD(ClientPtr client, DrawablePtr pDraw, XID id, int fd)
+{
+    SyncFence  *pFence;
+    int         status;
+
+    pFence = (SyncFence *) SyncCreate(client, id, SYNC_FENCE);
+    if (!pFence)
+        return BadAlloc;
+
+    status = miSyncInitFenceFromDMAFenceFD(pDraw->pScreen, pFence, fd);
+    if (status != Success) {
+        dixFreeObjectWithPrivates(pFence, PRIVATE_SYNC_FENCE);
+        return status;
+    }
+
+    if (!AddResource(id, RTFence, (void *) pFence))
+        return BadAlloc;
+
+    return Success;
+}
+
+int
+SyncDMAFenceFDFromFence(ClientPtr client, DrawablePtr pDraw, SyncFence *pFence)
+{
+    return miSyncDMAFenceFDFromFence(pDraw->pScreen, pFence);
+}
+
 static SyncCounter *
 SyncCreateCounter(ClientPtr client, XSyncCounter id, int64_t initialvalue)
 {
@@ -1931,6 +1959,9 @@ ProcSyncTriggerFence(ClientPtr client)
     if (rc != Success)
         return rc;
 
+    if (pFence->type == SYNC_FENCE_DMA)
+        return BadMatch;
+
     miSyncTriggerFence(pFence);
 
     return Success;
@@ -1950,7 +1981,8 @@ ProcSyncResetFence(ClientPtr client)
     if (rc != Success)
         return rc;
 
-    if (pFence->funcs.CheckTriggered(pFence) != TRUE)
+    if (pFence->type == SYNC_FENCE_DMA ||
+        pFence->funcs.CheckTriggered(pFence) != TRUE)
         return BadMatch;
 
     pFence->funcs.Reset(pFence);
diff --git a/Xext/syncsrv.h b/Xext/syncsrv.h
index 63f91a980..43fadbad5 100644
--- a/Xext/syncsrv.h
+++ b/Xext/syncsrv.h
@@ -142,6 +142,12 @@ SyncCreateFenceFromFD(ClientPtr client, DrawablePtr pDraw, XID id, int fd, BOOL
 int
 SyncFDFromFence(ClientPtr client, DrawablePtr pDraw, SyncFence *fence);
 
+int
+SyncCreateFenceFromDMAFenceFD(ClientPtr client, DrawablePtr pDraw, XID id, int fd);
+
+int
+SyncDMAFenceFDFromFence(ClientPtr client, DrawablePtr pDraw, SyncFence *fence);
+
 void
 SyncDeleteTriggerFromSyncObject(SyncTrigger * pTrigger);
 
diff --git a/hw/xfree86/sdksyms.sh b/hw/xfree86/sdksyms.sh
index 9aa1eec4f..554d5590e 100755
--- a/hw/xfree86/sdksyms.sh
+++ b/hw/xfree86/sdksyms.sh
@@ -44,6 +44,7 @@ cat > sdksyms.c << EOF
 /* miext/sync/Makefile.am */
 #include "misync.h"
 #include "misyncstr.h"
+#include "misyncdma.h"
 #if HAVE_XSHMFENCE
 #include "misyncshm.h"
 #endif
diff --git a/miext/sync/Makefile.am b/miext/sync/Makefile.am
index 34961d5ff..cf62cd617 100644
--- a/miext/sync/Makefile.am
+++ b/miext/sync/Makefile.am
@@ -5,7 +5,7 @@ AM_CFLAGS = $(DIX_CFLAGS)
 AM_CPPFLAGS = 
 
 if XORG
-sdk_HEADERS = misync.h misyncstr.h misyncshm.h misyncfd.h
+sdk_HEADERS = misync.h misyncstr.h misyncshm.h misyncfd.h misyncdma.h
 endif
 
 XSHMFENCE_SRCS = misyncshm.c
@@ -14,7 +14,8 @@ libsync_la_SOURCES =	\
 	misync.c	\
 	misync.h	\
 	misyncfd.c	\
-	misyncstr.h
+	misyncstr.h \
+	misyncdma.c
 
 if XSHMFENCE
 libsync_la_SOURCES += $(XSHMFENCE_SRCS)
diff --git a/miext/sync/meson.build b/miext/sync/meson.build
index da86fcc84..d9847d0bf 100644
--- a/miext/sync/meson.build
+++ b/miext/sync/meson.build
@@ -1,6 +1,7 @@
 srcs_miext_sync = [
     'misync.c',
     'misyncfd.c',
+    'misyncdma.c',
 ]
 
 if build_dri3
diff --git a/miext/sync/misync.h b/miext/sync/misync.h
index b3838f1e2..c32e4c961 100644
--- a/miext/sync/misync.h
+++ b/miext/sync/misync.h
@@ -28,6 +28,10 @@
 #ifndef _MISYNC_H_
 #define _MISYNC_H_
 
+/* Sync fence types */
+#define SYNC_FENCE_SHM          0
+#define SYNC_FENCE_DMA          1
+
 typedef struct _SyncFence SyncFence;
 typedef struct _SyncTrigger SyncTrigger;
 
@@ -73,6 +77,9 @@ extern _X_EXPORT SyncScreenFuncsPtr miSyncGetScreenFuncs(ScreenPtr pScreen);
 extern _X_EXPORT Bool
  miSyncSetup(ScreenPtr pScreen);
 
+extern _X_EXPORT int
+miSyncGetFenceType(SyncFence * pFence);
+
 Bool
 miSyncFenceCheckTriggered(SyncFence * pFence);
 
@@ -97,4 +104,13 @@ miSyncInitFenceFromFD(DrawablePtr pDraw, SyncFence *pFence, int fd, BOOL initial
 int
 miSyncFDFromFence(DrawablePtr pDraw, SyncFence *pFence);
 
+extern _X_EXPORT int
+miSyncDMAFenceFDFromFence(ScreenPtr pScreen, SyncFence *pFence);
+
+extern _X_EXPORT int
+miSyncInitFenceFromDMAFenceFD(ScreenPtr pScreen, SyncFence *pFence, int fd);
+
+extern _X_EXPORT int
+miSyncTakeDMAFenceFDFromFence(ScreenPtr pScreen, SyncFence *pFence);
+
 #endif                          /* _MISYNC_H_ */
diff --git a/miext/sync/misyncdma.c b/miext/sync/misyncdma.c
new file mode 100644
index 000000000..01a75a04f
--- /dev/null
+++ b/miext/sync/misyncdma.c
@@ -0,0 +1,145 @@
+/*
+ * Copyright © 2017 Intel Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  The copyright holders make no representations
+ * about the suitability of this software for any purpose.  It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "scrnintstr.h"
+#include "misync.h"
+#include "misyncstr.h"
+#include "misyncdma.h"
+#include "pixmapstr.h"
+#include <sys/mman.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <poll.h>
+#include <X11/xshmfence.h>
+
+static DevPrivateKeyRec syncDmaFencePrivateKey;
+
+typedef struct _SyncDmaFencePrivate {
+    int                        fd;
+} SyncDmaFencePrivateRec, *SyncDmaFencePrivatePtr;
+
+#define SYNC_FENCE_PRIV(pFence) \
+    (SyncDmaFencePrivatePtr) dixLookupPrivate(&pFence->devPrivates, &syncDmaFencePrivateKey)
+
+static void
+miSyncDmaFenceSetTriggered(SyncFence * pFence)
+{
+}
+
+static void
+miSyncDmaFenceReset(SyncFence * pFence)
+{
+}
+
+static Bool
+miSyncDmaFenceCheckTriggered(SyncFence * pFence)
+{
+    SyncDmaFencePrivatePtr pPriv = SYNC_FENCE_PRIV(pFence);
+    struct pollfd fds;
+
+    if (pPriv->fd > 0) {
+        fds.fd = pPriv->fd;
+        fds.events = POLLOUT;
+        fds.revents = 0;
+        poll(&fds, 1, 0);
+        return fds.revents & POLLOUT;
+    } else {
+        return miSyncFenceCheckTriggered(pFence);
+    }
+}
+
+static void
+miSyncDmaFenceAddTrigger(SyncTrigger * pTrigger)
+{
+    miSyncFenceAddTrigger(pTrigger);
+}
+
+static void
+miSyncDmaFenceDeleteTrigger(SyncTrigger * pTrigger)
+{
+    miSyncFenceDeleteTrigger(pTrigger);
+}
+
+static void
+miSyncDmaFenceDestroy(SyncFence * pFence)
+{
+    SyncDmaFencePrivatePtr pPriv = SYNC_FENCE_PRIV(pFence);
+
+    if (pPriv->fd >= 0)
+        close(pPriv->fd);
+    pPriv->fd = -1;
+}
+
+static const SyncFenceFuncsRec miSyncDmaFenceFuncs = {
+    &miSyncDmaFenceSetTriggered,
+    &miSyncDmaFenceReset,
+    &miSyncDmaFenceCheckTriggered,
+    &miSyncDmaFenceAddTrigger,
+    &miSyncDmaFenceDeleteTrigger,
+    &miSyncDmaFenceDestroy
+};
+
+int
+miSyncInitFenceFromDMAFenceFD(ScreenPtr pScreen, SyncFence *pFence, int fd)
+{
+    SyncDmaFencePrivatePtr pPriv = SYNC_FENCE_PRIV(pFence);
+
+    pFence->pScreen = pScreen;
+    pFence->funcs = miSyncDmaFenceFuncs;
+    pFence->type = SYNC_FENCE_DMA;
+
+    pPriv->fd = fd < 0 ? -1 : dup(fd);
+    return Success;
+}
+
+int
+miSyncDMAFenceFDFromFence(ScreenPtr pScreen, SyncFence *pFence)
+{
+    SyncDmaFencePrivatePtr pPriv = SYNC_FENCE_PRIV(pFence);
+
+    return pPriv->fd;
+}
+
+int
+miSyncTakeDMAFenceFDFromFence(ScreenPtr pScreen, SyncFence *pFence)
+{
+    SyncDmaFencePrivatePtr pPriv = SYNC_FENCE_PRIV(pFence);
+    int fd = pPriv->fd;
+    pPriv->fd = -1;
+    return fd;
+}
+
+_X_EXPORT Bool miSyncDmaScreenInit(ScreenPtr pScreen)
+{
+    if (!dixPrivateKeyRegistered(&syncDmaFencePrivateKey)) {
+        if (!dixRegisterPrivateKey(&syncDmaFencePrivateKey, PRIVATE_SYNC_FENCE,
+                                   sizeof(SyncDmaFencePrivateRec)))
+            return FALSE;
+    }
+
+    return TRUE;
+}
+
diff --git a/miext/sync/misyncdma.h b/miext/sync/misyncdma.h
new file mode 100644
index 000000000..8a27069d7
--- /dev/null
+++ b/miext/sync/misyncdma.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright © 2017 Intel Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  The copyright holders make no representations
+ * about the suitability of this software for any purpose.  It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#ifndef _MISYNCDMA_H_
+#define _MISYNCDMA_H_
+
+extern _X_EXPORT Bool miSyncDmaScreenInit(ScreenPtr pScreen);
+
+#endif /* _MISYNCDMA_H_ */
diff --git a/miext/sync/misyncshm.c b/miext/sync/misyncshm.c
index f55a3f8a5..0b93696c8 100644
--- a/miext/sync/misyncshm.c
+++ b/miext/sync/misyncshm.c
@@ -119,6 +119,7 @@ miSyncShmScreenCreateFence(ScreenPtr pScreen, SyncFence * pFence,
     pPriv->fence = NULL;
     miSyncScreenCreateFence(pScreen, pFence, initially_triggered);
     pFence->funcs = miSyncShmFenceFuncs;
+    pFence->type = SYNC_FENCE_SHM;
 }
 
 static int
diff --git a/miext/sync/misyncstr.h b/miext/sync/misyncstr.h
index 2eab2aa57..6d97894f0 100644
--- a/miext/sync/misyncstr.h
+++ b/miext/sync/misyncstr.h
@@ -57,6 +57,7 @@ struct _SyncFence {
     ScreenPtr pScreen;          /* Screen of this fence object */
     SyncFenceFuncsRec funcs;    /* Funcs for performing ops on fence */
     Bool triggered;             /* fence state */
+    unsigned char type;         /* fence type */
     PrivateRec *devPrivates;    /* driver-specific per-fence data */
 };
 
-- 
2.13.0



More information about the xorg-devel mailing list