summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2013-11-18 11:32:59 +1000
committerBen Skeggs <bskeggs@redhat.com>2013-11-22 14:54:19 +1000
commit257c1c0eb9fbc06a123d47f9b05716f259ff1ed0 (patch)
tree161d3d9f09c6c9cd6a27b9a5fa10a97d64791370
parent1addf315792bbfcd7f02d0b26ffe68809248e7d9 (diff)
downloadxorg-driver-xf86-video-nouveau-257c1c0eb9fbc06a123d47f9b05716f259ff1ed0.tar.gz
sync: initial support for misyncshm
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
-rw-r--r--configure.ac3
-rw-r--r--src/Makefile.am7
-rw-r--r--src/nouveau_sync.c114
-rw-r--r--src/nouveau_sync.h26
-rw-r--r--src/nv_driver.c8
-rw-r--r--src/nv_proto.h9
-rw-r--r--src/nv_type.h3
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;