xserver: Branch 'master' - 2 commits

Kristian Høgsberg krh at kemper.freedesktop.org
Thu Feb 14 16:59:14 PST 2008


 GL/glx/Makefile.am             |    2 
 GL/glx/glxdri2.c               |  573 +++++++++++++++++++++++++++++++++++++++++
 GL/glx/glxscreens.c            |   26 +
 configure.ac                   |   14 +
 hw/xfree86/Makefile.am         |    8 
 hw/xfree86/dixmods/glxmodule.c |    3 
 hw/xfree86/dri2/Makefile.am    |   15 +
 hw/xfree86/dri2/dri2.c         |  448 ++++++++++++++++++++++++++++++++
 hw/xfree86/dri2/dri2.h         |   77 +++++
 include/dix-config.h.in        |    3 
 include/xorg-config.h.in       |    3 
 include/xorg-server.h.in       |    3 
 12 files changed, 1173 insertions(+), 2 deletions(-)

New commits:
commit 879515b1399f87a47010532af70f34b9b09e2a9b
Author: Kristian Høgsberg <krh at sasori.boston.redhat.com>
Date:   Mon Feb 4 13:13:35 2008 -0500

    Add GLX provider for DRI2.

diff --git a/GL/glx/Makefile.am b/GL/glx/Makefile.am
index 4cf56e8..e37e499 100644
--- a/GL/glx/Makefile.am
+++ b/GL/glx/Makefile.am
@@ -25,6 +25,7 @@ INCLUDES = \
 	-I$(top_srcdir)/hw/xfree86/os-support/bus \
 	-I$(top_srcdir)/hw/xfree86/common \
 	-I$(top_srcdir)/hw/xfree86/dri \
+	-I$(top_srcdir)/hw/xfree86/dri2 \
 	-I$(top_srcdir)/mi
 
 
@@ -36,6 +37,7 @@ nodist_libglx_la_SOURCES = indirect_size.h \
 
 libglxdri_la_SOURCES = \
         glxdri.c \
+        glxdri2.c \
         extension_string.c \
         extension_string.h
 
