[Intel-gfx] [PATCH 3/4] Add DRI3 and miSyncShm support
Keith Packard
keithp at keithp.com
Wed Nov 20 21:53:36 CET 2013
Signed-off-by: Keith Packard <keithp at keithp.com>
---
configure.ac | 14 ++++
src/uxa/Makefile.am | 7 ++
src/uxa/intel.h | 17 +++++
src/uxa/intel_dri3.c | 184 +++++++++++++++++++++++++++++++++++++++++++++++++
src/uxa/intel_driver.c | 13 ++++
src/uxa/intel_sync.c | 109 +++++++++++++++++++++++++++++
src/uxa/intel_uxa.c | 1 +
7 files changed, 345 insertions(+)
create mode 100644 src/uxa/intel_dri3.c
create mode 100644 src/uxa/intel_sync.c
diff --git a/configure.ac b/configure.ac
index 0783d61..13b9970 100644
--- a/configure.ac
+++ b/configure.ac
@@ -276,6 +276,7 @@ XORG_DRIVER_CHECK_EXT(RANDR, randrproto)
XORG_DRIVER_CHECK_EXT(RENDER, renderproto)
XORG_DRIVER_CHECK_EXT(XF86DRI, xextproto x11)
XORG_DRIVER_CHECK_EXT(DPMSExtension, xextproto)
+XORG_DRIVER_CHECK_EXT(DRI3, dri3proto)
# Obtain compiler/linker options for the driver dependencies
PKG_CHECK_MODULES(DRM, [libdrm >= 2.4.20]) # libdrm_intel is checked separately
@@ -463,6 +464,19 @@ else
UXA=no
fi
+if test "x$DRI3" != "xno"; then
+ save_CFLAGS=$CFLAGS
+ CFLAGS="$XORG_CFLAGS $DRM_CFLAGS $DRI_CFLAGS $DRI3_CFLAGS"
+ AC_CHECK_DECL(DRI3,
+ [DRI3=yes], [DRI3=no],
+ [#include <xorg-server.h>])
+ CFLAGS=$save_CFLAGS
+ dri_msg="$dri_msg DRI3"
+fi
+AC_MSG_CHECKING([whether to include DRI3 support])
+AM_CONDITIONAL(DRI3, test "x$DRI3" = xyes)
+AC_MSG_RESULT([$DRI3])
+
AC_CHECK_HEADERS([X11/extensions/dpmsconst.h])
AC_MSG_CHECKING([whether to include UXA support])
diff --git a/src/uxa/Makefile.am b/src/uxa/Makefile.am
index 971ac21..3c9e693 100644
--- a/src/uxa/Makefile.am
+++ b/src/uxa/Makefile.am
@@ -80,6 +80,13 @@ libuxa_la_LIBADD += \
$(NULL)
endif
+if DRI3
+libuxa_la_SOURCES += \
+ intel_dri3.c \
+ intel_sync.c \
+ $(NULL)
+endif
+
if XVMC
AM_CFLAGS += -I$(top_srcdir)/xvmc
libuxa_la_SOURCES += \
diff --git a/src/uxa/intel.h b/src/uxa/intel.h
index 922b208..c3d00f4 100644
--- a/src/uxa/intel.h
+++ b/src/uxa/intel.h
@@ -59,6 +59,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "xf86xv.h"
#include "xf86Crtc.h"
#include "xf86RandR12.h"
+#include "misync.h"
#include "xorg-server.h"
#include <pciaccess.h>
@@ -352,6 +353,11 @@ typedef struct intel_screen_private {
InputHandlerProc uevent_handler;
#endif
Bool has_prime_vmap_flush;
+
+ SyncScreenFuncsRec save_sync_screen_funcs;
+
+ void (*flush_rendering)(struct intel_screen_private *intel);
+
} intel_screen_private;
#define INTEL_INFO(intel) ((intel)->info)
@@ -519,6 +525,9 @@ void I830DRI2FrameEventHandler(unsigned int frame, unsigned int tv_sec,
void I830DRI2FlipEventHandler(unsigned int frame, unsigned int tv_sec,
unsigned int tv_usec, DRI2FrameEventPtr flip_info);
+/* intel_dri3.c */
+Bool intel_dri3_screen_init(ScreenPtr screen);
+
extern Bool intel_crtc_on(xf86CrtcPtr crtc);
int intel_crtc_to_pipe(xf86CrtcPtr crtc);
@@ -725,4 +734,12 @@ static inline Bool intel_pixmap_is_offscreen(PixmapPtr pixmap)
return priv && priv->offscreen;
}
+#if DRI3
+Bool
+intel_sync_init(ScreenPtr screen);
+#endif
+
+void
+intel_sync_close(ScreenPtr screen);
+
#endif /* _I830_H_ */
diff --git a/src/uxa/intel_dri3.c b/src/uxa/intel_dri3.c
new file mode 100644
index 0000000..99ac9d5
--- /dev/null
+++ b/src/uxa/intel_dri3.c
@@ -0,0 +1,184 @@
+/*
+ * Copyright © 2013 Keith Packard
+ *
+ * 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_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/time.h>
+#include <time.h>
+#include <errno.h>
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+
+#include "xf86Pci.h"
+#include "xf86drm.h"
+
+#include "windowstr.h"
+#include "shadow.h"
+#include "fb.h"
+
+#include "intel.h"
+#include "i830_reg.h"
+
+#include "i915_drm.h"
+
+#include "dri3.h"
+
+#include "intel_glamor.h"
+#include "uxa.h"
+
+static int
+intel_dri3_open(ScreenPtr screen,
+ RRProviderPtr provider,
+ int *fdp)
+{
+ ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+ intel_screen_private *intel = intel_get_screen_private(scrn);
+ drm_magic_t magic;
+ int fd;
+
+ /* Open the device for the client */
+ fd = open(intel->deviceName, O_RDWR | O_CLOEXEC);
+ if (fd == -1 && errno == EINVAL) {
+ fd = open(intel->deviceName, O_RDWR);
+ if (fd != -1)
+ fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC);
+ }
+
+ if (fd < 0)
+ return BadAlloc;
+
+ /* Go through the auth dance locally */
+ if (drmGetMagic(fd, &magic) < 0) {
+ close(fd);
+ return BadMatch;
+ }
+
+ if (drmAuthMagic(intel->drmSubFD, magic) < 0) {
+ close (fd);
+ return BadMatch;
+ }
+
+ /* And we're done */
+ *fdp = fd;
+ return Success;
+}
+
+static PixmapPtr intel_dri3_pixmap_from_fd (ScreenPtr screen,
+ int fd,
+ CARD16 width,
+ CARD16 height,
+ CARD16 stride,
+ CARD8 depth,
+ CARD8 bpp)
+{
+ ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+ intel_screen_private *intel = intel_get_screen_private(scrn);
+ struct intel_pixmap *priv;
+ PixmapPtr pixmap;
+ uint32_t bit_6_swizzle, tiling;
+ int ret;
+
+ if (depth == 1)
+ return NULL;
+
+ pixmap = fbCreatePixmap(screen, 0, 0, depth, 0);
+ if (!pixmap)
+ goto no_pixmap;
+ priv = calloc(1, sizeof (struct intel_pixmap));
+ if (priv == NULL)
+ goto no_priv;
+
+ priv->bo = drm_intel_bo_gem_create_from_prime(intel->bufmgr,
+ fd, (uint32_t) height * stride);
+ if (priv->bo == NULL)
+ goto no_bo;
+
+ ret = drm_intel_bo_get_tiling(priv->bo, &tiling, &bit_6_swizzle);
+ if (ret != 0)
+ goto no_tiling;
+
+ priv->stride = stride;
+ priv->tiling = tiling;
+ priv->offscreen = 1;
+ list_init(&priv->batch);
+ intel_set_pixmap_private(pixmap, priv);
+
+ screen->ModifyPixmapHeader(pixmap, width, height, 0, 0, stride, NULL);
+
+ return pixmap;
+no_tiling:
+ drm_intel_bo_unreference(priv->bo);
+no_bo:
+ free (priv);
+no_priv:
+ fbDestroyPixmap(pixmap);
+no_pixmap:
+ return NULL;
+}
+
+static int intel_dri3_fd_from_pixmap (ScreenPtr screen,
+ PixmapPtr pixmap,
+ CARD16 *stride,
+ CARD32 *size)
+{
+ struct intel_pixmap *priv;
+ ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+ intel_screen_private *intel = intel_get_screen_private(scrn);
+ int fd;
+ int ret;
+
+ priv = intel_get_pixmap_private(pixmap);
+ if (!priv)
+ return -1;
+ (*intel->flush_rendering)(intel);
+ ret = drm_intel_bo_gem_export_to_prime(priv->bo, &fd);
+ if (ret < 0)
+ return -1;
+ *stride = priv->stride;
+ *size = priv->bo->size;
+ return fd;
+}
+
+static dri3_screen_info_rec intel_dri3_screen_info = {
+ .version = DRI3_SCREEN_INFO_VERSION,
+
+ .open = intel_dri3_open,
+ .pixmap_from_fd = intel_dri3_pixmap_from_fd,
+ .fd_from_pixmap = intel_dri3_fd_from_pixmap
+};
+
+Bool
+intel_dri3_screen_init(ScreenPtr screen)
+{
+ return dri3_screen_init(screen, &intel_dri3_screen_info);
+}
diff --git a/src/uxa/intel_driver.c b/src/uxa/intel_driver.c
index 431c34b..12c7b34 100644
--- a/src/uxa/intel_driver.c
+++ b/src/uxa/intel_driver.c
@@ -1050,6 +1050,10 @@ I830ScreenInit(SCREEN_INIT_ARGS_DECL)
if (intel->XvEnabled)
I830InitVideo(screen);
+#if DRI3
+ intel_dri3_screen_init(screen);
+#endif
+
#if defined(DRI2)
switch (intel->directRenderingType) {
case DRI_DRI2:
@@ -1076,6 +1080,11 @@ I830ScreenInit(SCREEN_INIT_ARGS_DECL)
intel_mode_init(intel);
+
+#if DRI3
+ (void) intel_sync_init(screen);
+#endif
+
intel->suspended = FALSE;
#if HAVE_UDEV
@@ -1163,6 +1172,10 @@ static Bool I830CloseScreen(CLOSE_SCREEN_ARGS_DECL)
I830UeventFini(scrn);
#endif
+#if DRI3
+ intel_sync_close(screen);
+#endif
+
intel_mode_close(intel);
DeleteCallback(&FlushCallback, intel_flush_callback, scrn);
diff --git a/src/uxa/intel_sync.c b/src/uxa/intel_sync.c
new file mode 100644
index 0000000..94426d3
--- /dev/null
+++ b/src/uxa/intel_sync.c
@@ -0,0 +1,109 @@
+/*
+ * Copyright © 2013 Keith Packard
+ *
+ * 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.
+ */
+
+#include "intel.h"
+#include "misyncshm.h"
+#include "misyncstr.h"
+
+/*
+ * This whole file exists to wrap a sync fence trigger operation
+ * so that we can flush the batch buffer to provide serialization
+ * between the server and the shm fence client
+ */
+
+static DevPrivateKeyRec intel_sync_fence_private_key;
+
+typedef struct _intel_sync_fence_private {
+ SyncFenceSetTriggeredFunc set_triggered;
+} intel_sync_fence_private;
+
+#define SYNC_FENCE_PRIV(pFence) \
+ (intel_sync_fence_private *) dixLookupPrivate(&pFence->devPrivates, &intel_sync_fence_private_key)
+
+static void
+intel_sync_fence_set_triggered (SyncFence *fence)
+{
+ ScreenPtr screen = fence->pScreen;
+ ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+ intel_screen_private *intel = intel_get_screen_private(scrn);
+ intel_sync_fence_private *private = SYNC_FENCE_PRIV(fence);
+
+
+ /* Flush pending rendering operations */
+ if (intel->flush_rendering)
+ intel->flush_rendering(intel);
+
+ fence->funcs.SetTriggered = private->set_triggered;
+ (*fence->funcs.SetTriggered)(fence);
+ private->set_triggered = fence->funcs.SetTriggered;
+ fence->funcs.SetTriggered = intel_sync_fence_set_triggered;
+}
+
+static void
+intel_sync_create_fence(ScreenPtr screen,
+ SyncFence *fence,
+ Bool initially_triggered)
+{
+ ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+ intel_screen_private *intel = intel_get_screen_private(scrn);
+ SyncScreenFuncsPtr screen_funcs = miSyncGetScreenFuncs(screen);
+ intel_sync_fence_private *private = SYNC_FENCE_PRIV(fence);
+
+ screen_funcs->CreateFence = intel->save_sync_screen_funcs.CreateFence;
+ (*screen_funcs->CreateFence)(screen, fence, initially_triggered);
+
+ private->set_triggered = fence->funcs.SetTriggered;
+ fence->funcs.SetTriggered = intel_sync_fence_set_triggered;
+}
+
+Bool
+intel_sync_init(ScreenPtr screen)
+{
+ ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+ intel_screen_private *intel = intel_get_screen_private(scrn);
+ SyncScreenFuncsPtr screen_funcs;
+ if (!miSyncShmScreenInit(screen))
+ return FALSE;
+
+ if (!dixPrivateKeyRegistered(&intel_sync_fence_private_key)) {
+ if (!dixRegisterPrivateKey(&intel_sync_fence_private_key,
+ PRIVATE_SYNC_FENCE,
+ sizeof (intel_sync_fence_private)))
+ return FALSE;
+ }
+
+ screen_funcs = miSyncGetScreenFuncs(screen);
+ intel->save_sync_screen_funcs.CreateFence = screen_funcs->CreateFence;
+ screen_funcs->CreateFence = intel_sync_create_fence;
+ return TRUE;
+}
+
+void
+intel_sync_close(ScreenPtr screen)
+{
+ ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+ intel_screen_private *intel = intel_get_screen_private(scrn);
+ SyncScreenFuncsPtr screen_funcs = miSyncGetScreenFuncs(screen);
+
+ if (screen_funcs)
+ screen_funcs->CreateFence = intel->save_sync_screen_funcs.CreateFence;
+}
diff --git a/src/uxa/intel_uxa.c b/src/uxa/intel_uxa.c
index 6fb1333..a31d196 100644
--- a/src/uxa/intel_uxa.c
+++ b/src/uxa/intel_uxa.c
@@ -1420,5 +1420,6 @@ Bool intel_uxa_init(ScreenPtr screen)
uxa_set_fallback_debug(screen, intel->fallback_debug);
uxa_set_force_fallback(screen, intel->force_fallback);
+ intel->flush_rendering = intel_flush_rendering;
return TRUE;
}
--
1.8.4.2
More information about the Intel-gfx
mailing list