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 <l...@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 _______________________________________________ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: https://lists.x.org/mailman/listinfo/xorg-devel