[RFC xserver 03/12] sync: Add support for DMA fences
Louis-Francis Ratté-Boulianne
lfrb at collabora.com
Wed Aug 30 05:16:52 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 a8db0ec22..42338b96d 100644
--- a/Xext/sync.c
+++ b/Xext/sync.c
@@ -952,6 +952,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, CARD64 initialvalue)
{
@@ -1938,6 +1966,9 @@ ProcSyncTriggerFence(ClientPtr client)
if (rc != Success)
return rc;
+ if (pFence->type == SYNC_FENCE_DMA)
+ return BadMatch;
+
miSyncTriggerFence(pFence);
return Success;
@@ -1957,7 +1988,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 a8062d1c6..df0480436 100644
--- a/Xext/syncsrv.h
+++ b/Xext/syncsrv.h
@@ -143,6 +143,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 ad69e8eca..f12ffb3cc 100644
--- a/miext/sync/misyncstr.h
+++ b/miext/sync/misyncstr.h
@@ -58,6 +58,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