[RFC xserver v3 04/11] sync: Add support for DMA fences
Louis-Francis Ratté-Boulianne
lfrb at collabora.com
Mon Nov 6 21:42:53 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.
v2: Make SetTriggered and Reset return a status and remove fence type
Signed-off-by: Louis-Francis Ratté-Boulianne <lfrb at collabora.com>
---
Xext/sync.c | 39 ++++++++++---
Xext/syncsrv.h | 6 ++
glamor/glamor_sync.c | 7 ++-
hw/xfree86/sdksyms.sh | 1 +
miext/sync/Makefile.am | 5 +-
miext/sync/meson.build | 1 +
miext/sync/misync.c | 17 ++++--
miext/sync/misync.h | 22 +++++--
miext/sync/misyncdma.c | 152 +++++++++++++++++++++++++++++++++++++++++++++++++
miext/sync/misyncdma.h | 28 +++++++++
miext/sync/misyncshm.c | 11 +++-
11 files changed, 265 insertions(+), 24 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 37d41f224..034f9bf51 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,9 +1959,7 @@ ProcSyncTriggerFence(ClientPtr client)
if (rc != Success)
return rc;
- miSyncTriggerFence(pFence);
-
- return Success;
+ return miSyncTriggerFence(pFence);
}
static int
@@ -1950,12 +1976,7 @@ ProcSyncResetFence(ClientPtr client)
if (rc != Success)
return rc;
- if (pFence->funcs.CheckTriggered(pFence) != TRUE)
- return BadMatch;
-
- pFence->funcs.Reset(pFence);
-
- return Success;
+ return pFence->funcs.Reset(pFence);
}
static int
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/glamor/glamor_sync.c b/glamor/glamor_sync.c
index 907e0c613..71835fcc4 100644
--- a/glamor/glamor_sync.c
+++ b/glamor/glamor_sync.c
@@ -44,21 +44,24 @@ glamor_get_sync_fence(SyncFence *fence)
return (struct glamor_sync_fence *) dixLookupPrivate(&fence->devPrivates, &glamor_sync_fence_key);
}
-static void
+static int
glamor_sync_fence_set_triggered (SyncFence *fence)
{
ScreenPtr screen = fence->pScreen;
glamor_screen_private *glamor = glamor_get_screen_private(screen);
struct glamor_sync_fence *glamor_fence = glamor_get_sync_fence(fence);
+ int ret;
/* Flush pending rendering operations */
glamor_make_current(glamor);
glFlush();
fence->funcs.SetTriggered = glamor_fence->set_triggered;
- fence->funcs.SetTriggered(fence);
+ ret = fence->funcs.SetTriggered(fence);
glamor_fence->set_triggered = fence->funcs.SetTriggered;
fence->funcs.SetTriggered = glamor_sync_fence_set_triggered;
+
+ return ret;
}
static void
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.c b/miext/sync/misync.c
index d7880d39c..87c157cd6 100644
--- a/miext/sync/misync.c
+++ b/miext/sync/misync.c
@@ -42,16 +42,20 @@ miSyncScreenCreateFence(ScreenPtr pScreen, SyncFence * pFence,
}
/* Default implementations of the per-object functions */
-void
+int
miSyncFenceSetTriggered(SyncFence * pFence)
{
pFence->triggered = TRUE;
+
+ return Success;
}
-void
+int
miSyncFenceReset(SyncFence * pFence)
{
pFence->triggered = FALSE;
+
+ return Success;
}
Bool
@@ -123,12 +127,15 @@ miSyncDestroyFence(SyncFence * pFence)
dixFreeObjectWithPrivates(pFence, PRIVATE_SYNC_FENCE);
}
-void
+int
miSyncTriggerFence(SyncFence * pFence)
{
SyncTriggerList *ptl, *pNext;
+ int ret;
- pFence->funcs.SetTriggered(pFence);
+ ret = pFence->funcs.SetTriggered(pFence);
+ if (ret != Success)
+ return ret;
/* run through triggers to see if any fired */
for (ptl = pFence->sync.pTriglist; ptl; ptl = pNext) {
@@ -136,6 +143,8 @@ miSyncTriggerFence(SyncFence * pFence)
if ((*ptl->pTrigger->CheckTrigger) (ptl->pTrigger, 0))
(*ptl->pTrigger->TriggerFired) (ptl->pTrigger);
}
+
+ return Success;
}
SyncScreenFuncsPtr
diff --git a/miext/sync/misync.h b/miext/sync/misync.h
index b3838f1e2..78a7d4998 100644
--- a/miext/sync/misync.h
+++ b/miext/sync/misync.h
@@ -44,8 +44,8 @@ extern _X_EXPORT void
miSyncScreenCreateFence(ScreenPtr pScreen, SyncFence * pFence,
Bool initially_triggered);
-typedef void (*SyncFenceSetTriggeredFunc) (SyncFence * pFence);
-typedef void (*SyncFenceResetFunc) (SyncFence * pFence);
+typedef int (*SyncFenceSetTriggeredFunc) (SyncFence * pFence);
+typedef int (*SyncFenceResetFunc) (SyncFence * pFence);
typedef Bool (*SyncFenceCheckTriggeredFunc) (SyncFence * pFence);
typedef void (*SyncFenceAddTriggerFunc) (SyncTrigger * pTrigger);
typedef void (*SyncFenceDeleteTriggerFunc) (SyncTrigger * pTrigger);
@@ -66,7 +66,7 @@ miSyncInitFence(ScreenPtr pScreen, SyncFence * pFence,
Bool initially_triggered);
extern _X_EXPORT void
miSyncDestroyFence(SyncFence * pFence);
-extern _X_EXPORT void
+extern _X_EXPORT int
miSyncTriggerFence(SyncFence * pFence);
extern _X_EXPORT SyncScreenFuncsPtr miSyncGetScreenFuncs(ScreenPtr pScreen);
@@ -76,10 +76,10 @@ extern _X_EXPORT Bool
Bool
miSyncFenceCheckTriggered(SyncFence * pFence);
-void
+int
miSyncFenceSetTriggered(SyncFence * pFence);
-void
+int
miSyncFenceReset(SyncFence * pFence);
void
@@ -97,4 +97,16 @@ miSyncInitFenceFromFD(DrawablePtr pDraw, SyncFence *pFence, int fd, BOOL initial
int
miSyncFDFromFence(DrawablePtr pDraw, SyncFence *pFence);
+extern _X_EXPORT Bool
+miSyncIsDMAFence(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..9aaf04e6a
--- /dev/null
+++ b/miext/sync/misyncdma.c
@@ -0,0 +1,152 @@
+/*
+ * 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 int
+miSyncDmaFenceSetTriggered(SyncFence * pFence)
+{
+ return BadMatch;
+}
+
+static int
+miSyncDmaFenceReset(SyncFence * pFence)
+{
+ return BadMatch;
+}
+
+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
+};
+
+Bool
+miSyncIsDMAFence(SyncFence *pFence)
+{
+ return (pFence->funcs.Destroy == &miSyncDmaFenceDestroy);
+}
+
+int
+miSyncInitFenceFromDMAFenceFD(ScreenPtr pScreen, SyncFence *pFence, int fd)
+{
+ SyncDmaFencePrivatePtr pPriv = SYNC_FENCE_PRIV(pFence);
+
+ pFence->pScreen = pScreen;
+ pFence->funcs = miSyncDmaFenceFuncs;
+
+ 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..0f1f828bf 100644
--- a/miext/sync/misyncshm.c
+++ b/miext/sync/misyncshm.c
@@ -45,7 +45,7 @@ typedef struct _SyncShmFencePrivate {
#define SYNC_FENCE_PRIV(pFence) \
(SyncShmFencePrivatePtr) dixLookupPrivate(&pFence->devPrivates, &syncShmFencePrivateKey)
-static void
+static int
miSyncShmFenceSetTriggered(SyncFence * pFence)
{
SyncShmFencePrivatePtr pPriv = SYNC_FENCE_PRIV(pFence);
@@ -53,16 +53,23 @@ miSyncShmFenceSetTriggered(SyncFence * pFence)
if (pPriv->fence)
xshmfence_trigger(pPriv->fence);
miSyncFenceSetTriggered(pFence);
+
+ return Success;
}
-static void
+static int
miSyncShmFenceReset(SyncFence * pFence)
{
SyncShmFencePrivatePtr pPriv = SYNC_FENCE_PRIV(pFence);
+ if (!miSyncFenceCheckTriggered(pFence))
+ return BadMatch;
+
if (pPriv->fence)
xshmfence_reset(pPriv->fence);
miSyncFenceReset(pFence);
+
+ return Success;
}
static Bool
--
2.13.0
More information about the xorg-devel
mailing list