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