diff --git a/GL/glx/glxdri2.c b/GL/glx/glxdri2.c
new file mode 100644
index 0000000..d8df604
--- /dev/null
+++ b/GL/glx/glxdri2.c
@@ -0,0 +1,573 @@
+/*
+ * Copyright © 2007 Red Hat, Inc
+ *
+ * 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 Red Hat,
+ * Inc not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission.  Red Hat, Inc makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
+ * NO EVENT SHALL RED HAT, INC 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 <stdint.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/time.h>
+#include <dlfcn.h>
+
+#include <drm.h>
+#include <GL/gl.h>
+#include <GL/internal/dri_interface.h>
+
+#include <windowstr.h>
+#include <os.h>
+
+#define _XF86DRI_SERVER_
+#include <xf86drm.h>
+#include <xf86dristr.h>
+#include <xf86str.h>
+#include <xf86.h>
+#include <dri2.h>
+
+#include "glxserver.h"
+#include "glxutil.h"
+#include "glcontextmodes.h"
+
+#include "g_disptab.h"
+#include "glapitable.h"
+#include "glapi.h"
+#include "glthread.h"
+#include "dispatch.h"
+#include "extension_string.h"
+
+#define containerOf(ptr, type, member)			\
+    (type *)( (char *)ptr - offsetof(type,member) )
+
+typedef struct __GLXDRIscreen   __GLXDRIscreen;
+typedef struct __GLXDRIcontext  __GLXDRIcontext;
+typedef struct __GLXDRIdrawable __GLXDRIdrawable;
+
+struct __GLXDRIscreen {
+    __GLXscreen		 base;
+    __DRIscreen		 driScreen;
+    void		*driver;
+    int			 fd;
+
+    xf86EnterVTProc	*enterVT;
+    xf86LeaveVTProc	*leaveVT;
+
+    __DRIcopySubBufferExtension *copySubBuffer;
+    __DRIswapControlExtension *swapControl;
+
+    unsigned char glx_enable_bits[__GLX_EXT_BYTES];
+};
+
+struct __GLXDRIcontext {
+    __GLXcontext base;
+    __DRIcontext driContext;
+    drm_context_t hwContext;
+};
+
+struct __GLXDRIdrawable {
+    __GLXdrawable base;
+    __DRIdrawable driDrawable;
+};
+
+static const char CREATE_NEW_SCREEN_FUNC[] = __DRI2_CREATE_NEW_SCREEN_STRING;
+
+static void
+__glXDRIdrawableDestroy(__GLXdrawable *drawable)
+{
+    __GLXDRIdrawable *private = (__GLXDRIdrawable *) drawable;
+
+    (*private->driDrawable.destroyDrawable)(&private->driDrawable);
+
+    /* If the X window was destroyed, the dri DestroyWindow hook will
+     * aready have taken care of this, so only call if pDraw isn't NULL. */
+    if (drawable->pDraw != NULL)
+	DRI2DestroyDrawable(drawable->pDraw->pScreen, drawable->pDraw);
+
+    xfree(private);
+}
+
+static GLboolean
+__glXDRIdrawableResize(__GLXdrawable *glxPriv)
+{
+    /* Nothing to do here, the DRI driver asks the server for drawable
+     * geometry when it sess the SAREA timestamps change.*/
+
+    return GL_TRUE;
+}
+
+static GLboolean
+__glXDRIdrawableSwapBuffers(__GLXdrawable *basePrivate)
+{
+    __GLXDRIdrawable *private = (__GLXDRIdrawable *) basePrivate;
+
+    (*private->driDrawable.swapBuffers)(&private->driDrawable);
+
+    return TRUE;
+}
+
+
+static int
+__glXDRIdrawableSwapInterval(__GLXdrawable *baseDrawable, int interval)
+{
+    __GLXDRIdrawable *draw = (__GLXDRIdrawable *) baseDrawable;
+    __GLXDRIscreen *screen = (__GLXDRIscreen *)
+	glxGetScreen(baseDrawable->pDraw->pScreen);
+
+    if (screen->swapControl)
+	screen->swapControl->setSwapInterval(&draw->driDrawable, interval);
+
+    return 0;
+}
+
+
+static void
+__glXDRIdrawableCopySubBuffer(__GLXdrawable *basePrivate,
+			       int x, int y, int w, int h)
+{
+    __GLXDRIdrawable *private = (__GLXDRIdrawable *) basePrivate;
+    __GLXDRIscreen *screen = (__GLXDRIscreen *)
+	glxGetScreen(basePrivate->pDraw->pScreen);
+
+    if (screen->copySubBuffer)
+	screen->copySubBuffer->copySubBuffer(&private->driDrawable,
+					     x, y, w, h);
+}
+
+static void
+__glXDRIcontextDestroy(__GLXcontext *baseContext)
+{
+    __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext;
+    __GLXDRIscreen *screen = (__GLXDRIscreen *) baseContext->pGlxScreen;
+
+    context->driContext.destroyContext(&context->driContext);
+    drmDestroyContext(screen->fd, context->hwContext);
+    __glXContextDestroy(&context->base);
+    xfree(context);
+}
+
+static int
+__glXDRIcontextMakeCurrent(__GLXcontext *baseContext)
+{
+    __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext;
+    __GLXDRIdrawable *draw = (__GLXDRIdrawable *) baseContext->drawPriv;
+    __GLXDRIdrawable *read = (__GLXDRIdrawable *) baseContext->readPriv;
+
+    return (*context->driContext.bindContext)(&context->driContext,
+					      &draw->driDrawable,
+					      &read->driDrawable);
+}					      
+
+static int
+__glXDRIcontextLoseCurrent(__GLXcontext *baseContext)
+{
+    __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext;
+
+    return (*context->driContext.unbindContext)(&context->driContext);
+}
+
+static int
+__glXDRIcontextCopy(__GLXcontext *baseDst, __GLXcontext *baseSrc,
+		    unsigned long mask)
+{
+    __GLXDRIcontext *dst = (__GLXDRIcontext *) baseDst;
+    __GLXDRIcontext *src = (__GLXDRIcontext *) baseSrc;
+
+    /* FIXME: We will need to add DRIcontext::copyContext for this. */
+
+    (void) dst;
+    (void) src;
+
+    return FALSE;
+}
+
+static int
+__glXDRIcontextForceCurrent(__GLXcontext *baseContext)
+{
+    __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext;
+    __GLXDRIdrawable *draw = (__GLXDRIdrawable *) baseContext->drawPriv;
+    __GLXDRIdrawable *read = (__GLXDRIdrawable *) baseContext->readPriv;
+
+    return (*context->driContext.bindContext)(&context->driContext,
+					      &draw->driDrawable,
+					      &read->driDrawable);
+}
+
+static int
+__glXDRIbindTexImage(__GLXcontext *baseContext,
+		     int buffer,
+		     __GLXdrawable *glxPixmap)
+{
+    return Success;
+}
+
+static int
+__glXDRIreleaseTexImage(__GLXcontext *baseContext,
+			int buffer,
+			__GLXdrawable *pixmap)
+{
+    return Success;
+}
+
+static __GLXtextureFromPixmap __glXDRItextureFromPixmap = {
+    __glXDRIbindTexImage,
+    __glXDRIreleaseTexImage
+};
+
+static void
+__glXDRIscreenDestroy(__GLXscreen *baseScreen)
+{
+    __GLXDRIscreen *screen = (__GLXDRIscreen *) baseScreen;
+
+    screen->driScreen.destroyScreen(&screen->driScreen);
+
+    dlclose(screen->driver);
+
+    __glXScreenDestroy(baseScreen);
+
+    xfree(screen);
+}
+
+static __GLXcontext *
+__glXDRIscreenCreateContext(__GLXscreen *baseScreen,
+			    __GLcontextModes *modes,
+			    __GLXcontext *baseShareContext)
+{
+    __GLXDRIscreen *screen = (__GLXDRIscreen *) baseScreen;
+    __GLXDRIcontext *context, *shareContext;
+    __DRIcontext *driShare;
+
+    shareContext = (__GLXDRIcontext *) baseShareContext;
+    if (shareContext)
+	driShare = &shareContext->driContext;
+    else
+	driShare = NULL;
+
+    context = xalloc(sizeof *context);
+    if (context == NULL)
+	return NULL;
+
+    memset(context, 0, sizeof *context);
+    context->base.destroy           = __glXDRIcontextDestroy;
+    context->base.makeCurrent       = __glXDRIcontextMakeCurrent;
+    context->base.loseCurrent       = __glXDRIcontextLoseCurrent;
+    context->base.copy              = __glXDRIcontextCopy;
+    context->base.forceCurrent      = __glXDRIcontextForceCurrent;
+    context->base.textureFromPixmap = &__glXDRItextureFromPixmap;
+
+    if (drmCreateContext(screen->fd, &context->hwContext))
+	    return GL_FALSE;
+
+    context->driContext.private =
+	screen->driScreen.createNewContext(&screen->driScreen,
+					   modes,
+					   0, /* render type */
+					   driShare,
+					   context->hwContext,
+					   &context->driContext);
+
+    return &context->base;
+}
+
+static __GLXdrawable *
+__glXDRIscreenCreateDrawable(__GLXscreen *screen,
+			     DrawablePtr pDraw,
+			     int type,
+			     XID drawId,
+			     __GLcontextModes *modes)
+{
+    __GLXDRIscreen *driScreen = (__GLXDRIscreen *) screen;
+    __GLXDRIdrawable *private;
+    GLboolean retval;
+    drm_drawable_t hwDrawable;
+
+    private = xalloc(sizeof *private);
+    if (private == NULL)
+	return NULL;
+
+    memset(private, 0, sizeof *private);
+
+    if (!__glXDrawableInit(&private->base, screen,
+			   pDraw, type, drawId, modes)) {
+        xfree(private);
+	return NULL;
+    }
+
+    private->base.destroy       = __glXDRIdrawableDestroy;
+    private->base.resize        = __glXDRIdrawableResize;
+    private->base.swapBuffers   = __glXDRIdrawableSwapBuffers;
+    private->base.copySubBuffer = __glXDRIdrawableCopySubBuffer;
+
+    retval = DRI2CreateDrawable(screen->pScreen, pDraw, &hwDrawable);
+
+    private->driDrawable.private =
+	(driScreen->driScreen.createNewDrawable)(&driScreen->driScreen,
+						 modes,
+						 &private->driDrawable,
+						 hwDrawable, 0, NULL);
+
+    return &private->base;
+}
+
+static int
+getUST(int64_t *ust)
+{
+    struct timeval  tv;
+    
+    if (ust == NULL)
+	return -EFAULT;
+
+    if (gettimeofday(&tv, NULL) == 0) {
+	ust[0] = (tv.tv_sec * 1000000) + tv.tv_usec;
+	return 0;
+    } else {
+	return -errno;
+    }
+}
+
+static void __glXReportDamage(__DRIdrawable *driDraw,
+			      int x, int y,
+			      drm_clip_rect_t *rects, int num_rects,
+			      GLboolean front_buffer)
+{
+    __GLXDRIdrawable *drawable =
+	    containerOf(driDraw, __GLXDRIdrawable, driDrawable);
+    DrawablePtr pDraw = drawable->base.pDraw;
+    RegionRec region;
+
+    REGION_INIT(pDraw->pScreen, &region, (BoxPtr) rects, num_rects);
+    REGION_TRANSLATE(pScreen, &region, pDraw->x, pDraw->y);
+    DamageDamageRegion(pDraw, &region);
+    REGION_UNINIT(pDraw->pScreen, &region);
+}
+
+/* Table of functions that we export to the driver. */
+static const __DRIinterfaceMethods interface_methods = {
+    _gl_context_modes_create,
+    _gl_context_modes_destroy,
+
+    NULL,
+
+    getUST,
+    NULL,
+
+    __glXReportDamage,
+};
+
+static const char dri_driver_path[] = DRI_DRIVER_PATH;
+
+static Bool
+glxDRIEnterVT (int index, int flags)
+{
+    __GLXDRIscreen *screen = (__GLXDRIscreen *) 
+	glxGetScreen(screenInfo.screens[index]);
+
+    LogMessage(X_INFO, "AIGLX: Resuming AIGLX clients after VT switch\n");
+
+    if (!(*screen->enterVT) (index, flags))
+	return FALSE;
+    
+    glxResumeClients();
+
+    return TRUE;
+}
+
+static void
+glxDRILeaveVT (int index, int flags)
+{
+    __GLXDRIscreen *screen = (__GLXDRIscreen *)
+	glxGetScreen(screenInfo.screens[index]);
+
+    LogMessage(X_INFO, "AIGLX: Suspending AIGLX clients for VT switch\n");
+
+    glxSuspendClients();
+
+    return (*screen->leaveVT) (index, flags);
+}
+
+static void
+initializeExtensions(__GLXDRIscreen *screen)
+{
+    const __DRIextension **extensions;
+    int i;
+
+    extensions = screen->driScreen.getExtensions(&screen->driScreen);
+    for (i = 0; extensions[i]; i++) {
+#ifdef __DRI_COPY_SUB_BUFFER
+	if (strcmp(extensions[i]->name, __DRI_COPY_SUB_BUFFER) == 0) {
+	    screen->copySubBuffer = (__DRIcopySubBufferExtension *) extensions[i];
+	    __glXEnableExtension(screen->glx_enable_bits,
+				 "GLX_MESA_copy_sub_buffer");
+	    
+	    LogMessage(X_INFO, "AIGLX: enabled GLX_MESA_copy_sub_buffer\n");
+	}
+#endif
+
+#ifdef __DRI_SWAP_CONTROL
+	if (strcmp(extensions[i]->name, __DRI_SWAP_CONTROL) == 0) {
+	    screen->swapControl = (__DRIswapControlExtension *) extensions[i];
+	    __glXEnableExtension(screen->glx_enable_bits,
+				 "GLX_SGI_swap_control");
+	    __glXEnableExtension(screen->glx_enable_bits,
+				 "GLX_MESA_swap_control");
+	    
+	    LogMessage(X_INFO, "AIGLX: enabled GLX_SGI_swap_control and GLX_MESA_swap_control\n");
+	}
+#endif
+	/* Ignore unknown extensions */
+    }
+}
+    
+static __GLXscreen *
+__glXDRIscreenProbe(ScreenPtr pScreen)
+{
+    __DRI2_CREATE_NEW_SCREEN_FUNC *createNewScreen;
+    __DRIversion   ddx_version;
+    __DRIversion   dri_version;
+    __DRIversion   drm_version;
+    drmVersionPtr version;
+    const char *driverName;
+    __GLXDRIscreen *screen;
+    char filename[128];
+    size_t buffer_size;
+    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+    unsigned int sareaHandle;
+
+    screen = xalloc(sizeof *screen);
+    if (screen == NULL)
+      return NULL;
+    memset(screen, 0, sizeof *screen);
+
+    if (!xf86LoaderCheckSymbol("DRI2Connect") ||
+	!DRI2Connect(pScreen,
+		     &screen->fd,
+		     &driverName,
+		     &ddx_version.major,
+		     &ddx_version.minor,
+		     &ddx_version.patch,
+		     &sareaHandle)) {
+	LogMessage(X_INFO,
+		   "AIGLX: Screen %d is not DRI2 capable\n", pScreen->myNum);
+	return NULL;
+    }
+
+    screen->base.destroy        = __glXDRIscreenDestroy;
+    screen->base.createContext  = __glXDRIscreenCreateContext;
+    screen->base.createDrawable = __glXDRIscreenCreateDrawable;
+    screen->base.swapInterval   = __glXDRIdrawableSwapInterval;
+    screen->base.pScreen       = pScreen;
+
+    __glXInitExtensionEnableBits(screen->glx_enable_bits);
+
+    /* DRI protocol version. */
+    dri_version.major = XF86DRI_MAJOR_VERSION;
+    dri_version.minor = XF86DRI_MINOR_VERSION;
+    dri_version.patch = XF86DRI_PATCH_VERSION;
+
+    version = drmGetVersion(screen->fd);
+    if (version) {
+	drm_version.major = version->version_major;
+	drm_version.minor = version->version_minor;
+	drm_version.patch = version->version_patchlevel;
+	drmFreeVersion(version);
+    }
+    else {
+	drm_version.major = -1;
+	drm_version.minor = -1;
+	drm_version.patch = -1;
+    }
+
+    snprintf(filename, sizeof filename, "%s/%s_dri.so",
+             dri_driver_path, driverName);
+
+    screen->driver = dlopen(filename, RTLD_LAZY | RTLD_LOCAL);
+    if (screen->driver == NULL) {
+	LogMessage(X_ERROR, "AIGLX error: dlopen of %s failed (%s)\n",
+		   filename, dlerror());
+        goto handle_error;
+    }
+
+    createNewScreen = dlsym(screen->driver, CREATE_NEW_SCREEN_FUNC);
+    if (createNewScreen == NULL) {
+	LogMessage(X_ERROR, "AIGLX error: dlsym for %s failed (%s)\n",
+		   CREATE_NEW_SCREEN_FUNC, dlerror());
+      goto handle_error;
+    }
+    
+    screen->driScreen.private =
+	(*createNewScreen)(pScreen->myNum,
+			   &screen->driScreen,
+			   &ddx_version,
+			   &dri_version,
+			   &drm_version,
+			   screen->fd,
+			   sareaHandle,
+			   &interface_methods,
+			   &screen->base.fbconfigs);
+
+    if (screen->driScreen.private == NULL) {
+	LogMessage(X_ERROR, "AIGLX error: Calling driver entry point failed");
+	goto handle_error;
+    }
+
+    initializeExtensions(screen);
+
+    __glXScreenInit(&screen->base, pScreen);
+
+    buffer_size = __glXGetExtensionString(screen->glx_enable_bits, NULL);
+    if (buffer_size > 0) {
+	if (screen->base.GLXextensions != NULL) {
+	    xfree(screen->base.GLXextensions);
+	}
+
+	screen->base.GLXextensions = xnfalloc(buffer_size);
+	(void) __glXGetExtensionString(screen->glx_enable_bits, 
+				       screen->base.GLXextensions);
+    }
+
+    screen->enterVT = pScrn->EnterVT;
+    pScrn->EnterVT = glxDRIEnterVT; 
+    screen->leaveVT = pScrn->LeaveVT;
+    pScrn->LeaveVT = glxDRILeaveVT;
+
+    LogMessage(X_INFO,
+	       "AIGLX: Loaded and initialized %s\n", filename);
+
+    return &screen->base;
+
+ handle_error:
+    if (screen->driver)
+        dlclose(screen->driver);
+
+    xfree(screen);
+
+    LogMessage(X_ERROR, "AIGLX: reverting to software rendering\n");
+
+    return NULL;
+}
+
+__GLXprovider __glXDRI2Provider = {
+    __glXDRIscreenProbe,
+    "DRI2",
+    NULL
+};
diff --git a/GL/glx/glxscreens.c b/GL/glx/glxscreens.c
index 88773a7..6575b27 100644
--- a/GL/glx/glxscreens.c
+++ b/GL/glx/glxscreens.c
@@ -280,6 +280,30 @@ void GlxSetVisualConfigs(int nconfigs,
      * call it. */
 }
 
