diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2013-11-18 11:32:59 +1000 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2013-11-22 14:54:19 +1000 |
commit | 257c1c0eb9fbc06a123d47f9b05716f259ff1ed0 (patch) | |
tree | 161d3d9f09c6c9cd6a27b9a5fa10a97d64791370 | |
parent | 1addf315792bbfcd7f02d0b26ffe68809248e7d9 (diff) | |
download | xorg-driver-xf86-video-nouveau-257c1c0eb9fbc06a123d47f9b05716f259ff1ed0.tar.gz |
sync: initial support for misyncshm
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
-rw-r--r-- | configure.ac | 3 | ||||
-rw-r--r-- | src/Makefile.am | 7 | ||||
-rw-r--r-- | src/nouveau_sync.c | 114 | ||||
-rw-r--r-- | src/nouveau_sync.h | 26 | ||||
-rw-r--r-- | src/nv_driver.c | 8 | ||||
-rw-r--r-- | src/nv_proto.h | 9 | ||||
-rw-r--r-- | src/nv_type.h | 3 |
7 files changed, 167 insertions, 3 deletions
diff --git a/configure.ac b/configure.ac index c524660..635d9bf 100644 --- a/configure.ac +++ b/configure.ac @@ -79,6 +79,9 @@ XORG_DRIVER_CHECK_EXT(XV, videoproto) XORG_DRIVER_CHECK_EXT(DPMSExtension, xextproto) XORG_DRIVER_CHECK_EXT(DRI2, [dri2proto >= 2.6]) +XORG_DRIVER_CHECK_EXT(DRI3, dri3proto) +AM_CONDITIONAL(DRI3, [ test "$_EXT_CHECK" != "no" ] ) + # Checks for pkg-config packages PKG_CHECK_MODULES(LIBDRM, [libdrm >= 2.4.17]) PKG_CHECK_MODULES(LIBDRM_NOUVEAU, [libdrm_nouveau >= 2.4.25]) diff --git a/src/Makefile.am b/src/Makefile.am index 82d7c14..2806852 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -29,7 +29,11 @@ nouveau_drv_la_LDFLAGS = -module -avoid-version @LIBDRM_NOUVEAU_LIBS@ \ @LIBUDEV_LIBS@ @LIBDRM_LIBS@ nouveau_drv_ladir = @moduledir@/drivers -nouveau_drv_la_SOURCES = \ +if DRI3 +NOUVEAU_DRI3_SOURCES = nouveau_sync.c +endif + +nouveau_drv_la_SOURCES = $(NOUVEAU_DRI3_SOURCES) \ nouveau_exa.c nouveau_xv.c nouveau_dri2.c \ nouveau_wfb.c \ nv_accel_common.c \ @@ -116,6 +120,7 @@ EXTRA_DIST = hwdefs/nv_3ddefs.xml.h \ shader/xfrm2nvf0.vpc \ shader/Makefile \ nouveau_local.h \ + nouveau_sync.h \ nv_const.h \ nv_dma.h \ nv_include.h \ diff --git a/src/nouveau_sync.c b/src/nouveau_sync.c new file mode 100644 index 0000000..e394932 --- /dev/null +++ b/src/nouveau_sync.c @@ -0,0 +1,114 @@ +/* + * Copyright 2013 Red Hat Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: Ben Skeggs <bskeggs@redhat.com> + */ + +#include "nouveau_sync.h" + +static DevPrivateKeyRec nouveau_syncobj_key; + +struct nouveau_syncobj { + SyncFenceSetTriggeredFunc SetTriggered; +}; + +#define nouveau_syncobj(fence) \ + dixLookupPrivate(&(fence)->devPrivates, &nouveau_syncobj_key) + +struct nouveau_syncctx { + SyncScreenCreateFenceFunc CreateFence; +}; + +#define nouveau_syncctx(screen) ({ \ + ScrnInfoPtr scrn = xf86ScreenToScrn(screen); \ + NVPtr pNv = NVPTR(scrn); \ + pNv->sync; \ +}) + +static void +nouveau_syncobj_flush(SyncFence *fence) +{ + struct nouveau_syncobj *pobj = nouveau_syncobj(fence); + ScrnInfoPtr scrn = xf86ScreenToScrn(fence->pScreen); + NVPtr pNv = NVPTR(scrn); + SyncFenceFuncsPtr func = &fence->funcs; + + nouveau_pushbuf_kick(pNv->pushbuf, pNv->channel); + if (pNv->ce_pushbuf) + nouveau_pushbuf_kick(pNv->ce_pushbuf, pNv->ce_channel); + + swap(pobj, func, SetTriggered); + func->SetTriggered(fence); + swap(pobj, func, SetTriggered); +} + +static void +nouveau_syncobj_new(ScreenPtr screen, SyncFence *fence, Bool triggered) +{ + struct nouveau_syncctx *priv = nouveau_syncctx(screen); + struct nouveau_syncobj *pobj = nouveau_syncobj(fence); + SyncScreenFuncsPtr sync = miSyncGetScreenFuncs(screen); + SyncFenceFuncsPtr func = &fence->funcs; + + swap(priv, sync, CreateFence); + sync->CreateFence(screen, fence, triggered); + swap(priv, sync, CreateFence); + + wrap(pobj, func, SetTriggered, nouveau_syncobj_flush); +} + +void +nouveau_sync_fini(ScreenPtr screen) +{ + struct nouveau_syncctx *priv = nouveau_syncctx(screen); + SyncScreenFuncsPtr sync = miSyncGetScreenFuncs(screen); + ScrnInfoPtr scrn = xf86ScreenToScrn(screen); + NVPtr pNv = NVPTR(scrn); + + unwrap(priv, sync, CreateFence); + + pNv->sync = NULL; + free(priv); +} + +Bool +nouveau_sync_init(ScreenPtr screen) +{ + ScrnInfoPtr scrn = xf86ScreenToScrn(screen); + NVPtr pNv = NVPTR(scrn); + struct nouveau_syncctx *priv; + SyncScreenFuncsPtr sync; + + priv = pNv->sync = calloc(1, sizeof(*priv)); + if (!priv) + return FALSE; + + if (!dixPrivateKeyRegistered(&nouveau_syncobj_key) && + !dixRegisterPrivateKey(&nouveau_syncobj_key, PRIVATE_SYNC_FENCE, + sizeof(struct nouveau_syncobj))) + return FALSE; + + if (!miSyncShmScreenInit(screen)) + return FALSE; + sync = miSyncGetScreenFuncs(screen); + wrap(priv, sync, CreateFence, nouveau_syncobj_new); + return TRUE; +} diff --git a/src/nouveau_sync.h b/src/nouveau_sync.h new file mode 100644 index 0000000..98332b8 --- /dev/null +++ b/src/nouveau_sync.h @@ -0,0 +1,26 @@ +#ifndef __NOUVEAU_SYNC_H__ +#define __NOUVEAU_SYNC_H__ + +#include "nv_include.h" + +#include "misync.h" +#include "misyncshm.h" +#include "misyncstr.h" + +#define wrap(priv, parn, name, func) { \ + priv->name = parn->name; \ + parn->name = func; \ +} + +#define unwrap(priv, parn, name) { \ + if (priv && priv->name) \ + parn->name = priv->name; \ +} + +#define swap(priv, parn, name) { \ + void *tmp = priv->name; \ + priv->name = parn->name; \ + parn->name = tmp; \ +} + +#endif diff --git a/src/nv_driver.c b/src/nv_driver.c index 078be99..8d02917 100644 --- a/src/nv_driver.c +++ b/src/nv_driver.c @@ -566,8 +566,10 @@ NVCloseScreen(CLOSE_SCREEN_ARGS_DECL) if (XF86_CRTC_CONFIG_PTR(pScrn)->num_crtc) drmmode_screen_fini(pScreen); - if (!pNv->NoAccel) + if (!pNv->NoAccel) { + nouveau_sync_fini(pScreen); nouveau_dri2_fini(pScreen); + } if (pScrn->vtSema) { NVLeaveVT(VT_FUNC_ARGS(0)); @@ -1272,8 +1274,10 @@ NVScreenInit(SCREEN_INIT_ARGS_DECL) } } - if (!pNv->NoAccel) + if (!pNv->NoAccel) { + nouveau_sync_init(pScreen); nouveau_dri2_init(pScreen); + } /* Allocate and map memory areas we need */ if (!NVMapMem(pScrn)) diff --git a/src/nv_proto.h b/src/nv_proto.h index 937cedd..8175e98 100644 --- a/src/nv_proto.h +++ b/src/nv_proto.h @@ -30,6 +30,15 @@ Bool nouveau_allocate_surface(ScrnInfoPtr scrn, int width, int height, int bpp, int usage_hint, int *pitch, struct nouveau_bo **bo); +/* in nouveau_sync.c */ +#ifdef DRI3 +Bool nouveau_sync_init(ScreenPtr pScreen); +void nouveau_sync_fini(ScreenPtr pScreen); +#else +static inline Bool nouveau_sync_init(ScreenPtr pScreen) { return FALSE; } +static inline void nouveau_sync_fini(ScreenPtr pScreen) { } +#endif + /* in nouveau_dri2.c */ Bool nouveau_dri2_init(ScreenPtr pScreen); void nouveau_dri2_fini(ScreenPtr pScreen); diff --git a/src/nv_type.h b/src/nv_type.h index e6945bc..5284f8e 100644 --- a/src/nv_type.h +++ b/src/nv_type.h @@ -108,6 +108,9 @@ typedef struct _NVRec { struct nouveau_pushbuf *ce_pushbuf; struct nouveau_object *NvCopy; + /* SYNC extension private */ + void *sync; + /* Acceleration context */ PixmapPtr pspix, pmpix, pdpix; PicturePtr pspict, pmpict; |