diff --git a/Makefile.am b/Makefile.am index 7be4271d4..7a8fc5ba7 100644 --- a/Makefile.am +++ b/Makefile.am @@ -17,6 +17,10 @@ if RECORD RECORD_DIR=record endif +if DRI3 +DRI3_DIR=dri3 +endif + SUBDIRS = \ doc \ man \ @@ -38,6 +42,7 @@ SUBDIRS = \ damageext \ $(COMPOSITE_DIR) \ $(GLX_DIR) \ + $(DRI3_DIR) \ exa \ config \ hw \ diff --git a/Xext/sync.c b/Xext/sync.c index b2ee92e37..126ce43a1 100644 --- a/Xext/sync.c +++ b/Xext/sync.c @@ -141,7 +141,7 @@ SyncCheckWarnIsCounter(const SyncObject * pSync, const char *warning) * interested in the counter. The two functions below are used to * delete and add triggers on this list. */ -static void +void SyncDeleteTriggerFromSyncObject(SyncTrigger * pTrigger) { SyncTriggerList *pCur; @@ -184,7 +184,7 @@ SyncDeleteTriggerFromSyncObject(SyncTrigger * pTrigger) } } -static int +int SyncAddTriggerToSyncObject(SyncTrigger * pTrigger) { SyncTriggerList *pCur; @@ -916,6 +916,34 @@ SyncCreate(ClientPtr client, XID id, unsigned char type) return pSync; } +int +SyncCreateFenceFromFD(ClientPtr client, DrawablePtr pDraw, XID id, int fd, BOOL initially_triggered) +{ + SyncFence *pFence; + int status; + + pFence = (SyncFence *) SyncCreate(client, id, SYNC_FENCE); + if (!pFence) + return BadAlloc; + + status = miSyncInitFenceFromFD(pDraw, pFence, fd, initially_triggered); + if (status != Success) { + miSyncDestroyFence(pFence); + return status; + } + + if (!AddResource(id, RTFence, (pointer) pFence)) + return BadAlloc; + + return Success; +} + +int +SyncFDFromFence(ClientPtr client, DrawablePtr pDraw, SyncFence *pFence) +{ + return miSyncFDFromFence(pDraw, pFence); +} + static SyncCounter * SyncCreateCounter(ClientPtr client, XSyncCounter id, CARD64 initialvalue) { diff --git a/Xext/syncsrv.h b/Xext/syncsrv.h index c68229f46..45fca04da 100644 --- a/Xext/syncsrv.h +++ b/Xext/syncsrv.h @@ -136,4 +136,17 @@ extern void SyncDestroySystemCounter(pointer pCounter); extern SyncCounter *SyncInitDeviceIdleTime(DeviceIntPtr dev); extern void SyncRemoveDeviceIdleTime(SyncCounter *counter); + +int +SyncCreateFenceFromFD(ClientPtr client, DrawablePtr pDraw, XID id, int fd, BOOL initially_triggered); + +int +SyncFDFromFence(ClientPtr client, DrawablePtr pDraw, SyncFence *fence); + +void +SyncDeleteTriggerFromSyncObject(SyncTrigger * pTrigger); + +int +SyncAddTriggerToSyncObject(SyncTrigger * pTrigger); + #endif /* _SYNCSRV_H_ */ diff --git a/configure.ac b/configure.ac index d29f1706a..546790d4c 100644 --- a/configure.ac +++ b/configure.ac @@ -613,6 +613,7 @@ AC_ARG_ENABLE(xdm-auth-1, AS_HELP_STRING([--disable-xdm-auth-1], [Build XDM- AC_ARG_ENABLE(glx, AS_HELP_STRING([--disable-glx], [Build GLX extension (default: enabled)]), [GLX=$enableval], [GLX=yes]) AC_ARG_ENABLE(dri, AS_HELP_STRING([--enable-dri], [Build DRI extension (default: auto)]), [DRI=$enableval]) AC_ARG_ENABLE(dri2, AS_HELP_STRING([--enable-dri2], [Build DRI2 extension (default: auto)]), [DRI2=$enableval], [DRI2=auto]) +AC_ARG_ENABLE(dri3, AS_HELP_STRING([--enable-dri3], [Build DRI3 extension (default: auto)]), [DRI3=$enableval], [DRI3=auto]) AC_ARG_ENABLE(xinerama, AS_HELP_STRING([--disable-xinerama], [Build Xinerama extension (default: enabled)]), [XINERAMA=$enableval], [XINERAMA=yes]) AC_ARG_ENABLE(xf86vidmode, AS_HELP_STRING([--disable-xf86vidmode], [Build XF86VidMode extension (default: auto)]), [XF86VIDMODE=$enableval], [XF86VIDMODE=auto]) AC_ARG_ENABLE(xace, AS_HELP_STRING([--disable-xace], [Build X-ACE extension (default: enabled)]), [XACE=$enableval], [XACE=yes]) @@ -715,6 +716,7 @@ case $host_os in CONFIG_UDEV_KMS=no DGA=no DRI2=no + DRI3=no INT10MODULE=no PCI=no VGAHW=no @@ -732,6 +734,7 @@ case $host_os in VBE=no DRM=no DRI2=no + DRI3=no if test x$XQUARTZ = xauto; then AC_CACHE_CHECK([whether to build Xquartz],xorg_cv_Carbon_framework,[ @@ -781,6 +784,7 @@ SCRNSAVERPROTO="scrnsaverproto >= 1.1" RESOURCEPROTO="resourceproto >= 1.2.0" DRIPROTO="xf86driproto >= 2.1.0" DRI2PROTO="dri2proto >= 2.8" +DRI3PROTO="dri3proto >= 1.0" XINERAMAPROTO="xineramaproto" BIGFONTPROTO="xf86bigfontproto >= 1.2.0" DGAPROTO="xf86dgaproto >= 2.0.99.1" @@ -1113,7 +1117,22 @@ case "$DRI2,$HAVE_DRI2PROTO" in esac AM_CONDITIONAL(DRI2, test "x$DRI2" = xyes) -if test "x$DRI" = xyes || test "x$DRI2" = xyes || test "x$CONFIG_UDEV_KMS" = xyes; then +PKG_CHECK_MODULES([DRI3PROTO], $DRI3PROTO, + [HAVE_DRI3PROTO=yes], [HAVE_DRI3PROTO=no]) +case "$DRI3,$HAVE_DRI3PROTO" in + yes,no) + AC_MSG_ERROR([DRI3 requested, but dri3proto not found.]) + ;; + yes,yes | auto,yes) + AC_DEFINE(DRI3, 1, [Build DRI3 extension]) + DRI3=yes + DRI3_LIB='$(top_builddir)/dri3/libdri3.la' + SDK_REQUIRED_MODULES="$SDK_REQUIRED_MODULES $DRI3PROTO" + ;; +esac +AM_CONDITIONAL(DRI3, test "x$DRI3" = xyes) + +if test "x$DRI" = xyes || test "x$DRI2" = xyes || test "x$DRI3" = xyes || test "x$CONFIG_UDEV_KMS" = xyes; then if test "x$DRM" = xyes; then AC_DEFINE(WITH_LIBDRM, 1, [Building with libdrm support]) PKG_CHECK_MODULES([LIBDRM], $LIBDRM) @@ -1306,6 +1325,7 @@ if test "x$XDMAUTH" = xyes; then XDMCP_MODULES="xdmcp" fi fi +REQUIRED_LIBS="$REQUIRED_LIBS xshmfence" AC_DEFINE_DIR(COMPILEDDEFAULTFONTPATH, FONTPATH, [Default font path]) AC_DEFINE_DIR(SERVER_MISC_CONFIG_PATH, SERVERCONFIG, [Server miscellaneous config path]) @@ -1577,7 +1597,7 @@ AC_MSG_RESULT([$XVFB]) AM_CONDITIONAL(XVFB, [test "x$XVFB" = xyes]) if test "x$XVFB" = xyes; then - XVFB_LIBS="$FB_LIB $FIXES_LIB $XEXT_LIB $DBE_LIB $RECORD_LIB $GLX_LIBS $RANDR_LIB $RENDER_LIB $DAMAGE_LIB $MIEXT_SYNC_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB" + XVFB_LIBS="$FB_LIB $FIXES_LIB $XEXT_LIB $DBE_LIB $RECORD_LIB $GLX_LIBS $RANDR_LIB $RENDER_LIB $DAMAGE_LIB $DRI3_LIB $MIEXT_SYNC_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB" XVFB_SYS_LIBS="$XVFBMODULES_LIBS $GLX_SYS_LIBS" AC_SUBST([XVFB_LIBS]) AC_SUBST([XVFB_SYS_LIBS]) @@ -1598,7 +1618,7 @@ if test "x$XNEST" = xyes; then if test "x$have_xnest" = xno; then AC_MSG_ERROR([Xnest build explicitly requested, but required modules not found.]) fi - XNEST_LIBS="$FB_LIB $FIXES_LIB $MI_LIB $XEXT_LIB $DBE_LIB $RECORD_LIB $GLX_LIBS $RANDR_LIB $RENDER_LIB $DAMAGE_LIB $MIEXT_SYNC_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB $MAIN_LIB $DIX_LIB $OS_LIB" + XNEST_LIBS="$FB_LIB $FIXES_LIB $MI_LIB $XEXT_LIB $DBE_LIB $RECORD_LIB $GLX_LIBS $RANDR_LIB $RENDER_LIB $DAMAGE_LIB $DRI3_LIB $MIEXT_SYNC_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB $MAIN_LIB $DIX_LIB $OS_LIB" XNEST_SYS_LIBS="$XNESTMODULES_LIBS $GLX_SYS_LIBS" AC_SUBST([XNEST_LIBS]) AC_SUBST([XNEST_SYS_LIBS]) @@ -1623,7 +1643,7 @@ if test "x$XORG" = xyes; then XORG_OSINCS='-I$(top_srcdir)/hw/xfree86/os-support -I$(top_srcdir)/hw/xfree86/os-support/bus -I$(top_srcdir)/os' XORG_INCS="$XORG_DDXINCS $XORG_OSINCS" XORG_CFLAGS="$XORGSERVER_CFLAGS -DHAVE_XORG_CONFIG_H" - XORG_LIBS="$COMPOSITE_LIB $FIXES_LIB $XEXT_LIB $DBE_LIB $RECORD_LIB $RANDR_LIB $RENDER_LIB $DAMAGE_LIB $MIEXT_SYNC_LIB $MIEXT_DAMAGE_LIB $XI_LIB $XKB_LIB" + XORG_LIBS="$COMPOSITE_LIB $FIXES_LIB $XEXT_LIB $DBE_LIB $RECORD_LIB $RANDR_LIB $RENDER_LIB $DAMAGE_LIB $DRI3_LIB $MIEXT_SYNC_LIB $MIEXT_DAMAGE_LIB $XI_LIB $XKB_LIB" dnl ================================================================== dnl symbol visibility @@ -2036,7 +2056,7 @@ if test "x$DMX" = xyes; then fi DMX_INCLUDES="$XEXT_INC $RENDER_INC $RECORD_INC" XDMX_CFLAGS="$DMXMODULES_CFLAGS" - XDMX_LIBS="$FB_LIB $MI_LIB $XEXT_LIB $RENDER_LIB $RECORD_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $MIEXT_SYNC_LIB $MIEXT_SHADOW_LIB $MIEXT_DAMAGE_LIB $COMPOSITE_LIB $DAMAGE_LIB $MAIN_LIB $DIX_LIB $CONFIG_LIB $OS_LIB $FIXES_LIB" + XDMX_LIBS="$FB_LIB $MI_LIB $XEXT_LIB $RENDER_LIB $RECORD_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $DRI3_LIB $MIEXT_SYNC_LIB $MIEXT_SHADOW_LIB $MIEXT_DAMAGE_LIB $COMPOSITE_LIB $DAMAGE_LIB $MAIN_LIB $DIX_LIB $CONFIG_LIB $OS_LIB $FIXES_LIB" XDMX_SYS_LIBS="$DMXMODULES_LIBS" AC_SUBST([XDMX_CFLAGS]) AC_SUBST([XDMX_LIBS]) @@ -2145,7 +2165,7 @@ if test "$KDRIVE" = yes; then KDRIVE_CFLAGS="$XSERVER_CFLAGS -DHAVE_KDRIVE_CONFIG_H $TSLIB_CFLAGS" - KDRIVE_PURE_LIBS="$FB_LIB $MI_LIB $FIXES_LIB $XEXT_LIB $DBE_LIB $RECORD_LIB $GLX_LIBS $RANDR_LIB $RENDER_LIB $DAMAGE_LIB $MIEXT_SYNC_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB $OS_LIB" + KDRIVE_PURE_LIBS="$FB_LIB $MI_LIB $FIXES_LIB $XEXT_LIB $DBE_LIB $RECORD_LIB $GLX_LIBS $RANDR_LIB $RENDER_LIB $DAMAGE_LIB $DRI3_LIB $MIEXT_SYNC_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB $OS_LIB" KDRIVE_LIB='$(top_builddir)/hw/kdrive/src/libkdrive.la' case $host_os in *linux*) @@ -2267,6 +2287,7 @@ Xext/Makefile Xi/Makefile xfixes/Makefile exa/Makefile +dri3/Makefile hw/Makefile hw/xfree86/Makefile hw/xfree86/common/Makefile diff --git a/dri3/Makefile.am b/dri3/Makefile.am new file mode 100644 index 000000000..e47a734e0 --- /dev/null +++ b/dri3/Makefile.am @@ -0,0 +1,13 @@ +noinst_LTLIBRARIES = libdri3.la +AM_CFLAGS = \ + -DHAVE_XORG_CONFIG_H \ + @DIX_CFLAGS@ @XORG_CFLAGS@ + +libdri3_la_SOURCES = \ + dri3.h \ + dri3_priv.h \ + dri3.c \ + dri3_request.c \ + dri3_screen.c + +sdk_HEADERS = dri3.h diff --git a/dri3/dri3.c b/dri3/dri3.c new file mode 100644 index 000000000..2bca7ae9b --- /dev/null +++ b/dri3/dri3.c @@ -0,0 +1,87 @@ +/* + * 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_XORG_CONFIG_H +#include +#endif + +#include "dri3_priv.h" + +int dri3_request; +DevPrivateKeyRec dri3_screen_private_key; +DevPrivateKeyRec dri3_window_private_key; + +static Bool +dri3_close_screen(ScreenPtr screen) +{ + dri3_screen_priv_ptr screen_priv = dri3_screen_priv(screen); + + unwrap(screen_priv, screen, CloseScreen); + + free(screen_priv); + return (*screen->CloseScreen) (screen); +} + +Bool +dri3_screen_init(ScreenPtr screen, dri3_screen_info_ptr info) +{ + if (!dixRegisterPrivateKey(&dri3_screen_private_key, PRIVATE_SCREEN, 0)) + return FALSE; + + if (!dri3_screen_priv(screen)) { + dri3_screen_priv_ptr screen_priv = calloc(1, sizeof (dri3_screen_priv_rec)); + if (!screen_priv) + return FALSE; + + wrap(screen_priv, screen, CloseScreen, dri3_close_screen); + + screen_priv->info = info; + + dixSetPrivate(&screen->devPrivates, &dri3_screen_private_key, screen_priv); + } + + return TRUE; +} + +void +dri3_extension_init(void) +{ + ExtensionEntry *extension; + int i; + + extension = AddExtension(DRI3_NAME, DRI3NumberEvents, DRI3NumberErrors, + proc_dri3_dispatch, sproc_dri3_dispatch, + NULL, StandardMinorOpcode); + if (!extension) + goto bail; + + dri3_request = extension->base; + + for (i = 0; i < screenInfo.numScreens; i++) { + if (!dri3_screen_init(screenInfo.screens[i], NULL)) + goto bail; + } + return; + +bail: + FatalError("Cannot initialize DRI3 extension"); +} diff --git a/dri3/dri3.h b/dri3/dri3.h new file mode 100644 index 000000000..7774c8757 --- /dev/null +++ b/dri3/dri3.h @@ -0,0 +1,59 @@ +/* + * 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. + */ + +#ifndef _DRI3_H_ +#define _DRI3_H_ + +#include +#include + +#define DRI3_SCREEN_INFO_VERSION 0 + +typedef int (*dri3_open_proc)(ScreenPtr screen, + RRProviderPtr provider, + int *fd); + +typedef PixmapPtr (*dri3_pixmap_from_fd_proc) (ScreenPtr screen, + int fd, + CARD16 width, + CARD16 height, + CARD16 stride, + CARD8 depth, + CARD8 bpp); + +typedef int (*dri3_fd_from_pixmap_proc) (ScreenPtr screen, + PixmapPtr pixmap, + CARD16 *stride, + CARD32 *size); + +typedef struct dri3_screen_info { + uint32_t version; + + dri3_open_proc open; + dri3_pixmap_from_fd_proc pixmap_from_fd; + dri3_fd_from_pixmap_proc fd_from_pixmap; +} dri3_screen_info_rec, *dri3_screen_info_ptr; + +extern _X_EXPORT Bool +dri3_screen_init(ScreenPtr screen, dri3_screen_info_ptr info); + +#endif /* _DRI3_H_ */ diff --git a/dri3/dri3_event.c b/dri3/dri3_event.c new file mode 100644 index 000000000..02f0f6579 --- /dev/null +++ b/dri3/dri3_event.c @@ -0,0 +1,163 @@ +/* + * 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_XORG_CONFIG_H +#include +#endif + +#include "dri3_priv.h" + +RESTYPE dri3_event_type; + +static int +dri3_free_event(pointer data, XID id) +{ + dri3_event_ptr dri3_event = (dri3_event_ptr) data; + dri3_window_priv_ptr window_priv = dri3_window_priv(dri3_event->window); + dri3_event_ptr *previous, current; + + for (previous = &window_priv->events; (current = *previous); previous = ¤t->next) { + if (current == dri3_event) { + *previous = dri3_event->next; + break; + } + } + free((pointer) dri3_event); + return 1; + +} + +void +dri3_free_events(WindowPtr window) +{ + dri3_window_priv_ptr window_priv = dri3_window_priv(window); + dri3_event_ptr event; + + if (!window_priv) + return; + + while ((event = window_priv->events)) + FreeResource(event->id, RT_NONE); +} + +static void +dri3_event_swap(xGenericEvent *from, xGenericEvent *to) +{ + *to = *from; + swaps(&to->sequenceNumber); + swapl(&to->length); + swaps(&to->evtype); + switch (from->evtype) { + case DRI3_ConfigureNotify: { + xDRI3ConfigureNotify *c = (xDRI3ConfigureNotify *) to; + + swapl(&c->eid); + swapl(&c->window); + swaps(&c->x); + swaps(&c->y); + swaps(&c->width); + swaps(&c->height); + swaps(&c->off_x); + swaps(&c->off_y); + swaps(&c->pixmap_width); + swaps(&c->pixmap_height); + swapl(&c->pixmap_flags); + break; + } + } +} + +void +dri3_send_config_notify(WindowPtr window, int x, int y, int w, int h, int bw, WindowPtr sibling) +{ + dri3_window_priv_ptr window_priv = dri3_window_priv(window); + + if (window_priv) { + xDRI3ConfigureNotify cn = { + .type = GenericEvent, + .extension = dri3_request, + .length = (sizeof(xDRI3ConfigureNotify) - 32) >> 2, + .evtype = DRI3_ConfigureNotify, + .eid = 0, + .window = window->drawable.id, + .x = x, + .y = y, + .width = w, + .height = h, + .off_x = 0, + .off_y = 0, + .pixmap_width = w, + .pixmap_height = h, + .pixmap_flags = 0 + }; + dri3_event_ptr event; + dri3_screen_priv_ptr screen_priv = dri3_screen_priv(window->drawable.pScreen); + + if (screen_priv->info && screen_priv->info->driver_config) + screen_priv->info->driver_config(window, &cn); + + for (event = window_priv->events; event; event = event->next) { + if (event->mask & (1 << DRI3ConfigureNotify)) { + cn.eid = event->id; + WriteEventsToClient(event->client, 1, (xEvent *) &cn); + } + } + } +} + +int +dri3_select_input(ClientPtr client, XID eid, WindowPtr window, CARD32 mask) +{ + dri3_window_priv_ptr window_priv = dri3_window_priv(window); + dri3_event_ptr event; + + if (!window_priv) + return BadAlloc; + + event = calloc (1, sizeof (dri3_event_rec)); + if (!event) + return BadAlloc; + + event->client = client; + event->window = window; + event->id = eid; + event->mask = mask; + + event->next = window_priv->events; + window_priv->events = event; + + if (!AddResource(event->id, dri3_event_type, (pointer) event)) + return BadAlloc; + + return Success; +} + +Bool +dri3_event_init(void) +{ + dri3_event_type = CreateNewResourceType(dri3_free_event, "DRI3Event"); + if (!dri3_event_type) + return FALSE; + + GERegisterExtension(dri3_request, dri3_event_swap); + return TRUE; +} diff --git a/dri3/dri3_priv.h b/dri3/dri3_priv.h new file mode 100644 index 000000000..e2fed839b --- /dev/null +++ b/dri3/dri3_priv.h @@ -0,0 +1,80 @@ +/* + * 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. + */ + +#ifndef _DRI3PRIV_H_ +#define _DRI3PRIV_H_ + +#include +#include "scrnintstr.h" +#include "misc.h" +#include "list.h" +#include "windowstr.h" +#include "dixstruct.h" +#include +#include "dri3.h" + +extern int dri3_request; + +extern DevPrivateKeyRec dri3_screen_private_key; + +typedef struct dri3_screen_priv { + CloseScreenProcPtr CloseScreen; + ConfigNotifyProcPtr ConfigNotify; + DestroyWindowProcPtr DestroyWindow; + + dri3_screen_info_ptr info; +} dri3_screen_priv_rec, *dri3_screen_priv_ptr; + +#define wrap(priv,real,mem,func) {\ + priv->mem = real->mem; \ + real->mem = func; \ +} + +#define unwrap(priv,real,mem) {\ + real->mem = priv->mem; \ +} + +static inline dri3_screen_priv_ptr +dri3_screen_priv(ScreenPtr screen) +{ + return (dri3_screen_priv_ptr)dixLookupPrivate(&(screen)->devPrivates, &dri3_screen_private_key); +} + +int +proc_dri3_dispatch(ClientPtr client); + +int +sproc_dri3_dispatch(ClientPtr client); + +/* DDX interface */ + +int +dri3_open(ClientPtr client, ScreenPtr screen, RRProviderPtr provider, int *fd); + +int +dri3_pixmap_from_fd(PixmapPtr *ppixmap, ScreenPtr screen, int fd, + CARD16 width, CARD16 height, CARD16 stride, CARD8 depth, CARD8 bpp); + +int +dri3_fd_from_pixmap(int *pfd, PixmapPtr pixmap, CARD16 *stride, CARD32 *size); + +#endif /* _DRI3PRIV_H_ */ diff --git a/dri3/dri3_request.c b/dri3/dri3_request.c new file mode 100644 index 000000000..3ebb9d509 --- /dev/null +++ b/dri3/dri3_request.c @@ -0,0 +1,394 @@ +/* + * 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_XORG_CONFIG_H +#include +#endif + +#include "dri3_priv.h" +#include +#include +#include +#include "../Xext/syncsdk.h" + +static int +proc_dri3_query_version(ClientPtr client) +{ + REQUEST(xDRI3QueryVersionReq); + xDRI3QueryVersionReply rep = { + .type = X_Reply, + .sequenceNumber = client->sequence, + .length = 0, + .majorVersion = DRI3_MAJOR, + .minorVersion = DRI3_MINOR + }; + + REQUEST_SIZE_MATCH(xDRI3QueryVersionReq); + (void) stuff; + if (client->swapped) { + swaps(&rep.sequenceNumber); + swapl(&rep.length); + swapl(&rep.majorVersion); + swapl(&rep.minorVersion); + } + WriteToClient(client, sizeof(rep), &rep); + return Success; +} + +static int +proc_dri3_open(ClientPtr client) +{ + REQUEST(xDRI3OpenReq); + xDRI3OpenReply rep = { + .type = X_Reply, + .nfd = 1, + .sequenceNumber = client->sequence, + .length = 0, + }; + RRProviderPtr provider; + DrawablePtr drawable; + ScreenPtr screen; + int fd; + int status; + + REQUEST_SIZE_MATCH(xDRI3OpenReq); + + status = dixLookupDrawable(&drawable, stuff->drawable, client, 0, DixReadAccess); + if (status != Success) + return status; + + if (stuff->provider == None) + provider = NULL; + else if (!RRProviderType) { + return BadMatch; + } else { + VERIFY_RR_PROVIDER(stuff->provider, provider, DixReadAccess); + if (drawable->pScreen != provider->pScreen) + return BadMatch; + } + screen = drawable->pScreen; + + status = dri3_open(client, screen, provider, &fd); + if (status != Success) + return status; + + if (client->swapped) { + swaps(&rep.sequenceNumber); + swapl(&rep.length); + } + + if (WriteFdToClient(client, fd, TRUE) < 0) { + close(fd); + return BadAlloc; + } + + WriteToClient(client, sizeof (rep), &rep); + + return Success; +} + +static int +proc_dri3_pixmap_from_buffer(ClientPtr client) +{ + REQUEST(xDRI3PixmapFromBufferReq); + int fd; + DrawablePtr drawable; + PixmapPtr pixmap; + int rc; + + SetReqFds(client, 1); + REQUEST_SIZE_MATCH(xDRI3PixmapFromBufferReq); + LEGAL_NEW_RESOURCE(stuff->pixmap, client); + rc = dixLookupDrawable(&drawable, stuff->drawable, client, M_ANY, DixGetAttrAccess); + if (rc != Success) { + client->errorValue = stuff->drawable; + return rc; + } + + if (!stuff->width || !stuff->height) { + client->errorValue = 0; + return BadValue; + } + + if (stuff->width > 32767 || stuff->height > 32767) + return BadAlloc; + + if (stuff->depth != 1) { + DepthPtr depth = drawable->pScreen->allowedDepths; + int i; + for (i = 0; i < drawable->pScreen->numDepths; i++, depth++) + if (depth->depth == stuff->depth) + break; + if (i == drawable->pScreen->numDepths) { + client->errorValue = stuff->depth; + return BadValue; + } + } + + fd = ReadFdFromClient(client); + if (fd < 0) + return BadValue; + + rc = dri3_pixmap_from_fd(&pixmap, + drawable->pScreen, fd, + stuff->width, stuff->height, + stuff->stride, stuff->depth, + stuff->bpp); + close (fd); + if (rc != Success) + return rc; + + pixmap->drawable.id = stuff->pixmap; + + /* security creation/labeling check */ + rc = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pixmap, RT_PIXMAP, + pixmap, RT_NONE, NULL, DixCreateAccess); + + if (rc != Success) { + (*drawable->pScreen->DestroyPixmap) (pixmap); + return rc; + } + if (AddResource(stuff->pixmap, RT_PIXMAP, (pointer) pixmap)) + return Success; + + return Success; +} + +static int +proc_dri3_buffer_from_pixmap(ClientPtr client) +{ + REQUEST(xDRI3BufferFromPixmapReq); + xDRI3BufferFromPixmapReply rep = { + .type = X_Reply, + .nfd = 1, + .sequenceNumber = client->sequence, + .length = 0, + }; + int rc; + int fd; + PixmapPtr pixmap; + + REQUEST_SIZE_MATCH(xDRI3BufferFromPixmapReq); + rc = dixLookupResourceByType((pointer *) &pixmap, stuff->pixmap, RT_PIXMAP, + client, DixWriteAccess); + if (rc != Success) { + client->errorValue = stuff->pixmap; + return rc; + } + + rep.width = pixmap->drawable.width; + rep.height = pixmap->drawable.height; + rep.depth = pixmap->drawable.depth; + rep.bpp = pixmap->drawable.bitsPerPixel; + + rc = dri3_fd_from_pixmap(&fd, pixmap, &rep.stride, &rep.size); + if (rc != Success) + return rc; + + if (client->swapped) { + swaps(&rep.sequenceNumber); + swapl(&rep.length); + swapl(&rep.size); + swaps(&rep.width); + swaps(&rep.height); + swaps(&rep.stride); + } + if (WriteFdToClient(client, fd, TRUE) < 0) { + close(fd); + return BadAlloc; + } + + WriteToClient(client, sizeof(rep), &rep); + + return client->noClientException; +} + +static int +proc_dri3_fence_from_fd(ClientPtr client) +{ + REQUEST(xDRI3FenceFromFDReq); + DrawablePtr drawable; + int fd; + int status; + + SetReqFds(client, 1); + REQUEST_SIZE_MATCH(xDRI3FenceFromFDReq); + LEGAL_NEW_RESOURCE(stuff->fence, client); + + status = dixLookupDrawable(&drawable, stuff->drawable, client, M_ANY, DixGetAttrAccess); + if (status != Success) + return status; + + fd = ReadFdFromClient(client); + if (fd < 0) + return BadValue; + + status = SyncCreateFenceFromFD(client, drawable, stuff->fence, + fd, stuff->initially_triggered); + + return status; +} + +static int +proc_dri3_fd_from_fence(ClientPtr client) +{ + REQUEST(xDRI3FDFromFenceReq); + xDRI3FDFromFenceReply rep = { + .type = X_Reply, + .nfd = 1, + .sequenceNumber = client->sequence, + .length = 0, + }; + DrawablePtr drawable; + int fd; + int status; + SyncFence *fence; + + REQUEST_SIZE_MATCH(xDRI3FDFromFenceReq); + + status = dixLookupDrawable(&drawable, stuff->drawable, client, M_ANY, DixGetAttrAccess); + if (status != Success) + return status; + status = SyncVerifyFence(&fence, stuff->fence, client, DixWriteAccess); + if (status != Success) + return status; + + fd = SyncFDFromFence(client, drawable, fence); + if (fd < 0) + return BadMatch; + + if (client->swapped) { + swaps(&rep.sequenceNumber); + swapl(&rep.length); + } + if (WriteFdToClient(client, fd, FALSE) < 0) + return BadAlloc; + + WriteToClient(client, sizeof(rep), &rep); + + return client->noClientException; +} + +int (*proc_dri3_vector[DRI3NumberRequests]) (ClientPtr) = { + proc_dri3_query_version, /* 0 */ + proc_dri3_open, /* 1 */ + proc_dri3_pixmap_from_buffer, /* 2 */ + proc_dri3_buffer_from_pixmap, /* 3 */ + proc_dri3_fence_from_fd, /* 4 */ + proc_dri3_fd_from_fence, /* 5 */ +}; + +int +proc_dri3_dispatch(ClientPtr client) +{ + REQUEST(xReq); + if (stuff->data >= DRI3NumberRequests || !proc_dri3_vector[stuff->data]) + return BadRequest; + return (*proc_dri3_vector[stuff->data]) (client); +} + +static int +sproc_dri3_query_version(ClientPtr client) +{ + REQUEST(xDRI3QueryVersionReq); + + swaps(&stuff->length); + swapl(&stuff->majorVersion); + swapl(&stuff->minorVersion); + return (*proc_dri3_vector[stuff->dri3ReqType]) (client); +} + +static int +sproc_dri3_open(ClientPtr client) +{ + REQUEST(xDRI3OpenReq); + + swaps(&stuff->length); + swapl(&stuff->drawable); + swapl(&stuff->provider); + return (*proc_dri3_vector[stuff->dri3ReqType]) (client); +} + +static int +sproc_dri3_pixmap_from_buffer(ClientPtr client) +{ + REQUEST(xDRI3PixmapFromBufferReq); + + swaps(&stuff->length); + swapl(&stuff->pixmap); + swapl(&stuff->drawable); + swapl(&stuff->size); + swaps(&stuff->width); + swaps(&stuff->height); + swaps(&stuff->stride); + return (*proc_dri3_vector[stuff->dri3ReqType]) (client); +} + +static int +sproc_dri3_buffer_from_pixmap(ClientPtr client) +{ + REQUEST(xDRI3BufferFromPixmapReq); + + swaps(&stuff->length); + swapl(&stuff->pixmap); + return (*proc_dri3_vector[stuff->dri3ReqType]) (client); +} + +static int +sproc_dri3_fence_from_fd(ClientPtr client) +{ + REQUEST(xDRI3FenceFromFDReq); + + swaps(&stuff->length); + swapl(&stuff->drawable); + swapl(&stuff->fence); + return (*proc_dri3_vector[stuff->dri3ReqType]) (client); +} + +static int +sproc_dri3_fd_from_fence(ClientPtr client) +{ + REQUEST(xDRI3FDFromFenceReq); + + swaps(&stuff->length); + swapl(&stuff->drawable); + swapl(&stuff->fence); + return (*proc_dri3_vector[stuff->dri3ReqType]) (client); +} + +int (*sproc_dri3_vector[DRI3NumberRequests]) (ClientPtr) = { + sproc_dri3_query_version, /* 0 */ + sproc_dri3_open, /* 1 */ + sproc_dri3_pixmap_from_buffer, /* 2 */ + sproc_dri3_buffer_from_pixmap, /* 3 */ + sproc_dri3_fence_from_fd, /* 4 */ + sproc_dri3_fd_from_fence, /* 5 */ +}; + +int +sproc_dri3_dispatch(ClientPtr client) +{ + REQUEST(xReq); + if (stuff->data >= DRI3NumberRequests || !sproc_dri3_vector[stuff->data]) + return BadRequest; + return (*sproc_dri3_vector[stuff->data]) (client); +} diff --git a/dri3/dri3_screen.c b/dri3/dri3_screen.c new file mode 100644 index 000000000..cf2735b8d --- /dev/null +++ b/dri3/dri3_screen.c @@ -0,0 +1,80 @@ +/* + * 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_XORG_CONFIG_H +#include +#endif + +#include "dri3_priv.h" +#include +#include +#include +#include + +int +dri3_open(ClientPtr client, ScreenPtr screen, RRProviderPtr provider, int *fd) +{ + dri3_screen_priv_ptr ds = dri3_screen_priv(screen); + dri3_screen_info_ptr info = ds->info; + int rc; + + if (!info || !info->open) + return BadMatch; + + rc = (*info->open) (screen, provider, fd); + if (rc != Success) + return rc; + + return Success; +} + +int +dri3_pixmap_from_fd(PixmapPtr *ppixmap, ScreenPtr screen, int fd, + CARD16 width, CARD16 height, CARD16 stride, CARD8 depth, CARD8 bpp) +{ + dri3_screen_priv_ptr ds = dri3_screen_priv(screen); + dri3_screen_info_ptr info = ds->info; + PixmapPtr pixmap; + + pixmap = (*info->pixmap_from_fd) (screen, fd, width, height, stride, depth, bpp); + if (!pixmap) + return BadAlloc; + + *ppixmap = pixmap; + return Success; +} + +int +dri3_fd_from_pixmap(int *pfd, PixmapPtr pixmap, CARD16 *stride, CARD32 *size) +{ + ScreenPtr screen = pixmap->drawable.pScreen; + dri3_screen_priv_ptr ds = dri3_screen_priv(screen); + dri3_screen_info_ptr info = ds->info; + int fd; + + fd = (*info->fd_from_pixmap)(screen, pixmap, stride, size); + if (fd < 0) + return BadAlloc; + *pfd = fd; + return Success; +} + diff --git a/dri3/dri3int.h b/dri3/dri3int.h new file mode 100644 index 000000000..7f53eba45 --- /dev/null +++ b/dri3/dri3int.h @@ -0,0 +1,26 @@ +/* + * Copyright © 2011 Daniel Stone + * + * 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 (including the next + * paragraph) 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 AUTHORS OR COPYRIGHT HOLDERS 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. + * + * Author: Daniel Stone + */ + +extern Bool DRI2ModuleSetup(void); diff --git a/hw/dmx/dmxinit.c b/hw/dmx/dmxinit.c index 65416ed26..bd868a092 100644 --- a/hw/dmx/dmxinit.c +++ b/hw/dmx/dmxinit.c @@ -109,6 +109,8 @@ Bool dmxGLXSyncSwap = FALSE; Bool dmxGLXFinishSwap = FALSE; #endif +RESTYPE RRProviderType = 0; + Bool dmxIgnoreBadFontPaths = FALSE; Bool dmxAddRemoveScreens = FALSE; diff --git a/hw/xfree86/Makefile.am b/hw/xfree86/Makefile.am index 59cfb5f6f..eea16a851 100644 --- a/hw/xfree86/Makefile.am +++ b/hw/xfree86/Makefile.am @@ -41,7 +41,7 @@ nodist_Xorg_SOURCES = sdksyms.c AM_CFLAGS = $(DIX_CFLAGS) @XORG_CFLAGS@ AM_CPPFLAGS = $(XORG_INCS) -I$(srcdir)/parser -I$(top_srcdir)/miext/cw \ -I$(srcdir)/ddc -I$(srcdir)/i2c -I$(srcdir)/modes -I$(srcdir)/ramdac \ - -I$(srcdir)/dri -I$(srcdir)/dri2 + -I$(srcdir)/dri -I$(srcdir)/dri2 -I$(top_srcdir)/dri3 LOCAL_LIBS = \ $(MAIN_LIB) \ @@ -59,6 +59,8 @@ LOCAL_LIBS = \ dixmods/libxorgxkb.la \ $(DRI_LIB) \ $(DRI2_LIB) \ + $(top_builddir)/dri3/libdri3.la \ + $(top_builddir)/miext/sync/libsync.la \ $(top_builddir)/mi/libmi.la \ $(top_builddir)/os/libos.la Xorg_LDADD = \ diff --git a/hw/xfree86/sdksyms.sh b/hw/xfree86/sdksyms.sh index 48b48b5db..7c9734c07 100755 --- a/hw/xfree86/sdksyms.sh +++ b/hw/xfree86/sdksyms.sh @@ -99,6 +99,7 @@ cat > sdksyms.c << EOF # include "dri2.h" #endif +# include "dri3.h" /* hw/xfree86/vgahw/Makefile.am -- module */ /* diff --git a/include/dix-config.h.in b/include/dix-config.h.in index a643dfcc8..d96da6a27 100644 --- a/include/dix-config.h.in +++ b/include/dix-config.h.in @@ -39,6 +39,9 @@ /* Build DPMS extension */ #undef DPMSExtension +/* Build DRI3 extension */ +#undef DRI3 + /* Build GLX extension */ #undef GLXEXT diff --git a/include/extinit.h b/include/extinit.h index 6d67bf2e5..bdb149ca6 100644 --- a/include/extinit.h +++ b/include/extinit.h @@ -176,4 +176,9 @@ extern void XvExtensionInit(void); extern void XvMCExtensionInit(void); #endif +#if defined(DRI3) +#include +extern void dri3_extension_init(void); +#endif + #endif diff --git a/include/xorg-server.h.in b/include/xorg-server.h.in index 81935be5c..5b3b664a4 100644 --- a/include/xorg-server.h.in +++ b/include/xorg-server.h.in @@ -28,6 +28,9 @@ /* Build DPMS extension */ #undef DPMSExtension +/* Build DRI3 extension */ +#undef DRI3 + /* Build GLX extension */ #undef GLXEXT diff --git a/mi/miinitext.c b/mi/miinitext.c index 145da38e9..e49948bb5 100644 --- a/mi/miinitext.c +++ b/mi/miinitext.c @@ -287,6 +287,7 @@ static ExtensionModule staticExtensions[] = { #ifdef DPMSExtension {DPMSExtensionInit, DPMSExtensionName, &noDPMSExtension}, #endif + {dri3_extension_init, DRI3_NAME, NULL}, #ifdef RES {ResExtensionInit, XRES_NAME, &noResExtension}, #endif diff --git a/miext/sync/Makefile.am b/miext/sync/Makefile.am index 9aa1ba5d5..e25ceacb0 100644 --- a/miext/sync/Makefile.am +++ b/miext/sync/Makefile.am @@ -5,10 +5,11 @@ AM_CFLAGS = $(DIX_CFLAGS) AM_CPPFLAGS = if XORG -sdk_HEADERS = misync.h misyncstr.h +sdk_HEADERS = misync.h misyncstr.h misyncshm.h endif libsync_la_SOURCES = \ misync.c \ misync.h \ + misyncshm.c \ misyncstr.h diff --git a/miext/sync/misync.c b/miext/sync/misync.c index f38054754..3d03d1b59 100644 --- a/miext/sync/misync.c +++ b/miext/sync/misync.c @@ -29,20 +29,7 @@ #include "misync.h" #include "misyncstr.h" -static DevPrivateKeyRec syncScreenPrivateKeyRec; -static DevPrivateKey syncScreenPrivateKey = &syncScreenPrivateKeyRec; - -#define SYNC_SCREEN_PRIV(pScreen) \ - (SyncScreenPrivPtr) dixLookupPrivate(&pScreen->devPrivates, \ - syncScreenPrivateKey) - -typedef struct _syncScreenPriv { - /* Wrappable sync-specific screen functions */ - SyncScreenFuncsRec funcs; - - /* Wrapped screen functions */ - CloseScreenProcPtr CloseScreen; -} SyncScreenPrivRec, *SyncScreenPrivPtr; +DevPrivateKeyRec miSyncScreenPrivateKey; /* Default implementations of the sync screen functions */ void @@ -62,25 +49,25 @@ miSyncScreenDestroyFence(ScreenPtr pScreen, SyncFence * pFence) } /* Default implementations of the per-object functions */ -static void +void miSyncFenceSetTriggered(SyncFence * pFence) { pFence->triggered = TRUE; } -static void +void miSyncFenceReset(SyncFence * pFence) { pFence->triggered = FALSE; } -static Bool +Bool miSyncFenceCheckTriggered(SyncFence * pFence) { return pFence->triggered; } -static void +void miSyncFenceAddTrigger(SyncTrigger * pTrigger) { (void) pTrigger; @@ -88,7 +75,7 @@ miSyncFenceAddTrigger(SyncTrigger * pTrigger) return; } -static void +void miSyncFenceDeleteTrigger(SyncTrigger * pTrigger) { (void) pTrigger; @@ -182,8 +169,8 @@ miSyncSetup(ScreenPtr pScreen) &miSyncScreenDestroyFence }; - if (!dixPrivateKeyRegistered(syncScreenPrivateKey)) { - if (!dixRegisterPrivateKey(syncScreenPrivateKey, PRIVATE_SCREEN, + if (!dixPrivateKeyRegistered(&miSyncScreenPrivateKey)) { + if (!dixRegisterPrivateKey(&miSyncScreenPrivateKey, PRIVATE_SCREEN, sizeof(SyncScreenPrivRec))) return FALSE; } diff --git a/miext/sync/misync.h b/miext/sync/misync.h index deebb82bc..f63ec2b82 100644 --- a/miext/sync/misync.h +++ b/miext/sync/misync.h @@ -76,4 +76,25 @@ extern _X_EXPORT SyncScreenFuncsPtr miSyncGetScreenFuncs(ScreenPtr pScreen); extern _X_EXPORT Bool miSyncSetup(ScreenPtr pScreen); +Bool +miSyncFenceCheckTriggered(SyncFence * pFence); + +void +miSyncFenceSetTriggered(SyncFence * pFence); + +void +miSyncFenceReset(SyncFence * pFence); + +void +miSyncFenceAddTrigger(SyncTrigger * pTrigger); + +void +miSyncFenceDeleteTrigger(SyncTrigger * pTrigger); + +int +miSyncInitFenceFromFD(DrawablePtr pDraw, SyncFence *pFence, int fd, BOOL initially_triggered); + +int +miSyncFDFromFence(DrawablePtr pDraw, SyncFence *pFence); + #endif /* _MISYNC_H_ */ diff --git a/miext/sync/misyncshm.c b/miext/sync/misyncshm.c new file mode 100644 index 000000000..ddd15ae49 --- /dev/null +++ b/miext/sync/misyncshm.c @@ -0,0 +1,176 @@ +/* + * 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_DIX_CONFIG_H +#include +#endif + +#include "scrnintstr.h" +#include "misync.h" +#include "misyncstr.h" +#include "misyncshm.h" +#include "pixmapstr.h" +#include +#include +#include + +static DevPrivateKeyRec syncShmFencePrivateKey; + +typedef struct _SyncShmFencePrivate { + int32_t *fence; + int fd; +} SyncShmFencePrivateRec, *SyncShmFencePrivatePtr; + +#define SYNC_FENCE_PRIV(pFence) \ + (SyncShmFencePrivatePtr) dixLookupPrivate(&pFence->devPrivates, &syncShmFencePrivateKey) + +static void +miSyncShmFenceSetTriggered(SyncFence * pFence) +{ + SyncShmFencePrivatePtr pPriv = SYNC_FENCE_PRIV(pFence); + + if (pPriv->fence) + xshmfence_trigger(pPriv->fence); + miSyncFenceSetTriggered(pFence); +} + +static void +miSyncShmFenceReset(SyncFence * pFence) +{ + SyncShmFencePrivatePtr pPriv = SYNC_FENCE_PRIV(pFence); + + if (pPriv->fence) + xshmfence_reset(pPriv->fence); + miSyncFenceReset(pFence); +} + +static Bool +miSyncShmFenceCheckTriggered(SyncFence * pFence) +{ + SyncShmFencePrivatePtr pPriv = SYNC_FENCE_PRIV(pFence); + + if (pPriv->fence) + return xshmfence_query(pPriv->fence); + else + return miSyncFenceCheckTriggered(pFence); +} + +static void +miSyncShmFenceAddTrigger(SyncTrigger * pTrigger) +{ + miSyncFenceAddTrigger(pTrigger); +} + +static void +miSyncShmFenceDeleteTrigger(SyncTrigger * pTrigger) +{ + miSyncFenceDeleteTrigger(pTrigger); +} + +static const SyncFenceFuncsRec miSyncShmFenceFuncs = { + &miSyncShmFenceSetTriggered, + &miSyncShmFenceReset, + &miSyncShmFenceCheckTriggered, + &miSyncShmFenceAddTrigger, + &miSyncShmFenceDeleteTrigger +}; + +static void +miSyncShmScreenCreateFence(ScreenPtr pScreen, SyncFence * pFence, + Bool initially_triggered) +{ + SyncShmFencePrivatePtr pPriv = SYNC_FENCE_PRIV(pFence); + + pPriv->fence = NULL; + miSyncScreenCreateFence(pScreen, pFence, initially_triggered); + pFence->funcs = miSyncShmFenceFuncs; +} + +static void +miSyncShmScreenDestroyFence(ScreenPtr pScreen, SyncFence * pFence) +{ + SyncShmFencePrivatePtr pPriv = SYNC_FENCE_PRIV(pFence); + + if (pPriv->fence) { + xshmfence_trigger(pPriv->fence); + xshmfence_unmap_shm(pPriv->fence); + close(pPriv->fd); + } + miSyncScreenDestroyFence(pScreen, pFence); +} + +int +miSyncInitFenceFromFD(DrawablePtr pDraw, SyncFence *pFence, int fd, BOOL initially_triggered) + +{ + SyncShmFencePrivatePtr pPriv = SYNC_FENCE_PRIV(pFence); + + miSyncInitFence(pDraw->pScreen, pFence, initially_triggered); + + pPriv->fence = xshmfence_map_shm(fd); + if (pPriv->fence) { + pPriv->fd = fd; + return Success; + } + else + close(fd); + return BadValue; +} + +int +miSyncFDFromFence(DrawablePtr pDraw, SyncFence *pFence) +{ + SyncShmFencePrivatePtr pPriv = SYNC_FENCE_PRIV(pFence); + + if (!pPriv->fence) { + pPriv->fd = xshmfence_alloc_shm(); + if (pPriv->fd < 0) + return -1; + pPriv->fence = xshmfence_map_shm(pPriv->fd); + if (!pPriv->fence) { + close (pPriv->fd); + return -1; + } + } + return pPriv->fd; +} + +_X_EXPORT Bool miSyncShmScreenInit(ScreenPtr pScreen) +{ + SyncScreenFuncsPtr funcs; + + if (!miSyncSetup(pScreen)) + return FALSE; + + if (!dixPrivateKeyRegistered(&syncShmFencePrivateKey)) { + if (!dixRegisterPrivateKey(&syncShmFencePrivateKey, PRIVATE_SYNC_FENCE, + sizeof(SyncShmFencePrivateRec))) + return FALSE; + } + + funcs = miSyncGetScreenFuncs(pScreen); + + funcs->CreateFence = miSyncShmScreenCreateFence; + funcs->DestroyFence = miSyncShmScreenDestroyFence; + return TRUE; +} + diff --git a/miext/sync/misyncshm.h b/miext/sync/misyncshm.h new file mode 100644 index 000000000..4edbb50c3 --- /dev/null +++ b/miext/sync/misyncshm.h @@ -0,0 +1,28 @@ +/* + * 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. + */ + +#ifndef _MISYNCSHM_H_ +#define _MISYNCSYM_H_ + +extern _X_EXPORT Bool miSyncShmScreenInit(ScreenPtr pScreen); + +#endif /* _MISYNCSHM_H_ */ diff --git a/miext/sync/misyncstr.h b/miext/sync/misyncstr.h index e19256fee..b5bf6fd91 100644 --- a/miext/sync/misyncstr.h +++ b/miext/sync/misyncstr.h @@ -29,6 +29,7 @@ #define _MISYNCSTR_H_ #include "dix.h" +#include "scrnintstr.h" #include #define CARD64 XSyncValue /* XXX temporary! need real 64 bit values for Alpha */ @@ -79,4 +80,18 @@ typedef struct _SyncTriggerList { struct _SyncTriggerList *next; } SyncTriggerList; +extern DevPrivateKeyRec miSyncScreenPrivateKey; + +#define SYNC_SCREEN_PRIV(pScreen) \ + (SyncScreenPrivPtr) dixLookupPrivate(&pScreen->devPrivates, \ + &miSyncScreenPrivateKey) + +typedef struct _syncScreenPriv { + /* Wrappable sync-specific screen functions */ + SyncScreenFuncsRec funcs; + + /* Wrapped screen functions */ + CloseScreenProcPtr CloseScreen; +} SyncScreenPrivRec, *SyncScreenPrivPtr; + #endif /* _MISYNCSTR_H_ */ diff --git a/test/Makefile.am b/test/Makefile.am index eff0c9d81..e59c412ee 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -19,7 +19,7 @@ AM_CPPFLAGS += -I$(top_srcdir)/hw/xfree86/parser \ -I$(top_srcdir)/hw/xfree86/ddc \ -I$(top_srcdir)/hw/xfree86/i2c -I$(top_srcdir)/hw/xfree86/modes \ -I$(top_srcdir)/hw/xfree86/ramdac -I$(top_srcdir)/hw/xfree86/dri \ - -I$(top_srcdir)/hw/xfree86/dri2 + -I$(top_srcdir)/hw/xfree86/dri2 -I$(top_srcdir)/dri3 endif TEST_LDADD=libxservertest.la $(XORG_SYS_LIBS) $(XSERVER_SYS_LIBS) $(GLX_SYS_LIBS) @@ -64,6 +64,10 @@ if DRI2 libxservertest_la_LIBADD += $(top_builddir)/hw/xfree86/dri2/libdri2.la endif +if DRI3 +libxservertest_la_LIBADD += $(top_builddir)/dri3/libdri3.la +endif + else nodist_libxservertest_la_SOURCES = \ ddxstubs.c \ @@ -105,6 +109,11 @@ libxservertest_la_LIBADD += \ $(top_builddir)/record/librecord.la endif +if DRI3 +libxservertest_la_LIBADD += \ + $(top_builddir)/dri3/libdri3.la +endif + if XQUARTZ libxservertest_la_LIBADD += \ $(top_builddir)/miext/rootless/librootless.la