+static void
+filterOutNativeConfigs(__GLXscreen *pGlxScreen)
+{
+    __GLcontextModes *m, *next, *native_modes, **last;
+    ScreenPtr pScreen = pGlxScreen->pScreen;
+    int i, depth;
+
+    last = &pGlxScreen->fbconfigs;
+    for (m = pGlxScreen->fbconfigs; m != NULL; m = next) {
+	next = m->next;
+	depth = m->redBits + m->blueBits + m->greenBits;
+
+	for (i = 0; i < pScreen->numVisuals; i++) {
+	    if (pScreen->visuals[i].nplanes == depth) {
+		*last = m;
+		last = &m->next;
+		break;
+	    }
+	}
+    }
+
+    *last = NULL;
+}
+
 static XID
 findVisualForConfig(ScreenPtr pScreen, __GLcontextModes *m)
 {
@@ -513,6 +537,8 @@ void __glXScreenInit(__GLXscreen *pGlxScreen, ScreenPtr pScreen)
     pGlxScreen->CloseScreen = pScreen->CloseScreen;
     pScreen->CloseScreen = glxCloseScreen;
 
+    filterOutNativeConfigs(pGlxScreen);
+
     i = 0;
     for (m = pGlxScreen->fbconfigs; m != NULL; m = m->next) {
 	m->fbconfigID = FakeClientID(0);
diff --git a/hw/xfree86/dixmods/glxmodule.c b/hw/xfree86/dixmods/glxmodule.c
index 0ff867d..a1a0886 100644
--- a/hw/xfree86/dixmods/glxmodule.c
+++ b/hw/xfree86/dixmods/glxmodule.c
@@ -125,6 +125,9 @@ glxSetup(pointer module, pointer opts, int *errmaj, int *errmin)
       provider = LoaderSymbol("__glXDRIProvider");
       if (provider)
 	GlxPushProvider(provider);
+      provider = LoaderSymbol("__glXDRI2Provider");
+      if (provider)
+	GlxPushProvider(provider);
     }
 
     switch (xf86Info.glxVisuals) {
commit b71dc54352bc56a889823040ec19c1d8e118a1f3
Author: Kristian Høgsberg <krh at sasori.boston.redhat.com>
Date:   Mon Feb 4 11:58:24 2008 -0500

    Add DRI2 module.

diff --git a/configure.ac b/configure.ac
index d8b78ea..10aa241 100644
--- a/configure.ac
+++ b/configure.ac
@@ -368,6 +368,7 @@ AM_CONDITIONAL(PPC_VIDEO, [test "x$PPC_VIDEO" = xyes])
 AM_CONDITIONAL(SPARC64_VIDEO, [test "x$SPARC64_VIDEO" = xyes])
 
 DRI=no
+DRI2=no
 KDRIVE_HW=no
 dnl it would be nice to autodetect these *CONS_SUPPORTs
 case $host_os in
@@ -380,6 +381,7 @@ case $host_os in
 	AC_DEFINE(PCVT_SUPPORT, 1, [System has PCVT console])
 	AC_DEFINE(SYSCONS_SUPPORT, 1, [System has syscons console])
 	DRI=yes
+	DRI2=yes
 	;;
   *netbsd*)
 	AC_DEFINE(CSRG_BASED, 1, [System is BSD-like])
@@ -387,6 +389,7 @@ case $host_os in
 	AC_DEFINE(PCVT_SUPPORT, 1, [System has PCVT console])
 	AC_DEFINE(WSCONS_SUPPORT, 1, [System has wscons console])
 	DRI=yes
+	DRI2=yes
 	;;
   *openbsd*)
 	AC_DEFINE(CSRG_BASED, 1, [System is BSD-like])
@@ -395,6 +398,7 @@ case $host_os in
 	;;
   *linux*)
 	DRI=yes
+	DRI2=yes
 	KDRIVE_HW=yes
 	;;
   *solaris*)
@@ -535,6 +539,7 @@ AC_ARG_ENABLE(xdmcp,          AS_HELP_STRING([--disable-xdmcp], [Build XDMCP ext
 AC_ARG_ENABLE(xdm-auth-1,     AS_HELP_STRING([--disable-xdm-auth-1], [Build XDM-Auth-1 extension (default: auto)]), [XDMAUTH=$enableval], [XDMAUTH=auto])
 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])
 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(xf86misc,       AS_HELP_STRING([--disable-xf86misc], [Build XF86Misc extension (default: auto)]), [XF86MISC=$enableval], [XF86MISC=auto])
@@ -857,6 +862,14 @@ if test "x$DRI" = xyes; then
 	AC_SUBST(GL_CFLAGS)
 fi
 
+AM_CONDITIONAL(DRI2, test "x$DRI2" = xyes)
+if test "x$DRI2" = xyes; then
+	# FIXME: Bump the versions once we have releases of these.
+	AC_DEFINE(DRI2, 1, [Build DRI2 extension])
+	PKG_CHECK_MODULES([DRIPROTO], [xf86driproto >= 2.0.3])
+	PKG_CHECK_MODULES([LIBDRM], [libdrm >= 2.3.1])
+fi
+
 AM_CONDITIONAL(XINERAMA, [test "x$XINERAMA" = xyes])
 if test "x$XINERAMA" = xyes; then
 	AC_DEFINE(XINERAMA, 1, [Support Xinerama extension])
@@ -2129,6 +2142,7 @@ hw/xfree86/doc/devel/Makefile
 hw/xfree86/doc/man/Makefile
 hw/xfree86/doc/sgml/Makefile
 hw/xfree86/dri/Makefile
+hw/xfree86/dri2/Makefile
 hw/xfree86/dummylib/Makefile
 hw/xfree86/exa/Makefile
 hw/xfree86/fbdevhw/Makefile
diff --git a/hw/xfree86/Makefile.am b/hw/xfree86/Makefile.am
index 4afc3a4..03c2c3a 100644
--- a/hw/xfree86/Makefile.am
+++ b/hw/xfree86/Makefile.am
@@ -4,6 +4,10 @@ if DRI
 DRI_SUBDIR = dri
 endif
 
+if DRI2
+DRI2_SUBDIR = dri2
+endif
+
 if XF86UTILS
 XF86UTILS_SUBDIR = utils
 endif
@@ -21,11 +25,11 @@ DOC_SUBDIR = doc
 SUBDIRS = common ddc dummylib i2c x86emu int10 fbdevhw os-support parser rac \
 	  ramdac shadowfb vbe vgahw xaa $(MFB_SUBDIR) $(CFB_SUBDIR) \
 	  xf8_16bpp loader dixmods exa modes \
-	  $(DRI_SUBDIR) $(XF86UTILS_SUBDIR) $(DOC_SUBDIR)
+	  $(DRI_SUBDIR) $(DRI2_SUBDIR) $(XF86UTILS_SUBDIR) $(DOC_SUBDIR)
 
 DIST_SUBDIRS = common ddc dummylib i2c x86emu int10 fbdevhw os-support \
                parser rac ramdac shadowfb vbe vgahw xaa xf1bpp xf4bpp \
-               xf8_16bpp xf8_32bpp loader dixmods dri exa modes \
+               xf8_16bpp xf8_32bpp loader dixmods dri dri2 exa modes \
 	       utils doc
 
 bin_PROGRAMS = Xorg
diff --git a/hw/xfree86/dri2/Makefile.am b/hw/xfree86/dri2/Makefile.am
new file mode 100644
index 0000000..be3cea4
--- /dev/null
+++ b/hw/xfree86/dri2/Makefile.am
@@ -0,0 +1,15 @@
+libdri2_la_LTLIBRARIES = libdri2.la
+libdri2_la_CFLAGS = \
+	-DHAVE_XORG_CONFIG_H \
+	-I at MESA_SOURCE@/include \
+	@DIX_CFLAGS@ @DRIPROTO_CFLAGS@ @LIBDRM_CFLAGS@ \
+	-I$(top_srcdir)/hw/xfree86/common \
+	-I$(top_srcdir)/hw/xfree86/os-support/bus
+
+libdri2_la_LDFLAGS = -module -avoid-version @LIBDRM_LIBS@
+libdri2_ladir = $(moduledir)/extensions
+libdri2_la_SOURCES = \
+	dri2.c \
+	dri2.h
+
+sdk_HEADERS = dri2.h
diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c
new file mode 100644
index 0000000..7c703a7
--- /dev/null
+++ b/hw/xfree86/dri2/dri2.c
@@ -0,0 +1,448 @@
+/*
+ * Copyright © 2007 Red Hat, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Soft-
+ * ware"), to deal in the Software without restriction, including without
+ * limitation the rights to use, copy, modify, merge, publish, distribute,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, provided that the above copyright
+ * notice(s) and this permission notice appear in all copies of the Soft-
+ * ware and that both the above copyright notice(s) and this permission
+ * notice appear in supporting documentation.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
+ * ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY
+ * RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN
+ * THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSE-
+ * QUENTIAL 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 PERFOR-
+ * MANCE OF THIS SOFTWARE.
+ *
+ * Except as contained in this notice, the name of a copyright holder shall
+ * not be used in advertising or otherwise to promote the sale, use or
+ * other dealings in this Software without prior written authorization of
+ * the copyright holder.
+ *
+ * Authors:
+ *   Kristian Høgsberg (krh at redhat.com)
+ */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include <xf86drm.h>
+#include "xf86Module.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include "dri2.h"
+#include <GL/internal/dri_sarea.h>
+
+#include "xf86.h"
+
+static DevPrivateKey dri2ScreenPrivateKey = &dri2ScreenPrivateKey;
+static DevPrivateKey dri2WindowPrivateKey = &dri2WindowPrivateKey;
+static DevPrivateKey dri2PixmapPrivateKey = &dri2PixmapPrivateKey;
+
+typedef struct _DRI2DrawablePriv {
+    drm_drawable_t		 drawable;
+    unsigned int		 handle;
+} DRI2DrawablePrivRec, *DRI2DrawablePrivPtr;
+
+typedef struct _DRI2Screen {
+    int				 fd;
+    drmBO			 sareaBO;
+    void			*sarea;
+    unsigned int		 sareaSize;
+    const char			*driverName;
+    int				 ddxVersionMajor;
+    int				 ddxVersionMinor;
+    int				 ddxVersionPatch;
+
+    __DRIEventBuffer		*buffer;
+    int				 locked;
+
+    DRI2GetPixmapHandleProcPtr   getPixmapHandle;
+    DRI2BeginClipNotifyProcPtr	 beginClipNotify;
+    DRI2EndClipNotifyProcPtr	 endClipNotify;
+
+    ClipNotifyProcPtr		 ClipNotify;
+    HandleExposuresProcPtr	 HandleExposures;
+} DRI2ScreenRec, *DRI2ScreenPtr;
+
+static DRI2ScreenPtr
+DRI2GetScreen(ScreenPtr pScreen)
+{
+    return dixLookupPrivate(&pScreen->devPrivates, dri2ScreenPrivateKey);
+}
+
+static void *
+DRI2ScreenAllocEvent(DRI2ScreenPtr ds, size_t size)
+{
+    unsigned int *pad, mask = ds->buffer->size - 1;
+    size_t pad_size;
+    void *p;
+    
+    if ((ds->buffer->head & mask) + size > ds->buffer->size) {
+	/* The requested event size would wrap the buffer, so pad to
+	 * the end and allocate the event from the start. */
+	pad_size = ds->buffer->size - (ds->buffer->head & mask);
+	pad = (unsigned int *)
+	    (ds->buffer->data + (ds->buffer->prealloc & mask));
+	*pad = DRI2_EVENT_HEADER(DRI2_EVENT_PAD, pad_size);
+	ds->buffer->prealloc += pad_size;
+    }
+
+    p = ds->buffer->data + (ds->buffer->prealloc & mask);
+    ds->buffer->prealloc += size;
+
+    return p;
+}
+
+static void
+DRI2ScreenCommitEvents(DRI2ScreenPtr ds)
+{
+    ds->buffer->head = ds->buffer->prealloc;
+}
+
+static void
+DRI2PostDrawableConfig(DrawablePtr pDraw)
+{
+    ScreenPtr			 pScreen = pDraw->pScreen;
+    DRI2ScreenPtr		 ds = DRI2GetScreen(pScreen);
+    DRI2DrawablePrivPtr		 pPriv;
+    WindowPtr			 pWin;
+    PixmapPtr			 pPixmap;
+    BoxPtr			 pBox;
+    BoxRec			 pixmapBox;
+    int				 nBox;
+    int				 i;
+    __DRIDrawableConfigEvent	*e;
+    size_t			 size;
+
+    if (pDraw->type == DRAWABLE_WINDOW) {
+	pWin = (WindowPtr) pDraw;
+	pPriv = dixLookupPrivate(&pWin->devPrivates, dri2WindowPrivateKey);
+
+	nBox = REGION_NUM_RECTS(&pWin->clipList);
+	pBox = REGION_RECTS(&pWin->clipList);
+
+	pPixmap = pScreen->GetWindowPixmap(pWin);
+    } else {
+	pPixmap = (PixmapPtr) pDraw;
+	pPriv = dixLookupPrivate(&pPixmap->devPrivates, dri2PixmapPrivateKey);
+
+	pixmapBox.x1 = 0;
+	pixmapBox.y1 = 0;
+	pixmapBox.x2 = pDraw->width;
+	pixmapBox.y2 = pDraw->height;
+	nBox = 1;
+	pBox = &pixmapBox;
+    }
+
+    if (!pPriv)
+	return;
+
+    size = sizeof *e + nBox * sizeof e->rects[0];
+
+    e = DRI2ScreenAllocEvent(ds, size);
+    e->event_header = DRI2_EVENT_HEADER(DRI2_EVENT_DRAWABLE_CONFIG, size);
+    e->drawable = pPriv->drawable;
+    e->x = pDraw->x - pPixmap->screen_x;
+    e->y = pDraw->y - pPixmap->screen_y;
+    e->width = pDraw->width;
+    e->height = pDraw->height;
+
+    e->num_rects = nBox;
+    for (i = 0; i < nBox; i++) {
+	e->rects[i].x1 = pBox->x1 - pPixmap->screen_x;
+	e->rects[i].y1 = pBox->y1 - pPixmap->screen_y;
+	e->rects[i].x2 = pBox->x2 - pPixmap->screen_x;
+	e->rects[i].y2 = pBox->y2 - pPixmap->screen_y;
+	pBox++;
+    }
+}
+
+static void
+DRI2PostBufferAttach(DrawablePtr pDraw)
+{
+    ScreenPtr			 pScreen = pDraw->pScreen;
+    DRI2ScreenPtr		 ds = DRI2GetScreen(pScreen);
+    DRI2DrawablePrivPtr		 pPriv;
+    WindowPtr			 pWin;
+    PixmapPtr			 pPixmap;
+    __DRIBufferAttachEvent	*e;
+    size_t			 size;
+    unsigned int		 handle, flags;
+
+    if (pDraw->type == DRAWABLE_WINDOW) {
+	pWin = (WindowPtr) pDraw;
+	pPixmap = pScreen->GetWindowPixmap(pWin);
+	pPriv = dixLookupPrivate(&pWin->devPrivates, dri2WindowPrivateKey);
+    } else {
+	pPixmap = (PixmapPtr) pDraw;
+	pPriv = dixLookupPrivate(&pPixmap->devPrivates, dri2PixmapPrivateKey);
+    }
+
+    if (!pPriv)
+	return;
+
+    size = sizeof *e;
+
+    handle = ds->getPixmapHandle(pPixmap, &flags);
+    if (handle == 0 || handle == pPriv->handle)
+	return;
+
+    e = DRI2ScreenAllocEvent(ds, size);
+    e->event_header = DRI2_EVENT_HEADER(DRI2_EVENT_BUFFER_ATTACH, size);
+    e->drawable = pPriv->drawable;
+    e->buffer.attachment = DRI_DRAWABLE_BUFFER_FRONT_LEFT;
+    e->buffer.handle = handle;
+    e->buffer.pitch = pPixmap->devKind;
+    e->buffer.cpp = pPixmap->drawable.bitsPerPixel / 8;
+    e->buffer.flags = flags;
+
+    pPriv->handle = handle;
+}
+
+static void
+DRI2ClipNotify(WindowPtr pWin, int dx, int dy)
+{
+    ScreenPtr		pScreen = pWin->drawable.pScreen;
+    DRI2ScreenPtr	ds = DRI2GetScreen(pScreen);
+
+    if (!ds->locked) {
+        ds->beginClipNotify(pScreen);
+	ds->locked = 1;
+    }
+
+    if (ds->ClipNotify) {
+	pScreen->ClipNotify = ds->ClipNotify;
+	pScreen->ClipNotify(pWin, dx, dy);
+	pScreen->ClipNotify = DRI2ClipNotify;
+    }
+
+    DRI2PostDrawableConfig(&pWin->drawable);
+    DRI2PostBufferAttach(&pWin->drawable);
+}
+
+static void
+DRI2HandleExposures(WindowPtr pWin)
+{
+    ScreenPtr		pScreen = pWin->drawable.pScreen;
+    DRI2ScreenPtr	ds = DRI2GetScreen(pScreen);
+
+    if (ds->HandleExposures) {
+	pScreen->HandleExposures = ds->HandleExposures;
+	pScreen->HandleExposures(pWin);
+	pScreen->HandleExposures = DRI2HandleExposures;
+    }
+
+    DRI2ScreenCommitEvents(ds);
+
+    if (ds->locked) {
+        ds->endClipNotify(pScreen);
+	ds->locked = 0;
+    }
+}
+
+void
+DRI2CloseScreen(ScreenPtr pScreen)
+{
+    DRI2ScreenPtr	ds = DRI2GetScreen(pScreen);
+
+    pScreen->ClipNotify		= ds->ClipNotify;
+    pScreen->HandleExposures	= ds->HandleExposures;
+
+    drmBOUnmap(ds->fd, &ds->sareaBO);
+    drmBOUnreference(ds->fd, &ds->sareaBO);
+
+    xfree(ds);
+    dixSetPrivate(&pScreen->devPrivates, dri2ScreenPrivateKey, NULL);
+}
+
+Bool
+DRI2CreateDrawable(ScreenPtr pScreen,
+		   DrawablePtr pDraw, drm_drawable_t *pDrmDrawable)
+{
+    DRI2ScreenPtr	ds = DRI2GetScreen(pScreen);
+    WindowPtr		pWin;
+    PixmapPtr		pPixmap;
+    DRI2DrawablePrivPtr pPriv;
+    DevPrivateKey	key;
+    PrivateRec		**devPrivates;
+
+    if (pDraw->type == DRAWABLE_WINDOW) {
+	pWin = (WindowPtr) pDraw;
+	devPrivates = &pWin->devPrivates;
+	key = dri2WindowPrivateKey;
+    } else {
+	pPixmap = (PixmapPtr) pDraw;
+	devPrivates = &pPixmap->devPrivates;
+	key = dri2PixmapPrivateKey;
+    }
+
+    pPriv = dixLookupPrivate(devPrivates, key);
+    if (pPriv == NULL) {
+	pPriv = xalloc(sizeof *pPriv);
+	if (drmCreateDrawable(ds->fd, &pPriv->drawable))
+	    return FALSE;
+
+	dixSetPrivate(devPrivates, key, pPriv);
+    }
+
+    *pDrmDrawable = pPriv->drawable;
+
+    DRI2PostDrawableConfig(pDraw);
+    DRI2PostBufferAttach(pDraw);
+    DRI2ScreenCommitEvents(ds);
+
+    return TRUE;
+}
+
+void
+DRI2DestroyDrawable(ScreenPtr pScreen, DrawablePtr pDraw)
+{
+    DRI2ScreenPtr ds = DRI2GetScreen(pScreen);
+    PixmapPtr pPixmap;
+    WindowPtr pWin;
+    DRI2DrawablePrivPtr pPriv;
+
+    if (pDraw->type == DRAWABLE_WINDOW) {
+	pWin = (WindowPtr) pDraw;
+	pPriv = dixLookupPrivate(&pWin->devPrivates, dri2WindowPrivateKey);
+	dixSetPrivate(&pWin->devPrivates, dri2WindowPrivateKey, NULL);
+    } else {
+	pPixmap = (PixmapPtr) pDraw;
+	pPriv = dixLookupPrivate(&pPixmap->devPrivates, dri2PixmapPrivateKey);
+	dixSetPrivate(&pPixmap->devPrivates, dri2PixmapPrivateKey, NULL);
+    }
+
+    if (pPriv == NULL)
+	return;
+    
+    drmDestroyDrawable(ds->fd, pPriv->drawable);
+    xfree(pPriv);
+}
+
+Bool
+DRI2Connect(ScreenPtr pScreen, int *fd, const char **driverName,
+	    int *ddxMajor, int *ddxMinor, int *ddxPatch,
+	    unsigned int *sareaHandle)
+{
+    DRI2ScreenPtr ds = DRI2GetScreen(pScreen);
+
+    if (ds == NULL)
+	return FALSE;
+
+    *fd = ds->fd;
+    *driverName = ds->driverName;
+    *ddxMajor = ds->ddxVersionMajor;
+    *ddxMinor = ds->ddxVersionMinor;
+    *ddxPatch = ds->ddxVersionPatch;
+    *sareaHandle = ds->sareaBO.handle;
+
+    return TRUE;
+}
+
+static void *
+DRI2SetupSAREA(ScreenPtr pScreen, size_t driverSareaSize)
+{
+    DRI2ScreenPtr ds = DRI2GetScreen(pScreen);
+    unsigned long mask;
+    const size_t event_buffer_size = 32 * 1024;
+
+    ds->sareaSize = 
+	sizeof(*ds->buffer) + event_buffer_size +
+	driverSareaSize +
+	sizeof (unsigned int);
+
+    mask = DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE | DRM_BO_FLAG_MAPPABLE |
+	DRM_BO_FLAG_MEM_LOCAL | DRM_BO_FLAG_SHAREABLE;
+
+    if (drmBOCreate(ds->fd, ds->sareaSize, 1, NULL, mask, 0, &ds->sareaBO))
+	return NULL;
+
+    if (drmBOMap(ds->fd, &ds->sareaBO,
+		 DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, 0, &ds->sarea)) {
+	drmBOUnreference(ds->fd, &ds->sareaBO);
+	return NULL;
+    }
+
+    xf86DrvMsg(pScreen->myNum, X_INFO,
+	       "[DRI2] Allocated %d byte SAREA, BO handle 0x%08x\n",
+	       ds->sareaSize, ds->sareaBO.handle);
+    memset(ds->sarea, 0, ds->sareaSize);
+
+    ds->buffer = ds->sarea;
+    ds->buffer->block_header =
+	DRI2_SAREA_BLOCK_HEADER(DRI2_SAREA_BLOCK_EVENT_BUFFER,
+				sizeof *ds->buffer + event_buffer_size);
+    ds->buffer->size = event_buffer_size;
+
+    return DRI2_SAREA_BLOCK_NEXT(ds->buffer);
+}
+
+void *
+DRI2ScreenInit(ScreenPtr pScreen, DRI2InfoPtr info)
+{
+    DRI2ScreenPtr ds;
+    void *p;
+
+    ds = xalloc(sizeof *ds);
+    if (!ds)
+	return NULL;
+
+    ds->fd = info->fd;
+    ds->driverName		= info->driverName;
+    ds->ddxVersionMajor		= info->ddxVersionMajor;
+    ds->ddxVersionMinor		= info->ddxVersionMinor;
+    ds->ddxVersionPatch		= info->ddxVersionPatch;
+
+    ds->getPixmapHandle		= info->getPixmapHandle;
+    ds->beginClipNotify		= info->beginClipNotify;
+    ds->endClipNotify		= info->endClipNotify;
+
+    ds->ClipNotify		= pScreen->ClipNotify;
+    pScreen->ClipNotify		= DRI2ClipNotify;
+    ds->HandleExposures		= pScreen->HandleExposures;
+    pScreen->HandleExposures	= DRI2HandleExposures;
+
+    dixSetPrivate(&pScreen->devPrivates, dri2ScreenPrivateKey, ds);
+
+    p = DRI2SetupSAREA(pScreen, info->driverSareaSize);
+    if (p == NULL) {
+	xfree(ds);
+	return NULL;
+    }
+
+    xf86DrvMsg(pScreen->myNum, X_INFO, "[DRI2] Setup complete\n");
+
+    return p;
+}
+
+static pointer
+DRI2Setup(pointer module, pointer opts, int *errmaj, int *errmin)
+{
+    return (pointer) 1;
+}
+
+static XF86ModuleVersionInfo DRI2VersRec =
+{
+    "dri2",
+    MODULEVENDORSTRING,
+    MODINFOSTRING1,
+    MODINFOSTRING2,
+    XORG_VERSION_CURRENT,
+    1, 0, 0,
+    ABI_CLASS_EXTENSION,
+    ABI_EXTENSION_VERSION,
+    MOD_CLASS_NONE,
+    { 0, 0, 0, 0 }
+};
+
+_X_EXPORT XF86ModuleData dri2ModuleData = { &DRI2VersRec, DRI2Setup, NULL };
+
diff --git a/hw/xfree86/dri2/dri2.h b/hw/xfree86/dri2/dri2.h
new file mode 100644
index 0000000..65b4c6b
--- /dev/null
+++ b/hw/xfree86/dri2/dri2.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright © 2007 Red Hat, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Soft-
+ * ware"), to deal in the Software without restriction, including without
+ * limitation the rights to use, copy, modify, merge, publish, distribute,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, provided that the above copyright
+ * notice(s) and this permission notice appear in all copies of the Soft-
+ * ware and that both the above copyright notice(s) and this permission
+ * notice appear in supporting documentation.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
+ * ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY
+ * RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN
+ * THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSE-
+ * QUENTIAL 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 PERFOR-
+ * MANCE OF THIS SOFTWARE.
+ *
+ * Except as contained in this notice, the name of a copyright holder shall
+ * not be used in advertising or otherwise to promote the sale, use or
+ * other dealings in this Software without prior written authorization of
+ * the copyright holder.
+ *
+ * Authors:
+ *   Kristian Høgsberg (krh at redhat.com)
+ */
+
+#ifndef _DRI2_H_
+#define _DRI2_H_
+
+typedef unsigned int	(*DRI2GetPixmapHandleProcPtr)(PixmapPtr p,
+						      unsigned int *flags);
+typedef void		(*DRI2BeginClipNotifyProcPtr)(ScreenPtr pScreen);
+typedef void		(*DRI2EndClipNotifyProcPtr)(ScreenPtr pScreen);
+
+typedef struct {
+    unsigned int version;	/* Version of this struct */
+    int fd;
+    size_t driverSareaSize;
+    const char *driverName;
+    int ddxVersionMajor, ddxVersionMinor, ddxVersionPatch;
+    DRI2GetPixmapHandleProcPtr getPixmapHandle;
+    DRI2BeginClipNotifyProcPtr beginClipNotify;
+    DRI2EndClipNotifyProcPtr endClipNotify;
+}  DRI2InfoRec, *DRI2InfoPtr;
+
+void *DRI2ScreenInit(ScreenPtr	pScreen,
+		     DRI2InfoPtr info);
+
+void DRI2CloseScreen(ScreenPtr pScreen);
+
+Bool DRI2Connect(ScreenPtr pScreen,
+		 int *fd,
+		 const char **driverName,
+		 int *ddxMajor,
+		 int *ddxMinor,
+		 int *ddxPatch,
+		 unsigned int *sareaHandle);
+
+void DRI2Lock(ScreenPtr pScreen);
+void DRI2Unlock(ScreenPtr pScreen);
+
+Bool DRI2CreateDrawable(ScreenPtr	 pScreen,
+			DrawablePtr	 pDraw,
+			drm_drawable_t	*pDrmDrawable);
+
+void DRI2DestroyDrawable(ScreenPtr	pScreen,
+			 DrawablePtr	pDraw);
+
+void DRI2ExtensionInit(void);
+
+#endif
diff --git a/include/dix-config.h.in b/include/dix-config.h.in
index 068b551..38639d6 100644
--- a/include/dix-config.h.in
+++ b/include/dix-config.h.in
@@ -436,6 +436,9 @@
 
 #undef XEPHYR_DRI
 
+/* Build DRI2 extension */
+#undef DRI2
+
 /* Build DBE support */
 #undef DBE
 
diff --git a/include/xorg-config.h.in b/include/xorg-config.h.in
index b91ea92..0603eab 100644
--- a/include/xorg-config.h.in
+++ b/include/xorg-config.h.in
@@ -54,6 +54,9 @@
 /* Building DRI-capable DDX. */
 #undef XF86DRI
 
+/* Build DRI2 extension */
+#undef DRI2
+
 /* Solaris 8 or later? */
 #undef __SOL8__
 
diff --git a/include/xorg-server.h.in b/include/xorg-server.h.in
index dc6f1b3..1d41b4c 100644
--- a/include/xorg-server.h.in
+++ b/include/xorg-server.h.in
@@ -142,6 +142,9 @@
 /* Build DRI extension */
 #undef XF86DRI
 
+/* Build DRI2 extension */
+#undef DRI2
+
 /* Build Xorg server */
 #undef XORGSERVER
 


More information about the xorg-commit mailing list