Bring in DRI2 changes
authorAlan Hourihane <alanh@tungstengraphics.com>
Tue, 10 Jun 2008 19:17:16 +0000 (20:17 +0100)
committerAlan Hourihane <alanh@tungstengraphics.com>
Wed, 11 Jun 2008 13:10:08 +0000 (14:10 +0100)
33 files changed:
bin/mklib
include/GL/internal/dri_interface.h
include/GL/internal/glcore.h
src/gallium/winsys/dri/intel/intel_context.c
src/gallium/winsys/dri/intel/intel_screen.c
src/glx/x11/Makefile
src/glx/x11/XF86dri.c
src/glx/x11/dri_glx.c
src/glx/x11/glcontextmodes.c
src/glx/x11/glcontextmodes.h
src/glx/x11/glx_pbuffer.c
src/glx/x11/glx_texture_compression.c [deleted file]
src/glx/x11/glxclient.h
src/glx/x11/glxcmds.c
src/glx/x11/glxext.c
src/glx/x11/glxextensions.c
src/glx/x11/glxextensions.h
src/glx/x11/indirect.c
src/glx/x11/indirect.h
src/glx/x11/indirect_init.c
src/glx/x11/indirect_vertex_array.c
src/glx/x11/singlepix.c
src/glx/x11/xf86dri.h
src/glx/x11/xfont.c
src/mesa/drivers/dri/common/dri_util.c
src/mesa/drivers/dri/common/dri_util.h
src/mesa/drivers/dri/common/drirenderbuffer.c
src/mesa/drivers/dri/common/spantmp2.h
src/mesa/drivers/dri/common/utils.c
src/mesa/drivers/dri/common/utils.h
src/mesa/drivers/dri/common/vblank.c
src/mesa/drivers/dri/common/vblank.h
src/mesa/drivers/dri/common/xmlconfig.c

index e17e2fe..2fb215e 100755 (executable)
--- a/bin/mklib
+++ b/bin/mklib
@@ -34,6 +34,7 @@ MINOR=0
 PATCH=""
 DEPS=""
 LINK=""
+LDFLAGS=""
 CPLUSPLUS=0
 STATIC=0
 DLOPEN=0
@@ -63,12 +64,14 @@ do
            echo '  -LDIR         search in DIR for library dependencies'
            echo '  -linker L     explicity specify the linker program to use (eg: gcc, g++)'
            echo '                Not observed on all systems at this time.'
+           echo '  -ldflags OPT  specify any additional linker flags in OPT'
            echo '  -cplusplus    link with C++ runtime'
            echo '  -static       make a static library (default is dynamic/shared)'
            echo '  -dlopen       make a shared library suitable for dynamic loading'
            echo '  -install DIR  put resulting library file(s) in DIR'
            echo '  -arch ARCH    override using `uname` to determine host system'
            echo '  -archopt OPT  specify an extra achitecture-specific option OPT'
+           echo '  -altopts OPTS alternate options to override all others'
            echo "  -noprefix     don't prefix library name with 'lib' nor add any suffix"
            echo '  -exports FILE only export the symbols listed in FILE'
            echo '  -h, --help    display this information and exit'
@@ -94,12 +97,19 @@ do
            shift 1;
            LINK=$1
            ;;
+       '-ldflags')
+           shift 1;
+           LDFLAGS=$1
+           ;;
        -l*)
            DEPS="$DEPS $1"
            ;;
        -L*)
            DEPS="$DEPS $1"
            ;;
+       -Wl*)
+            DEPS="$DEPS $1"
+            ;;
        -pthread)
            # this is a special case (see bugzilla 10876)
            DEPS="$DEPS $1"
@@ -128,6 +138,10 @@ do
            shift 1;
            ARCHOPT=$1
            ;;
+       '-altopts')
+            shift 1;
+            ALTOPTS=$1
+            ;;
        '-noprefix')
            NOPREFIX=1
            ;;
@@ -187,7 +201,7 @@ fi
 #
 case $ARCH in
 
-    'Linux' | 'OpenBSD' | 'GNU' | GNU/*)
+    'Linux' | 'OpenBSD' | 'DragonFly' | 'GNU' | GNU/*)
        # we assume gcc
 
        if [ "x$LINK" = "x" ] ; then
@@ -218,9 +232,13 @@ case $ARCH in
                OPTS="-m32 ${OPTS}"
            fi
 
+            if [ "${ALTOPTS}" ] ; then
+                OPTS=${ALTOPTS}
+            fi
+
             rm -f ${LIBNAME}
             # make lib
-            ${LINK} ${OPTS} -o ${LIBNAME} ${OBJECTS} ${DEPS}
+            ${LINK} ${OPTS} ${LDFLAGS} -o ${LIBNAME} ${OBJECTS} ${DEPS}
             # finish up
             FINAL_LIBS="${LIBNAME}"
         elif [ $STATIC = 1 ] ; then
@@ -228,6 +246,9 @@ case $ARCH in
             echo "mklib: Making" $ARCH "static library: " ${LIBNAME}
             LINK="ar"
             OPTS="-ru"
+            if [ "${ALTOPTS}" ] ; then
+                OPTS=${ALTOPTS}
+            fi
             rm -f ${LIBNAME}
             # make lib
             ${LINK} ${OPTS} ${LIBNAME} ${OBJECTS}
@@ -263,6 +284,9 @@ case $ARCH in
            if [ "${ABI32}" -a `uname -m` = "x86_64" ] ; then
                OPTS="-m32 ${OPTS}"
            fi
+            if [ "${ALTOPTS}" ] ; then
+                OPTS=${ALTOPTS}
+            fi
 
            if [ x${PATCH} = "x" ] ; then
                VERSION="${MAJOR}.${MINOR}"
@@ -278,7 +302,7 @@ case $ARCH in
             rm -f ${LIBNAME}.so
 
             # make lib
-            ${LINK} ${OPTS} -o ${LIBNAME}.so.${VERSION} ${OBJECTS} ${DEPS}
+            ${LINK} ${OPTS} ${LDFLAGS} -o ${LIBNAME}.so.${VERSION} ${OBJECTS} ${DEPS}
             # make usual symlinks
             ln -s ${LIBNAME}.so.${VERSION} ${LIBNAME}.so.${MAJOR}
             ln -s ${LIBNAME}.so.${MAJOR} ${LIBNAME}.so
@@ -345,15 +369,17 @@ case $ARCH in
            if [ "${SPARCV9}" ] ; then
                OPTS="${OPTS} -xarch=v9"
            fi
-
+            if [ "${ALTOPTS}" ] ; then
+                OPTS=${ALTOPTS}
+            fi
            # for debug:
            #echo "mklib: linker is" ${LINK} ${OPTS}
            if [ $NOPREFIX = 1 ] ; then
                rm -f ${LIBNAME}
-               ${LINK} ${OPTS} -o ${LIBNAME} ${OBJECTS} ${DEPS}
+               ${LINK} ${OPTS} ${LDFLAGS} -o ${LIBNAME} ${OBJECTS} ${DEPS}
            else
                rm -f ${LIBNAME}.${MAJOR} ${LIBNAME}
-               ${LINK} ${OPTS} -o ${LIBNAME}.${MAJOR} ${OBJECTS} ${DEPS}
+               ${LINK} ${OPTS} ${LDFLAGS} -o ${LIBNAME}.${MAJOR} ${OBJECTS} ${DEPS}
                ln -s ${LIBNAME}.${MAJOR} ${LIBNAME}
            fi
            FINAL_LIBS="${LIBNAME}.${MAJOR} ${LIBNAME}"
@@ -376,8 +402,11 @@ case $ARCH in
            # No "lib" or ".so" part
            echo "mklib: Making FreeBSD shared library: " ${LIBNAME}
            OPTS="-shared"
+            if [ "${ALTOPTS}" ] ; then
+                OPTS=${ALTOPTS}
+            fi
            rm -f ${LIBNAME}
-           ${LINK} ${OPTS} -o ${LIBNAME} ${OBJECTS} ${DEPS}
+           ${LINK} ${OPTS} ${LDFLAGS} -o ${LIBNAME} ${OBJECTS} ${DEPS}
            FINAL_LIBS=${LIBNAME}
         elif [ $STATIC = 1 ] ; then
            STLIB="lib${LIBNAME}.a"
@@ -389,9 +418,12 @@ case $ARCH in
        else
            SHLIB="lib${LIBNAME}.so.${MAJOR}"
            OPTS="-shared -Wl,-soname,${SHLIB}"
+            if [ "${ALTOPTS}" ] ; then
+                OPTS=${ALTOPTS}
+            fi
            echo "mklib: Making FreeBSD shared library: " ${SHLIB}
            rm -f ${SHLIB}
-           ${LINK} ${OPTS} -o ${SHLIB} ${OBJECTS} ${DEPS}
+           ${LINK} ${OPTS} ${LDFLAGS} -o ${SHLIB} ${OBJECTS} ${DEPS}
            ln -sf ${SHLIB} "lib${LIBNAME}.so"
            FINAL_LIBS="${SHLIB} lib${LIBNAME}.so"
        fi
@@ -442,6 +474,10 @@ case $ARCH in
                exit 1
            fi
 
+            if [ "${ALTOPTS}" ] ; then
+                OPTS=${ALTOPTS}
+            fi
+
            if [ $CPLUSPLUS = 1 ] ; then
                LINK="CC"
            else
@@ -449,7 +485,7 @@ case $ARCH in
            fi
 
            echo "mklib: Making IRIX " ${ABI} " shared library: " ${LIBNAME}
-           ${LINK} ${OPTS} -o ${LIBNAME} ${OBJECTS} ${DEPS}
+           ${LINK} ${OPTS} ${LDFLAGS} -o ${LIBNAME} ${OBJECTS} ${DEPS}
            FINAL_LIBS=${LIBNAME}
        fi
        ;;
@@ -522,12 +558,16 @@ case $ARCH in
                }
            }' | sort -u >> ${EXPFILE}
 
+            if [ "${ALTOPTS}" ] ; then
+                OPTS=${ALTOPTS}
+            fi
+
             # On AIX a shared library is linked differently when
             # you want to dlopen the file
            if [ $DLOPEN = "1" ] ; then
-               cc -G ${OPTS} -o ${LIBNAME} ${OBJECTS} ${DEPS}
+               cc -G ${OPTS} ${LDFLAGS} -o ${LIBNAME} ${OBJECTS} ${DEPS}
            else
-               cc ${OPTS} -o ${OFILE} ${OBJECTS} ${DEPS}
+               cc ${OPTS} ${LDFLAGS} -o ${OFILE} ${OBJECTS} ${DEPS}
                ar ${X64} -r ${LIBNAME} ${OFILE}
            fi
 
@@ -573,6 +613,9 @@ case $ARCH in
             echo "mklib: Making Darwin static library: " ${LIBNAME}
             LINK="ar"
             OPTS="-ruvs"
+            if [ "${ALTOPTS}" ] ; then
+                OPTS=${ALTOPTS}
+            fi
             ${LINK} ${OPTS} ${LIBNAME} ${OBJECTS}
             FINAL_LIBS=${LIBNAME}
         else
@@ -584,19 +627,37 @@ case $ARCH in
                LIBSUFFIX="dylib"
                 OPTS="${ARCHOPT} -dynamiclib -multiply_defined suppress -current_version ${MAJOR}.${MINOR}.0 -compatibility_version ${MAJOR}.${MINOR}.0 -install_name lib${LIBNAME}.${MAJOR}.${LIBSUFFIX}"
             fi
-            LINKNAME="lib${LIBNAME}.${LIBSUFFIX}"
-            LIBNAME="lib${LIBNAME}.${MAJOR}.${LIBSUFFIX}"
+
+            if [ ${EXPORTS} ] ; then
+                OPTS="${OPTS} -exported_symbols_list ${EXPORTS}"
+            fi 
+
+            LINKNAME="lib${LIBNAME}.${MAJOR}.${LIBSUFFIX}"
+            LINKNAME2="lib${LIBNAME}.${LIBSUFFIX}"
+            LIBNAME="lib${LIBNAME}.${MAJOR}.${MINOR}.${LIBSUFFIX}"
 
            # examine first object to determine ABI
            set ${OBJECTS}
-           ABI_PPC=`file $1 | grep 'object ppc'`
-           ABI_I386=`file $1 | grep 'object i386'`
-           if [ "${ABI_PPC}" ] ; then
-               OPTS="${OPTS} -arch ppc"
-           fi
-           if [ "${ABI_I386}" ] ; then
-               OPTS="${OPTS} -arch i386"
-           fi
+            ABI_PPC=`file $1 | grep ' ppc'`
+            ABI_I386=`file $1 | grep ' i386'`
+            ABI_PPC64=`file $1 | grep ' ppc64'`
+            ABI_X86_64=`file $1 | grep ' x86_64'`
+            if [ "${ABI_PPC}" ] ; then
+                OPTS="${OPTS} -arch ppc"
+            fi
+            if [ "${ABI_I386}" ] ; then
+                OPTS="${OPTS} -arch i386"
+            fi
+            if [ "${ABI_PPC64}" ] ; then
+                OPTS="${OPTS} -arch ppc64"
+            fi
+            if [ "${ABI_X86_64}" ] ; then
+                OPTS="${OPTS} -arch x86_64"
+            fi
+
+            if [ "${ALTOPTS}" ] ; then
+                OPTS=${ALTOPTS}
+            fi
 
            # XXX can we always add -isysroot /Developer/SDKs/MacOSX10.4u.sdk
            # to OPTS here?
@@ -609,9 +670,11 @@ case $ARCH in
            fi
 
             echo "mklib: Making Darwin shared library: " ${LIBNAME}
-            ${LINK} ${OPTS} -o ${LIBNAME} ${OBJECTS} ${DEPS}
+
+            ${LINK} ${OPTS} ${LDFLAGS} -o ${LIBNAME} ${OBJECTS} ${DEPS}
             ln -s ${LIBNAME} ${LINKNAME}
-            FINAL_LIBS="${LIBNAME} ${LINKNAME}"
+            ln -s ${LIBNAME} ${LINKNAME2}
+            FINAL_LIBS="${LIBNAME} ${LINKNAME} ${LINKNAME2}"
         fi
         ;;
 
@@ -663,6 +726,9 @@ case $ARCH in
             echo "mklib: Making Intel ICC static library: " ${LIBNAME}.a
             LINK="ar"
             OPTS="-ruv"
+            if [ "${ALTOPTS}" ] ; then
+                OPTS=${ALTOPTS}
+            fi
             # make lib
             ${LINK} ${OPTS} ${LIBNAME}.a ${OBJECTS}
             # finish up
@@ -673,6 +739,9 @@ case $ARCH in
             else
                  OPTS="-shared"
             fi
+            if [ "${ALTOPTS}" ] ; then
+                OPTS=${ALTOPTS}
+            fi
             VERSION="${MAJOR}.${MINOR}.${PATCH}"
             echo "mklib: Making Intel ICC shared library: " ${LIBNAME}.so.${VERSION}
 
@@ -686,7 +755,7 @@ case $ARCH in
             rm -f ${LIBNAME}.so.${MAJOR}
             rm -f ${LIBNAME}.so
             # make lib
-            ${LINK} ${OPTS} -o ${LIBNAME}.so.${VERSION} ${OBJECTS} ${DEPS}
+            ${LINK} ${OPTS} ${LDFLAGS} -o ${LIBNAME}.so.${VERSION} ${OBJECTS} ${DEPS}
             # make usual symlinks
             ln -s ${LIBNAME}.so.${VERSION} ${LIBNAME}.so.${MAJOR}
             ln -s ${LIBNAME}.so.${MAJOR} ${LIBNAME}.so
@@ -737,6 +806,9 @@ case $ARCH in
             echo "mklib: Making" $ARCH "static library: " ${LIBNAME}.a
             LINK="ar"
             OPTS="-ru"
+            if [ "${ALTOPTS}" ] ; then
+                OPTS=${ALTOPTS}
+            fi
             # make lib
             ${LINK} ${OPTS} ${LIBNAME}.a ${OBJECTS}
            ranlib ${LIBNAME}.a
@@ -744,6 +816,9 @@ case $ARCH in
             FINAL_LIBS=${LIBNAME}.a
         else
            OPTS="-shared -Wl,-export-all -Wl,--out-implib=${LIBNAME}-${MAJOR}.dll.a"
+            if [ "${ALTOPTS}" ] ; then
+                OPTS=${ALTOPTS}
+            fi
             echo "mklib: Making" $ARCH "shared library: " ${LIBNAME}-${MAJOR}.dll
 
             if [ $CPLUSPLUS = 1 ] ; then
@@ -758,7 +833,7 @@ case $ARCH in
             rm -f ${LIBNAME}.a
 
             # make lib
-            ${LINK} ${OPTS} -o ${CYGNAME}-${MAJOR}.dll ${OBJECTS} ${DEPS}
+            ${LINK} ${OPTS} ${LDFLAGS} -o ${CYGNAME}-${MAJOR}.dll ${OBJECTS} ${DEPS}
             # make usual symlinks
             ln -s ${LIBNAME}-${MAJOR}.dll.a ${LIBNAME}.dll.a
             # finish up
index 8d24e31..033d7a4 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
+ * Copyright 2007-2008 Red Hat, Inc.
  * (C) Copyright IBM Corporation 2004
  * All Rights Reserved.
  *
  * 
  * \author Kevin E. Martin <kevin@precisioninsight.com>
  * \author Ian Romanick <idr@us.ibm.com>
+ * \author Kristian Høgsberg <krh@redhat.com>
  */
 
 #ifndef DRI_INTERFACE_H
 #define DRI_INTERFACE_H
 
-#include <GL/internal/glcore.h>
 #include <drm.h>
 
 /**
  * side library and the DRI (direct rendering infrastructure).
  */
 /*@{*/
-typedef struct __DRIdisplayRec  __DRIdisplay;
-typedef struct __DRIscreenRec   __DRIscreen;
-typedef struct __DRIcontextRec  __DRIcontext;
-typedef struct __DRIdrawableRec __DRIdrawable;
-typedef struct __DRIdriverRec   __DRIdriver;
-typedef struct __DRIframebufferRec __DRIframebuffer;
-typedef struct __DRIversionRec     __DRIversion;
-typedef struct __DRIinterfaceMethodsRec  __DRIinterfaceMethods;
-typedef unsigned long __DRIid;
-typedef void __DRInativeDisplay;
+typedef struct __DRIdisplayRec         __DRIdisplay;
+typedef struct __DRIscreenRec          __DRIscreen;
+typedef struct __DRIcontextRec         __DRIcontext;
+typedef struct __DRIdrawableRec                __DRIdrawable;
+typedef struct __DRIconfigRec          __DRIconfig;
+typedef struct __DRIframebufferRec     __DRIframebuffer;
+typedef struct __DRIversionRec         __DRIversion;
+
+typedef struct __DRIcoreExtensionRec           __DRIcoreExtension;
+typedef struct __DRIextensionRec               __DRIextension;
+typedef struct __DRIcopySubBufferExtensionRec  __DRIcopySubBufferExtension;
+typedef struct __DRIswapControlExtensionRec    __DRIswapControlExtension;
+typedef struct __DRIallocateExtensionRec       __DRIallocateExtension;
+typedef struct __DRIframeTrackingExtensionRec  __DRIframeTrackingExtension;
+typedef struct __DRImediaStreamCounterExtensionRec     __DRImediaStreamCounterExtension;
+typedef struct __DRItexOffsetExtensionRec      __DRItexOffsetExtension;
+typedef struct __DRItexBufferExtensionRec      __DRItexBufferExtension;
+typedef struct __DRIlegacyExtensionRec         __DRIlegacyExtension;
+typedef struct __DRIswrastExtensionRec         __DRIswrastExtension;
 /*@}*/
 
 
 /**
- * \name Functions provided by the driver loader.
- */
-/*@{*/
-/**
- * Type of a pointer to \c glXGetScreenDriver, as returned by
- * \c glXGetProcAddress.  This function is used to get the name of the DRI
- * driver for the specified screen of the specified display.  The driver
- * name is typically used with \c glXGetDriverConfig.
+ * Extension struct.  Drivers 'inherit' from this struct by embedding
+ * it as the first element in the extension struct.
  *
- * \sa glXGetScreenDriver, glXGetProcAddress, glXGetDriverConfig
+ * We never break API in for a DRI extension.  If we need to change
+ * the way things work in a non-backwards compatible manner, we
+ * introduce a new extension.  During a transition period, we can
+ * leave both the old and the new extension in the driver, which
+ * allows us to move to the new interface without having to update the
+ * loader(s) in lock step.
+ *
+ * However, we can add entry points to an extension over time as long
+ * as we don't break the old ones.  As we add entry points to an
+ * extension, we increase the version number.  The corresponding
+ * #define can be used to guard code that accesses the new entry
+ * points at compile time and the version field in the extension
+ * struct can be used at run-time to determine how to use the
+ * extension.
  */
-typedef const char * (* PFNGLXGETSCREENDRIVERPROC) (__DRInativeDisplay *dpy, int scrNum);
+struct __DRIextensionRec {
+    const char *name;
+    int version;
+};
 
 /**
- * Type of a pointer to \c glXGetDriverConfig, as returned by
- * \c glXGetProcAddress.  This function is used to get the XML document
- * describing the configuration options available for the specified driver.
- *
- * \sa glXGetDriverConfig, glXGetProcAddress, glXGetScreenDriver
+ * The first set of extension are the screen extensions, returned by
+ * __DRIcore::getExtensions().  This entry point will return a list of
+ * extensions and the loader can use the ones it knows about by
+ * casting them to more specific extensions and advertising any GLX
+ * extensions the DRI extensions enables.
  */
-typedef const char * (* PFNGLXGETDRIVERCONFIGPROC) (const char *driverName);
 
 /**
- * Type of a pointer to \c glxEnableExtension, as returned by
- * \c __DRIinterfaceMethods::getProcAddress.  This function is used to enable
- * a GLX extension on the specified screen.
+ * Used by drivers to indicate support for setting the read drawable.
  */
-typedef void (* PFNGLXSCRENABLEEXTENSIONPROC) ( void *psc, const char * name );
-/*@}*/
-
+#define __DRI_READ_DRAWABLE "DRI_ReadDrawable"
+#define __DRI_READ_DRAWABLE_VERSION 1
 
 /**
- * \name Functions and data provided by the driver.
+ * Used by drivers that implement the GLX_MESA_copy_sub_buffer extension.
  */
-/*@{*/
-
-typedef void *(CREATENEWSCREENFUNC)(__DRInativeDisplay *dpy, int scrn,
-    __DRIscreen *psc, const __GLcontextModes * modes,
-    const __DRIversion * ddx_version, const __DRIversion * dri_version,
-    const __DRIversion * drm_version, const __DRIframebuffer * frame_buffer,
-    void * pSAREA, int fd, int internal_api_version,
-    const __DRIinterfaceMethods * interface,
-    __GLcontextModes ** driver_modes);
-typedef CREATENEWSCREENFUNC* PFNCREATENEWSCREENFUNC;
-extern CREATENEWSCREENFUNC __driCreateNewScreen_20050727;
-
+#define __DRI_COPY_SUB_BUFFER "DRI_CopySubBuffer"
+#define __DRI_COPY_SUB_BUFFER_VERSION 1
+struct __DRIcopySubBufferExtensionRec {
+    __DRIextension base;
+    void (*copySubBuffer)(__DRIdrawable *drawable, int x, int y, int w, int h);
+};
 
 /**
- * XML document describing the configuration options supported by the
- * driver.
+ * Used by drivers that implement the GLX_SGI_swap_control or
+ * GLX_MESA_swap_control extension.
  */
-extern const char __driConfigOptions[];
-
-/*@}*/
-
+#define __DRI_SWAP_CONTROL "DRI_SwapControl"
+#define __DRI_SWAP_CONTROL_VERSION 1
+struct __DRIswapControlExtensionRec {
+    __DRIextension base;
+    void (*setSwapInterval)(__DRIdrawable *drawable, unsigned int inteval);
+    unsigned int (*getSwapInterval)(__DRIdrawable *drawable);
+};
 
 /**
- * Stored version of some component (i.e., server-side DRI module, kernel-side
- * DRM, etc.).
- * 
- * \todo
- * There are several data structures that explicitly store a major version,
- * minor version, and patch level.  These structures should be modified to
- * have a \c __DRIversionRec instead.
+ * Used by drivers that implement the GLX_MESA_allocate_memory.
  */
-struct __DRIversionRec {
-    int    major;        /**< Major version number. */
-    int    minor;        /**< Minor version number. */
-    int    patch;        /**< Patch-level. */
-};
+#define __DRI_ALLOCATE "DRI_Allocate"
+#define __DRI_ALLOCATE_VERSION 1
+struct __DRIallocateExtensionRec {
+    __DRIextension base;
 
+    void *(*allocateMemory)(__DRIscreen *screen, GLsizei size,
+                           GLfloat readfreq, GLfloat writefreq,
+                           GLfloat priority);
+   
+    void (*freeMemory)(__DRIscreen *screen, GLvoid *pointer);
+   
+    GLuint (*memoryOffset)(__DRIscreen *screen, const GLvoid *pointer);
+};
 
-typedef void (*__DRIfuncPtr)(void);
+/**
+ * Used by drivers that implement the GLX_MESA_swap_frame_usage extension.
+ */
+#define __DRI_FRAME_TRACKING "DRI_FrameTracking"
+#define __DRI_FRAME_TRACKING_VERSION 1
+struct __DRIframeTrackingExtensionRec {
+    __DRIextension base;
 
-struct __DRIinterfaceMethodsRec {
     /**
-     * Get pointer to named function.
+     * Enable or disable frame usage tracking.
+     * 
+     * \since Internal API version 20030317.
      */
-    __DRIfuncPtr (*getProcAddress)( const char * proc_name );
+    int (*frameTracking)(__DRIdrawable *drawable, GLboolean enable);
 
     /**
-     * Create a list of \c __GLcontextModes structures.
+     * Retrieve frame usage information.
+     * 
+     * \since Internal API version 20030317.
      */
-    __GLcontextModes * (*createContextModes)(unsigned count,
-        size_t minimum_bytes_per_struct);
+    int (*queryFrameTracking)(__DRIdrawable *drawable,
+                             int64_t * sbc, int64_t * missedFrames,
+                             float * lastMissedUsage, float * usage);
+};
+
+
+/**
+ * Used by drivers that implement the GLX_SGI_video_sync extension.
+ */
+#define __DRI_MEDIA_STREAM_COUNTER "DRI_MediaStreamCounter"
+#define __DRI_MEDIA_STREAM_COUNTER_VERSION 1
+struct __DRImediaStreamCounterExtensionRec {
+    __DRIextension base;
 
     /**
-     * Destroy a list of \c __GLcontextModes structures.
-     *
-     * \todo
-     * Determine if the drivers actually need to call this.
+     * Wait for the MSC to equal target_msc, or, if that has already passed,
+     * the next time (MSC % divisor) is equal to remainder.  If divisor is
+     * zero, the function will return as soon as MSC is greater than or equal
+     * to target_msc.
      */
-    void (*destroyContextModes)( __GLcontextModes * modes );
+    int (*waitForMSC)(__DRIdrawable *drawable,
+                     int64_t target_msc, int64_t divisor, int64_t remainder,
+                     int64_t * msc, int64_t * sbc);
 
     /**
-     * Get the \c __DRIscreen for a given display and screen number.
+     * Get the number of vertical refreshes since some point in time before
+     * this function was first called (i.e., system start up).
      */
-    __DRIscreen *(*getScreen)(__DRInativeDisplay *dpy, int screenNum);
+    int (*getDrawableMSC)(__DRIscreen *screen, __DRIdrawable *drawable,
+                         int64_t *msc);
+};
+
 
+#define __DRI_TEX_OFFSET "DRI_TexOffset"
+#define __DRI_TEX_OFFSET_VERSION 1
+struct __DRItexOffsetExtensionRec {
+    __DRIextension base;
 
     /**
-     * \name Client/server protocol functions.
+     * Method to override base texture image with a driver specific 'offset'.
+     * The depth passed in allows e.g. to ignore the alpha channel of texture
+     * images where the non-alpha components don't occupy a whole texel.
      *
-     * These functions implement the DRI client/server protocol for
-     * context and drawable operations.  Platforms that do not implement
-     * the wire protocol (e.g., EGL) will implement glorified no-op functions.
-     */
-    /*@{*/
-    /**
-     * Determine if the specified window ID still exists.
-     * 
-     * \note
-     * Implementations may assume that the driver will only pass an ID into
-     * this function that actually corresponds to a window.  On
-     * implementations where windows can only be destroyed by the DRI driver
-     * (e.g., EGL), this function is allowed to always return \c GL_TRUE.
+     * For GLX_EXT_texture_from_pixmap with AIGLX.
      */
-    GLboolean (*windowExists)(__DRInativeDisplay *dpy, __DRIid draw);
+    void (*setTexOffset)(__DRIcontext *pDRICtx, GLint texname,
+                        unsigned long long offset, GLint depth, GLuint pitch);
+};
 
-    /**
-     * Create the server-side portion of the GL context.
-     */
-    GLboolean (* createContext)( __DRInativeDisplay *dpy, int screenNum,
-        int configID, void * contextID, drm_context_t * hw_context );
 
-    /**
-     * Destroy the server-side portion of the GL context.
-     */
-    GLboolean (* destroyContext)( __DRInativeDisplay *dpy, int screenNum,
-        __DRIid context );
+#define __DRI_TEX_BUFFER "DRI_TexBuffer"
+#define __DRI_TEX_BUFFER_VERSION 1
+struct __DRItexBufferExtensionRec {
+    __DRIextension base;
 
     /**
-     * Create the server-side portion of the drawable.
+     * Method to override base texture image with the contents of a
+     * __DRIdrawable. 
+     *
+     * For GLX_EXT_texture_from_pixmap with AIGLX.
      */
-    GLboolean (*createDrawable)( __DRInativeDisplay * ndpy, int screen,
-        __DRIid drawable, drm_drawable_t * hHWDrawable );
+    void (*setTexBuffer)(__DRIcontext *pDRICtx,
+                        GLint target,
+                        __DRIdrawable *pDraw);
+};
 
-    /**
-     * Destroy the server-side portion of the drawable.
-     */
-    GLboolean (*destroyDrawable)( __DRInativeDisplay * ndpy, int screen,
-        __DRIid drawable );
+
+/**
+ * XML document describing the configuration options supported by the
+ * driver.
+ */
+extern const char __driConfigOptions[];
+
+/*@}*/
+
+/**
+ * The following extensions describe loader features that the DRI
+ * driver can make use of.  Some of these are mandatory, such as the
+ * getDrawableInfo extension for DRI and the DRI Loader extensions for
+ * DRI2, while others are optional, and if present allow the driver to
+ * expose certain features.  The loader pass in a NULL terminated
+ * array of these extensions to the driver in the createNewScreen
+ * constructor.
+ */
+
+typedef struct __DRIgetDrawableInfoExtensionRec __DRIgetDrawableInfoExtension;
+typedef struct __DRIsystemTimeExtensionRec __DRIsystemTimeExtension;
+typedef struct __DRIdamageExtensionRec __DRIdamageExtension;
+typedef struct __DRIloaderExtensionRec __DRIloaderExtension;
+typedef struct __DRIswrastLoaderExtensionRec __DRIswrastLoaderExtension;
+
+
+/**
+ * Callback to getDrawableInfo protocol
+ */
+#define __DRI_GET_DRAWABLE_INFO "DRI_GetDrawableInfo"
+#define __DRI_GET_DRAWABLE_INFO_VERSION 1
+struct __DRIgetDrawableInfoExtensionRec {
+    __DRIextension base;
 
     /**
      * This function is used to get information about the position, size, and
      * clip rects of a drawable.
      */
-    GLboolean (* getDrawableInfo) ( __DRInativeDisplay *dpy, int scrn,
-        __DRIid draw, unsigned int * index, unsigned int * stamp,
+    GLboolean (* getDrawableInfo) ( __DRIdrawable *drawable,
+       unsigned int * index, unsigned int * stamp,
         int * x, int * y, int * width, int * height,
         int * numClipRects, drm_clip_rect_t ** pClipRects,
         int * backX, int * backY,
-        int * numBackClipRects, drm_clip_rect_t ** pBackClipRects );
-    /*@}*/
+       int * numBackClipRects, drm_clip_rect_t ** pBackClipRects,
+       void *loaderPrivate);
+};
 
+/**
+ * Callback to get system time for media stream counter extensions.
+ */
+#define __DRI_SYSTEM_TIME "DRI_SystemTime"
+#define __DRI_SYSTEM_TIME_VERSION 1
+struct __DRIsystemTimeExtensionRec {
+    __DRIextension base;
 
     /**
-     * \name Timing related functions.
-     */
-    /*@{*/
-    /**
      * Get the 64-bit unadjusted system time (UST).
      */
     int (*getUST)(int64_t * ust);
@@ -234,9 +301,18 @@ struct __DRIinterfaceMethodsRec {
      * the rate of the "media stream counter".  In practical terms, this is
      * the frame refresh rate of the display.
      */
-    GLboolean (*getMSCRate)(__DRInativeDisplay * dpy, __DRIid drawable,
-        int32_t * numerator, int32_t * denominator);
-    /*@}*/
+    GLboolean (*getMSCRate)(__DRIdrawable *draw,
+                           int32_t * numerator, int32_t * denominator,
+                           void *loaderPrivate);
+};
+
+/**
+ * Damage reporting
+ */
+#define __DRI_DAMAGE "DRI_Damage"
+#define __DRI_DAMAGE_VERSION 1
+struct __DRIdamageExtensionRec {
+    __DRIextension base;
 
     /**
      * Reports areas of the given drawable which have been modified by the
@@ -251,15 +327,221 @@ struct __DRIinterfaceMethodsRec {
      * \param front_buffer boolean flag for whether the drawing to the
      *               drawable was actually done directly to the front buffer (instead
      *       of backing storage, for example)
+     * \param loaderPrivate the data passed in at createNewDrawable time
      */
-    void (*reportDamage)(__DRInativeDisplay * dpy, int screen,
-                        __DRIid drawable,
+    void (*reportDamage)(__DRIdrawable *draw,
                         int x, int y,
                         drm_clip_rect_t *rects, int num_rects,
-                        int front_buffer);
+                        GLboolean front_buffer,
+                        void *loaderPrivate);
+};
+
+/**
+ * DRI2 Loader extension.  This extension describes the basic
+ * functionality the loader needs to provide for the DRI driver.
+ */
+#define __DRI_LOADER "DRI_Loader"
+#define __DRI_LOADER_VERSION 1
+struct __DRIloaderExtensionRec {
+    __DRIextension base;
+
+    /**
+     * Ping the windowing system to get it to reemit info for the
+     * specified drawable in the DRI2 event buffer.
+     *
+     * \param draw the drawable for which to request info
+     * \param tail the new event buffer tail pointer
+     */
+    void (*reemitDrawableInfo)(__DRIdrawable *draw, unsigned int *tail,
+                              void *loaderPrivate);
+
+    void (*postDamage)(__DRIdrawable *draw, struct drm_clip_rect *rects,
+                      int num_rects, void *loaderPrivate);
+};
+
+#define __DRI_SWRAST_IMAGE_OP_DRAW     1
+#define __DRI_SWRAST_IMAGE_OP_CLEAR    2
+#define __DRI_SWRAST_IMAGE_OP_SWAP     3
+
+/**
+ * SWRast Loader extension.
+ */
+#define __DRI_SWRAST_LOADER "DRI_SWRastLoader"
+#define __DRI_SWRAST_LOADER_VERSION 1
+struct __DRIswrastLoaderExtensionRec {
+    __DRIextension base;
+
+    /*
+     * Drawable position and size
+     */
+    void (*getDrawableInfo)(__DRIdrawable *drawable,
+                           int *x, int *y, int *width, int *height,
+                           void *loaderPrivate);
+
+    /**
+     * Put image to drawable
+     */
+    void (*putImage)(__DRIdrawable *drawable, int op,
+                    int x, int y, int width, int height, char *data,
+                    void *loaderPrivate);
+
+    /**
+     * Get image from drawable
+     */
+    void (*getImage)(__DRIdrawable *drawable,
+                    int x, int y, int width, int height, char *data,
+                    void *loaderPrivate);
+};
+
+/**
+ * The remaining extensions describe driver extensions, immediately
+ * available interfaces provided by the driver.  To start using the
+ * driver, dlsym() for the __DRI_DRIVER_EXTENSIONS symbol and look for
+ * the extension you need in the array.
+ */
+#define __DRI_DRIVER_EXTENSIONS "__driDriverExtensions"
+
+/**
+ * Tokens for __DRIconfig attribs.  A number of attributes defined by
+ * GLX or EGL standards are not in the table, as they must be provided
+ * by the loader.  For example, FBConfig ID or visual ID, drawable type.
+ */
+
+#define __DRI_ATTRIB_BUFFER_SIZE                1
+#define __DRI_ATTRIB_LEVEL                      2
+#define __DRI_ATTRIB_RED_SIZE                   3
+#define __DRI_ATTRIB_GREEN_SIZE                         4
+#define __DRI_ATTRIB_BLUE_SIZE                  5
+#define __DRI_ATTRIB_LUMINANCE_SIZE             6
+#define __DRI_ATTRIB_ALPHA_SIZE                         7
+#define __DRI_ATTRIB_ALPHA_MASK_SIZE            8
+#define __DRI_ATTRIB_DEPTH_SIZE                         9
+#define __DRI_ATTRIB_STENCIL_SIZE              10
+#define __DRI_ATTRIB_ACCUM_RED_SIZE            11
+#define __DRI_ATTRIB_ACCUM_GREEN_SIZE          12
+#define __DRI_ATTRIB_ACCUM_BLUE_SIZE           13
+#define __DRI_ATTRIB_ACCUM_ALPHA_SIZE          14
+#define __DRI_ATTRIB_SAMPLE_BUFFERS            15
+#define __DRI_ATTRIB_SAMPLES                   16
+#define __DRI_ATTRIB_RENDER_TYPE               17
+#define __DRI_ATTRIB_CONFIG_CAVEAT             18
+#define __DRI_ATTRIB_CONFORMANT                        19
+#define __DRI_ATTRIB_DOUBLE_BUFFER             20
+#define __DRI_ATTRIB_STEREO                    21
+#define __DRI_ATTRIB_AUX_BUFFERS               22
+#define __DRI_ATTRIB_TRANSPARENT_TYPE          23
+#define __DRI_ATTRIB_TRANSPARENT_INDEX_VALUE   24
+#define __DRI_ATTRIB_TRANSPARENT_RED_VALUE     25
+#define __DRI_ATTRIB_TRANSPARENT_GREEN_VALUE   26
+#define __DRI_ATTRIB_TRANSPARENT_BLUE_VALUE    27
+#define __DRI_ATTRIB_TRANSPARENT_ALPHA_VALUE   28
+#define __DRI_ATTRIB_FLOAT_MODE                        29
+#define __DRI_ATTRIB_RED_MASK                  30
+#define __DRI_ATTRIB_GREEN_MASK                        31
+#define __DRI_ATTRIB_BLUE_MASK                 32
+#define __DRI_ATTRIB_ALPHA_MASK                        33
+#define __DRI_ATTRIB_MAX_PBUFFER_WIDTH         34
+#define __DRI_ATTRIB_MAX_PBUFFER_HEIGHT                35
+#define __DRI_ATTRIB_MAX_PBUFFER_PIXELS                36
+#define __DRI_ATTRIB_OPTIMAL_PBUFFER_WIDTH     37
+#define __DRI_ATTRIB_OPTIMAL_PBUFFER_HEIGHT    38
+#define __DRI_ATTRIB_VISUAL_SELECT_GROUP       39
+#define __DRI_ATTRIB_SWAP_METHOD               40
+#define __DRI_ATTRIB_MAX_SWAP_INTERVAL         41
+#define __DRI_ATTRIB_MIN_SWAP_INTERVAL         42
+#define __DRI_ATTRIB_BIND_TO_TEXTURE_RGB       43
+#define __DRI_ATTRIB_BIND_TO_TEXTURE_RGBA      44
+#define __DRI_ATTRIB_BIND_TO_MIPMAP_TEXTURE    45
+#define __DRI_ATTRIB_BIND_TO_TEXTURE_TARGETS   46
+#define __DRI_ATTRIB_YINVERTED                 47
+
+/* __DRI_ATTRIB_RENDER_TYPE */
+#define __DRI_ATTRIB_RGBA_BIT                  0x01    
+#define __DRI_ATTRIB_COLOR_INDEX_BIT           0x02
+#define __DRI_ATTRIB_LUMINANCE_BIT             0x04
+
+/* __DRI_ATTRIB_CONFIG_CAVEAT */
+#define __DRI_ATTRIB_SLOW_BIT                  0x01
+#define __DRI_ATTRIB_NON_CONFORMANT_CONFIG     0x02
+
+/* __DRI_ATTRIB_TRANSPARENT_TYPE */
+#define __DRI_ATTRIB_TRANSPARENT_RGB           0x00
+#define __DRI_ATTRIB_TRANSPARENT_INDEX         0x01
+
+/* __DRI_ATTRIB_BIND_TO_TEXTURE_TARGETS         */
+#define __DRI_ATTRIB_TEXTURE_1D_BIT            0x01
+#define __DRI_ATTRIB_TEXTURE_2D_BIT            0x02
+#define __DRI_ATTRIB_TEXTURE_RECTANGLE_BIT     0x04
+
+/**
+ * This extension defines the core DRI functionality.
+ */
+#define __DRI_CORE "DRI_Core"
+#define __DRI_CORE_VERSION 1
+
+struct __DRIcoreExtensionRec {
+    __DRIextension base;
+
+    __DRIscreen *(*createNewScreen)(int screen, int fd,
+                                   unsigned int sarea_handle,
+                                   const __DRIextension **extensions,
+                                   const __DRIconfig ***driverConfigs,
+                                   void *loaderPrivate);
+
+    void (*destroyScreen)(__DRIscreen *screen);
+
+    const __DRIextension **(*getExtensions)(__DRIscreen *screen);
+
+    int (*getConfigAttrib)(const __DRIconfig *config,
+                          unsigned int attrib,
+                          unsigned int *value);
+
+    int (*indexConfigAttrib)(const __DRIconfig *config, int index,
+                            unsigned int *attrib, unsigned int *value);
+
+    __DRIdrawable *(*createNewDrawable)(__DRIscreen *screen,
+                                       const __DRIconfig *config,
+                                       unsigned int drawable_id,
+                                       unsigned int head,
+                                       void *loaderPrivate);
+
+    void (*destroyDrawable)(__DRIdrawable *drawable);
+
+    void (*swapBuffers)(__DRIdrawable *drawable);
+
+    __DRIcontext *(*createNewContext)(__DRIscreen *screen,
+                                     const __DRIconfig *config,
+                                     __DRIcontext *shared,
+                                     void *loaderPrivate);
+
+    int (*copyContext)(__DRIcontext *dest,
+                      __DRIcontext *src,
+                      unsigned long mask);
+
+    void (*destroyContext)(__DRIcontext *context);
+
+    int (*bindContext)(__DRIcontext *ctx,
+                      __DRIdrawable *pdraw,
+                      __DRIdrawable *pread);
+
+    int (*unbindContext)(__DRIcontext *ctx);
+};
+
+/**
+ * Stored version of some component (i.e., server-side DRI module, kernel-side
+ * DRM, etc.).
+ * 
+ * \todo
+ * There are several data structures that explicitly store a major version,
+ * minor version, and patch level.  These structures should be modified to
+ * have a \c __DRIversionRec instead.
+ */
+struct __DRIversionRec {
+    int    major;        /**< Major version number. */
+    int    minor;        /**< Minor version number. */
+    int    patch;        /**< Patch-level. */
 };
 
-   
 /**
  * Framebuffer information record.  Used by libGL to communicate information
  * about the framebuffer to the driver's \c __driCreateNewScreen function.
@@ -289,229 +571,59 @@ struct __DRIframebufferRec {
 
 
 /**
- * Screen dependent methods.  This structure is initialized during the
- * \c __DRIdisplayRec::createScreen call.
+ * This extension provides alternative screen, drawable and context
+ * constructors for legacy DRI functionality.  This is used in
+ * conjunction with the core extension.
  */
-struct __DRIscreenRec {
-    /**
-     * Method to destroy the private DRI screen data.
-     */
-    void (*destroyScreen)(__DRInativeDisplay *dpy, int scrn, void *screenPrivate);
-
-    /**
-     * Method to create the private DRI drawable data and initialize the
-     * drawable dependent methods.
-     */
-    void *(*createNewDrawable)(__DRInativeDisplay *dpy, const __GLcontextModes *modes,
-                              __DRIid draw, __DRIdrawable *pdraw,
-                              int renderType, const int *attrs);
-
-    /**
-     * Method to return a pointer to the DRI drawable data.
-     */
-    __DRIdrawable *(*getDrawable)(__DRInativeDisplay *dpy, __DRIid draw,
-                                 void *drawablePrivate);
-
-    /**
-     * Opaque pointer to private per screen direct rendering data.  \c NULL
-     * if direct rendering is not supported on this screen.  Never
-     * dereferenced in libGL.
-     */
-    void *private;
-
-    /**
-     * Get the number of vertical refreshes since some point in time before
-     * this function was first called (i.e., system start up).
-     * 
-     * \since Internal API version 20030317.
-     */
-    int (*getMSC)( void *screenPrivate, int64_t *msc );
-
-    /**
-     * Opaque pointer that points back to the containing 
-     * \c __GLXscreenConfigs.  This data structure is shared with DRI drivers
-     * but \c __GLXscreenConfigs is not. However, they are needed by some GLX
-     * functions called by DRI drivers.
-     *
-     * \since Internal API version 20030813.
-     */
-    void *screenConfigs;
-
-    /**
-     * Functions associated with MESA_allocate_memory.
-     *
-     * \since Internal API version 20030815.
-     */
-    /*@{*/
-    void *(*allocateMemory)(__DRInativeDisplay *dpy, int scrn, GLsizei size,
-                           GLfloat readfreq, GLfloat writefreq,
-                           GLfloat priority);
-   
-    void (*freeMemory)(__DRInativeDisplay *dpy, int scrn, GLvoid *pointer);
-   
-    GLuint (*memoryOffset)(__DRInativeDisplay *dpy, int scrn, const GLvoid *pointer);
-    /*@}*/
-
-    /**
-     * Method to create the private DRI context data and initialize the
-     * context dependent methods.
-     *
-     * \since Internal API version 20031201.
-     */
-    void * (*createNewContext)(__DRInativeDisplay *dpy, const __GLcontextModes *modes,
-                              int render_type,
-                              void *sharedPrivate, __DRIcontext *pctx);
-
-    /**
-     * Method to override base texture image with a driver specific 'offset'.
-     * The depth passed in allows e.g. to ignore the alpha channel of texture
-     * images where the non-alpha components don't occupy a whole texel.
-     *
-     * For GLX_EXT_texture_from_pixmap with AIGLX.
-     *
-     * \since Internal API version 20070121.
-     */
-    void (*setTexOffset)(__DRIcontext *pDRICtx, GLint texname,
-                        unsigned long long offset, GLint depth, GLuint pitch);
+#define __DRI_LEGACY "DRI_Legacy"
+#define __DRI_LEGACY_VERSION 1
+
+struct __DRIlegacyExtensionRec {
+    __DRIextension base;
+
+    __DRIscreen *(*createNewScreen)(int screen,
+                                   const __DRIversion *ddx_version,
+                                   const __DRIversion *dri_version,
+                                   const __DRIversion *drm_version,
+                                   const __DRIframebuffer *frame_buffer,
+                                   void *pSAREA, int fd, 
+                                   const __DRIextension **extensions,
+                                   const __DRIconfig ***driver_configs,
+                                   void *loaderPrivate);
+
+    __DRIdrawable *(*createNewDrawable)(__DRIscreen *screen,
+                                       const __DRIconfig *config,
+                                       drm_drawable_t hwDrawable,
+                                       int renderType, const int *attrs,
+                                       void *loaderPrivate);
+
+    __DRIcontext *(*createNewContext)(__DRIscreen *screen,
+                                     const __DRIconfig *config,
+                                     int render_type,
+                                     __DRIcontext *shared,
+                                     drm_context_t hwContext,
+                                     void *loaderPrivate);
 };
 
 /**
- * Context dependent methods.  This structure is initialized during the
- * \c __DRIscreenRec::createContext call.
+ * This extension provides alternative screen, drawable and context
+ * constructors for swrast DRI functionality.  This is used in
+ * conjunction with the core extension.
  */
-struct __DRIcontextRec {
-    /**
-     * Method to destroy the private DRI context data.
-     */
-    void (*destroyContext)(__DRInativeDisplay *dpy, int scrn, void *contextPrivate);
+#define __DRI_SWRAST "DRI_SWRast"
+#define __DRI_SWRAST_VERSION 1
 
-    /**
-     * Opaque pointer to private per context direct rendering data.
-     * \c NULL if direct rendering is not supported on the display or
-     * screen used to create this context.  Never dereferenced in libGL.
-     */
-    void *private;
-
-    /**
-     * Pointer to the mode used to create this context.
-     *
-     * \since Internal API version 20040317.
-     */
-    const __GLcontextModes * mode;
-
-    /**
-     * Method to bind a DRI drawable to a DRI graphics context.
-     *
-     * \since Internal API version 20050727.
-     */
-    GLboolean (*bindContext)(__DRInativeDisplay *dpy, int scrn, __DRIid draw,
-                        __DRIid read, __DRIcontext *ctx);
-
-    /**
-     * Method to unbind a DRI drawable from a DRI graphics context.
-     *
-     * \since Internal API version 20050727.
-     */
-    GLboolean (*unbindContext)(__DRInativeDisplay *dpy, int scrn, __DRIid draw,
-                          __DRIid read, __DRIcontext *ctx);
-};
-
-/**
- * Drawable dependent methods.  This structure is initialized during the
- * \c __DRIscreenRec::createDrawable call.  \c createDrawable is not called
- * by libGL at this time.  It's currently used via the dri_util.c utility code
- * instead.
- */
-struct __DRIdrawableRec {
-    /**
-     * Method to destroy the private DRI drawable data.
-     */
-    void (*destroyDrawable)(__DRInativeDisplay *dpy, void *drawablePrivate);
-
-    /**
-     * Method to swap the front and back buffers.
-     */
-    void (*swapBuffers)(__DRInativeDisplay *dpy, void *drawablePrivate);
-
-    /**
-     * Opaque pointer to private per drawable direct rendering data.
-     * \c NULL if direct rendering is not supported on the display or
-     * screen used to create this drawable.  Never dereferenced in libGL.
-     */
-    void *private;
-
-    /**
-     * Get the number of completed swap buffers for this drawable.
-     *
-     * \since Internal API version 20030317.
-     */
-    int (*getSBC)(__DRInativeDisplay *dpy, void *drawablePrivate, int64_t *sbc );
-
-    /**
-     * Wait for the SBC to be greater than or equal target_sbc.
-     *
-     * \since Internal API version 20030317.
-     */
-    int (*waitForSBC)( __DRInativeDisplay * dpy, void *drawablePriv,
-                      int64_t target_sbc,
-                      int64_t * msc, int64_t * sbc );
-
-    /**
-     * Wait for the MSC to equal target_msc, or, if that has already passed,
-     * the next time (MSC % divisor) is equal to remainder.  If divisor is
-     * zero, the function will return as soon as MSC is greater than or equal
-     * to target_msc.
-     * 
-     * \since Internal API version 20030317.
-     */
-    int (*waitForMSC)( __DRInativeDisplay * dpy, void *drawablePriv,
-                      int64_t target_msc, int64_t divisor, int64_t remainder,
-                      int64_t * msc, int64_t * sbc );
+struct __DRIswrastExtensionRec {
+    __DRIextension base;
 
-    /**
-     * Like \c swapBuffers, but does NOT have an implicit \c glFlush.  Once
-     * rendering is complete, waits until MSC is equal to target_msc, or
-     * if that has already passed, waits until (MSC % divisor) is equal
-     * to remainder.  If divisor is zero, the swap will happen as soon as
-     * MSC is greater than or equal to target_msc.
-     * 
-     * \since Internal API version 20030317.
-     */
-    int64_t (*swapBuffersMSC)(__DRInativeDisplay *dpy, void *drawablePrivate,
-                             int64_t target_msc,
-                             int64_t divisor, int64_t remainder);
+    __DRIscreen *(*createNewScreen)(int screen,
+                                   const __DRIextension **extensions,
+                                   const __DRIconfig ***driver_configs,
+                                   void *loaderPrivate);
 
-    /**
-     * Enable or disable frame usage tracking.
-     * 
-     * \since Internal API version 20030317.
-     */
-    int (*frameTracking)(__DRInativeDisplay *dpy, void *drawablePrivate, GLboolean enable);
-
-    /**
-     * Retrieve frame usage information.
-     * 
-     * \since Internal API version 20030317.
-     */
-    int (*queryFrameTracking)(__DRInativeDisplay *dpy, void *drawablePrivate,
-                             int64_t * sbc, int64_t * missedFrames,
-                             float * lastMissedUsage, float * usage );
-
-    /**
-     * Used by drivers that implement the GLX_SGI_swap_control or
-     * GLX_MESA_swap_control extension.
-     *
-     * \since Internal API version 20030317.
-     */
-    unsigned swap_interval;
-
-    /**
-     * Used by drivers that implement the GLX_MESA_copy_sub_buffer extension.
-     *
-     * \since Internal API version 20060314.
-     */
-    void (*copySubBuffer)(__DRInativeDisplay *dpy, void *drawablePrivate,
-                         int x, int y, int w, int h);
+    __DRIdrawable *(*createNewDrawable)(__DRIscreen *screen,
+                                       const __DRIconfig *config,
+                                       void *loaderPrivate);
 };
 
 #endif
index fc0aaf3..1bb63c1 100644 (file)
@@ -41,6 +41,7 @@
 #define GL_CORE_SGI  1
 #define GL_CORE_MESA 2
 #define GL_CORE_APPLE 4
+#define GL_CORE_WINDOWS 8
 
 typedef struct __GLcontextRec __GLcontext;
 
index 8284e0e..ecc4b0a 100644 (file)
@@ -67,7 +67,6 @@ int __intel_debug = 0;
 #define need_GL_NV_vertex_program
 #include "extension_helper.h"
 
-
 /**
  * Extension strings exported by the intel driver.
  *
@@ -75,7 +74,7 @@ int __intel_debug = 0;
  * It appears that ARB_texture_env_crossbar has "disappeared" compared to the
  * old i830-specific driver.
  */
-const struct dri_extension card_extensions[] = {
+static const struct dri_extension card_extensions[] = {
    {"GL_ARB_multisample", GL_ARB_multisample_functions},
    {"GL_ARB_multitexture", NULL},
    {"GL_ARB_point_parameters", GL_ARB_point_parameters_functions},
@@ -86,22 +85,27 @@ const struct dri_extension card_extensions[] = {
    {"GL_ARB_texture_env_combine", NULL},
    {"GL_ARB_texture_env_dot3", NULL},
    {"GL_ARB_texture_mirrored_repeat", NULL},
+   {"GL_ARB_texture_non_power_of_two",   NULL },
    {"GL_ARB_texture_rectangle", NULL},
+   {"GL_NV_texture_rectangle", NULL},
+   {"GL_EXT_texture_rectangle", NULL},
+   {"GL_ARB_point_parameters", NULL}, 
    {"GL_ARB_vertex_buffer_object", GL_ARB_vertex_buffer_object_functions},
-   {"GL_ARB_pixel_buffer_object", NULL},
    {"GL_ARB_vertex_program", GL_ARB_vertex_program_functions},
    {"GL_ARB_window_pos", GL_ARB_window_pos_functions},
    {"GL_EXT_blend_color", GL_EXT_blend_color_functions},
-   {"GL_EXT_blend_equation_separate", GL_EXT_blend_equation_separate_functions},
+   {"GL_EXT_blend_equation_separate",
+    GL_EXT_blend_equation_separate_functions},
    {"GL_EXT_blend_func_separate", GL_EXT_blend_func_separate_functions},
    {"GL_EXT_blend_minmax", GL_EXT_blend_minmax_functions},
+   {"GL_EXT_blend_logic_op", NULL},
    {"GL_EXT_blend_subtract", NULL},
    {"GL_EXT_cull_vertex", GL_EXT_cull_vertex_functions},
    {"GL_EXT_fog_coord", GL_EXT_fog_coord_functions},
-   {"GL_EXT_framebuffer_object", GL_EXT_framebuffer_object_functions},
    {"GL_EXT_multi_draw_arrays", GL_EXT_multi_draw_arrays_functions},
+#if 1                           /* XXX FBO temporary? */
    {"GL_EXT_packed_depth_stencil", NULL},
-   {"GL_EXT_pixel_buffer_object", NULL},
+#endif
    {"GL_EXT_secondary_color", GL_EXT_secondary_color_functions},
    {"GL_EXT_stencil_wrap", NULL},
    {"GL_EXT_texture_edge_clamp", NULL},
@@ -116,10 +120,67 @@ const struct dri_extension card_extensions[] = {
    {"GL_NV_blend_square", NULL},
    {"GL_NV_vertex_program", GL_NV_vertex_program_functions},
    {"GL_NV_vertex_program1_1", NULL},
-   {"GL_SGIS_generate_mipmap", NULL },
+   { "GL_SGIS_generate_mipmap", NULL },
    {NULL, NULL}
 };
 
+#if 0
+static const struct dri_extension brw_extensions[] = {
+   { "GL_ARB_shading_language_100",       GL_VERSION_2_0_functions},
+   { "GL_ARB_shading_language_120",       GL_VERSION_2_1_functions},
+   { "GL_ARB_shader_objects",             GL_ARB_shader_objects_functions},
+   { "GL_ARB_vertex_shader",              GL_ARB_vertex_shader_functions},
+   { "GL_ARB_point_sprite",              NULL},
+   { "GL_ARB_fragment_shader",            NULL },
+   { "GL_ARB_draw_buffers",               NULL },
+   { "GL_ARB_depth_texture",              NULL },
+   { "GL_ARB_fragment_program",           NULL },
+   { "GL_ARB_shadow",                     NULL },
+   { "GL_EXT_shadow_funcs",               NULL },
+   /* ARB extn won't work if not enabled */
+   { "GL_SGIX_depth_texture",             NULL },
+   { "GL_ARB_texture_env_crossbar",       NULL },
+   { "GL_EXT_texture_sRGB",              NULL},
+   { NULL,                                NULL }
+};
+
+static const struct dri_extension arb_oc_extensions[] = {
+   {"GL_ARB_occlusion_query",            GL_ARB_occlusion_query_functions},
+   {NULL, NULL}
+};
+
+static const struct dri_extension ttm_extensions[] = {
+   {"GL_EXT_framebuffer_object", GL_EXT_framebuffer_object_functions},
+   {"GL_ARB_pixel_buffer_object", NULL},
+   {NULL, NULL}
+};
+#endif
+
+/**
+ * Initializes potential list of extensions if ctx == NULL, or actually enables
+ * extensions for a context.
+ */
+void intelInitExtensions(GLcontext *ctx, GLboolean enable_imaging)
+{
+   /* Disable imaging extension until convolution is working in teximage paths.
+    */
+   enable_imaging = GL_FALSE;
+
+   driInitExtensions(ctx, card_extensions, enable_imaging);
+
+#if 0
+   if (intel == NULL || intel->ttm)
+      driInitExtensions(ctx, ttm_extensions, GL_FALSE);
+
+   if (intel == NULL || 
+       (IS_965(intel->intelScreen->deviceID) && 
+       intel->intelScreen->drmMinor >= 8))
+      driInitExtensions(ctx, arb_oc_extensions, GL_FALSE);
+
+   if (intel == NULL || IS_965(intel->intelScreen->deviceID))
+      driInitExtensions(ctx, brw_extensions, GL_FALSE);
+#endif
+}
 
 
 #ifdef DEBUG
@@ -204,10 +265,10 @@ intelCreateContext(const __GLcontextModes * visual,
    /*
     * memory pools
     */
-   DRM_LIGHT_LOCK(sPriv->fd, &sPriv->pSAREA->lock, driContextPriv->hHWContext);
+   DRM_LIGHT_LOCK(sPriv->fd, &sPriv->lock, driContextPriv->hHWContext);
    // ZZZ JB should be per screen and not be done per context
    havePools = intelCreatePools(sPriv);
-   DRM_UNLOCK(sPriv->fd, &sPriv->pSAREA->lock, driContextPriv->hHWContext);
+   DRM_UNLOCK(sPriv->fd, &sPriv->lock, driContextPriv->hHWContext);
    if (!havePools)
       return GL_FALSE;
 
@@ -215,7 +276,7 @@ intelCreateContext(const __GLcontextModes * visual,
    /* Dri stuff */
    intel->hHWContext = driContextPriv->hHWContext;
    intel->driFd = sPriv->fd;
-   intel->driHwLock = (drmLock *) & sPriv->pSAREA->lock;
+   intel->driHwLock = (drmLock *) & sPriv->lock;
 
    fthrottle_mode = driQueryOptioni(&intel->optionCache, "fthrottle_mode");
    intel->iw.irq_seq = -1;
@@ -265,7 +326,7 @@ intelCreateContext(const __GLcontextModes * visual,
 
    intel->st = st_create_context(pipe, visual, st_share);
 
-   driInitExtensions( intel->st->ctx, card_extensions, GL_TRUE );
+   intelInitExtensions( intel->st->ctx, GL_TRUE );
 
    return GL_TRUE;
 }
index 8817a80..23889c8 100644 (file)
@@ -60,7 +60,190 @@ static PFNGLXCREATECONTEXTMODES create_context_modes = NULL;
 
 extern const struct dri_extension card_extensions[];
 
+static GLboolean
+intel_get_param(__DRIscreenPrivate *psp, int param, int *value)
+{
+   int ret;
+   struct drm_i915_getparam gp;
+
+   gp.param = param;
+   gp.value = value;
+
+   ret = drmCommandWriteRead(psp->fd, DRM_I915_GETPARAM, &gp, sizeof(gp));
+   if (ret) {
+      fprintf(stderr, "drm_i915_getparam: %d\n", ret);
+      return GL_FALSE;
+   }
+
+   return GL_TRUE;
+}
+
+static void
+intelSetTexOffset(__DRIcontext *pDRICtx, int texname,
+                 unsigned long long offset, int depth, uint pitch)
+{
+   abort();
+#if 0
+   struct intel_context *intel = (struct intel_context*)
+      ((__DRIcontextPrivate*)pDRICtx->private)->driverPrivate;
+   struct gl_texture_object *tObj = _mesa_lookup_texture(&intel->ctx, texname);
+   struct st_texture_object *stObj = st_texture_object(tObj);
+
+   if (!stObj)
+      return;
+
+   if (stObj->pt)
+      st->pipe->texture_release(intel->st->pipe, &stObj->pt);
+
+   stObj->imageOverride = GL_TRUE;
+   stObj->depthOverride = depth;
+   stObj->pitchOverride = pitch;
+
+   if (offset)
+      stObj->textureOffset = offset;
+#endif
+}
+
+
+static void
+intelHandleDrawableConfig(__DRIdrawablePrivate *dPriv,
+                         __DRIcontextPrivate *pcp,
+                         __DRIDrawableConfigEvent *event)
+{
+   struct intel_framebuffer *intel_fb = dPriv->driverPrivate;
+   struct intel_region *region = NULL;
+   struct intel_renderbuffer *rb, *depth_rb, *stencil_rb;
+   struct intel_context *intel = pcp->driverPrivate;
+   struct intel_screen *intelScreen = intel_screen(dPriv->driScreenPriv);
+   int cpp, pitch;
+
+#if 0
+   cpp = intelScreen->front.cpp;
+   pitch = ((cpp * dPriv->w + 63) & ~63) / cpp;
+
+   back_surf = st_get_framebuffer_surface(intel_fb->stfb,
+                                          ST_SURFACE_BACK_LEFT);
+   rb = intel_fb->color_rb[1];
+   if (rb) {
+      region = intel_region_alloc(intel, cpp, pitch, dPriv->h);
+      intel_renderbuffer_set_region(rb, region);
+   }
+
+   rb = intel_fb->color_rb[2];
+   if (rb) {
+      region = intel_region_alloc(intel, cpp, pitch, dPriv->h);
+      intel_renderbuffer_set_region(rb, region);
+   }
+
+   depth_rb = intel_get_renderbuffer(&intel_fb->Base, BUFFER_DEPTH);
+   stencil_rb = intel_get_renderbuffer(&intel_fb->Base, BUFFER_STENCIL);
+   if (depth_rb || stencil_rb)
+      region = intel_region_alloc(intel, cpp, pitch, dPriv->h);
+   if (depth_rb)
+      intel_renderbuffer_set_region(depth_rb, region);
+   if (stencil_rb)
+      intel_renderbuffer_set_region(stencil_rb, region);
+
+   /* FIXME: Tell the X server about the regions we just allocated and
+    * attached. */
+#endif
+
+}
+
+#define BUFFER_FLAG_TILED 0x0100
+
+static void
+intelHandleBufferAttach(__DRIdrawablePrivate *dPriv,
+                       __DRIcontextPrivate *pcp,
+                       __DRIBufferAttachEvent *ba)
+{
+   struct intel_screen *intelScreen = intel_screen(dPriv->driScreenPriv);
+   struct intel_framebuffer *intel_fb = dPriv->driverPrivate;
+   struct intel_renderbuffer *rb;
+   struct intel_region *region;
+   struct intel_context *intel = pcp->driverPrivate;
+   struct pipe_surface *surf;
+   GLuint tiled;
+
+   switch (ba->buffer.attachment) {
+   case DRI_DRAWABLE_BUFFER_FRONT_LEFT:
+   #if 0
+   intelScreen->front.width = ba->width;
+   intelScreen->front.height = ba->height;
+   intelScreen->front.offset = sarea->front_offset;
+   #endif
+   intelScreen->front.pitch = ba->buffer.pitch * ba->buffer.cpp;
+   #if 0
+   intelScreen->front.size = sarea->front_size;
+   #endif
+      driGenBuffers(intelScreen->base.staticPool, "front", 1, &intelScreen->front.buffer, 0, 0, 0);
+      driBOSetReferenced(intelScreen->front.buffer, ba->buffer.handle);
+       
+      break;
+
+#if 0
+   case DRI_DRAWABLE_BUFFER_BACK_LEFT:
+      rb = intel_fb->color_rb[0];
+      break;
+
+   case DRI_DRAWABLE_BUFFER_DEPTH:
+     rb = intel_get_renderbuffer(&intel_fb->Base, BUFFER_DEPTH);
+     break;
+
+   case DRI_DRAWABLE_BUFFER_STENCIL:
+     rb = intel_get_renderbuffer(&intel_fb->Base, BUFFER_STENCIL);
+     break;
+#endif
+
+   case DRI_DRAWABLE_BUFFER_ACCUM:
+   default:
+      fprintf(stderr, "unhandled buffer attach event, attacment type %d\n",
+             ba->buffer.attachment);
+      return;
+   }
+
+#if 0
+   /* FIXME: Add this so we can filter out when the X server sends us
+    * attachment events for the buffers we just allocated.  Need to
+    * get the BO handle for a render buffer. */
+   if (intel_renderbuffer_get_region_handle(rb) == ba->buffer.handle)
+      return;
+#endif
+
+#if 0
+   tiled = (ba->buffer.flags & BUFFER_FLAG_TILED) > 0;
+
+   region = intel_region_alloc_for_handle(intel, ba->buffer.cpp,
+                                         ba->buffer.pitch / ba->buffer.cpp,
+                                         dPriv->h, tiled,
+                                         ba->buffer.handle);
+
+   intel_renderbuffer_set_region(rb, region);
+#endif
+}
+
+static const __DRItexOffsetExtension intelTexOffsetExtension = {
+   { __DRI_TEX_OFFSET },
+   intelSetTexOffset,
+};
+
+#if 0
+static const __DRItexBufferExtension intelTexBufferExtension = {
+    { __DRI_TEX_BUFFER, __DRI_TEX_BUFFER_VERSION },
+   intelSetTexBuffer,
+};
+#endif
 
+static const __DRIextension *intelScreenExtensions[] = {
+    &driReadDrawableExtension,
+    &driCopySubBufferExtension.base,
+    &driSwapControlExtension.base,
+    &driFrameTrackingExtension.base,
+    &driMediaStreamCounterExtension.base,
+    &intelTexOffsetExtension.base,
+//    &intelTexBufferExtension.base,
+    NULL
+};
 
 
 static void
@@ -177,7 +360,8 @@ intelCreatePools(__DRIscreenPrivate * sPriv)
 
    intelScreen->havePools = GL_TRUE;
 
-   intelUpdateScreenRotation(sPriv, intelScreen->sarea);
+   if (intelScreen->sarea)
+       intelUpdateScreenRotation(sPriv, intelScreen->sarea);
 
    return GL_TRUE;
 }
@@ -210,11 +394,6 @@ intelInitDriver(__DRIscreenPrivate * sPriv)
    struct intel_screen *intelScreen;
    I830DRIPtr gDRIPriv = (I830DRIPtr) sPriv->pDevPriv;
 
-   PFNGLXSCRENABLEEXTENSIONPROC glx_enable_extension =
-      (PFNGLXSCRENABLEEXTENSIONPROC) (*dri_interface->
-                                      getProcAddress("glxEnableExtension"));
-   void *const psc = sPriv->psc->screenConfigs;
-
    if (sPriv->devPrivSize != sizeof(I830DRIRec)) {
       fprintf(stderr,
               "\nERROR!  sizeof(I830DRIRec) does not match passed size from device driver\n");
@@ -231,28 +410,17 @@ intelInitDriver(__DRIscreenPrivate * sPriv)
                       __driConfigOptions, __driNConfigOptions);
 
    sPriv->private = (void *) intelScreen;
-
    intelScreen->sarea = (drmI830Sarea *) (((GLubyte *) sPriv->pSAREA) +
-                                         gDRIPriv->sarea_priv_offset);
-   intelScreen->deviceID = gDRIPriv->deviceID;
-   intelScreen->front.cpp = gDRIPriv->cpp;
-   intelScreen->drmMinor = sPriv->drmMinor;
+                                            gDRIPriv->sarea_priv_offset);
 
-   assert(gDRIPriv->bitsPerPixel == 16 ||
-         gDRIPriv->bitsPerPixel == 32);
+   intelScreen->deviceID = gDRIPriv->deviceID;
 
    intelUpdateScreenRotation(sPriv, intelScreen->sarea);
 
    if (0)
       intelPrintDRIInfo(intelScreen, sPriv, gDRIPriv);
 
-   if (glx_enable_extension != NULL) {
-      (*glx_enable_extension) (psc, "GLX_SGI_swap_control");
-      (*glx_enable_extension) (psc, "GLX_SGI_video_sync");
-      (*glx_enable_extension) (psc, "GLX_MESA_swap_control");
-      (*glx_enable_extension) (psc, "GLX_MESA_swap_frame_usage");
-      (*glx_enable_extension) (psc, "GLX_SGI_make_current_read");
-   }
+   sPriv->extensions = intelScreenExtensions;
 
    intel_be_init_device(&intelScreen->base, sPriv->fd);
    intelScreen->base.base.flush_frontbuffer = intel_flush_frontbuffer;
@@ -351,65 +519,19 @@ intelGetSwapInfo(__DRIdrawablePrivate * dPriv, __DRIswapInfo * sInfo)
    return 0;
 }
 
-
-static void
-intelSetTexOffset(__DRIcontext *pDRICtx, int texname,
-                 unsigned long long offset, int depth, uint pitch)
+static __DRIconfig **
+intelFillInModes(__DRIscreenPrivate *psp,
+                unsigned pixel_bits, unsigned depth_bits,
+                 unsigned stencil_bits, GLboolean have_back_buffer)
 {
-   abort();
-#if 0
-   struct intel_context *intel = (struct intel_context*)
-      ((__DRIcontextPrivate*)pDRICtx->private)->driverPrivate;
-   struct gl_texture_object *tObj = _mesa_lookup_texture(&intel->ctx, texname);
-   struct st_texture_object *stObj = st_texture_object(tObj);
-
-   if (!stObj)
-      return;
-
-   if (stObj->pt)
-      st->pipe->texture_release(intel->st->pipe, &stObj->pt);
-
-   stObj->imageOverride = GL_TRUE;
-   stObj->depthOverride = depth;
-   stObj->pitchOverride = pitch;
-
-   if (offset)
-      stObj->textureOffset = offset;
-#endif
-}
-
-
-static const struct __DriverAPIRec intelAPI = {
-   .InitDriver = intelInitDriver,
-   .DestroyScreen = intelDestroyScreen,
-   .CreateContext = intelCreateContext,
-   .DestroyContext = intelDestroyContext,
-   .CreateBuffer = intelCreateBuffer,
-   .DestroyBuffer = intelDestroyBuffer,
-   .SwapBuffers = intelSwapBuffers,
-   .MakeCurrent = intelMakeCurrent,
-   .UnbindContext = intelUnbindContext,
-   .GetSwapInfo = intelGetSwapInfo,
-   .GetMSC = driGetMSC32,
-   .WaitForMSC = driWaitForMSC32,
-   .WaitForSBC = NULL,
-   .SwapBuffersMSC = NULL,
-   .CopySubBuffer = intelCopySubBuffer,
-   .setTexOffset = intelSetTexOffset,
-};
-
-
-static __GLcontextModes *
-intelFillInModes(unsigned pixel_bits, unsigned depth_bits,
-                 unsigned stencil_bits, boolean have_back_buffer)
-{
-   __GLcontextModes *modes;
+   __DRIconfig **configs;
    __GLcontextModes *m;
    unsigned num_modes;
    unsigned depth_buffer_factor;
    unsigned back_buffer_factor;
    GLenum fb_format;
    GLenum fb_type;
+   int i;
 
    /* GLX_SWAP_COPY_OML is only supported because the Intel driver doesn't
     * support pageflipping at all.
@@ -451,100 +573,143 @@ intelFillInModes(unsigned pixel_bits, unsigned depth_bits,
       fb_type = GL_UNSIGNED_INT_8_8_8_8_REV;
    }
 
-   modes =
-      (*dri_interface->createContextModes) (num_modes,
-                                            sizeof(__GLcontextModes));
-   m = modes;
-   if (!driFillInModes(&m, fb_format, fb_type,
-                       depth_bits_array, stencil_bits_array,
-                       depth_buffer_factor, back_buffer_modes,
-                       back_buffer_factor, GLX_TRUE_COLOR)) {
-      fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__,
-              __LINE__);
-      return NULL;
-   }
-   if (!driFillInModes(&m, fb_format, fb_type,
-                       depth_bits_array, stencil_bits_array,
-                       depth_buffer_factor, back_buffer_modes,
-                       back_buffer_factor, GLX_DIRECT_COLOR)) {
-      fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__,
+   configs = driCreateConfigs(fb_format, fb_type,
+                             depth_bits_array, stencil_bits_array,
+                             depth_buffer_factor, back_buffer_modes,
+                             back_buffer_factor);
+   if (configs == NULL) {
+    fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__,
               __LINE__);
       return NULL;
    }
 
    /* Mark the visual as slow if there are "fake" stencil bits.
     */
-   for (m = modes; m != NULL; m = m->next) {
+   for (i = 0; configs[i]; i++) {
+      m = &configs[i]->modes;
       if ((m->stencilBits != 0) && (m->stencilBits != stencil_bits)) {
          m->visualRating = GLX_SLOW_CONFIG;
       }
    }
 
-   return modes;
+   return configs;
 }
 
-
 /**
- * This is the bootstrap function for the driver.  libGL supplies all of the
- * requisite information about the system, and the driver initializes itself.
- * This routine also fills in the linked list pointed to by \c driver_modes
- * with the \c __GLcontextModes that the driver can support for windows or
- * pbuffers.
+ * This is the driver specific part of the createNewScreen entry point.
+ * 
+ * \todo maybe fold this into intelInitDriver
  *
- * \return A pointer to a \c __DRIscreenPrivate on success, or \c NULL on
- *         failure.
+ * \return the __GLcontextModes supported by this driver
  */
-PUBLIC void *
-__driCreateNewScreen_20050727(__DRInativeDisplay * dpy, int scrn,
-                              __DRIscreen * psc,
-                              const __GLcontextModes * modes,
-                              const __DRIversion * ddx_version,
-                              const __DRIversion * dri_version,
-                              const __DRIversion * drm_version,
-                              const __DRIframebuffer * frame_buffer,
-                              drmAddress pSAREA, int fd,
-                              int internal_api_version,
-                              const __DRIinterfaceMethods * interface,
-                              __GLcontextModes ** driver_modes)
+static const __DRIconfig **intelInitScreen(__DRIscreenPrivate *psp)
 {
-   __DRIscreenPrivate *psp;
-   static const __DRIversion ddx_expected = { 1, 7, 0 };
+#ifdef I915
+   static const __DRIversion ddx_expected = { 1, 5, 0 };
+#else
+   static const __DRIversion ddx_expected = { 1, 6, 0 };
+#endif
    static const __DRIversion dri_expected = { 4, 0, 0 };
-   static const __DRIversion drm_expected = { 1, 7, 0 };
-
-   dri_interface = interface;
+   static const __DRIversion drm_expected = { 1, 5, 0 };
+   I830DRIPtr dri_priv = (I830DRIPtr) psp->pDevPriv;
 
    if (!driCheckDriDdxDrmVersions2("i915",
-                                   dri_version, &dri_expected,
-                                   ddx_version, &ddx_expected,
-                                   drm_version, &drm_expected)) {
+                                   &psp->dri_version, &dri_expected,
+                                   &psp->ddx_version, &ddx_expected,
+                                   &psp->drm_version, &drm_expected)) {
       return NULL;
    }
 
-   psp = __driUtilCreateNewScreen(dpy, scrn, psc, NULL,
-                                  ddx_version, dri_version, drm_version,
-                                  frame_buffer, pSAREA, fd,
-                                  internal_api_version, &intelAPI);
-
-   if (psp != NULL) {
-      I830DRIPtr dri_priv = (I830DRIPtr) psp->pDevPriv;
-      *driver_modes = intelFillInModes(dri_priv->cpp * 8,
-                                       (dri_priv->cpp == 2) ? 16 : 24,
-                                       (dri_priv->cpp == 2) ? 0 : 8, 1);
-
-      /* Calling driInitExtensions here, with a NULL context pointer,
-       * does not actually enable the extensions.  It just makes sure
-       * that all the dispatch offsets for all the extensions that
-       * *might* be enables are known.  This is needed because the
-       * dispatch offsets need to be known when _mesa_context_create
-       * is called, but we can't enable the extensions until we have a
-       * context pointer.
-       *
-       * Hello chicken.  Hello egg.  How are you two today?
-       */
-      driInitExtensions(NULL, card_extensions, GL_FALSE);
+   /* Calling driInitExtensions here, with a NULL context pointer,
+    * does not actually enable the extensions.  It just makes sure
+    * that all the dispatch offsets for all the extensions that
+    * *might* be enables are known.  This is needed because the
+    * dispatch offsets need to be known when _mesa_context_create is
+    * called, but we can't enable the extensions until we have a
+    * context pointer.
+    *
+    * Hello chicken.  Hello egg.  How are you two today?
+    */
+   intelInitExtensions(NULL, GL_TRUE);
+          
+   if (!intelInitDriver(psp))
+       return NULL;
+
+   psp->extensions = intelScreenExtensions;
+
+   return (const __DRIconfig **)
+       intelFillInModes(psp, dri_priv->cpp * 8,
+                       (dri_priv->cpp == 2) ? 16 : 24,
+                       (dri_priv->cpp == 2) ? 0  : 8, 1);
+}
+
+/**
+ * This is the driver specific part of the createNewScreen entry point.
+ * 
+ * \return the __GLcontextModes supported by this driver
+ */
+static const
+__DRIconfig **intelInitScreen2(__DRIscreenPrivate *psp)
+{
+   struct intel_screen *intelScreen;
+
+   /* Calling driInitExtensions here, with a NULL context pointer,
+    * does not actually enable the extensions.  It just makes sure
+    * that all the dispatch offsets for all the extensions that
+    * *might* be enables are known.  This is needed because the
+    * dispatch offsets need to be known when _mesa_context_create is
+    * called, but we can't enable the extensions until we have a
+    * context pointer.
+    *
+    * Hello chicken.  Hello egg.  How are you two today?
+    */
+   intelInitExtensions(NULL, GL_TRUE);
+
+   /* Allocate the private area */
+   intelScreen = CALLOC_STRUCT(intel_screen);
+   if (!intelScreen) {
+      fprintf(stderr, "\nERROR!  Allocating private area failed\n");
+      return GL_FALSE;
    }
+   /* parse information in __driConfigOptions */
+   driParseOptionInfo(&intelScreen->optionCache,
+                      __driConfigOptions, __driNConfigOptions);
 
-   return (void *) psp;
+   psp->private = (void *) intelScreen;
+
+   intelScreen->drmMinor = psp->drm_version.minor;
+
+   /* Determine chipset ID? */
+   if (!intel_get_param(psp, I915_PARAM_CHIPSET_ID,
+                       &intelScreen->deviceID))
+      return GL_FALSE;
+
+   psp->extensions = intelScreenExtensions;
+
+   intel_be_init_device(&intelScreen->base, psp->fd);
+   intelScreen->base.base.flush_frontbuffer = intel_flush_frontbuffer;
+   intelScreen->base.base.get_name = intel_get_name;
+
+   return driConcatConfigs(intelFillInModes(psp, 16, 16, 0, 1),
+                          intelFillInModes(psp, 32, 24, 8, 1));
 }
 
+const struct __DriverAPIRec driDriverAPI = {
+   .InitScreen          = intelInitScreen,
+   .DestroyScreen       = intelDestroyScreen,
+   .CreateContext       = intelCreateContext,
+   .DestroyContext      = intelDestroyContext,
+   .CreateBuffer        = intelCreateBuffer,
+   .DestroyBuffer       = intelDestroyBuffer,
+   .SwapBuffers                 = intelSwapBuffers,
+   .MakeCurrent                 = intelMakeCurrent,
+   .UnbindContext       = intelUnbindContext,
+   .GetSwapInfo                 = intelGetSwapInfo,
+   .GetDrawableMSC      = driDrawableGetMSC32,
+   .WaitForMSC          = driWaitForMSC32,
+   .CopySubBuffer       = intelCopySubBuffer,
+
+   .InitScreen2                 = intelInitScreen2,
+   .HandleDrawableConfig = intelHandleDrawableConfig,
+   .HandleBufferAttach  = intelHandleBufferAttach,
+};
index b404727..1304311 100644 (file)
@@ -10,12 +10,14 @@ SOURCES = \
          compsize.c \
          eval.c \
          glxcmds.c \
+         glxcurrent.c \
          glxext.c \
          glxextensions.c \
          indirect.c \
          indirect_init.c \
          indirect_size.c \
          indirect_window_pos.c \
+         indirect_texture_compression.c \
          indirect_transpose_matrix.c \
          indirect_vertex_array.c \
          indirect_vertex_program.c \
@@ -29,13 +31,16 @@ SOURCES = \
          xfont.c \
          glx_pbuffer.c \
          glx_query.c \
-         glx_texture_compression.c \
+         dri_common.c \
          dri_glx.c \
-         XF86dri.c
+         XF86dri.c \
+         glxhash.c \
+         dri2_glx.c \
+         dri2.c
 
 include $(TOP)/src/mesa/sources
 
-MESA_GLAPI_ASM_SOURCES = $(addprefix $(TOP)/src/mesa/, $(GLAPI_ASM_SOURCES))
+MESA_ASM_API = $(addprefix $(TOP)/src/mesa/, $(ASM_API))
 MESA_GLAPI_SOURCES = $(addprefix $(TOP)/src/mesa/, $(GLAPI_SOURCES))
 MESA_GLAPI_OBJECTS = $(addprefix $(TOP)/src/mesa/, $(GLAPI_OBJECTS))
 
@@ -46,8 +51,8 @@ INCLUDES = -I. \
        -I$(TOP)/include/GL/internal \
        -I$(TOP)/src/mesa \
        -I$(TOP)/src/mesa/main \
-       -I$(TOP)/src/mesa/glapi \
        $(LIBDRM_CFLAGS) \
+       $(DRI2PROTO_CFLAGS) \
        $(X11_INCLUDES)
 
 
@@ -65,29 +70,28 @@ default: depend $(TOP)/$(LIB_DIR)/$(GL_LIB_NAME)
 
 # Make libGL
 $(TOP)/$(LIB_DIR)/$(GL_LIB_NAME):  $(OBJECTS) Makefile
-       $(TOP)/bin/mklib -o $(GL_LIB) -linker '$(CC)' \
+       $(TOP)/bin/mklib -o $(GL_LIB) -linker '$(CC)' -ldflags '$(LDFLAGS)' \
                -major 1 -minor 2 $(MKLIB_OPTIONS) \
                -install $(TOP)/$(LIB_DIR) $(GL_LIB_DEPS) $(OBJECTS)
 
 
-depend: $(SOURCES) $(MESA_GLAPI_SOURCES) $(MESA_GLAPI_ASM_SOURCES) Makefile
-       rm -f depend
+depend: $(SOURCES) $(MESA_GLAPI_SOURCES) $(MESA_ASM_API) Makefile
        touch depend
        $(MKDEP) $(MKDEP_OPTIONS) $(INCLUDES) $(SOURCES) \
-               $(MESA_GLAPI_SOURCES) $(MESA_GLAPI_ASM_SOURCES
+               $(MESA_GLAPI_SOURCES) $(MESA_ASM_API
 
 
 # Emacs tags
 tags:
        etags `find . -name \*.[ch]` `find $(TOP)/include`
 
-# Dummy install target
-install:
+install: $(TOP)/$(LIB_DIR)/$(GL_LIB_NAME)
+       $(MAKE) -C $(TOP)/src/mesa install-libgl
 
 # Remove .o and backup files
 clean:
        -rm -f $(TOP)/$(LIB_DIR)/libGL.so*
        -rm -f *.o *~
-       -rm -f depend
+       -rm -f depend depend.bak
 
 include depend
index 9919a40..ba38949 100644 (file)
@@ -374,10 +374,9 @@ PUBLIC Bool XF86DRICreateContext(dpy, screen, visual, context, hHWContext)
                                           context, hHWContext );
 }
 
-PUBLIC GLboolean XF86DRIDestroyContext( __DRInativeDisplay * ndpy, int screen, 
-    __DRIid context )
+PUBLIC GLboolean XF86DRIDestroyContext(Display *dpy, int screen, 
+    XID context )
 {
-    Display * const dpy = (Display *) ndpy;
     XExtDisplayInfo *info = find_display (dpy);
     xXF86DRIDestroyContextReq *req;
 
@@ -396,10 +395,9 @@ PUBLIC GLboolean XF86DRIDestroyContext( __DRInativeDisplay * ndpy, int screen,
     return True;
 }
 
-PUBLIC GLboolean XF86DRICreateDrawable( __DRInativeDisplay * ndpy, int screen, 
-    __DRIid drawable, drm_drawable_t * hHWDrawable )
+PUBLIC GLboolean XF86DRICreateDrawable(Display *dpy, int screen, 
+    XID drawable, drm_drawable_t * hHWDrawable )
 {
-    Display * const dpy = (Display *) ndpy;
     XExtDisplayInfo *info = find_display (dpy);
     xXF86DRICreateDrawableReply rep;
     xXF86DRICreateDrawableReq *req;
@@ -426,16 +424,36 @@ PUBLIC GLboolean XF86DRICreateDrawable( __DRInativeDisplay * ndpy, int screen,
     return True;
 }
 
-PUBLIC GLboolean XF86DRIDestroyDrawable( __DRInativeDisplay * ndpy, int screen,
-    __DRIid drawable )
+static int noopErrorHandler(Display *dpy, XErrorEvent *xerr)
+{
+    return 0;
+}
+
+PUBLIC GLboolean XF86DRIDestroyDrawable(Display *dpy, int screen,
+    XID drawable )
 {
-    Display * const dpy = (Display *) ndpy;
     XExtDisplayInfo *info = find_display (dpy);
     xXF86DRIDestroyDrawableReq *req;
+    int (*oldXErrorHandler)(Display *, XErrorEvent *);
 
     TRACE("DestroyDrawable...");
     XF86DRICheckExtension (dpy, info, False);
 
+    /* This is called from the DRI driver, which used call it like this
+     *
+     *   if (windowExists(drawable))
+     *     destroyDrawable(drawable);
+     *
+     * which is a textbook race condition - the window may disappear
+     * from the server between checking for its existance and
+     * destroying it.  Instead we change the semantics of
+     * __DRIinterfaceMethodsRec::destroyDrawable() to succeed even if
+     * the windows is gone, by wrapping the destroy call in an error
+     * handler. */
+
+    XSync(dpy, GL_FALSE);
+    oldXErrorHandler = XSetErrorHandler(noopErrorHandler);
+
     LockDisplay(dpy);
     GetReq(XF86DRIDestroyDrawable, req);
     req->reqType = info->codes->major_opcode;
@@ -444,6 +462,9 @@ PUBLIC GLboolean XF86DRIDestroyDrawable( __DRInativeDisplay * ndpy, int screen,
     req->drawable = drawable;
     UnlockDisplay(dpy);
     SyncHandle();
+
+    XSetErrorHandler(oldXErrorHandler);
+
     TRACE("DestroyDrawable... return True");
     return True;
 }
index 21e07c1..1cb3204 100644 (file)
@@ -34,260 +34,47 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 #ifdef GLX_DIRECT_RENDERING
 
-#include <unistd.h>
-#include <X11/Xlibint.h>
-#include <X11/extensions/Xext.h>
-#include <X11/extensions/extutil.h>
+#include <X11/Xlib.h>
+#include <X11/extensions/Xfixes.h>
+#include <X11/extensions/Xdamage.h>
 #include "glheader.h"
 #include "glxclient.h"
+#include "glcontextmodes.h"
 #include "xf86dri.h"
 #include "sarea.h"
-#include <stdio.h>
 #include <dlfcn.h>
-#include "dri_glx.h"
 #include <sys/types.h>
-#include <stdarg.h>
-
-#ifndef RTLD_NOW
-#define RTLD_NOW 0
-#endif
-#ifndef RTLD_GLOBAL
-#define RTLD_GLOBAL 0
-#endif
-
-
-#ifndef DEFAULT_DRIVER_DIR
-/* this is normally defined in Mesa/configs/default with DRI_DRIVER_SEARCH_PATH */
-#define DEFAULT_DRIVER_DIR "/usr/X11R6/lib/modules/dri"
-#endif
-
-static __DRIdriver *Drivers = NULL;
-
-
-/*
- * printf wrappers
- */
-
-static void InfoMessageF(const char *f, ...)
-{
-    va_list args;
-    const char *env;
-
-    if ((env = getenv("LIBGL_DEBUG")) && strstr(env, "verbose")) {
-       fprintf(stderr, "libGL: ");
-       va_start(args, f);
-       vfprintf(stderr, f, args);
-       va_end(args);
-    }
-}
-
-/**
- * Print error to stderr, unless LIBGL_DEBUG=="quiet".
- */
-static void ErrorMessageF(const char *f, ...)
-{
-    va_list args;
-    const char *env;
-
-    if ((env = getenv("LIBGL_DEBUG")) && !strstr(env, "quiet")) {
-       fprintf(stderr, "libGL error: ");
-       va_start(args, f);
-       vfprintf(stderr, f, args);
-       va_end(args);
-    }
-}
-
-
-/**
- * Extract the ith directory path out of a colon-separated list of paths.  No
- * more than \c dirLen characters, including the terminating \c NUL, will be
- * written to \c dir.
- *
- * \param index  Index of path to extract (starting at zero)
- * \param paths  The colon-separated list of paths
- * \param dirLen Maximum length of result to store in \c dir
- * \param dir    Buffer to hold the extracted directory path
- *
- * \returns
- * The number of characters that would have been written to \c dir had there
- * been enough room.  This does not include the terminating \c NUL.  When
- * extraction fails, zero will be returned.
- * 
- * \todo
- * It seems like this function could be rewritten to use \c strchr.
- */
-static size_t
-ExtractDir(int index, const char *paths, int dirLen, char *dir)
-{
-   int i, len;
-   const char *start, *end;
-
-   /* find ith colon */
-   start = paths;
-   i = 0;
-   while (i < index) {
-      if (*start == ':') {
-         i++;
-         start++;
-      }
-      else if (*start == 0) {
-         /* end of string and couldn't find ith colon */
-         dir[0] = 0;
-         return 0;
-      }
-      else {
-         start++;
-      }
-   }
-
-   while (*start == ':')
-      start++;
-
-   /* find next colon, or end of string */
-   end = start + 1;
-   while (*end != ':' && *end != 0) {
-      end++;
-   }
-
-   /* copy string between <start> and <end> into result string */
-   len = end - start;
-   if (len > dirLen - 1)
-      len = dirLen - 1;
-   strncpy(dir, start, len);
-   dir[len] = 0;
-
-   return( end - start );
-}
-
-
-/**
- * Versioned name of the expected \c __driCreateNewScreen function.
- * 
- * The version of the last incompatible loader/driver inteface change is
- * appended to the name of the \c __driCreateNewScreen function.  This
- * prevents loaders from trying to load drivers that are too old.
- * 
- * \todo
- * Create a macro or something so that this is automatically updated.
- */
-static const char createNewScreenName[] = "__driCreateNewScreen_20050727";
-
-
-/**
- * Try to \c dlopen the named driver.
- *
- * This function adds the "_dri.so" suffix to the driver name and searches the
- * directories specified by the \c LIBGL_DRIVERS_PATH environment variable in
- * order to find the driver.
- *
- * \param driverName - a name like "tdfx", "i810", "mga", etc.
- *
- * \returns
- * A handle from \c dlopen, or \c NULL if driver file not found.
- */
-static __DRIdriver *OpenDriver(const char *driverName)
-{
-   void *glhandle = NULL;
-   char *libPaths = NULL;
-   char libDir[1000];
-   int i;
-   __DRIdriver *driver;
-
-   /* First, search Drivers list to see if we've already opened this driver */
-   for (driver = Drivers; driver; driver = driver->next) {
-      if (strcmp(driver->name, driverName) == 0) {
-         /* found it */
-         return driver;
-      }
-   }
-
-   /* Attempt to make sure libGL symbols will be visible to the driver */
-   glhandle = dlopen("libGL.so.1", RTLD_NOW | RTLD_GLOBAL);
-
-   if (geteuid() == getuid()) {
-      /* don't allow setuid apps to use LIBGL_DRIVERS_PATH */
-      libPaths = getenv("LIBGL_DRIVERS_PATH");
-      if (!libPaths)
-         libPaths = getenv("LIBGL_DRIVERS_DIR"); /* deprecated */
-   }
-   if (!libPaths)
-      libPaths = DEFAULT_DRIVER_DIR;
-
-   for ( i = 0 ; ExtractDir(i, libPaths, 1000, libDir) != 0 ; i++ ) {
-      char realDriverName[200];
-      void *handle = NULL;
-
-      
-      /* If TLS support is enabled, try to open the TLS version of the driver
-       * binary first.  If that fails, try the non-TLS version.
-       */
-#ifdef GLX_USE_TLS
-      snprintf(realDriverName, 200, "%s/tls/%s_dri.so", libDir, driverName);
-      InfoMessageF("OpenDriver: trying %s\n", realDriverName);
-      handle = dlopen(realDriverName, RTLD_NOW | RTLD_GLOBAL);
-#endif
-
-      if ( handle == NULL ) {
-        snprintf(realDriverName, 200, "%s/%s_dri.so", libDir, driverName);
-        InfoMessageF("OpenDriver: trying %s\n", realDriverName);
-        handle = dlopen(realDriverName, RTLD_NOW | RTLD_GLOBAL);
-      }
-
-      if ( handle != NULL ) {
-         /* allocate __DRIdriver struct */
-         driver = (__DRIdriver *) Xmalloc(sizeof(__DRIdriver));
-         if (!driver)
-            break; /* out of memory! */
-         /* init the struct */
-         driver->name = __glXstrdup(driverName);
-         if (!driver->name) {
-            Xfree(driver);
-            driver = NULL;
-            break; /* out of memory! */
-         }
-
-         driver->createNewScreenFunc = (PFNCREATENEWSCREENFUNC)
-            dlsym(handle, createNewScreenName);
-
-         if ( driver->createNewScreenFunc == NULL ) {
-            /* If the driver doesn't have this symbol then something's
-             * really, really wrong.
-             */
-            ErrorMessageF("%s not defined in %s_dri.so!\n"
-                         "Your driver may be too old for this libGL.\n",
-                         createNewScreenName, driverName);
-            Xfree(driver);
-            driver = NULL;
-            dlclose(handle);
-            continue;
-         }
-         driver->handle = handle;
-         /* put at head of linked list */
-         driver->next = Drivers;
-         Drivers = driver;
-         break;
-      }
-      else {
-        ErrorMessageF("dlopen %s failed (%s)\n", realDriverName, dlerror());
-      }
-   }
-
-   if (!driver)
-      ErrorMessageF("unable to load driver: %s_dri.so\n", driverName);
-
-   if (glhandle)
-      dlclose(glhandle);
-
-   return driver;
-}
-
+#include <sys/mman.h>
+#include "xf86drm.h"
+#include "dri_common.h"
+
+typedef struct __GLXDRIdisplayPrivateRec __GLXDRIdisplayPrivate;
+typedef struct __GLXDRIcontextPrivateRec __GLXDRIcontextPrivate;
+
+struct __GLXDRIdisplayPrivateRec {
+    __GLXDRIdisplay base;
+
+    /*
+    ** XFree86-DRI version information
+    */
+    int driMajor;
+    int driMinor;
+    int driPatch;
+};
+
+struct __GLXDRIcontextPrivateRec {
+    __GLXDRIcontext base;
+    __DRIcontext *driContext;
+    XID hwContextID;
+    __GLXscreenConfigs *psc;
+};
 
 /*
  * Given a display pointer and screen number, determine the name of
  * the DRI driver for the screen. (I.e. "r128", "tdfx", etc).
  * Return True for success, False for failure.
  */
-static Bool GetDriverName(Display *dpy, int scrNum, char **driverName)
+static Bool driGetDriverName(Display *dpy, int scrNum, char **driverName)
 {
    int directCapable;
    Bool b;
@@ -317,25 +104,6 @@ static Bool GetDriverName(Display *dpy, int scrNum, char **driverName)
    return True;
 }
 
-
-/*
- * Given a display pointer and screen number, return a __DRIdriver handle.
- * Return NULL if anything goes wrong.
- */
-__DRIdriver *driGetDriver(Display *dpy, int scrNum)
-{
-   char *driverName;
-   if (GetDriverName(dpy, scrNum, &driverName)) {
-      __DRIdriver *ret;
-      ret = OpenDriver(driverName);
-      if (driverName)
-        Xfree(driverName);
-      return ret;
-   }
-   return NULL;
-}
-
-
 /*
  * Exported function for querying the DRI driver for a given screen.
  *
@@ -345,7 +113,7 @@ __DRIdriver *driGetDriver(Display *dpy, int scrNum)
 PUBLIC const char *glXGetScreenDriver (Display *dpy, int scrNum) {
    static char ret[32];
    char *driverName;
-   if (GetDriverName(dpy, scrNum, &driverName)) {
+   if (driGetDriverName(dpy, scrNum, &driverName)) {
       int len;
       if (!driverName)
         return NULL;
@@ -359,7 +127,6 @@ PUBLIC const char *glXGetScreenDriver (Display *dpy, int scrNum) {
    return NULL;
 }
 
-
 /*
  * Exported function for obtaining a driver's option list (UTF-8 encoded XML).
  *
@@ -371,71 +138,532 @@ PUBLIC const char *glXGetScreenDriver (Display *dpy, int scrNum) {
  *
  * Note: The driver remains opened after this function returns.
  */
-PUBLIC const char *glXGetDriverConfig (const char *driverName) {
-   __DRIdriver *driver = OpenDriver (driverName);
-   if (driver)
-      return dlsym (driver->handle, "__driConfigOptions");
+PUBLIC const char *glXGetDriverConfig (const char *driverName)
+{
+   void *handle = driOpenDriver (driverName);
+   if (handle)
+      return dlsym (handle, "__driConfigOptions");
    else
       return NULL;
 }
 
+#ifdef XDAMAGE_1_1_INTERFACE
 
-/* Called from __glXFreeDisplayPrivate.
+static GLboolean has_damage_post(Display *dpy)
+{
+    static GLboolean inited = GL_FALSE;
+    static GLboolean has_damage;
+
+    if (!inited) {
+       int major, minor;
+
+       if (XDamageQueryVersion(dpy, &major, &minor) &&
+           major == 1 && minor >= 1)
+       {
+           has_damage = GL_TRUE;
+       } else {
+           has_damage = GL_FALSE;
+       }
+       inited = GL_TRUE;
+    }
+
+    return has_damage;
+}
+
+static void __glXReportDamage(__DRIdrawable *driDraw,
+                             int x, int y,
+                             drm_clip_rect_t *rects, int num_rects,
+                             GLboolean front_buffer,
+                             void *loaderPrivate)
+{
+    XRectangle *xrects;
+    XserverRegion region;
+    int i;
+    int x_off, y_off;
+    __GLXDRIdrawable *glxDraw = loaderPrivate;
+    __GLXscreenConfigs *psc = glxDraw->psc;
+    Display *dpy = psc->dpy;
+    Drawable drawable;
+
+    if (!has_damage_post(dpy))
+       return;
+
+    if (front_buffer) {
+       x_off = x;
+       y_off = y;
+       drawable = RootWindow(dpy, psc->scr);
+    } else{
+       x_off = 0;
+       y_off = 0;
+       drawable = glxDraw->xDrawable;
+    }
+
+    xrects = malloc(sizeof(XRectangle) * num_rects);
+    if (xrects == NULL)
+       return;
+
+    for (i = 0; i < num_rects; i++) {
+       xrects[i].x = rects[i].x1 + x_off;
+       xrects[i].y = rects[i].y1 + y_off;
+       xrects[i].width = rects[i].x2 - rects[i].x1;
+       xrects[i].height = rects[i].y2 - rects[i].y1;
+    }
+    region = XFixesCreateRegion(dpy, xrects, num_rects);
+    free(xrects);
+    XDamageAdd(dpy, drawable, region);
+    XFixesDestroyRegion(dpy, region);
+}
+
+static const __DRIdamageExtension damageExtension = {
+    { __DRI_DAMAGE, __DRI_DAMAGE_VERSION },
+    __glXReportDamage,
+};
+
+#endif
+
+static GLboolean
+__glXDRIGetDrawableInfo(__DRIdrawable *drawable,
+                       unsigned int *index, unsigned int *stamp, 
+                       int *X, int *Y, int *W, int *H,
+                       int *numClipRects, drm_clip_rect_t ** pClipRects,
+                       int *backX, int *backY,
+                       int *numBackClipRects, drm_clip_rect_t **pBackClipRects,
+                       void *loaderPrivate)
+{
+    __GLXDRIdrawable *glxDraw = loaderPrivate;
+    __GLXscreenConfigs *psc = glxDraw->psc;
+    Display *dpy = psc->dpy;
+
+    return XF86DRIGetDrawableInfo(dpy, psc->scr, glxDraw->drawable,
+                                 index, stamp, X, Y, W, H,
+                                 numClipRects, pClipRects,
+                                 backX, backY,
+                                 numBackClipRects, pBackClipRects);
+}
+
+static const __DRIgetDrawableInfoExtension getDrawableInfoExtension = {
+    { __DRI_GET_DRAWABLE_INFO, __DRI_GET_DRAWABLE_INFO_VERSION },
+    __glXDRIGetDrawableInfo
+};
+
+static const __DRIextension *loader_extensions[] = {
+    &systemTimeExtension.base,
+    &getDrawableInfoExtension.base,
+#ifdef XDAMAGE_1_1_INTERFACE
+    &damageExtension.base,
+#endif
+    NULL
+};
+
+#ifndef GLX_USE_APPLEGL
+
+/**
+ * Perform the required libGL-side initialization and call the client-side
+ * driver's \c __driCreateNewScreen function.
+ * 
+ * \param dpy    Display pointer.
+ * \param scrn   Screen number on the display.
+ * \param psc    DRI screen information.
+ * \param driDpy DRI display information.
+ * \param createNewScreen  Pointer to the client-side driver's
+ *               \c __driCreateNewScreen function.
+ * \returns A pointer to the \c __DRIscreenPrivate structure returned by
+ *          the client-side driver on success, or \c NULL on failure.
  */
-static void driDestroyDisplay(Display *dpy, void *private)
+static void *
+CallCreateNewScreen(Display *dpy, int scrn, __GLXscreenConfigs *psc,
+                   __GLXDRIdisplayPrivate * driDpy)
+{
+    void *psp = NULL;
+    drm_handle_t hSAREA;
+    drmAddress pSAREA = MAP_FAILED;
+    char *BusID;
+    __DRIversion   ddx_version;
+    __DRIversion   dri_version;
+    __DRIversion   drm_version;
+    __DRIframebuffer  framebuffer;
+    int   fd = -1;
+    int   status;
+
+    drm_magic_t magic;
+    drmVersionPtr version;
+    int newlyopened;
+    char *driverName;
+    drm_handle_t  hFB;
+    int        junk;
+    const __DRIconfig **driver_configs;
+
+    /* DRI protocol version. */
+    dri_version.major = driDpy->driMajor;
+    dri_version.minor = driDpy->driMinor;
+    dri_version.patch = driDpy->driPatch;
+
+    framebuffer.base = MAP_FAILED;
+    framebuffer.dev_priv = NULL;
+
+    if (!XF86DRIOpenConnection(dpy, scrn, &hSAREA, &BusID)) {
+       fprintf(stderr, "libGL error: XF86DRIOpenConnection failed\n");
+       goto handle_error;
+    }
+
+    fd = drmOpenOnce(NULL, BusID, &newlyopened);
+
+    Xfree(BusID); /* No longer needed */
+
+    if (fd < 0) {
+       fprintf(stderr, "libGL error: drmOpenOnce failed (%s)\n",
+               strerror(-fd));
+       goto handle_error;
+    }
+
+    if (drmGetMagic(fd, &magic)) {
+       fprintf(stderr, "libGL error: drmGetMagic failed\n");
+       goto handle_error;
+    }
+
+    version = drmGetVersion(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;
+    }
+
+    if (newlyopened && !XF86DRIAuthConnection(dpy, scrn, magic)) {
+       fprintf(stderr, "libGL error: XF86DRIAuthConnection failed\n");
+       goto handle_error;
+    }
+
+    /* Get device name (like "tdfx") and the ddx version numbers.
+     * We'll check the version in each DRI driver's "createNewScreen"
+     * function. */
+    if (!XF86DRIGetClientDriverName(dpy, scrn,
+                                   &ddx_version.major,
+                                   &ddx_version.minor,
+                                   &ddx_version.patch,
+                                   &driverName)) {
+       fprintf(stderr, "libGL error: XF86DRIGetClientDriverName failed\n");
+       goto handle_error;
+    }
+
+    Xfree(driverName); /* No longer needed. */
+
+    /*
+     * Get device-specific info.  pDevPriv will point to a struct
+     * (such as DRIRADEONRec in xfree86/driver/ati/radeon_dri.h) that
+     * has information about the screen size, depth, pitch, ancilliary
+     * buffers, DRM mmap handles, etc.
+     */
+    if (!XF86DRIGetDeviceInfo(dpy, scrn, &hFB, &junk,
+                             &framebuffer.size, &framebuffer.stride,
+                             &framebuffer.dev_priv_size, &framebuffer.dev_priv)) {
+       fprintf(stderr, "libGL error: XF86DRIGetDeviceInfo failed");
+       goto handle_error;
+    }
+
+    framebuffer.width = DisplayWidth(dpy, scrn);
+    framebuffer.height = DisplayHeight(dpy, scrn);
+
+    /* Map the framebuffer region. */
+    status = drmMap(fd, hFB, framebuffer.size, 
+                   (drmAddressPtr)&framebuffer.base);
+    if (status != 0) {
+       fprintf(stderr, "libGL error: drmMap of framebuffer failed (%s)",
+               strerror(-status));
+       goto handle_error;
+    }
+
+    /* Map the SAREA region.  Further mmap regions may be setup in
+     * each DRI driver's "createNewScreen" function.
+     */
+    status = drmMap(fd, hSAREA, SAREA_MAX, &pSAREA);
+    if (status != 0) {
+       fprintf(stderr, "libGL error: drmMap of SAREA failed (%s)",
+               strerror(-status));
+       goto handle_error;
+    }
+
+    psp = (*psc->legacy->createNewScreen)(scrn,
+                                         &ddx_version,
+                                         &dri_version,
+                                         &drm_version,
+                                         &framebuffer,
+                                         pSAREA,
+                                         fd,
+                                         loader_extensions,
+                                         &driver_configs,
+                                         psc);
+
+    if (psp == NULL) {
+       fprintf(stderr, "libGL error: Calling driver entry point failed");
+       goto handle_error;
+    }
+
+    psc->configs = driConvertConfigs(psc->core, psc->configs, driver_configs);
+    psc->visuals = driConvertConfigs(psc->core, psc->visuals, driver_configs);
+
+    return psp;
+
+ handle_error:
+    if (pSAREA != MAP_FAILED)
+       drmUnmap(pSAREA, SAREA_MAX);
+
+    if (framebuffer.base != MAP_FAILED)
+       drmUnmap((drmAddress)framebuffer.base, framebuffer.size);
+
+    if (framebuffer.dev_priv != NULL)
+       Xfree(framebuffer.dev_priv);
+
+    if (fd >= 0)
+       drmCloseOnce(fd);
+
+    XF86DRICloseConnection(dpy, scrn);
+
+    fprintf(stderr, "libGL error: reverting to (slow) indirect rendering\n");
+
+    return NULL;
+}
+
+#else /* !GLX_USE_APPLEGL */
+
+static void *
+CallCreateNewScreen(Display *dpy, int scrn, __GLXscreenConfigs *psc,
+                   __GLXDRIdisplayPrivate * driDpy)
 {
-    __DRIdisplayPrivate *pdpyp = (__DRIdisplayPrivate *)private;
-
-    if (pdpyp) {
-        const int numScreens = ScreenCount(dpy);
-        int i;
-        for (i = 0; i < numScreens; i++) {
-          if (pdpyp->libraryHandles[i]) {
-             __DRIdriver *driver, *prev;
-
-             /* Remove driver from Drivers list */
-             for (prev = NULL, driver = Drivers; driver;
-                  prev = driver, driver = driver->next) {
-                if (driver->handle == pdpyp->libraryHandles[i]) {
-                   if (prev)
-                      prev->next = driver->next;
-                   else
-                      Drivers = driver->next;
-
-                   Xfree(driver->name);
-                   Xfree(driver);
-                   break;
-                }
-             }
-
-             dlclose(pdpyp->libraryHandles[i]);
-          }
-        }
-        Xfree(pdpyp->libraryHandles);
-       Xfree(pdpyp);
+    return NULL;
+}
+
+#endif /* !GLX_USE_APPLEGL */
+
+static void driDestroyContext(__GLXDRIcontext *context,
+                             __GLXscreenConfigs *psc, Display *dpy)
+{
+    __GLXDRIcontextPrivate *pcp = (__GLXDRIcontextPrivate *) context;
+                       
+    (*psc->core->destroyContext)(pcp->driContext);
+
+    XF86DRIDestroyContext(psc->dpy, psc->scr, pcp->hwContextID);
+}
+
+static Bool driBindContext(__GLXDRIcontext *context,
+                          __GLXDRIdrawable *draw, __GLXDRIdrawable *read)
+{
+    __GLXDRIcontextPrivate *pcp = (__GLXDRIcontextPrivate *) context;
+    const __DRIcoreExtension *core = pcp->psc->core;
+
+    return (*core->bindContext)(pcp->driContext,
+                               draw->driDrawable,
+                               read->driDrawable);
+}
+
+static void driUnbindContext(__GLXDRIcontext *context)
+{
+    __GLXDRIcontextPrivate *pcp = (__GLXDRIcontextPrivate *) context;
+    const __DRIcoreExtension *core = pcp->psc->core;
+
+    (*core->unbindContext)(pcp->driContext);
+}
+
+static __GLXDRIcontext *driCreateContext(__GLXscreenConfigs *psc,
+                                        const __GLcontextModes *mode,
+                                        GLXContext gc,
+                                        GLXContext shareList, int renderType)
+{
+    __GLXDRIcontextPrivate *pcp, *pcp_shared;
+    drm_context_t hwContext;
+    __DRIcontext *shared = NULL;
+    __GLXDRIconfigPrivate *config = (__GLXDRIconfigPrivate *) mode;
+
+    if (!psc || !psc->driScreen)
+       return NULL;
+
+    if (shareList) {
+       pcp_shared = (__GLXDRIcontextPrivate *) shareList->driContext;
+       shared = pcp_shared->driContext;
+    }
+
+    pcp = Xmalloc(sizeof *pcp);
+    if (pcp == NULL)
+       return NULL;
+
+    pcp->psc = psc;
+    if (!XF86DRICreateContextWithConfig(psc->dpy, psc->scr,
+                                       mode->visualID,
+                                       &pcp->hwContextID, &hwContext)) {
+       Xfree(pcp);
+       return NULL;
     }
+
+    pcp->driContext =
+        (*psc->legacy->createNewContext)(psc->__driScreen,
+                                        config->driConfig,
+                                        renderType,
+                                        shared,
+                                        hwContext,
+                                        pcp);
+    if (pcp->driContext == NULL) {
+       XF86DRIDestroyContext(psc->dpy, psc->scr, pcp->hwContextID);
+       Xfree(pcp);
+       return NULL;
+    }
+
+    pcp->base.destroyContext = driDestroyContext;
+    pcp->base.bindContext = driBindContext;
+    pcp->base.unbindContext = driUnbindContext;
+
+    return &pcp->base;
 }
 
+static void driDestroyDrawable(__GLXDRIdrawable *pdraw)
+{
+    __GLXscreenConfigs *psc = pdraw->psc;
+
+    (*psc->core->destroyDrawable)(pdraw->driDrawable);
+    XF86DRIDestroyDrawable(psc->dpy, psc->scr, pdraw->drawable);
+    Xfree(pdraw);
+}
+
+static __GLXDRIdrawable *driCreateDrawable(__GLXscreenConfigs *psc,
+                                          XID xDrawable,
+                                          GLXDrawable drawable,
+                                          const __GLcontextModes *modes)
+{
+    __GLXDRIdrawable *pdraw;
+    drm_drawable_t hwDrawable;
+    void *empty_attribute_list = NULL;
+    __GLXDRIconfigPrivate *config = (__GLXDRIconfigPrivate *) modes;
+
+    /* Old dri can't handle GLX 1.3+ drawable constructors. */
+    if (xDrawable != drawable)
+       return NULL;
+
+    pdraw = Xmalloc(sizeof(*pdraw));
+    if (!pdraw)
+       return NULL;
+
+    pdraw->drawable = drawable;
+    pdraw->psc = psc;
+
+    if (!XF86DRICreateDrawable(psc->dpy, psc->scr, drawable, &hwDrawable))
+       return NULL;
+
+    /* Create a new drawable */
+    pdraw->driDrawable =
+       (*psc->legacy->createNewDrawable)(psc->__driScreen,
+                                         config->driConfig,
+                                         hwDrawable,
+                                         GLX_WINDOW_BIT,
+                                         empty_attribute_list,
+                                         pdraw);
+
+    if (!pdraw->driDrawable) {
+       XF86DRIDestroyDrawable(psc->dpy, psc->scr, drawable);
+       Xfree(pdraw);
+       return NULL;
+    }
+
+    pdraw->destroyDrawable = driDestroyDrawable;
+
+    return pdraw;
+}
+
+static void driDestroyScreen(__GLXscreenConfigs *psc)
+{
+    /* Free the direct rendering per screen data */
+    if (psc->__driScreen)
+       (*psc->core->destroyScreen)(psc->__driScreen);
+    psc->__driScreen = NULL;
+    if (psc->driver)
+       dlclose(psc->driver);
+}
+
+static __GLXDRIscreen *driCreateScreen(__GLXscreenConfigs *psc, int screen,
+                                      __GLXdisplayPrivate *priv)
+{
+    __GLXDRIdisplayPrivate *pdp;
+    __GLXDRIscreen *psp;
+    const __DRIextension **extensions;
+    char *driverName;
+    int i;
+
+    psp = Xmalloc(sizeof *psp);
+    if (psp == NULL)
+       return NULL;
+
+    /* Initialize per screen dynamic client GLX extensions */
+    psc->ext_list_first_time = GL_TRUE;
+
+    if (!driGetDriverName(priv->dpy, screen, &driverName)) {
+       Xfree(psp);
+       return NULL;
+    }
+
+    psc->driver = driOpenDriver(driverName);
+    Xfree(driverName);
+    if (psc->driver == NULL) {
+       Xfree(psp);
+       return NULL;
+    }
+
+    extensions = dlsym(psc->driver, __DRI_DRIVER_EXTENSIONS);
+    if (extensions == NULL) {
+       ErrorMessageF("driver exports no extensions (%s)\n", dlerror());
+       Xfree(psp);
+       return NULL;
+    }
+
+    for (i = 0; extensions[i]; i++) {
+       if (strcmp(extensions[i]->name, __DRI_CORE) == 0)
+           psc->core = (__DRIcoreExtension *) extensions[i];
+       if (strcmp(extensions[i]->name, __DRI_LEGACY) == 0)
+           psc->legacy = (__DRIlegacyExtension *) extensions[i];
+    }
+
+    if (psc->core == NULL || psc->legacy == NULL) {
+       Xfree(psp);
+       return NULL;
+    }
+  
+    pdp = (__GLXDRIdisplayPrivate *) priv->driDisplay;
+    psc->__driScreen =
+       CallCreateNewScreen(psc->dpy, screen, psc, pdp);
+    if (psc->__driScreen == NULL) {
+       dlclose(psc->driver);
+       Xfree(psp);
+       return NULL;
+    }
+
+    driBindExtensions(psc);
+
+    psp->destroyScreen = driDestroyScreen;
+    psp->createContext = driCreateContext;
+    psp->createDrawable = driCreateDrawable;
+
+    return psp;
+}
+
+/* Called from __glXFreeDisplayPrivate.
+ */
+static void driDestroyDisplay(__GLXDRIdisplay *dpy)
+{
+    Xfree(dpy);
+}
 
 /*
  * Allocate, initialize and return a __DRIdisplayPrivate object.
  * This is called from __glXInitialize() when we are given a new
  * display pointer.
  */
-void *driCreateDisplay(Display *dpy, __DRIdisplay *pdisp)
+_X_HIDDEN __GLXDRIdisplay *driCreateDisplay(Display *dpy)
 {
-    const int numScreens = ScreenCount(dpy);
-    __DRIdisplayPrivate *pdpyp;
+    __GLXDRIdisplayPrivate *pdpyp;
     int eventBase, errorBase;
     int major, minor, patch;
-    int scrn;
-
-    /* Initialize these fields to NULL in case we fail.
-     * If we don't do this we may later get segfaults trying to free random
-     * addresses when the display is closed.
-     */
-    pdisp->private = NULL;
-    pdisp->destroyDisplay = NULL;
 
     if (!XF86DRIQueryExtension(dpy, &eventBase, &errorBase)) {
        return NULL;
@@ -445,7 +673,7 @@ void *driCreateDisplay(Display *dpy, __DRIdisplay *pdisp)
        return NULL;
     }
 
-    pdpyp = (__DRIdisplayPrivate *)Xmalloc(sizeof(__DRIdisplayPrivate));
+    pdpyp = Xmalloc(sizeof *pdpyp);
     if (!pdpyp) {
        return NULL;
     }
@@ -454,41 +682,10 @@ void *driCreateDisplay(Display *dpy, __DRIdisplay *pdisp)
     pdpyp->driMinor = minor;
     pdpyp->driPatch = patch;
 
-    pdisp->destroyDisplay = driDestroyDisplay;
-
-    /* allocate array of pointers to createNewScreen funcs */
-    pdisp->createNewScreen = (PFNCREATENEWSCREENFUNC *)
-      Xmalloc(numScreens * sizeof(void *));
-    if (!pdisp->createNewScreen) {
-       Xfree(pdpyp);
-       return NULL;
-    }
-
-    /* allocate array of library handles */
-    pdpyp->libraryHandles = (void **) Xmalloc(numScreens * sizeof(void*));
-    if (!pdpyp->libraryHandles) {
-       Xfree(pdisp->createNewScreen);
-       Xfree(pdpyp);
-       return NULL;
-    }
-
-    /* dynamically discover DRI drivers for all screens, saving each
-     * driver's "__driCreateScreen" function pointer.  That's the bootstrap
-     * entrypoint for all DRI drivers.
-     */
-    for (scrn = 0; scrn < numScreens; scrn++) {
-        __DRIdriver *driver = driGetDriver(dpy, scrn);
-        if (driver) {
-           pdisp->createNewScreen[scrn] = driver->createNewScreenFunc;
-           pdpyp->libraryHandles[scrn] = driver->handle;
-        }
-        else {
-           pdisp->createNewScreen[scrn] = NULL;
-           pdpyp->libraryHandles[scrn] = NULL;
-        }
-    }
+    pdpyp->base.destroyDisplay = driDestroyDisplay;
+    pdpyp->base.createScreen = driCreateScreen;
 
-    return (void *)pdpyp;
+    return &pdpyp->base;
 }
 
 #endif /* GLX_DIRECT_RENDERING */
index 788ecf6..326c8b2 100644 (file)
@@ -336,7 +336,8 @@ _gl_get_context_mode_data(const __GLcontextModes *mode, int attribute,
        *value_return = mode->bindToTextureRgba;
        return 0;
       case GLX_BIND_TO_MIPMAP_TEXTURE_EXT:
-       *value_return = mode->bindToMipmapTexture;
+       *value_return = mode->bindToMipmapTexture == GL_TRUE ? GL_TRUE :
+           GL_FALSE;
        return 0;
       case GLX_BIND_TO_TEXTURE_TARGETS_EXT:
        *value_return = mode->bindToTextureTargets;
@@ -417,7 +418,7 @@ _gl_context_modes_create( unsigned count, size_t minimum_size )
       (*next)->bindToTextureRgb = GLX_DONT_CARE;
       (*next)->bindToTextureRgba = GLX_DONT_CARE;
       (*next)->bindToMipmapTexture = GLX_DONT_CARE;
-      (*next)->bindToTextureTargets = 0;
+      (*next)->bindToTextureTargets = GLX_DONT_CARE;
       (*next)->yInverted = GLX_DONT_CARE;
 
       next = & ((*next)->next);
@@ -456,19 +457,28 @@ _gl_context_modes_destroy( __GLcontextModes * modes )
  */
 
 __GLcontextModes *
-_gl_context_modes_find_visual( __GLcontextModes * modes, int vid )
+_gl_context_modes_find_visual(__GLcontextModes *modes, int vid)
 {
-    while ( modes != NULL ) {
-       if ( modes->visualID == vid ) {
-           break;
-       }
+    __GLcontextModes *m;
 
-       modes = modes->next;
-    }
+    for (m = modes; m != NULL; m = m->next)
+       if (m->visualID == vid)
+           return m;
 
-    return modes;
+    return NULL;
 }
 
+__GLcontextModes *
+_gl_context_modes_find_fbconfig(__GLcontextModes *modes, int fbid)
+{
+    __GLcontextModes *m;
+
+    for (m = modes; m != NULL; m = m->next)
+       if (m->fbconfigID == fbid)
+           return m;
+
+    return NULL;
+}
 
 /**
  * Determine if two context-modes are the same.  This is intended to be used
index 4b5c6f6..afd09cd 100644 (file)
@@ -44,8 +44,10 @@ extern int _gl_get_context_mode_data( const __GLcontextModes *mode,
 extern __GLcontextModes * _gl_context_modes_create( unsigned count,
     size_t minimum_size );
 extern void _gl_context_modes_destroy( __GLcontextModes * modes );
-extern  __GLcontextModes * _gl_context_modes_find_visual(
-    __GLcontextModes * modes, int vid );
+extern  __GLcontextModes *
+    _gl_context_modes_find_visual(__GLcontextModes *modes, int vid);
+extern __GLcontextModes *
+    _gl_context_modes_find_fbconfig(__GLcontextModes *modes, int fbid);
 extern GLboolean _gl_context_modes_are_same( const __GLcontextModes * a,
     const __GLcontextModes * b );
 
index 1df2d0f..0f878f2 100644 (file)
@@ -164,6 +164,33 @@ DestroyPbuffer( Display * dpy, GLXDrawable drawable )
 }
 
 
+#ifdef GLX_DIRECT_RENDERING
+extern __GLXDRIdrawable *
+GetGLXDRIDrawable(Display *dpy, GLXDrawable drawable, int * const scrn_num);
+
+static GLenum
+determineTextureTarget(const int *attribs, int numAttribs)
+{
+    GLenum target = 0;
+    int i;
+
+    for (i = 0; i < numAttribs; i++) {
+       if (attribs[2 * i] == GLX_TEXTURE_TARGET_EXT) {
+           switch (attribs[2 * i + 1]) {
+           case GLX_TEXTURE_2D_EXT:
+               target = GL_TEXTURE_2D;
+               break;
+           case GLX_TEXTURE_RECTANGLE_EXT:
+               target = GL_TEXTURE_RECTANGLE_ARB;
+               break;
+           }
+       }
+    }
+    return target;
+}
+#endif
+
 /**
  * Get a drawable's attribute.
  *
@@ -261,6 +288,16 @@ GetDrawableAttribute( Display *dpy, GLXDrawable drawable,
               }
           }
 
+#ifdef GLX_DIRECT_RENDERING
+          {
+               __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, NULL);
+
+               if (pdraw != NULL && !pdraw->textureTarget)
+                   pdraw->textureTarget = determineTextureTarget((const int *)data,
+                                                                 num_attributes);
+          }
+#endif
+
           Xfree( data );
        }
    }
@@ -271,7 +308,6 @@ GetDrawableAttribute( Display *dpy, GLXDrawable drawable,
    return 0;
 }
 
-
 /**
  * Create a non-pbuffer GLX drawable.
  *
@@ -306,7 +342,7 @@ CreateDrawable( Display *dpy, const __GLcontextModes * fbconfig,
    req->glxCode = glxCode;
    req->screen = (CARD32) fbconfig->screen;
    req->fbconfig = fbconfig->fbconfigID;
-   req->window = (GLXPbuffer) drawable;
+   req->window = (CARD32) drawable;
    req->glxwindow = (GLXWindow) XAllocID(dpy);
    req->numAttribs = (CARD32) i;
 
@@ -315,6 +351,34 @@ CreateDrawable( Display *dpy, const __GLcontextModes * fbconfig,
    UnlockDisplay(dpy);
    SyncHandle();
    
+#ifdef GLX_DIRECT_RENDERING
+   do {
+       /* FIXME: Maybe delay __DRIdrawable creation until the drawable
+       * is actually bound to a context... */
+
+       __GLXdisplayPrivate * const priv = __glXInitialize(dpy);
+       __GLXDRIdrawable *pdraw;
+       __GLXscreenConfigs *psc;
+
+       psc = &priv->screenConfigs[fbconfig->screen];
+       if (psc->driScreen == NULL)
+          break;
+       pdraw = psc->driScreen->createDrawable(psc, drawable,
+                                             req->glxwindow, fbconfig);
+       if (pdraw == NULL) {
+          fprintf(stderr, "failed to create drawable\n");
+          break;
+       }
+          
+       if (__glxHashInsert(psc->drawHash, req->glxwindow, pdraw)) {
+          (*pdraw->destroyDrawable)(pdraw);
+          return None; /* FIXME: Check what we're supposed to do here... */
+       }
+
+       pdraw->textureTarget = determineTextureTarget(attrib_list, i);
+   } while (0);
+#endif
+
    return (GLXDrawable)req->glxwindow;
 }
 
@@ -350,6 +414,20 @@ DestroyDrawable( Display * dpy, GLXDrawable drawable, CARD32 glxCode )
    UnlockDisplay(dpy);
    SyncHandle();
 
+#ifdef GLX_DIRECT_RENDERING
+   {
+       int screen;
+       __GLXdisplayPrivate * const priv = __glXInitialize(dpy);
+       __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, &screen);
+       __GLXscreenConfigs *psc = &priv->screenConfigs[screen];
+
+       if (pdraw != NULL) {
+          (*pdraw->destroyDrawable)(pdraw);
+          __glxHashDelete(psc->drawHash, drawable);
+       }
+   }
+#endif
+
    return;
 }
 
@@ -460,8 +538,24 @@ glXCreateGLXPbufferSGIX(Display *dpy, GLXFBConfigSGIX config,
 PUBLIC GLXPbuffer
 glXCreatePbuffer(Display *dpy, GLXFBConfig config, const int *attrib_list)
 {
+   int i, width, height;
+
+   width = 0;
+   height = 0;
+
+   for (i = 0; attrib_list[i * 2]; i++) {
+      switch (attrib_list[i * 2]) {
+      case GLX_PBUFFER_WIDTH:
+        width = attrib_list[i * 2 + 1];
+        break;
+      case GLX_PBUFFER_HEIGHT:
+        height = attrib_list[i * 2 + 1];
+        break;
+      }
+   }
+
    return (GLXPbuffer) CreatePbuffer( dpy, (__GLcontextModes *) config,
-                                     0, 0,
+                                     width, height,
                                      attrib_list, GL_TRUE );
 }
 
diff --git a/src/glx/x11/glx_texture_compression.c b/src/glx/x11/glx_texture_compression.c
deleted file mode 100644 (file)
index 5676858..0000000
+++ /dev/null
@@ -1,347 +0,0 @@
-/*
- * (C) Copyright IBM Corporation 2004
- * All Rights Reserved.
- *
- * 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
- * on the rights to use, copy, modify, merge, publish, distribute, sub
- * license, 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 NON-INFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDERS AND/OR THEIR SUPPLIERS 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.
- */
-
-/**
- * \file glx_texture_compression.c
- * Contains the routines required to implement GLX protocol for
- * ARB_texture_compression and related extensions.
- *
- * \sa http://oss.sgi.com/projects/ogl-sample/registry/ARB/texture_compression.txt
- *
- * \author Ian Romanick <idr@us.ibm.com>
- */
-
-#include "packrender.h"
-#include "packsingle.h"
-#include "indirect.h"
-
-#include <assert.h>
-
-
-void
-__indirect_glGetCompressedTexImageARB( GLenum target, GLint level, 
-                                   GLvoid * img )
-{
-    __GLX_SINGLE_DECLARE_VARIABLES();
-    xGLXGetTexImageReply reply;
-    size_t image_bytes;
-
-    __GLX_SINGLE_LOAD_VARIABLES();
-    __GLX_SINGLE_BEGIN( X_GLsop_GetCompressedTexImage, 8 );
-    __GLX_SINGLE_PUT_LONG( 0, target );
-    __GLX_SINGLE_PUT_LONG( 4, level );
-    __GLX_SINGLE_READ_XREPLY();
-
-    image_bytes = reply.width;
-    assert( image_bytes <= ((4 * reply.length) - 0) );
-    assert( image_bytes >= ((4 * reply.length) - 3) );
-    
-    if ( image_bytes != 0 ) {
-       _XRead( dpy, (char *) img, image_bytes );
-       if ( image_bytes < (4 * reply.length) ) {
-           _XEatData( dpy, (4 * reply.length) - image_bytes );
-       }
-    }
-
-    __GLX_SINGLE_END();
-}
-
-
-/**
- * Internal function used for \c glCompressedTexImage1D and
- * \c glCompressedTexImage2D.
- */
-static void
-CompressedTexImage1D2D( GLenum target, GLint level,
-                       GLenum internal_format, 
-                       GLsizei width, GLsizei height,
-                       GLint border, GLsizei image_size,
-                       const GLvoid *data, CARD32 rop )
-{
-    __GLX_DECLARE_VARIABLES();
-
-    __GLX_LOAD_VARIABLES();
-    if ( gc->currentDpy == NULL ) {
-       return;
-    }
-
-    if ( (target == GL_PROXY_TEXTURE_1D)
-        || (target == GL_PROXY_TEXTURE_2D)
-        || (target == GL_PROXY_TEXTURE_CUBE_MAP) ) {
-       compsize = 0;
-    }
-    else {
-       compsize = image_size;
-    }
-
-    cmdlen = __GLX_PAD( __GLX_COMPRESSED_TEXIMAGE_CMD_HDR_SIZE 
-                       + compsize );
-    if ( cmdlen <= gc->maxSmallRenderCommandSize ) {
-       __GLX_BEGIN_VARIABLE( rop, cmdlen );
-       __GLX_PUT_LONG( 4, target );
-       __GLX_PUT_LONG( 8, level );
-       __GLX_PUT_LONG( 12, internal_format );
-       __GLX_PUT_LONG( 16, width );
-       __GLX_PUT_LONG( 20, height );
-       __GLX_PUT_LONG( 24, border );
-       __GLX_PUT_LONG( 28, image_size );
-       if ( compsize != 0 ) {
-           __GLX_PUT_CHAR_ARRAY( __GLX_COMPRESSED_TEXIMAGE_CMD_HDR_SIZE,
-                                 data, image_size );
-       }
-       __GLX_END( cmdlen );
-    }
-    else {
-       assert( compsize != 0 );
-
-       __GLX_BEGIN_VARIABLE_LARGE( rop, cmdlen + 4 );
-       __GLX_PUT_LONG( 8, target );
-       __GLX_PUT_LONG( 12, level );
-       __GLX_PUT_LONG( 16, internal_format );
-       __GLX_PUT_LONG( 20, width );
-       __GLX_PUT_LONG( 24, height );
-       __GLX_PUT_LONG( 28, border );
-       __GLX_PUT_LONG( 32, image_size );
-       __glXSendLargeCommand( gc, gc->pc,
-                              __GLX_COMPRESSED_TEXIMAGE_CMD_HDR_SIZE + 4,
-                              data, image_size );
-    }
-}
-
-
-/**
- * Internal function used for \c glCompressedTexSubImage1D and
- * \c glCompressedTexSubImage2D.
- */
-static void
-CompressedTexSubImage1D2D( GLenum target, GLint level,
-                          GLsizei xoffset, GLsizei yoffset,
-                          GLsizei width, GLsizei height,
-                          GLenum format, GLsizei image_size,
-                          const GLvoid *data, CARD32 rop )
-{
-    __GLX_DECLARE_VARIABLES();
-
-    __GLX_LOAD_VARIABLES();
-    if ( gc->currentDpy == NULL ) {
-       return;
-    }
-
-    if ( target == GL_PROXY_TEXTURE_3D ) {
-       compsize = 0;
-    }
-    else {
-       compsize = image_size;
-    }
-
-    cmdlen = __GLX_PAD( __GLX_COMPRESSED_TEXSUBIMAGE_CMD_HDR_SIZE
-                       + compsize );
-    if ( cmdlen <= gc->maxSmallRenderCommandSize ) {
-       __GLX_BEGIN_VARIABLE( rop, cmdlen );
-       __GLX_PUT_LONG( 4, target );
-       __GLX_PUT_LONG( 8, level );
-       __GLX_PUT_LONG( 12, xoffset );
-       __GLX_PUT_LONG( 16, yoffset );
-       __GLX_PUT_LONG( 20, width );
-       __GLX_PUT_LONG( 24, height );
-       __GLX_PUT_LONG( 28, format );
-       __GLX_PUT_LONG( 32, image_size );
-       if ( compsize != 0 ) {
-           __GLX_PUT_CHAR_ARRAY( __GLX_COMPRESSED_TEXSUBIMAGE_CMD_HDR_SIZE, 
-                                 data, image_size );
-       }
-       __GLX_END( cmdlen );
-    }
-    else {
-       assert( compsize != 0 );
-
-       __GLX_BEGIN_VARIABLE_LARGE( rop, cmdlen + 4 );
-       __GLX_PUT_LONG( 8, target );
-       __GLX_PUT_LONG( 12, level );
-       __GLX_PUT_LONG( 16, xoffset );
-       __GLX_PUT_LONG( 20, yoffset );
-       __GLX_PUT_LONG( 24, width );
-       __GLX_PUT_LONG( 28, height );
-       __GLX_PUT_LONG( 32, format );
-       __GLX_PUT_LONG( 36, image_size );
-       __glXSendLargeCommand( gc, gc->pc,
-                              __GLX_COMPRESSED_TEXSUBIMAGE_CMD_HDR_SIZE + 4,
-                              data, image_size );
-    }
-}
-
-
-void
-__indirect_glCompressedTexImage1DARB( GLenum target, GLint level,
-                                  GLenum internal_format, GLsizei width,
-                                  GLint border, GLsizei image_size,
-                                  const GLvoid *data )
-{
-    CompressedTexImage1D2D( target, level, internal_format, width, 0,
-                           border, image_size, data,
-                           X_GLrop_CompressedTexImage1D );
-}
-
-
-void
-__indirect_glCompressedTexImage2DARB( GLenum target, GLint level,
-                                  GLenum internal_format,
-                                  GLsizei width, GLsizei height,
-                                  GLint border, GLsizei image_size,
-                                  const GLvoid *data )
-{
-    CompressedTexImage1D2D( target, level, internal_format, width, height,
-                           border, image_size, data,
-                           X_GLrop_CompressedTexImage2D );
-}
-
-
-void
-__indirect_glCompressedTexImage3DARB( GLenum target, GLint level,
-                                  GLenum internal_format,
-                                  GLsizei width, GLsizei height, GLsizei depth,
-                                  GLint border, GLsizei image_size,
-                                  const GLvoid *data )
-{
-    __GLX_DECLARE_VARIABLES();
-    
-    __GLX_LOAD_VARIABLES();
-    if ( gc->currentDpy == NULL ) {
-       return;
-    }
-
-    cmdlen = __GLX_PAD( __GLX_COMPRESSED_TEXIMAGE_3D_CMD_HDR_SIZE
-                       + image_size );
-    if ( cmdlen <= gc->maxSmallRenderCommandSize ) {
-       __GLX_BEGIN_VARIABLE( X_GLrop_CompressedTexImage3D, cmdlen );
-       __GLX_PUT_LONG( 4, target );
-       __GLX_PUT_LONG( 8, level );
-       __GLX_PUT_LONG( 12, internal_format );
-       __GLX_PUT_LONG( 16, width );
-       __GLX_PUT_LONG( 20, height );
-       __GLX_PUT_LONG( 24, depth );
-       __GLX_PUT_LONG( 28, border );
-       __GLX_PUT_LONG( 32, image_size );
-       if ( image_size != 0 ) {
-           __GLX_PUT_CHAR_ARRAY( __GLX_COMPRESSED_TEXIMAGE_3D_CMD_HDR_SIZE,
-                                 data, image_size );
-       }
-       __GLX_END( cmdlen );
-    }
-    else {
-       __GLX_BEGIN_VARIABLE_LARGE( X_GLrop_CompressedTexImage3D,
-                                   cmdlen + 4 );
-       __GLX_PUT_LONG( 8, target );
-       __GLX_PUT_LONG( 12, level );
-       __GLX_PUT_LONG( 16, internal_format );
-       __GLX_PUT_LONG( 20, width );
-       __GLX_PUT_LONG( 24, height );
-       __GLX_PUT_LONG( 28, depth );
-       __GLX_PUT_LONG( 32, border );
-       __GLX_PUT_LONG( 36, image_size );
-       __glXSendLargeCommand( gc, gc->pc,
-                              __GLX_COMPRESSED_TEXIMAGE_3D_CMD_HDR_SIZE + 4,
-                              data, image_size );
-    }
-}
-
-
-void
-__indirect_glCompressedTexSubImage1DARB( GLenum target, GLint level,
-                                     GLint xoffset,
-                                     GLsizei width,
-                                     GLenum format, GLsizei image_size,
-                                     const GLvoid *data )
-{
-    CompressedTexSubImage1D2D( target, level, xoffset, 0, width, 0,
-                              format, image_size, data,
-                              X_GLrop_CompressedTexSubImage1D );
-}
-
-
-void
-__indirect_glCompressedTexSubImage2DARB( GLenum target, GLint level,
-                                     GLint xoffset, GLint yoffset,
-                                     GLsizei width, GLsizei height,
-                                     GLenum format, GLsizei image_size,
-                                     const GLvoid *data )
-{
-    CompressedTexSubImage1D2D( target, level, xoffset, yoffset, width, height,
-                              format, image_size, data,
-                              X_GLrop_CompressedTexSubImage2D );
-}
-
-
-void
-__indirect_glCompressedTexSubImage3DARB( GLenum target, GLint level,
-                                     GLint xoffset, GLint yoffset, GLint zoffset,
-                                     GLsizei width, GLsizei height, GLsizei depth,
-                                     GLenum format, GLsizei image_size,
-                                     const GLvoid *data )
-{
-    __GLX_DECLARE_VARIABLES();
-    
-    __GLX_LOAD_VARIABLES();
-    if ( gc->currentDpy == NULL ) {
-       return;
-    }
-
-    cmdlen = __GLX_PAD( __GLX_COMPRESSED_TEXSUBIMAGE_3D_CMD_HDR_SIZE
-                       + image_size );
-    if ( cmdlen <= gc->maxSmallRenderCommandSize ) {
-       __GLX_BEGIN_VARIABLE( X_GLrop_CompressedTexSubImage3D, cmdlen );
-       __GLX_PUT_LONG( 4, target );
-       __GLX_PUT_LONG( 8, level );
-       __GLX_PUT_LONG( 12, xoffset );
-       __GLX_PUT_LONG( 16, yoffset );
-       __GLX_PUT_LONG( 20, zoffset );
-       __GLX_PUT_LONG( 24, width );
-       __GLX_PUT_LONG( 28, height );
-       __GLX_PUT_LONG( 32, depth );
-       __GLX_PUT_LONG( 36, format );
-       __GLX_PUT_LONG( 40, image_size );
-       if ( image_size != 0 ) {
-           __GLX_PUT_CHAR_ARRAY( __GLX_COMPRESSED_TEXSUBIMAGE_3D_CMD_HDR_SIZE,
-                                 data, image_size );
-       }
-       __GLX_END( cmdlen );
-    }
-    else {
-       __GLX_BEGIN_VARIABLE_LARGE( X_GLrop_CompressedTexSubImage3D,
-                                   cmdlen + 4 );
-       __GLX_PUT_LONG( 8, target );
-       __GLX_PUT_LONG( 12, level );
-       __GLX_PUT_LONG( 16, xoffset );
-       __GLX_PUT_LONG( 20, yoffset );
-       __GLX_PUT_LONG( 24, zoffset );
-       __GLX_PUT_LONG( 28, width );
-       __GLX_PUT_LONG( 32, height );
-       __GLX_PUT_LONG( 36, depth );
-       __GLX_PUT_LONG( 40, format );
-       __GLX_PUT_LONG( 44, image_size );
-       __glXSendLargeCommand( gc, gc->pc,
-                              __GLX_COMPRESSED_TEXSUBIMAGE_3D_CMD_HDR_SIZE + 4,
-                              data, image_size );
-    }
-}
index 03e44e5..73c278e 100644 (file)
@@ -58,7 +58,7 @@
 #include "GL/glxproto.h"
 #include "GL/internal/glcore.h"
 #include "glapitable.h"
-#include "glxextensions.h"
+#include "glxhash.h"
 #if defined( USE_XTHREADS )
 # include <X11/Xthreads.h>
 #elif defined( PTHREADS )
@@ -70,7 +70,9 @@
 
 #define __GLX_MAX_TEXTURE_UNITS 32
 
+typedef struct __GLXscreenConfigsRec __GLXscreenConfigs;
 typedef struct __GLXcontextRec __GLXcontext;
+typedef struct __GLXdrawableRec __GLXdrawable;
 typedef struct __GLXdisplayPrivateRec __GLXdisplayPrivate;
 typedef struct _glapi_table __GLapi;
 
@@ -78,6 +80,9 @@ typedef struct _glapi_table __GLapi;
 
 #ifdef GLX_DIRECT_RENDERING
 
+#define containerOf(ptr, type, member)                 \
+    (type *)( (char *)ptr - offsetof(type,member) )
+
 #include <GL/internal/dri_interface.h>
 
 
@@ -85,43 +90,64 @@ typedef struct _glapi_table __GLapi;
  * Display dependent methods.  This structure is initialized during the
  * \c driCreateDisplay call.
  */
-struct __DRIdisplayRec {
+typedef struct __GLXDRIdisplayRec __GLXDRIdisplay;
+typedef struct __GLXDRIscreenRec __GLXDRIscreen;
+typedef struct __GLXDRIdrawableRec __GLXDRIdrawable;
+typedef struct __GLXDRIcontextRec __GLXDRIcontext;
+
+#include "glxextensions.h"
+
+struct __GLXDRIdisplayRec {
     /**
      * Method to destroy the private DRI display data.
      */
-    void (*destroyDisplay)(Display *dpy, void *displayPrivate);
+    void (*destroyDisplay)(__GLXDRIdisplay *display);
 
-    /**
-     * Opaque pointer to private per display direct rendering data.
-     * \c NULL if direct rendering is not supported on this display.
-     */
-    struct __DRIdisplayPrivateRec *private;
+    __GLXDRIscreen *(*createScreen)(__GLXscreenConfigs *psc, int screen,
+                                   __GLXdisplayPrivate *priv);
+};
 
-    /**
-     * Array of pointers to methods to create and initialize the private DRI
-     * screen data.
-     */
-    PFNCREATENEWSCREENFUNC * createNewScreen;
+struct __GLXDRIscreenRec {
+
+    void (*destroyScreen)(__GLXscreenConfigs *psc);
+
+    __GLXDRIcontext *(*createContext)(__GLXscreenConfigs *psc,
+                                     const __GLcontextModes *mode,
+                                     GLXContext gc,
+                                     GLXContext shareList, int renderType);
+       
+    __GLXDRIdrawable *(*createDrawable)(__GLXscreenConfigs *psc,
+                                       XID drawable,
+                                       GLXDrawable glxDrawable,
+                                       const __GLcontextModes *modes);
 };
 
+struct __GLXDRIcontextRec {
+    void (*destroyContext)(__GLXDRIcontext *context, __GLXscreenConfigs *psc,
+                          Display *dpy);
+    Bool (*bindContext)(__GLXDRIcontext *context,
+                       __GLXDRIdrawable *pdraw,
+                       __GLXDRIdrawable *pread);
+    
+    void (*unbindContext)(__GLXDRIcontext *context);
+};
 
-/*
-** We keep a linked list of these structures, one per DRI device driver.
-*/
-struct __DRIdriverRec {
-   const char *name;
-   void *handle;
-   PFNCREATENEWSCREENFUNC createNewScreenFunc;
-   struct __DRIdriverRec *next;
+struct __GLXDRIdrawableRec {
+    void (*destroyDrawable)(__GLXDRIdrawable *drawable);
+
+    XID xDrawable;
+    XID drawable;
+    __GLXscreenConfigs *psc;
+    __DRIdrawable *driDrawable;
+    GLenum textureTarget;
 };
 
 /*
 ** Function to create and DRI display data and initialize the display
 ** dependent methods.
 */
-extern void *driCreateDisplay(Display *dpy, __DRIdisplay *pdisp);
-
-extern  __DRIdriver *driGetDriver(Display *dpy, int scrNum);
+extern __GLXDRIdisplay *driCreateDisplay(Display *dpy);
+extern __GLXDRIdisplay *dri2CreateDisplay(Display *dpy);
 
 extern void DRI_glXUseXFont( Font font, int first, int count, int listbase );
 
@@ -133,8 +159,6 @@ extern const char *glXGetScreenDriver (Display *dpy, int scrNum);
 
 extern const char *glXGetDriverConfig (const char *driverName);
 
-extern Bool __glXWindowExists(Display *dpy, GLXDrawable draw);
-
 #endif
 
 /************************************************************************/
@@ -226,18 +250,10 @@ struct __GLXcontextRec {
     XID share_xid;
 
     /**
-     * Visual id.
-     * 
-     * \deprecated
-     * This filed has been largely been replaced by the \c mode field, but
-     * the work is not quite done.
-     */
-    VisualID vid;
-
-    /**
      * Screen number.
      */
     GLint screen;
+    __GLXscreenConfigs *psc;
 
     /**
      * \c GL_TRUE if the context was created with ImportContext, which
@@ -343,24 +359,15 @@ struct __GLXcontextRec {
      */
     GLint majorOpcode;
 
-#ifdef GLX_DIRECT_RENDERING
     /**
-     * Per context direct rendering interface functions and data.
+     * Pointer to the mode used to create this context.
      */
-    __DRIcontext driContext;
+    const __GLcontextModes * mode;
+
+#ifdef GLX_DIRECT_RENDERING
+    __GLXDRIcontext *driContext;
+    __DRIcontext *__driContext;
 #endif
-    
-    /**
-     * \c GLXFBConfigID used to create this context.  May be \c None.  This
-     * field has been replaced by the \c mode field.
-     *
-     * \since Internal API version 20030317.
-     *
-     * \deprecated
-     * This filed has been largely been replaced by the \c mode field, but
-     * the work is not quite done.
-     */
-    GLXFBConfigID  fbconfigID;
 
     /**
      * The current read-drawable for this context.  Will be None if this
@@ -438,7 +445,7 @@ extern void __glFreeAttributeState(__GLXcontext *);
  * One of these records exists per screen of the display.  It contains
  * a pointer to the config data for that screen (if the screen supports GL).
  */
-typedef struct __GLXscreenConfigsRec {
+struct __GLXscreenConfigsRec {
     /**
      * GLX extension string reported by the X-server.
      */
@@ -454,13 +461,46 @@ typedef struct __GLXscreenConfigsRec {
     /**
      * Per screen direct rendering interface functions and data.
      */
-    __DRIscreen driScreen;
+    __DRIscreen *__driScreen;
+    const __DRIcoreExtension *core;
+    const __DRIlegacyExtension *legacy;
+    __glxHashTable *drawHash;
+    Display *dpy;
+    int scr, fd;
+    void *driver;
+
+    __GLXDRIscreen *driScreen;
+
+#ifdef __DRI_COPY_SUB_BUFFER
+    const __DRIcopySubBufferExtension *copySubBuffer;
+#endif
+
+#ifdef __DRI_SWAP_CONTROL
+    const __DRIswapControlExtension *swapControl;
+#endif
+
+#ifdef __DRI_ALLOCATE
+    const __DRIallocateExtension *allocate;
+#endif
+
+#ifdef __DRI_FRAME_TRACKING
+    const __DRIframeTrackingExtension *frameTracking;
+#endif
+
+#ifdef __DRI_MEDIA_STREAM_COUNTER
+    const __DRImediaStreamCounterExtension *msc;
+#endif
+
+#ifdef __DRI_TEX_BUFFER
+    const __DRItexBufferExtension *texBuffer;
+#endif
+
 #endif
 
     /**
-     * Linked list of configurations for this screen.
+     * Linked list of glx visuals and  fbconfigs for this screen.
      */
-    __GLcontextModes *configs;
+    __GLcontextModes *visuals, *configs;
 
     /**
      * Per-screen dynamic GLX extension tracking.  The \c direct_support
@@ -474,7 +514,7 @@ typedef struct __GLXscreenConfigsRec {
     GLboolean ext_list_first_time;
     /*@}*/
 
-} __GLXscreenConfigs;
+};
 
 /**
  * Per display private data.  One of these records exists for each display
@@ -523,11 +563,11 @@ struct __GLXdisplayPrivateRec {
     /**
      * Per display direct rendering interface functions and data.
      */
-    __DRIdisplay driDisplay;
+    __GLXDRIdisplay *driDisplay;
+    __GLXDRIdisplay *dri2Display;
 #endif
 };
 
-void __glXFreeContext(__GLXcontext*);
 
 extern GLubyte *__glXFlushRenderBuffer(__GLXcontext*, GLubyte*);
 
@@ -571,6 +611,10 @@ extern __GLXcontext *__glXcurrentContext;
 
 #endif /* defined( USE_XTHREADS ) || defined( PTHREADS ) */
 
+extern void __glXSetCurrentContextNull(void);
+
+extern void __glXFreeContext(__GLXcontext*);
+
 
 /*
 ** Global lock for all threads in this address space using the GLX
@@ -680,13 +724,16 @@ extern char *__glXstrdup(const char *str);
 extern const char __glXGLClientVersion[];
 extern const char __glXGLClientExtensions[];
 
-/* Determine the internal API version */
-extern int __glXGetInternalVersion(void);
-
 /* Get the unadjusted system time */
 extern int __glXGetUST( int64_t * ust );
 
-extern Bool __glXGetMscRateOML(Display * dpy, GLXDrawable drawable,
-    int32_t * numerator, int32_t * denominator);
+extern GLboolean __glXGetMscRateOML(Display * dpy, GLXDrawable drawable,
+                                   int32_t * numerator, int32_t * denominator);
+
+#ifdef GLX_DIRECT_RENDERING
+GLboolean
+__driGetMscRateOML(__DRIdrawable *draw,
+                  int32_t *numerator, int32_t *denominator, void *private);
+#endif
 
 #endif /* !__GLX_client_h__ */
index 8028189..4345678 100644 (file)
  * Client-side GLX interface.
  */
 
-#include <inttypes.h>
 #include "glxclient.h"
-#include <X11/extensions/extutil.h>
-#include <X11/extensions/Xext.h>
-#include <assert.h>
-#include <string.h>
 #include "glapi.h"
-#ifdef GLX_DIRECT_RENDERING
-#include "indirect_init.h"
-#include <X11/extensions/xf86vmode.h>
-#include "xf86dri.h"
-#endif
 #include "glxextensions.h"
 #include "glcontextmodes.h"
 #include "glheader.h"
+
+#ifdef GLX_DIRECT_RENDERING
 #include <sys/time.h>
+#include <X11/extensions/xf86vmode.h>
+#include "xf86dri.h"
+#endif
 
 static const char __glXGLXClientVendorName[] = "SGI";
 static const char __glXGLXClientVersion[] = "1.4";
 
 
 /****************************************************************************/
+
+#ifdef GLX_DIRECT_RENDERING
+
+static Bool windowExistsFlag;
+static int windowExistsErrorHandler(Display *dpy, XErrorEvent *xerr)
+{
+    if (xerr->error_code == BadWindow) {
+       windowExistsFlag = GL_FALSE;
+    }
+    return 0;
+}
+
+/**
+ * Find drawables in the local hash that have been destroyed on the
+ * server.
+ * 
+ * \param dpy    Display to destroy drawables for
+ * \param screen Screen number to destroy drawables for
+ */
+static void GarbageCollectDRIDrawables(Display *dpy, __GLXscreenConfigs *sc)
+{
+    XID draw;
+    __GLXDRIdrawable *pdraw;
+    XWindowAttributes xwa;
+    int (*oldXErrorHandler)(Display *, XErrorEvent *);
+
+    /* Set no-op error handler so Xlib doesn't bail out if the windows
+     * has alreay been destroyed on the server. */
+    XSync(dpy, GL_FALSE);
+    oldXErrorHandler = XSetErrorHandler(windowExistsErrorHandler);
+
+    if (__glxHashFirst(sc->drawHash, &draw, (void *)&pdraw) == 1) {
+       do {
+           windowExistsFlag = GL_TRUE;
+           XGetWindowAttributes(dpy, draw, &xwa); /* dummy request */
+           if (!windowExistsFlag) {
+               /* Destroy the local drawable data, if the drawable no
+                  longer exists in the Xserver */
+               (*pdraw->destroyDrawable)(pdraw);
+                __glxHashDelete(sc->drawHash, draw);
+           }
+       } while (__glxHashNext(sc->drawHash, &draw, (void *)&pdraw) == 1);
+    }
+
+    XSync(dpy, GL_FALSE);
+    XSetErrorHandler(oldXErrorHandler);
+}
+
+extern __GLXDRIdrawable *
+GetGLXDRIDrawable(Display *dpy, GLXDrawable drawable, int * const scrn_num);
+
 /**
  * Get the __DRIdrawable for the drawable associated with a GLXContext
  * 
  * \param dpy       The display associated with \c drawable.
  * \param drawable  GLXDrawable whose __DRIdrawable part is to be retrieved.
+ * \param scrn_num  If non-NULL, the drawables screen is stored there
  * \returns  A pointer to the context's __DRIdrawable on success, or NULL if
  *           the drawable is not associated with a direct-rendering context.
  */
-
-#ifdef GLX_DIRECT_RENDERING
-static __DRIdrawable *
-GetDRIDrawable( Display *dpy, GLXDrawable drawable, int * const scrn_num )
+_X_HIDDEN __GLXDRIdrawable *
+GetGLXDRIDrawable(Display *dpy, GLXDrawable drawable, int * const scrn_num)
 {
-    __GLXdisplayPrivate * const priv = __glXInitialize(dpy);
-
-    if ( (priv != NULL) && (priv->driDisplay.private != NULL) ) {
-       const unsigned  screen_count = ScreenCount(dpy);
-       unsigned   i;
-
-       for ( i = 0 ; i < screen_count ; i++ ) {
-           __DRIscreen * const psc = &priv->screenConfigs[i].driScreen;
-           __DRIdrawable * const pdraw = (psc->private != NULL)
-              ? (*psc->getDrawable)(dpy, drawable, psc->private) : NULL;
+    __GLXdisplayPrivate *priv = __glXInitialize(dpy);
+    __GLXDRIdrawable *pdraw;
+    const unsigned  screen_count = ScreenCount(dpy);
+    unsigned   i;
+    __GLXscreenConfigs *psc;
 
-           if ( pdraw != NULL ) {
-               if ( scrn_num != NULL ) {
-                   *scrn_num = i;
-               }
-               return pdraw;
-           }
+    if (priv == NULL)
+       return NULL;
+    
+    for (i = 0; i < screen_count; i++) {
+       psc = &priv->screenConfigs[i];
+       if (psc->drawHash == NULL)
+           continue;
+
+       if (__glxHashLookup(psc->drawHash, drawable, (void *) &pdraw) == 0) {
+           if (scrn_num != NULL)
+               *scrn_num = i;
+           return pdraw;
        }
     }
 
     return NULL;
 }
+
 #endif
 
 
@@ -264,9 +311,9 @@ GLXContext AllocateGLXContext( Display *dpy )
     */
     gc->fastImageUnpack = GL_FALSE;
     gc->fillImage = __glFillImage;
-    gc->isDirect = GL_FALSE;
     gc->pc = gc->buf;
     gc->bufEnd = gc->buf + bufSize;
+    gc->isDirect = GL_FALSE;
     if (__glXDebug) {
        /*
        ** Set limit register so that there will be one command per packet
@@ -312,6 +359,10 @@ CreateContext(Display *dpy, XVisualInfo *vis,
              Bool use_glx_1_3, int renderType)
 {
     GLXContext gc;
+#ifdef GLX_DIRECT_RENDERING
+    int screen = (fbconfig == NULL) ? vis->screen : fbconfig->screen;
+    __GLXscreenConfigs * const psc = GetGLXScreenConfigs(dpy, screen);
+#endif
 
     if ( dpy == NULL )
        return NULL;
@@ -325,41 +376,36 @@ CreateContext(Display *dpy, XVisualInfo *vis,
            return NULL;
 
 #ifdef GLX_DIRECT_RENDERING
-       if (allowDirect) {
-           int screen = (fbconfig == NULL) ? vis->screen : fbconfig->screen;
-           __GLXscreenConfigs * const psc = GetGLXScreenConfigs(dpy, screen);
+       if (allowDirect && psc->driScreen) {
            const __GLcontextModes * mode;
 
-           /* The value of fbconfig cannot change because it is tested
-            * later in the function.
-            */
-           if ( fbconfig == NULL ) {
-               /* FIXME: Is it possible for the __GLcontextModes structure
-                * FIXME: to not be found?
-                */
-               mode = _gl_context_modes_find_visual( psc->configs,
-                                                     vis->visualid );
-               assert( mode != NULL );
-               assert( mode->screen == screen );
+           if (fbconfig == NULL) {
+               mode = _gl_context_modes_find_visual(psc->visuals, vis->visualid);
+               if (mode == NULL) {
+                  xError error;
+
+                  error.errorCode = BadValue;
+                  error.resourceID = vis->visualid;
+                  error.sequenceNumber = dpy->request;
+                  error.type = X_Error;
+                  error.majorCode = gc->majorOpcode;
+                  error.minorCode = X_GLXCreateContext;
+                  _XError(dpy, &error);
+                  return None;
+               }
            }
            else {
                mode = fbconfig;
            }
 
-           if (psc && psc->driScreen.private) {
-               void * const shared = (shareList != NULL)
-                   ? shareList->driContext.private : NULL;
-               gc->driContext.private = 
-                 (*psc->driScreen.createNewContext)( dpy, mode, renderType,
-                                                     shared,
-                                                     &gc->driContext );
-               if (gc->driContext.private) {
-                   gc->isDirect = GL_TRUE;
-                   gc->screen = mode->screen;
-                   gc->vid = mode->visualID;
-                   gc->fbconfigID = mode->fbconfigID;
-                   gc->driContext.mode = mode;
-               }
+           gc->driContext = psc->driScreen->createContext(psc, mode, gc,
+                                                          shareList,
+                                                          renderType);
+           if (gc->driContext != NULL) {
+               gc->screen = mode->screen;
+               gc->psc = psc;
+               gc->mode = mode;
+               gc->isDirect = GL_TRUE;
            }
        }
 #endif
@@ -376,7 +422,7 @@ CreateContext(Display *dpy, XVisualInfo *vis,
            req->visual = vis->visualid;
            req->screen = vis->screen;
            req->shareList = shareList ? shareList->xid : None;
-           req->isDirect = gc->isDirect;
+           req->isDirect = gc->driContext != NULL;
        }
        else if ( use_glx_1_3 ) {
            xGLXCreateNewContextReq *req;
@@ -390,7 +436,7 @@ CreateContext(Display *dpy, XVisualInfo *vis,
            req->screen = fbconfig->screen;
            req->renderType = renderType;
            req->shareList = shareList ? shareList->xid : None;
-           req->isDirect = gc->isDirect;
+           req->isDirect = gc->driContext != NULL;
        }
        else {
            xGLXVendorPrivateWithReplyReq *vpreq;
@@ -408,7 +454,7 @@ CreateContext(Display *dpy, XVisualInfo *vis,
            req->screen = fbconfig->screen;
            req->renderType = renderType;
            req->shareList = shareList ? shareList->xid : None;
-           req->isDirect = gc->isDirect;
+           req->isDirect = gc->driContext != NULL;
        }
 
        UnlockDisplay(dpy);
@@ -430,7 +476,7 @@ PUBLIC GLXContext glXCreateContext(Display *dpy, XVisualInfo *vis,
                        False, 0);
 }
 
-void __glXFreeContext(__GLXcontext *gc)
+_X_HIDDEN void __glXFreeContext(__GLXcontext *gc)
 {
     if (gc->vendor) XFree((char *) gc->vendor);
     if (gc->renderer) XFree((char *) gc->renderer);
@@ -466,12 +512,10 @@ DestroyContext(Display *dpy, GLXContext gc)
 
 #ifdef GLX_DIRECT_RENDERING
     /* Destroy the direct rendering context */
-    if (gc->isDirect) {
-       if (gc->driContext.private) {
-           (*gc->driContext.destroyContext)(dpy, gc->screen,
-                                            gc->driContext.private);
-           gc->driContext.private = NULL;
-       }
+    if (gc->driContext) {
+       (*gc->driContext->destroyContext)(gc->driContext, gc->psc, dpy);
+       gc->driContext = NULL;
+       GarbageCollectDRIDrawables(dpy, gc->psc);
     }
 #endif
 
@@ -552,7 +596,7 @@ PUBLIC void glXWaitGL(void)
     __glXFlushRenderBuffer(gc, gc->pc);
 
 #ifdef GLX_DIRECT_RENDERING
-    if (gc->isDirect) {
+    if (gc->driContext) {
 /* This bit of ugliness unwraps the glFinish function */
 #ifdef glFinish
 #undef glFinish
@@ -588,7 +632,7 @@ PUBLIC void glXWaitX(void)
     __glXFlushRenderBuffer(gc, gc->pc);
 
 #ifdef GLX_DIRECT_RENDERING
-    if (gc->isDirect) {
+    if (gc->driContext) {
        XSync(dpy, False);
        return;
     }
@@ -618,7 +662,7 @@ PUBLIC void glXUseXFont(Font font, int first, int count, int listBase)
     (void) __glXFlushRenderBuffer(gc, gc->pc);
 
 #ifdef GLX_DIRECT_RENDERING
-    if (gc->isDirect) {
+    if (gc->driContext) {
       DRI_glXUseXFont(font, first, count, listBase);
       return;
     }
@@ -658,7 +702,7 @@ PUBLIC void glXCopyContext(Display *dpy, GLXContext source,
     }
 
 #ifdef GLX_DIRECT_RENDERING
-    if (gc->isDirect) {
+    if (gc->driContext) {
        /* NOT_DONE: This does not work yet */
     }
 #endif
@@ -730,7 +774,7 @@ PUBLIC Bool glXIsDirect(Display *dpy, GLXContext gc)
     if (!gc) {
        return GL_FALSE;
 #ifdef GLX_DIRECT_RENDERING
-    } else if (gc->isDirect) {
+    } else if (gc->driContext) {
        return GL_TRUE;
 #endif
     }
@@ -793,10 +837,10 @@ PUBLIC void glXSwapBuffers(Display *dpy, GLXDrawable drawable)
     GLXContextTag tag;
     CARD8 opcode;
 #ifdef GLX_DIRECT_RENDERING
-    __DRIdrawable *pdraw = GetDRIDrawable( dpy, drawable, NULL );
+    __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, NULL);
 
-    if ( pdraw != NULL ) {
-       (*pdraw->swapBuffers)(dpy, pdraw->private);
+    if (pdraw != NULL) {
+       (*pdraw->psc->core->swapBuffers)(pdraw->driDrawable);
        return;
     }
 #endif
@@ -840,12 +884,12 @@ PUBLIC int glXGetConfig(Display *dpy, XVisualInfo *vis, int attribute,
 {
     __GLXdisplayPrivate *priv;
     __GLXscreenConfigs *psc;
+    __GLcontextModes *modes;
     int   status;
 
     status = GetGLXPrivScreenConfig( dpy, vis->screen, & priv, & psc );
     if ( status == Success ) {
-       const __GLcontextModes * const modes = _gl_context_modes_find_visual(
-                                            psc->configs, vis->visualid );
+       modes = _gl_context_modes_find_visual(psc->visuals, vis->visualid);
 
        /* Lookup attribute after first finding a match on the visual */
        if ( modes != NULL ) {
@@ -1223,7 +1267,7 @@ PUBLIC XVisualInfo *glXChooseVisual(Display *dpy, int screen, int *attribList)
     ** Compute a score for those that do
     ** Remember which visual, if any, got the highest score
     */
-    for ( modes = psc->configs ; modes != NULL ; modes = modes->next ) {
+    for ( modes = psc->visuals ; modes != NULL ; modes = modes->next ) {
        if ( fbconfigs_compatible( & test_config, modes )
             && ((best_config == NULL)
                 || (fbconfig_compare( (const __GLcontextModes * const * const)&modes, &best_config ) < 0)) ) {
@@ -1268,7 +1312,7 @@ PUBLIC const char *glXQueryExtensionsString( Display *dpy, int screen )
 
        __glXCalculateUsableExtensions(psc,
 #ifdef GLX_DIRECT_RENDERING
-                                      (psc->driScreen.private != NULL),
+                                      (psc->driScreen != NULL),
 #else
                                       GL_FALSE,
 #endif
@@ -1447,13 +1491,15 @@ static int __glXQueryContextInfo(Display *dpy, GLXContext ctx)
                    ctx->share_xid = *pProp++;
                    break;
                case GLX_VISUAL_ID_EXT:
-                   ctx->vid = *pProp++;
+                   ctx->mode =
+                       _gl_context_modes_find_visual(ctx->psc->visuals, *pProp++);
                    break;
                case GLX_SCREEN:
                    ctx->screen = *pProp++;
                    break;
                case GLX_FBCONFIG_ID:
-                   ctx->fbconfigID = *pProp++;
+                   ctx->mode =
+                       _gl_context_modes_find_fbconfig(ctx->psc->configs, *pProp++);
                    break;
                case GLX_RENDER_TYPE:
                    ctx->renderType = *pProp++;
@@ -1478,7 +1524,7 @@ glXQueryContext(Display *dpy, GLXContext ctx, int attribute, int *value)
     int retVal;
 
     /* get the information from the server if we don't have it already */
-    if (!ctx->isDirect && (ctx->vid == None)) {
+    if (!ctx->driContext && (ctx->mode == NULL)) {
        retVal = __glXQueryContextInfo(dpy, ctx);
        if (Success != retVal) return retVal;
     }
@@ -1487,13 +1533,13 @@ glXQueryContext(Display *dpy, GLXContext ctx, int attribute, int *value)
        *value = (int)(ctx->share_xid);
        break;
     case GLX_VISUAL_ID_EXT:
-       *value = (int)(ctx->vid);
+       *value = ctx->mode ? ctx->mode->visualID : None;
        break;
     case GLX_SCREEN:
        *value = (int)(ctx->screen);
        break;
     case GLX_FBCONFIG_ID:
-       *value = (int)(ctx->fbconfigID);
+       *value = ctx->mode ? ctx->mode->fbconfigID : None;
        break;
     case GLX_RENDER_TYPE:
        *value = (int)(ctx->renderType);
@@ -1591,6 +1637,7 @@ PUBLIC GLXFBConfig *glXGetFBConfigs(Display *dpy, int screen, int *nelements)
     __GLcontextModes ** config = NULL;
     int   i;
 
+    *nelements = 0;
     if ( (priv->screenConfigs != NULL)
         && (screen >= 0) && (screen <= ScreenCount(dpy))
         && (priv->screenConfigs[screen].configs != NULL)
@@ -1615,8 +1662,10 @@ PUBLIC GLXFBConfig *glXGetFBConfigs(Display *dpy, int screen, int *nelements)
            for ( modes = priv->screenConfigs[screen].configs
                  ; modes != NULL
                  ; modes = modes->next ) {
-               config[i] = modes;
-               i++;
+               if ( modes->fbconfigID != GLX_DONT_CARE ) {
+                   config[i] = modes;
+                   i++;
+               }
            }
        }
     }
@@ -1668,16 +1717,15 @@ static int __glXSwapIntervalSGI(int interval)
       return GLX_BAD_VALUE;
    }
 
-#ifdef GLX_DIRECT_RENDERING
-   if ( gc->isDirect ) {
+#ifdef __DRI_SWAP_CONTROL
+   if (gc->driContext) {
        __GLXscreenConfigs * const psc = GetGLXScreenConfigs( gc->currentDpy,
                                                             gc->screen );
-       __DRIdrawable * const pdraw = GetDRIDrawable( gc->currentDpy,
-                                                    gc->currentDrawable,
-                                                    NULL );
-       if ( __glXExtensionBitIsEnabled( psc, SGI_swap_control_bit )
-           && (pdraw != NULL) ) {
-          pdraw->swap_interval = interval;
+       __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(gc->currentDpy,
+                                                  gc->currentDrawable,
+                                                  NULL);
+       if (psc->swapControl != NULL && pdraw != NULL) {
+          psc->swapControl->setSwapInterval(pdraw->driDrawable, interval);
           return 0;
        }
        else {
@@ -1715,25 +1763,22 @@ static int __glXSwapIntervalSGI(int interval)
 */
 static int __glXSwapIntervalMESA(unsigned int interval)
 {
-#ifdef GLX_DIRECT_RENDERING
+#ifdef __DRI_SWAP_CONTROL
    GLXContext gc = __glXGetCurrentContext();
 
    if ( interval < 0 ) {
       return GLX_BAD_VALUE;
    }
 
-   if ( (gc != NULL) && gc->isDirect ) {
+   if (gc != NULL && gc->driContext) {
       __GLXscreenConfigs * const psc = GetGLXScreenConfigs( gc->currentDpy,
                                                            gc->screen );
       
-      if ( (psc != NULL) && (psc->driScreen.private != NULL)
-          && __glXExtensionBitIsEnabled( psc, MESA_swap_control_bit ) ) {
-        __DRIdrawable * const pdraw = 
-            (*psc->driScreen.getDrawable)(gc->currentDpy,
-                                          gc->currentDrawable,
-                                          psc->driScreen.private);
-        if ( pdraw != NULL ) {
-           pdraw->swap_interval = interval;
+      if ( (psc != NULL) && (psc->driScreen != NULL) ) {
+        __GLXDRIdrawable *pdraw = 
+            GetGLXDRIDrawable(gc->currentDpy, gc->currentDrawable, NULL);
+        if (psc->swapControl != NULL && pdraw != NULL) {
+           psc->swapControl->setSwapInterval(pdraw->driDrawable, interval);
            return 0;
         }
       }
@@ -1748,21 +1793,18 @@ static int __glXSwapIntervalMESA(unsigned int interval)
 
 static int __glXGetSwapIntervalMESA(void)
 {
-#ifdef GLX_DIRECT_RENDERING
+#ifdef __DRI_SWAP_CONTROL
    GLXContext gc = __glXGetCurrentContext();
 
-   if ( (gc != NULL) && gc->isDirect ) {
+   if (gc != NULL && gc->driContext) {
       __GLXscreenConfigs * const psc = GetGLXScreenConfigs( gc->currentDpy,
                                                            gc->screen );
       
-      if ( (psc != NULL) && (psc->driScreen.private != NULL)
-          && __glXExtensionBitIsEnabled( psc, MESA_swap_control_bit ) ) {
-        __DRIdrawable * const pdraw = 
-            (*psc->driScreen.getDrawable)(gc->currentDpy,
-                                          gc->currentDrawable,
-                                          psc->driScreen.private);
-        if ( pdraw != NULL ) {
-           return pdraw->swap_interval;
+      if ( (psc != NULL) && (psc->driScreen != NULL) ) {
+        __GLXDRIdrawable *pdraw = 
+            GetGLXDRIDrawable(gc->currentDpy, gc->currentDrawable, NULL);
+        if (psc->swapControl != NULL && pdraw != NULL) {
+           return psc->swapControl->getSwapInterval(pdraw->driDrawable);
         }
       }
    }
@@ -1779,15 +1821,13 @@ static int __glXGetSwapIntervalMESA(void)
 static GLint __glXBeginFrameTrackingMESA(Display *dpy, GLXDrawable drawable)
 {
    int   status = GLX_BAD_CONTEXT;
-#ifdef GLX_DIRECT_RENDERING
+#ifdef __DRI_FRAME_TRACKING
    int screen;
-   __DRIdrawable * const pdraw = GetDRIDrawable(dpy, drawable, & screen);
+   __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, &screen);
    __GLXscreenConfigs * const psc = GetGLXScreenConfigs(dpy, screen);
 
-   if ( (pdraw != NULL) && (pdraw->frameTracking != NULL)
-       && __glXExtensionBitIsEnabled( psc, MESA_swap_frame_usage_bit ) ) {
-      status = pdraw->frameTracking( dpy, pdraw->private, GL_TRUE );
-   }
+   if (pdraw != NULL && psc->frameTracking != NULL)
+       status = psc->frameTracking->frameTracking(pdraw->driDrawable, GL_TRUE);
 #else
    (void) dpy;
    (void) drawable;
@@ -1799,15 +1839,14 @@ static GLint __glXBeginFrameTrackingMESA(Display *dpy, GLXDrawable drawable)
 static GLint __glXEndFrameTrackingMESA(Display *dpy, GLXDrawable drawable)
 {
    int   status = GLX_BAD_CONTEXT;
-#ifdef GLX_DIRECT_RENDERING
+#ifdef __DRI_FRAME_TRACKING
    int screen;
-   __DRIdrawable * const pdraw = GetDRIDrawable(dpy, drawable, & screen);
-   __GLXscreenConfigs * const psc = GetGLXScreenConfigs(dpy, screen);
+   __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, & screen);
+   __GLXscreenConfigs *psc = GetGLXScreenConfigs(dpy, screen);
 
-   if ( (pdraw != NULL) && (pdraw->frameTracking != NULL)
-       && __glXExtensionBitIsEnabled( psc, MESA_swap_frame_usage_bit ) ) {
-      status = pdraw->frameTracking( dpy, pdraw->private, GL_FALSE );
-   }
+   if (pdraw != NULL && psc->frameTracking != NULL)
+       status = psc->frameTracking->frameTracking(pdraw->driDrawable,
+                                                 GL_FALSE);
 #else
    (void) dpy;
    (void) drawable;
@@ -1820,19 +1859,20 @@ static GLint __glXGetFrameUsageMESA(Display *dpy, GLXDrawable drawable,
                                    GLfloat *usage)
 {
    int   status = GLX_BAD_CONTEXT;
-#ifdef GLX_DIRECT_RENDERING
+#ifdef __DRI_FRAME_TRACKING
    int screen;
-   __DRIdrawable * const pdraw = GetDRIDrawable(dpy, drawable, & screen);
+   __GLXDRIdrawable * const pdraw = GetGLXDRIDrawable(dpy, drawable, & screen);
    __GLXscreenConfigs * const psc = GetGLXScreenConfigs(dpy, screen);
 
-   if ( (pdraw != NULL ) && (pdraw->queryFrameTracking != NULL)
-       && __glXExtensionBitIsEnabled( psc, MESA_swap_frame_usage_bit ) ) {
-      int64_t sbc, missedFrames;
-      float   lastMissedUsage;
+   if (pdraw != NULL && psc->frameTracking != NULL) {
+       int64_t sbc, missedFrames;
+       float   lastMissedUsage;
 
-      status = pdraw->queryFrameTracking( dpy, pdraw->private, &sbc,
-                                         &missedFrames, &lastMissedUsage,
-                                         usage );
+       status = psc->frameTracking->queryFrameTracking(pdraw->driDrawable,
+                                                      &sbc,
+                                                      &missedFrames,
+                                                      &lastMissedUsage,
+                                                      usage);
    }
 #else
    (void) dpy;
@@ -1848,18 +1888,17 @@ static GLint __glXQueryFrameTrackingMESA(Display *dpy, GLXDrawable drawable,
                                         GLfloat *lastMissedUsage)
 {
    int   status = GLX_BAD_CONTEXT;
-#ifdef GLX_DIRECT_RENDERING
+#ifdef __DRI_FRAME_TRACKING
    int screen;
-   __DRIdrawable * const pdraw = GetDRIDrawable(dpy, drawable, & screen);
+   __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, & screen);
    __GLXscreenConfigs * const psc = GetGLXScreenConfigs(dpy, screen);
 
-   if ( (pdraw != NULL ) && (pdraw->queryFrameTracking != NULL)
-       && __glXExtensionBitIsEnabled( psc, MESA_swap_frame_usage_bit ) ) {
+   if (pdraw != NULL && psc->frameTracking != NULL) {
       float   usage;
 
-      status = pdraw->queryFrameTracking( dpy, pdraw->private, sbc,
-                                         missedFrames, lastMissedUsage,
-                                         & usage );
+      status = psc->frameTracking->queryFrameTracking(pdraw->driDrawable,
+                                                     sbc, missedFrames,
+                                                     lastMissedUsage, &usage);
    }
 #else
    (void) dpy;
@@ -1881,21 +1920,24 @@ static int __glXGetVideoSyncSGI(unsigned int *count)
     * FIXME: there should be a GLX encoding for this call.  I can find no
     * FIXME: documentation for the GLX encoding.
     */
-#ifdef GLX_DIRECT_RENDERING
+#ifdef __DRI_MEDIA_STREAM_COUNTER
    GLXContext gc = __glXGetCurrentContext();
 
 
-   if ( (gc != NULL) && gc->isDirect ) {
+   if (gc != NULL && gc->driContext) {
       __GLXscreenConfigs * const psc = GetGLXScreenConfigs( gc->currentDpy,
                                                            gc->screen );
-      if ( __glXExtensionBitIsEnabled( psc, SGI_video_sync_bit )
-          && psc->driScreen.private && psc->driScreen.getMSC) {
-        int       ret;
-        int64_t   temp;
+      if ( psc->msc && psc->driScreen ) {
+          __GLXDRIdrawable *pdraw = 
+              GetGLXDRIDrawable(gc->currentDpy, gc->currentDrawable, NULL);
+         int64_t temp; 
+         int ret;
+         ret = (*psc->msc->getDrawableMSC)(psc->__driScreen,
+                                           pdraw->driDrawable, &temp);
+         *count = (unsigned) temp;
 
-        ret = psc->driScreen.getMSC( psc->driScreen.private, & temp );
-        *count = (unsigned) temp;
-        return (ret == 0) ? 0 : GLX_BAD_CONTEXT;
+         return (ret == 0) ? 0 : GLX_BAD_CONTEXT;
       }
    }
 #else
@@ -1906,32 +1948,26 @@ static int __glXGetVideoSyncSGI(unsigned int *count)
 
 static int __glXWaitVideoSyncSGI(int divisor, int remainder, unsigned int *count)
 {
-#ifdef GLX_DIRECT_RENDERING
+#ifdef __DRI_MEDIA_STREAM_COUNTER
    GLXContext gc = __glXGetCurrentContext();
 
    if ( divisor <= 0 || remainder < 0 )
      return GLX_BAD_VALUE;
 
-   if ( (gc != NULL) && gc->isDirect ) {
+   if (gc != NULL && gc->driContext) {
       __GLXscreenConfigs * const psc = GetGLXScreenConfigs( gc->currentDpy,
                                                            gc->screen );
-      if ( __glXExtensionBitIsEnabled( psc, SGI_video_sync_bit )
-          && psc->driScreen.private ) {
-        __DRIdrawable * const pdraw = 
-            (*psc->driScreen.getDrawable)(gc->currentDpy,
-                                          gc->currentDrawable,
-                                          psc->driScreen.private);
-        if ( (pdraw != NULL) && (pdraw->waitForMSC != NULL) ) {
-           int       ret;
-           int64_t   msc;
-           int64_t   sbc;
-
-           ret = (*pdraw->waitForMSC)( gc->currentDpy, pdraw->private,
-                                       0, divisor, remainder,
-                                       & msc, & sbc );
-           *count = (unsigned) msc;
-           return (ret == 0) ? 0 : GLX_BAD_CONTEXT;
-        }
+      if (psc->msc != NULL && psc->driScreen ) {
+        __GLXDRIdrawable *pdraw = 
+            GetGLXDRIDrawable(gc->currentDpy, gc->currentDrawable, NULL);
+        int       ret;
+        int64_t   msc;
+        int64_t   sbc;
+
+        ret = (*psc->msc->waitForMSC)(pdraw->driDrawable, 0,
+                                      divisor, remainder, &msc, &sbc);
+        *count = (unsigned) msc;
+        return (ret == 0) ? 0 : GLX_BAD_CONTEXT;
       }
    }
 #else
@@ -2083,20 +2119,19 @@ static Bool __glXQueryMaxSwapBarriersSGIX(Display *dpy, int screen, int *max)
 static Bool __glXGetSyncValuesOML(Display *dpy, GLXDrawable drawable,
                                  int64_t *ust, int64_t *msc, int64_t *sbc)
 {
-#ifdef GLX_DIRECT_RENDERING
+#if defined(__DRI_SWAP_BUFFER_COUNTER) && defined(__DRI_MEDIA_STREAM_COUNTER)
     __GLXdisplayPrivate * const priv = __glXInitialize(dpy);
 
     if ( priv != NULL ) {
        int   i;
-       __DRIdrawable * const pdraw = GetDRIDrawable( dpy, drawable, & i );
+       __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, &i);
        __GLXscreenConfigs * const psc = &priv->screenConfigs[i];
 
        assert( (pdraw == NULL) || (i != -1) );
-       return ( (pdraw && pdraw->getSBC && psc->driScreen.getMSC)
-                && __glXExtensionBitIsEnabled( psc, OML_sync_control_bit )
-                && ((*psc->driScreen.getMSC)( psc->driScreen.private, msc ) == 0)
-                && ((*pdraw->getSBC)( dpy, psc->driScreen.private, sbc ) == 0)
-                && (__glXGetUST( ust ) == 0) );
+       return ( (pdraw && psc->sbc && psc->msc)
+                && ((*psc->msc->getMSC)(psc->driScreen, msc) == 0)
+                && ((*psc->sbc->getSBC)(pdraw->driDrawable, sbc) == 0)
+                && (__glXGetUST(ust) == 0) );
     }
 #else
    (void) dpy;
@@ -2108,6 +2143,68 @@ static Bool __glXGetSyncValuesOML(Display *dpy, GLXDrawable drawable,
    return False;
 }
 
+#ifdef GLX_DIRECT_RENDERING
+_X_HIDDEN GLboolean
+__driGetMscRateOML(__DRIdrawable *draw,
+                  int32_t *numerator, int32_t *denominator, void *private)
+{
+#ifdef XF86VIDMODE
+    __GLXscreenConfigs *psc;
+    XF86VidModeModeLine   mode_line;
+    int   dot_clock;
+    int   i;
+    __GLXDRIdrawable *glxDraw = private;
+
+    psc = glxDraw->psc;
+    if (XF86VidModeQueryVersion(psc->dpy, &i, &i) &&
+       XF86VidModeGetModeLine(psc->dpy, psc->scr, &dot_clock, &mode_line) ) {
+       unsigned   n = dot_clock * 1000;
+       unsigned   d = mode_line.vtotal * mode_line.htotal;
+       
+# define V_INTERLACE 0x010
+# define V_DBLSCAN   0x020
+
+       if (mode_line.flags & V_INTERLACE)
+           n *= 2;
+       else if (mode_line.flags & V_DBLSCAN)
+           d *= 2;
+
+       /* The OML_sync_control spec requires that if the refresh rate is a
+        * whole number, that the returned numerator be equal to the refresh
+        * rate and the denominator be 1.
+        */
+
+       if (n % d == 0) {
+           n /= d;
+           d = 1;
+       }
+       else {
+           static const unsigned f[] = { 13, 11, 7, 5, 3, 2, 0 };
+
+           /* This is a poor man's way to reduce a fraction.  It's far from
+            * perfect, but it will work well enough for this situation.
+            */
+
+           for (i = 0; f[i] != 0; i++) {
+               while (n % f[i] == 0 && d % f[i] == 0) {
+                   d /= f[i];
+                   n /= f[i];
+               }
+           }
+       }
+
+       *numerator = n;
+       *denominator = d;
+
+       return True;
+    }
+    else
+       return False;
+#else
+    return False;
+#endif
+}
+#endif
 
 /**
  * Determine the refresh rate of the specified drawable and display.
@@ -2125,70 +2222,17 @@ static Bool __glXGetSyncValuesOML(Display *dpy, GLXDrawable drawable,
  *       when GLX_OML_sync_control appears in the client extension string.
  */
 
-Bool __glXGetMscRateOML(Display * dpy, GLXDrawable drawable,
-                       int32_t * numerator, int32_t * denominator)
+_X_HIDDEN GLboolean __glXGetMscRateOML(Display * dpy, GLXDrawable drawable,
+                                      int32_t * numerator,
+                                      int32_t * denominator)
 {
 #if defined( GLX_DIRECT_RENDERING ) && defined( XF86VIDMODE )
-   __GLXdisplayPrivate * const priv = __glXInitialize(dpy);
-
-
-   if ( priv != NULL ) {
-      XF86VidModeModeLine   mode_line;
-      int   dot_clock;
-      int   screen_num;
-      int   i;
-
-
-      GetDRIDrawable( dpy, drawable, & screen_num );
-      if ( (screen_num != -1)
-          && XF86VidModeQueryVersion( dpy, & i, & i )
-          && XF86VidModeGetModeLine( dpy, screen_num, & dot_clock,
-                                     & mode_line ) ) {
-        unsigned   n = dot_clock * 1000;
-        unsigned   d = mode_line.vtotal * mode_line.htotal;
-
-# define V_INTERLACE 0x010
-# define V_DBLSCAN   0x020
-
-        if ( (mode_line.flags & V_INTERLACE) ) {
-           n *= 2;
-        }
-        else if ( (mode_line.flags & V_DBLSCAN) ) {
-           d *= 2;
-        }
-
-        /* The OML_sync_control spec requires that if the refresh rate is a
-         * whole number, that the returned numerator be equal to the refresh
-         * rate and the denominator be 1.
-         */
+    __GLXDRIdrawable *draw = GetGLXDRIDrawable(dpy, drawable, NULL);
 
-        if ( (n % d) == 0 ) {
-           n /= d;
-           d = 1;
-        }
-        else {
-           static const unsigned f[] = { 13, 11, 7, 5, 3, 2, 0 };
-
-
-           /* This is a poor man's way to reduce a fraction.  It's far from
-            * perfect, but it will work well enough for this situation.
-            */
-
-           for ( i = 0 ; f[i] != 0 ; i++ ) {
-              while ( ((n % f[i]) == 0) && ((d % f[i]) == 0) ) {
-                 d /= f[i];
-                 n /= f[i];
-              }
-           }
-        }
-
-        *numerator = n;
-        *denominator = d;
+    if (draw == NULL)
+       return False;
 
-        (void) drawable;
-        return True;
-      }
-   }
+    return __driGetMscRateOML(draw->driDrawable, numerator, denominator, draw);
 #else
    (void) dpy;
    (void) drawable;
@@ -2203,9 +2247,9 @@ static int64_t __glXSwapBuffersMscOML(Display *dpy, GLXDrawable drawable,
                                      int64_t target_msc, int64_t divisor,
                                      int64_t remainder)
 {
-#ifdef GLX_DIRECT_RENDERING
+#ifdef __DRI_SWAP_BUFFER_COUNTER
    int screen;
-   __DRIdrawable *pdraw = GetDRIDrawable( dpy, drawable, & screen );
+   __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, &screen);
    __GLXscreenConfigs * const psc = GetGLXScreenConfigs( dpy, screen );
 
    /* The OML_sync_control spec says these should "generate a GLX_BAD_VALUE
@@ -2218,11 +2262,10 @@ static int64_t __glXSwapBuffersMscOML(Display *dpy, GLXDrawable drawable,
    if ( divisor > 0 && remainder >= divisor )
       return -1;
 
-   if ( (pdraw != NULL) && (pdraw->swapBuffersMSC != NULL)
-       && __glXExtensionBitIsEnabled( psc, OML_sync_control_bit ) ) {
-      return (*pdraw->swapBuffersMSC)(dpy, pdraw->private, target_msc,
-                                     divisor, remainder);
-   }
+   if (pdraw != NULL && psc->counters != NULL)
+      return (*psc->sbc->swapBuffersMSC)(pdraw->driDrawable, target_msc,
+                                        divisor, remainder);
+
 #else
    (void) dpy;
    (void) drawable;
@@ -2239,9 +2282,9 @@ static Bool __glXWaitForMscOML(Display * dpy, GLXDrawable drawable,
                               int64_t remainder, int64_t *ust,
                               int64_t *msc, int64_t *sbc)
 {
-#ifdef GLX_DIRECT_RENDERING
+#ifdef __DRI_MEDIA_STREAM_COUNTER
    int screen;
-   __DRIdrawable *pdraw = GetDRIDrawable( dpy, drawable, & screen );
+   __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, &screen);
    __GLXscreenConfigs * const psc = GetGLXScreenConfigs( dpy, screen );
    int  ret;
 
@@ -2253,10 +2296,9 @@ static Bool __glXWaitForMscOML(Display * dpy, GLXDrawable drawable,
    if ( divisor > 0 && remainder >= divisor )
       return False;
 
-   if ( (pdraw != NULL) && (pdraw->waitForMSC != NULL)
-       && __glXExtensionBitIsEnabled( psc, OML_sync_control_bit ) ) {
-      ret = (*pdraw->waitForMSC)( dpy, pdraw->private, target_msc,
-                                 divisor, remainder, msc, sbc );
+   if (pdraw != NULL && psc->msc != NULL) {
+      ret = (*psc->msc->waitForMSC)(pdraw->driDrawable, target_msc,
+                                   divisor, remainder, msc, sbc);
 
       /* __glXGetUST returns zero on success and non-zero on failure.
        * This function returns True on success and False on failure.
@@ -2281,9 +2323,9 @@ static Bool __glXWaitForSbcOML(Display * dpy, GLXDrawable drawable,
                               int64_t target_sbc, int64_t *ust,
                               int64_t *msc, int64_t *sbc )
 {
-#ifdef GLX_DIRECT_RENDERING
+#ifdef __DRI_SWAP_BUFFER_COUNTER
    int screen;
-   __DRIdrawable *pdraw = GetDRIDrawable( dpy, drawable, & screen );
+   __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, &screen);
    __GLXscreenConfigs * const psc = GetGLXScreenConfigs( dpy, screen );
    int  ret;
 
@@ -2293,9 +2335,8 @@ static Bool __glXWaitForSbcOML(Display * dpy, GLXDrawable drawable,
    if ( target_sbc < 0 )
       return False;
 
-   if ( (pdraw != NULL) && (pdraw->waitForSBC != NULL)
-       && __glXExtensionBitIsEnabled( psc, OML_sync_control_bit )) {
-      ret = (*pdraw->waitForSBC)( dpy, pdraw->private, target_sbc, msc, sbc );
+   if (pdraw != NULL && psc->sbc != NULL) {
+      ret = (*psc->sbc->waitForSBC)(pdraw->driDrawable, target_sbc, msc, sbc);
 
       /* __glXGetUST returns zero on success and non-zero on failure.
        * This function returns True on success and False on failure.
@@ -2323,16 +2364,13 @@ PUBLIC void *glXAllocateMemoryMESA(Display *dpy, int scrn,
                                   size_t size, float readFreq,
                                   float writeFreq, float priority)
 {
-#ifdef GLX_DIRECT_RENDERING
+#ifdef __DRI_ALLOCATE
    __GLXscreenConfigs * const psc = GetGLXScreenConfigs( dpy, scrn );
 
-   if ( __glXExtensionBitIsEnabled( psc, MESA_allocate_memory_bit ) ) {
-      if (psc && psc->driScreen.private && psc->driScreen.allocateMemory) {
-        return (*psc->driScreen.allocateMemory)( dpy, scrn, size,
-                                                 readFreq, writeFreq,
-                                                 priority );
-      }
-   }
+   if (psc && psc->allocate)
+       return (*psc->allocate->allocateMemory)(psc->__driScreen, size,
+                                              readFreq, writeFreq, priority);
+
 #else
    (void) dpy;
    (void) scrn;
@@ -2348,14 +2386,12 @@ PUBLIC void *glXAllocateMemoryMESA(Display *dpy, int scrn,
 
 PUBLIC void glXFreeMemoryMESA(Display *dpy, int scrn, void *pointer)
 {
-#ifdef GLX_DIRECT_RENDERING
+#ifdef __DRI_ALLOCATE
    __GLXscreenConfigs * const psc = GetGLXScreenConfigs( dpy, scrn );
 
-   if ( __glXExtensionBitIsEnabled( psc, MESA_allocate_memory_bit ) ) {
-      if (psc && psc->driScreen.private && psc->driScreen.freeMemory) {
-        (*psc->driScreen.freeMemory)( dpy, scrn, pointer );
-      }
-   }
+   if (psc && psc->allocate)
+        (*psc->allocate->freeMemory)(psc->__driScreen, pointer);
+
 #else
    (void) dpy;
    (void) scrn;
@@ -2367,14 +2403,12 @@ PUBLIC void glXFreeMemoryMESA(Display *dpy, int scrn, void *pointer)
 PUBLIC GLuint glXGetMemoryOffsetMESA( Display *dpy, int scrn,
                                      const void *pointer )
 {
-#ifdef GLX_DIRECT_RENDERING
+#ifdef __DRI_ALLOCATE
    __GLXscreenConfigs * const psc = GetGLXScreenConfigs( dpy, scrn );
 
-   if ( __glXExtensionBitIsEnabled( psc, MESA_allocate_memory_bit ) ) {
-      if (psc && psc->driScreen.private && psc->driScreen.memoryOffset) {
-        return (*psc->driScreen.memoryOffset)( dpy, scrn, pointer );
-      }
-   }
+   if (psc && psc->allocate)
+       return (*psc->allocate->memoryOffset)(psc->__driScreen, pointer);
+
 #else
    (void) dpy;
    (void) scrn;
@@ -2447,13 +2481,14 @@ static void __glXCopySubBufferMESA(Display *dpy, GLXDrawable drawable,
     INT32 *x_ptr, *y_ptr, *w_ptr, *h_ptr;
     CARD8 opcode;
 
-#ifdef GLX_DIRECT_RENDERING
+#ifdef __DRI_COPY_SUB_BUFFER
     int screen;
-    __DRIdrawable *pdraw = GetDRIDrawable( dpy, drawable, & screen );
+    __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, &screen);
     if ( pdraw != NULL ) {
        __GLXscreenConfigs * const psc = GetGLXScreenConfigs( dpy, screen );
-       if ( __glXExtensionBitIsEnabled( psc, MESA_copy_sub_buffer_bit ) ) {
-           (*pdraw->copySubBuffer)(dpy, pdraw->private, x, y, width, height);
+       if (psc->copySubBuffer != NULL) {
+           (*psc->copySubBuffer->copySubBuffer)(pdraw->driDrawable,
+                                                x, y, width, height);
        }
 
        return;
@@ -2529,8 +2564,16 @@ static void __glXBindTexImageEXT(Display *dpy,
     }
  
 #ifdef GLX_DIRECT_RENDERING
-    if (gc->isDirect)
+    if (gc->driContext) {
+       __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, NULL);
+
+       if (pdraw != NULL)
+           (*pdraw->psc->texBuffer->setTexBuffer)(gc->__driContext,
+                                                  pdraw->textureTarget,
+                                                  pdraw->driDrawable);
+
        return;
+    }
 #endif
 
     opcode = __glXSetupForCommand(dpy);
@@ -2581,7 +2624,7 @@ static void __glXReleaseTexImageEXT(Display *dpy,
        return;
 
 #ifdef GLX_DIRECT_RENDERING
-    if (gc->isDirect)
+    if (gc->driContext)
        return;
 #endif
 
@@ -2613,7 +2656,7 @@ static void __glXReleaseTexImageEXT(Display *dpy,
  * 
  * \sa strdup
  */
-char *
+_X_HIDDEN char *
 __glXstrdup(const char *str)
 {
    char *copy;
@@ -2841,98 +2884,6 @@ PUBLIC void (*glXGetProcAddress(const GLubyte *procName))( void )
 
 #ifdef GLX_DIRECT_RENDERING
 /**
- * Retrieves the verion of the internal libGL API in YYYYMMDD format.  This
- * might be used by the DRI drivers to determine how new libGL is at runtime.
- * Drivers should not call this function directly.  They should instead use
- * \c glXGetProcAddress to obtain a pointer to the function.
- * 
- * \returns An 8-digit decimal number representing the internal libGL API in
- *          YYYYMMDD format.
- * 
- * \sa glXGetProcAddress, PFNGLXGETINTERNALVERSIONPROC
- *
- * \since Internal API version 20021121.
- */
-int __glXGetInternalVersion(void)
-{
-    /* History:
-     * 20021121 - Initial version
-     * 20021128 - Added __glXWindowExists() function
-     * 20021207 - Added support for dynamic GLX extensions,
-     *            GLX_SGI_swap_control, GLX_SGI_video_sync,
-     *            GLX_OML_sync_control, and GLX_MESA_swap_control.
-     *            Never officially released.  Do NOT test against
-     *            this version.  Use 20030317 instead.
-     * 20030317 - Added support GLX_SGIX_fbconfig,
-     *            GLX_MESA_swap_frame_usage, GLX_OML_swap_method,
-     *            GLX_{ARB,SGIS}_multisample, and
-     *            GLX_SGIX_visual_select_group.
-     * 20030606 - Added support for GLX_SGI_make_current_read.
-     * 20030813 - Made support for dynamic extensions multi-head aware.
-     * 20030818 - Added support for GLX_MESA_allocate_memory in place of the
-     *            deprecated GLX_NV_vertex_array_range & GLX_MESA_agp_offset
-     *            interfaces.
-     * 20031201 - Added support for the first round of DRI interface changes.
-     *            Do NOT test against this version!  It has binary
-     *            compatibility bugs, use 20040317 instead.
-     * 20040317 - Added the 'mode' field to __DRIcontextRec.
-     * 20040415 - Added support for bindContext3 and unbindContext3.
-     * 20040602 - Add __glXGetDrawableInfo.  I though that was there
-     *            months ago. :(
-     * 20050727 - Gut all the old interfaces.  This breaks compatability with
-     *            any DRI driver built to any previous version.
-     * 20060314 - Added support for GLX_MESA_copy_sub_buffer.
-     * 20070105 - Added support for damage reporting.
-     */
-    return 20070105;
-}
-
-
-
-static Bool windowExistsFlag;
-
-static int windowExistsErrorHandler(Display *dpy, XErrorEvent *xerr)
-{
-    if (xerr->error_code == BadWindow) {
-        windowExistsFlag = GL_FALSE;
-    }
-    return 0;
-}
-
-/**
- * Determine if a window associated with a \c GLXDrawable exists on the
- * X-server.  This function is not used internally by libGL.  It is provided
- * as a utility function for DRI drivers.
- * Drivers should not call this function directly.  They should instead use
- * \c glXGetProcAddress to obtain a pointer to the function.
- *
- * \param dpy  Display associated with the drawable to be queried.
- * \param draw \c GLXDrawable to test.
- * 
- * \returns \c GL_TRUE if a window exists that is associated with \c draw,
- *          otherwise \c GL_FALSE is returned.
- * 
- * \warning This function is not currently thread-safe.
- *
- * \sa glXGetProcAddress
- *
- * \since Internal API version 20021128.
- */
-Bool __glXWindowExists(Display *dpy, GLXDrawable draw)
-{
-    XWindowAttributes xwa;
-    int (*oldXErrorHandler)(Display *, XErrorEvent *);
-
-    XSync(dpy, GL_FALSE);
-    windowExistsFlag = GL_TRUE;
-    oldXErrorHandler = XSetErrorHandler(windowExistsErrorHandler);
-    XGetWindowAttributes(dpy, draw, &xwa); /* dummy request */
-    XSetErrorHandler(oldXErrorHandler);
-    return windowExistsFlag;
-}
-
-
-/**
  * Get the unadjusted system time (UST).  Currently, the UST is measured in
  * microseconds since Epoc.  The actual resolution of the UST may vary from
  * system to system, and the units may vary from release to release.
@@ -2946,7 +2897,7 @@ Bool __glXWindowExists(Display *dpy, GLXDrawable draw)
  *
  * \since Internal API version 20030317.
  */
-int __glXGetUST( int64_t * ust )
+_X_HIDDEN int __glXGetUST( int64_t * ust )
 {
     struct timeval  tv;
     
index 6403cbd..4d81474 100644 (file)
  */     
 
 #include "glxclient.h"
-#include <stdio.h>
 #include <X11/extensions/Xext.h>
 #include <X11/extensions/extutil.h>
-#include <X11/extensions/Xfixes.h>
-#include <X11/extensions/Xdamage.h>
-#include <assert.h>
-#include "indirect_init.h"
 #include "glapi.h"
 #include "glxextensions.h"
 #include "glcontextmodes.h"
 #include "glheader.h"
 
-#ifdef GLX_DIRECT_RENDERING
-#include <inttypes.h>
-#include <sys/mman.h>
-#include "xf86dri.h"
-#include "sarea.h"
-#include "dri_glx.h"
-#endif
-
 #ifdef USE_XCB
 #include <X11/Xlib-xcb.h>
 #include <xcb/xcb.h>
 #include <xcb/glx.h>
 #endif
 
-#include <assert.h>
 
 #ifdef DEBUG
 void __glXDumpDrawBuffer(__GLXcontext *ctx);
 #endif
 
 #ifdef USE_SPARC_ASM
-/*
- * This is where our dispatch table's bounds are.
- * And the static mesa_init is taken directly from
- * Mesa's 'sparc.c' initializer.
- *
- * We need something like this here, because this version
- * of openGL/glx never initializes a Mesa context, and so
- * the address of the dispatch table pointer never gets stuffed
- * into the dispatch jump table otherwise.
- *
- * It matters only on SPARC, and only if you are using assembler
- * code instead of C-code indirect dispatch.
- *
- * -- FEM, 04.xii.03
- */
-extern unsigned int _mesa_sparc_glapi_begin;
-extern unsigned int _mesa_sparc_glapi_end;
-extern void __glapi_sparc_icache_flush(unsigned int *);
 static void _glx_mesa_init_sparc_glapi_relocs(void);
 static int _mesa_sparc_needs_init = 1;
 #define INIT_MESA_SPARC { \
@@ -107,173 +75,11 @@ static int _mesa_sparc_needs_init = 1;
 #define INIT_MESA_SPARC
 #endif
 
-#ifdef GLX_DIRECT_RENDERING
-static __DRIscreen *__glXFindDRIScreen(__DRInativeDisplay *dpy, int scrn);
-#endif /* GLX_DIRECT_RENDERING */
-
-static Bool MakeContextCurrent(Display *dpy, GLXDrawable draw,
-    GLXDrawable read, GLXContext gc);
-
-/*
-** We setup some dummy structures here so that the API can be used
-** even if no context is current.
-*/
-
-static GLubyte dummyBuffer[__GLX_BUFFER_LIMIT_SIZE];
-
-/*
-** Dummy context used by small commands when there is no current context.
-** All the
-** gl and glx entry points are designed to operate as nop's when using
-** the dummy context structure.
-*/
-static __GLXcontext dummyContext = {
-    &dummyBuffer[0],
-    &dummyBuffer[0],
-    &dummyBuffer[0],
-    &dummyBuffer[__GLX_BUFFER_LIMIT_SIZE],
-    sizeof(dummyBuffer),
-};
-
-
-/*
-** All indirect rendering contexts will share the same indirect dispatch table.
-*/
-static __GLapi *IndirectAPI = NULL;
-
-
-/*
- * Current context management and locking
- */
-
-#if defined( USE_XTHREADS )
-
-/* thread safe */
-static GLboolean TSDinitialized = GL_FALSE;
-static xthread_key_t ContextTSD;
-
-__GLXcontext *__glXGetCurrentContext(void)
-{
-   if (!TSDinitialized) {
-      xthread_key_create(&ContextTSD, NULL);
-      TSDinitialized = GL_TRUE;
-      return &dummyContext;
-   }
-   else {
-      void *p;
-      xthread_get_specific(ContextTSD, &p);
-      if (!p)
-         return &dummyContext;
-      else
-         return (__GLXcontext *) p;
-   }
-}
-
-void __glXSetCurrentContext(__GLXcontext *c)
-{
-   if (!TSDinitialized) {
-      xthread_key_create(&ContextTSD, NULL);
-      TSDinitialized = GL_TRUE;
-   }
-   xthread_set_specific(ContextTSD, c);
-}
-
-
-/* Used by the __glXLock() and __glXUnlock() macros */
-xmutex_rec __glXmutex;
-
-#elif defined( PTHREADS )
-
-pthread_mutex_t __glXmutex = PTHREAD_MUTEX_INITIALIZER;
-
-# if defined( GLX_USE_TLS )
-
-/**
- * Per-thread GLX context pointer.
- * 
- * \c __glXSetCurrentContext is written is such a way that this pointer can
- * \b never be \c NULL.  This is important!  Because of this
- * \c __glXGetCurrentContext can be implemented as trivial macro.
- */
-__thread void * __glX_tls_Context __attribute__((tls_model("initial-exec")))
-    = &dummyContext;
-
-void __glXSetCurrentContext( __GLXcontext * c )
-{
-    __glX_tls_Context = (c != NULL) ? c : &dummyContext;
-}
-
-# else
-
-static pthread_once_t once_control = PTHREAD_ONCE_INIT;
-
-/**
- * Per-thread data key.
- * 
- * Once \c init_thread_data has been called, the per-thread data key will
- * take a value of \c NULL.  As each new thread is created the default
- * value, in that thread, will be \c NULL.
- */
-static pthread_key_t ContextTSD;
-
-/**
- * Initialize the per-thread data key.
- * 
- * This function is called \b exactly once per-process (not per-thread!) to
- * initialize the per-thread data key.  This is ideally done using the
- * \c pthread_once mechanism.
- */
-static void init_thread_data( void )
-{
-    if ( pthread_key_create( & ContextTSD, NULL ) != 0 ) {
-       perror( "pthread_key_create" );
-       exit( -1 );
-    }
-}
-
-void __glXSetCurrentContext( __GLXcontext * c )
-{
-    pthread_once( & once_control, init_thread_data );
-    pthread_setspecific( ContextTSD, c );
-}
-
-__GLXcontext * __glXGetCurrentContext( void )
-{
-    void * v;
-
-    pthread_once( & once_control, init_thread_data );
-
-    v = pthread_getspecific( ContextTSD );
-    return (v == NULL) ? & dummyContext : (__GLXcontext *) v;
-}
-
-# endif /* defined( GLX_USE_TLS ) */
-
-#elif defined( THREADS )
-
-#error Unknown threading method specified.
-
-#else
-
-/* not thread safe */
-__GLXcontext *__glXcurrentContext = &dummyContext;
-
-#endif
-
-
 /*
 ** You can set this cell to 1 to force the gl drawing stuff to be
 ** one command per packet
 */
-int __glXDebug = 0;
-
-/*
-** forward prototype declarations
-*/
-int __glXCloseDisplay(Display *dpy, XExtCodes *codes);
-
-
-/************************************************************************/
+_X_HIDDEN int __glXDebug = 0;
 
 /* Extension required boiler plate */
 
@@ -296,16 +102,13 @@ static /* const */ char *error_list[] = {
     "GLXBadWindow",
 };
 
-int __glXCloseDisplay(Display *dpy, XExtCodes *codes)
+static int __glXCloseDisplay(Display *dpy, XExtCodes *codes)
 {
   GLXContext gc;
 
   gc = __glXGetCurrentContext();
   if (dpy == gc->currentDpy) {
-    __glXSetCurrentContext(&dummyContext);
-#ifdef GLX_DIRECT_RENDERING
-    _glapi_set_dispatch(NULL);  /* no-op functions */
-#endif
+    __glXSetCurrentContextNull();
     __glXFreeContext(gc);
   }
 
@@ -360,11 +163,10 @@ static void FreeScreenConfigs(__GLXdisplayPrivate *priv)
        Xfree((char*) psc->serverGLXexts);
 
 #ifdef GLX_DIRECT_RENDERING
-       /* Free the direct rendering per screen data */
-       if (psc->driScreen.private)
-           (*psc->driScreen.destroyScreen)(priv->dpy, i,
-                                           psc->driScreen.private);
-       psc->driScreen.private = NULL;
+       if (psc->driScreen) {
+           psc->driScreen->destroyScreen(psc);
+           __glxHashDestroy(psc->drawHash);
+       }
 #endif
     }
     XFree((char*) priv->screenConfigs);
@@ -391,14 +193,12 @@ static int __glXFreeDisplayPrivate(XExtData *extension)
 
 #ifdef GLX_DIRECT_RENDERING
     /* Free the direct rendering per display data */
-    if (priv->driDisplay.private)
-       (*priv->driDisplay.destroyDisplay)(priv->dpy,
-                                          priv->driDisplay.private);
-    priv->driDisplay.private = NULL;
-    if (priv->driDisplay.createNewScreen) {
-        Xfree(priv->driDisplay.createNewScreen); /* free array of ptrs */
-        priv->driDisplay.createNewScreen = NULL;
-    }
+    if (priv->driDisplay)
+       (*priv->driDisplay->destroyDisplay)(priv->driDisplay);
+    priv->driDisplay = NULL;
+    if (priv->dri2Display)
+       (*priv->dri2Display->destroyDisplay)(priv->dri2Display);
+    priv->dri2Display = NULL;
 #endif
 
     Xfree((char*) priv);
@@ -440,7 +240,7 @@ static Bool QueryVersion(Display *dpy, int opcode, int *major, int *minor)
 }
 
 
-void 
+_X_HIDDEN void 
 __glXInitializeVisualConfigFromTags( __GLcontextModes *config, int count, 
                                     const INT32 *bp, Bool tagged_only,
                                     Bool fbconfig_style_tags )
@@ -634,371 +434,128 @@ __glXInitializeVisualConfigFromTags( __GLcontextModes *config, int count,
     config->haveStencilBuffer = (config->stencilBits > 0);
 }
 
-
-#ifdef GLX_DIRECT_RENDERING
-static unsigned
-filter_modes( __GLcontextModes ** server_modes,
-             const __GLcontextModes * driver_modes )
+static __GLcontextModes *
+createConfigsFromProperties(Display *dpy, int nvisuals, int nprops,
+                           int screen, GLboolean tagged_only)
 {
-    __GLcontextModes * m;
-    __GLcontextModes ** prev_next;
-    const __GLcontextModes * check;
-    unsigned modes_count = 0;
-
-    if ( driver_modes == NULL ) {
-       fprintf(stderr, "libGL warning: 3D driver returned no fbconfigs.\n");
-       return 0;
-    }
-
-    /* For each mode in server_modes, check to see if a matching mode exists
-     * in driver_modes.  If not, then the mode is not available.
-     */
+    INT32 buf[__GLX_TOTAL_CONFIG], *props;
+    unsigned prop_size;
+    __GLcontextModes *modes, *m;
+    int i;
 
-    prev_next = server_modes;
-    for ( m = *prev_next ; m != NULL ; m = *prev_next ) {
-       GLboolean do_delete = GL_TRUE;
+    if (nprops == 0)
+       return NULL;
 
-       for ( check = driver_modes ; check != NULL ; check = check->next ) {
-           if ( _gl_context_modes_are_same( m, check ) ) {
-               do_delete = GL_FALSE;
-               break;
-           }
-       }
+    /* FIXME: Is the __GLX_MIN_CONFIG_PROPS test correct for FBconfigs? */
 
-       /* The 3D has to support all the modes that match the GLX visuals
-        * sent from the X server.
-        */
-       if ( do_delete && (m->visualID != 0) ) {
-           do_delete = GL_FALSE;
+    /* Check number of properties */
+    if (nprops < __GLX_MIN_CONFIG_PROPS || nprops > __GLX_MAX_CONFIG_PROPS)
+       return NULL;
 
-            if (getenv("LIBGL_DEBUG")) {
-               fprintf(stderr, "libGL warning: 3D driver claims to not support "
-                       "visual 0x%02x\n", m->visualID);
-            }
-       }
+    /* Allocate memory for our config structure */
+    modes = _gl_context_modes_create(nvisuals, sizeof(__GLcontextModes));
+    if (!modes)
+       return NULL;
 
-       if ( do_delete ) {
-           *prev_next = m->next;
+    prop_size = nprops * __GLX_SIZE_INT32;
+    if (prop_size <= sizeof(buf))
+       props = buf;
+    else
+       props = Xmalloc(prop_size);
 
-           m->next = NULL;
-           _gl_context_modes_destroy( m );
-       }
-       else {
-           modes_count++;
-           prev_next = & m->next;
-       }
+    /* Read each config structure and convert it into our format */
+    m = modes;
+    for (i = 0; i < nvisuals; i++) {
+       _XRead(dpy, (char *)props, prop_size);
+       /* Older X servers don't send this so we default it here. */
+       m->drawableType = GLX_WINDOW_BIT;
+       __glXInitializeVisualConfigFromTags(m, nprops, props,
+                                           tagged_only, GL_TRUE);
+       m->screen = screen;
+       m = m->next;
     }
 
-    return modes_count;
-}
+    if (props != buf)
+       Xfree(props);
 
-
-/**
- * Implement \c __DRIinterfaceMethods::getProcAddress.
- */
-static __DRIfuncPtr get_proc_address( const char * proc_name )
-{
-    if (strcmp( proc_name, "glxEnableExtension" ) == 0) {
-       return (__DRIfuncPtr) __glXScrEnableExtension;
-    }
-    
-    return NULL;
+    return modes;
 }
 
-#ifdef XDAMAGE_1_1_INTERFACE
-static GLboolean has_damage_post(__DRInativeDisplay *dpy)
+static GLboolean
+getVisualConfigs(Display *dpy, __GLXdisplayPrivate *priv, int screen)
 {
-    static GLboolean inited = GL_FALSE;
-    static GLboolean has_damage;
-
-    if (!inited) {
-       int major, minor;
-
-       if (XDamageQueryVersion(dpy, &major, &minor) &&
-           major == 1 && minor >= 1)
-       {
-           has_damage = GL_TRUE;
-       } else {
-           has_damage = GL_FALSE;
-       }
-       inited = GL_TRUE;
-    }
+    xGLXGetVisualConfigsReq *req;
+    __GLXscreenConfigs *psc;
+    xGLXGetVisualConfigsReply reply;
+    
+    LockDisplay(dpy);
 
-    return has_damage;
-}
-#endif /* XDAMAGE_1_1_INTERFACE */
+    psc = priv->screenConfigs + screen;
+    psc->visuals = NULL;
+    GetReq(GLXGetVisualConfigs, req);
+    req->reqType = priv->majorOpcode;
+    req->glxCode = X_GLXGetVisualConfigs;
+    req->screen = screen;
 
-static void __glXReportDamage(__DRInativeDisplay *dpy, int screen,
-                             __DRIid drawable,
-                             int x, int y,
-                             drm_clip_rect_t *rects, int num_rects,
-                             GLboolean front_buffer)
-{
-#ifdef XDAMAGE_1_1_INTERFACE
-    XRectangle *xrects;
-    XserverRegion region;
-    int i;
-    int x_off, y_off;
-
-    if (!has_damage_post(dpy))
-       return;
-
-    if (front_buffer) {
-       x_off = x;
-       y_off = y;
-       drawable = RootWindow(dpy, screen);
-    } else{
-       x_off = 0;
-       y_off = 0;
-    }
+    if (!_XReply(dpy, (xReply*) &reply, 0, False))
+       goto out;
 
-    xrects = malloc(sizeof(XRectangle) * num_rects);
-    if (xrects == NULL)
-       return;
+    psc->visuals = createConfigsFromProperties(dpy,
+                                              reply.numVisuals,
+                                              reply.numProps,
+                                              screen, GL_FALSE);
 
-    for (i = 0; i < num_rects; i++) {
-       xrects[i].x = rects[i].x1 + x_off;
-       xrects[i].y = rects[i].y1 + y_off;
-       xrects[i].width = rects[i].x2 - rects[i].x1;
-       xrects[i].height = rects[i].y2 - rects[i].y1;
-    }
-    region = XFixesCreateRegion(dpy, xrects, num_rects);
-    free(xrects);
-    XDamageAdd(dpy, drawable, region);
-    XFixesDestroyRegion(dpy, region);
-#endif
+ out:
+    UnlockDisplay(dpy);
+    return psc->visuals != NULL;
 }
 
-/**
- * Table of functions exported by the loader to the driver.
- */
-static const __DRIinterfaceMethods interface_methods = {
-    get_proc_address,
-
-    _gl_context_modes_create,
-    _gl_context_modes_destroy,
-      
-    __glXFindDRIScreen,
-    __glXWindowExists,
-      
-    XF86DRICreateContextWithConfig,
-    XF86DRIDestroyContext,
-
-    XF86DRICreateDrawable,
-    XF86DRIDestroyDrawable,
-    XF86DRIGetDrawableInfo,
-
-    __glXGetUST,
-    __glXGetMscRateOML,
-
-    __glXReportDamage,
-};
-
-
-
-/**
- * Perform the required libGL-side initialization and call the client-side
- * driver's \c __driCreateNewScreen function.
- * 
- * \param dpy    Display pointer.
- * \param scrn   Screen number on the display.
- * \param psc    DRI screen information.
- * \param driDpy DRI display information.
- * \param createNewScreen  Pointer to the client-side driver's
- *               \c __driCreateNewScreen function.
- * \returns A pointer to the \c __DRIscreenPrivate structure returned by
- *          the client-side driver on success, or \c NULL on failure.
- * 
- * \todo This function needs to be modified to remove context-modes from the
- *       list stored in the \c __GLXscreenConfigsRec to match the list
- *       returned by the client-side driver.
- */
-static void *
-CallCreateNewScreen(Display *dpy, int scrn, __DRIscreen *psc,
-                   __DRIdisplay * driDpy,
-                   PFNCREATENEWSCREENFUNC createNewScreen)
+static GLboolean
+getFBConfigs(Display *dpy, __GLXdisplayPrivate *priv, int screen)
 {
-    __DRIscreenPrivate *psp = NULL;
-#ifndef GLX_USE_APPLEGL
-    drm_handle_t hSAREA;
-    drmAddress pSAREA = MAP_FAILED;
-    char *BusID;
-    __DRIversion   ddx_version;
-    __DRIversion   dri_version;
-    __DRIversion   drm_version;
-    __DRIframebuffer  framebuffer;
-    int   fd = -1;
-    int   status;
-    const char * err_msg;
-    const char * err_extra;
-    int api_ver = __glXGetInternalVersion();
-
-
-    dri_version.major = driDpy->private->driMajor;
-    dri_version.minor = driDpy->private->driMinor;
-    dri_version.patch = driDpy->private->driPatch;
-
-
-    err_msg = "XF86DRIOpenConnection";
-    err_extra = NULL;
-
-    framebuffer.base = MAP_FAILED;
-    framebuffer.dev_priv = NULL;
-
-    if (XF86DRIOpenConnection(dpy, scrn, &hSAREA, &BusID)) {
-        int newlyopened;
-       fd = drmOpenOnce(NULL,BusID, &newlyopened);
-       Xfree(BusID); /* No longer needed */
-
-       err_msg = "open DRM";
-       err_extra = strerror( -fd );
-
-       if (fd >= 0) {
-           drm_magic_t magic;
-
-           err_msg = "drmGetMagic";
-           err_extra = NULL;
-
-           if (!drmGetMagic(fd, &magic)) {
-               drmVersionPtr version = drmGetVersion(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;
-               }
-
-               err_msg = "XF86DRIAuthConnection";
-               if (!newlyopened || XF86DRIAuthConnection(dpy, scrn, magic)) {
-                   char *driverName;
-
-                   /*
-                    * Get device name (like "tdfx") and the ddx version
-                    * numbers.  We'll check the version in each DRI driver's
-                    * "createNewScreen" function.
-                    */
-                   err_msg = "XF86DRIGetClientDriverName";
-                   if (XF86DRIGetClientDriverName(dpy, scrn,
-                                                  &ddx_version.major,
-                                                  &ddx_version.minor,
-                                                  &ddx_version.patch,
-                                                  &driverName)) {
-                       drm_handle_t  hFB;
-                       int        junk;
-
-                       /* No longer needed. */
-                       Xfree( driverName );
-
-
-                       /*
-                        * Get device-specific info.  pDevPriv will point to a struct
-                        * (such as DRIRADEONRec in xfree86/driver/ati/radeon_dri.h)
-                        * that has information about the screen size, depth, pitch,
-                        * ancilliary buffers, DRM mmap handles, etc.
-                        */
-                       err_msg = "XF86DRIGetDeviceInfo";
-                       if (XF86DRIGetDeviceInfo(dpy, scrn,
-                                                &hFB,
-                                                &junk,
-                                                &framebuffer.size,
-                                                &framebuffer.stride,
-                                                &framebuffer.dev_priv_size,
-                                                &framebuffer.dev_priv)) {
-                           framebuffer.width = DisplayWidth(dpy, scrn);
-                           framebuffer.height = DisplayHeight(dpy, scrn);
-
-                           /*
-                            * Map the framebuffer region.
-                            */
-                           status = drmMap(fd, hFB, framebuffer.size, 
-                                           (drmAddressPtr)&framebuffer.base);
-
-                           err_msg = "drmMap of framebuffer";
-                           err_extra = strerror( -status );
-
-                           if ( status == 0 ) {
-                               /*
-                                * Map the SAREA region.  Further mmap regions
-                                * may be setup in each DRI driver's
-                                * "createNewScreen" function.
-                                */
-                               status = drmMap(fd, hSAREA, SAREA_MAX, 
-                                               &pSAREA);
-
-                               err_msg = "drmMap of sarea";
-                               err_extra = strerror( -status );
-
-                               if ( status == 0 ) {
-                                   __GLcontextModes * driver_modes = NULL;
-                                   __GLXscreenConfigs *configs = psc->screenConfigs;
-
-                                   err_msg = "InitDriver";
-                                   err_extra = NULL;
-                                   psp = (*createNewScreen)(dpy, scrn,
-                                                            psc,
-                                                            configs->configs,
-                                                            & ddx_version,
-                                                            & dri_version,
-                                                            & drm_version,
-                                                            & framebuffer,
-                                                            pSAREA,
-                                                            fd,
-                                                            api_ver,
-                                                            & interface_methods,
-                                                            & driver_modes );
-
-                                   filter_modes( & configs->configs,
-                                                 driver_modes );
-                                   _gl_context_modes_destroy( driver_modes );
-                               }
-                           }
-                       }
-                   }
-               }
-           }
-       }
-    }
-
-    if ( psp == NULL ) {
-       if ( pSAREA != MAP_FAILED ) {
-           (void)drmUnmap(pSAREA, SAREA_MAX);
-       }
-
-       if ( framebuffer.base != MAP_FAILED ) {
-           (void)drmUnmap((drmAddress)framebuffer.base, framebuffer.size);
-       }
+    xGLXGetFBConfigsReq *fb_req;
+    xGLXGetFBConfigsSGIXReq *sgi_req;
+    xGLXVendorPrivateWithReplyReq *vpreq;
+    xGLXGetFBConfigsReply reply;
+    __GLXscreenConfigs *psc;
 
-       if ( framebuffer.dev_priv != NULL ) {
-           Xfree(framebuffer.dev_priv);
-       }
+    psc = priv->screenConfigs + screen;
+    psc->serverGLXexts = __glXGetStringFromServer(dpy, priv->majorOpcode,
+                                                 X_GLXQueryServerString,
+                                                 screen, GLX_EXTENSIONS);
 
-       if ( fd >= 0 ) {
-           (void)drmCloseOnce(fd);
-       }
+    LockDisplay(dpy);
 
-       (void)XF86DRICloseConnection(dpy, scrn);
+    psc->configs = NULL;
+    if (atof(priv->serverGLXversion) >= 1.3) {
+       GetReq(GLXGetFBConfigs, fb_req);
+       fb_req->reqType = priv->majorOpcode;
+       fb_req->glxCode = X_GLXGetFBConfigs;
+       fb_req->screen = screen;
+    } else if (strstr(psc->serverGLXexts, "GLX_SGIX_fbconfig") != NULL) {
+       GetReqExtra(GLXVendorPrivateWithReply,
+                   sz_xGLXGetFBConfigsSGIXReq +
+                   sz_xGLXVendorPrivateWithReplyReq, vpreq);
+       sgi_req = (xGLXGetFBConfigsSGIXReq *) vpreq;
+       sgi_req->reqType = priv->majorOpcode;
+       sgi_req->glxCode = X_GLXVendorPrivateWithReply;
+       sgi_req->vendorCode = X_GLXvop_GetFBConfigsSGIX;
+       sgi_req->screen = screen;
+    } else
+       goto out;
 
-       if ( err_extra != NULL ) {
-           fprintf(stderr, "libGL error: %s failed (%s)\n", err_msg,
-                   err_extra);
-       }
-       else {
-           fprintf(stderr, "libGL error: %s failed\n", err_msg );
-       }
+    if (!_XReply(dpy, (xReply*) &reply, 0, False))
+       goto out;
 
-        fprintf(stderr, "libGL error: reverting to (slow) indirect rendering\n");
-    }
-#endif /* !GLX_USE_APPLEGL */
+    psc->configs = createConfigsFromProperties(dpy,
+                                              reply.numFBConfigs,
+                                              reply.numAttribs * 2,
+                                              screen, GL_TRUE);
 
-    return psp;
+ out:
+    UnlockDisplay(dpy);
+    return psc->configs != NULL;
 }
-#endif /* GLX_DIRECT_RENDERING */
-
 
 /*
 ** Allocate the memory for the per screen configs for each screen.
@@ -1006,17 +563,8 @@ CallCreateNewScreen(Display *dpy, int scrn, __DRIscreen *psc,
 */
 static Bool AllocAndFetchScreenConfigs(Display *dpy, __GLXdisplayPrivate *priv)
 {
-    xGLXGetVisualConfigsReq *req;
-    xGLXGetFBConfigsReq *fb_req;
-    xGLXVendorPrivateWithReplyReq *vpreq;
-    xGLXGetFBConfigsSGIXReq *sgi_req;
-    xGLXGetVisualConfigsReply reply;
     __GLXscreenConfigs *psc;
-    __GLcontextModes *config;
-    GLint i, j, nprops, screens;
-    INT32 buf[__GLX_TOTAL_CONFIG], *props;
-    unsigned supported_request = 0;
-    unsigned prop_size;
+    GLint i, screens;
 
     /*
     ** First allocate memory for the array of per screen configs.
@@ -1030,159 +578,30 @@ static Bool AllocAndFetchScreenConfigs(Display *dpy, __GLXdisplayPrivate *priv)
     priv->screenConfigs = psc;
     
     priv->serverGLXversion = __glXGetStringFromServer(dpy, priv->majorOpcode,
-                                        X_GLXQueryServerString,
-                                        0, GLX_VERSION);
+                                                     X_GLXQueryServerString,
+                                                     0, GLX_VERSION);
     if ( priv->serverGLXversion == NULL ) {
        FreeScreenConfigs(priv);
        return GL_FALSE;
     }
 
-    if ( atof( priv->serverGLXversion ) >= 1.3 ) {
-       supported_request = 1;
-    }
-
-    /*
-    ** Now fetch each screens configs structures.  If a screen supports
-    ** GL (by returning a numVisuals > 0) then allocate memory for our
-    ** config structure and then fill it in.
-    */
     for (i = 0; i < screens; i++, psc++) {
-       if ( supported_request != 1 ) {
-           psc->serverGLXexts = __glXGetStringFromServer(dpy, priv->majorOpcode,
-                                                         X_GLXQueryServerString,
-                                                         i, GLX_EXTENSIONS);
-           if ( strstr( psc->serverGLXexts, "GLX_SGIX_fbconfig" ) != NULL ) {
-               supported_request = 2;
-           }
-           else {
-               supported_request = 3;
-           }
-       }
-
-
-       LockDisplay(dpy);
-       switch( supported_request ) {
-           case 1:
-           GetReq(GLXGetFBConfigs,fb_req);
-           fb_req->reqType = priv->majorOpcode;
-           fb_req->glxCode = X_GLXGetFBConfigs;
-           fb_req->screen = i;
-           break;
-          
-           case 2:
-           GetReqExtra(GLXVendorPrivateWithReply,
-                       sz_xGLXGetFBConfigsSGIXReq-sz_xGLXVendorPrivateWithReplyReq,vpreq);
-           sgi_req = (xGLXGetFBConfigsSGIXReq *) vpreq;
-           sgi_req->reqType = priv->majorOpcode;
-           sgi_req->glxCode = X_GLXVendorPrivateWithReply;
-           sgi_req->vendorCode = X_GLXvop_GetFBConfigsSGIX;
-           sgi_req->screen = i;
-           break;
-
-           case 3:
-           GetReq(GLXGetVisualConfigs,req);
-           req->reqType = priv->majorOpcode;
-           req->glxCode = X_GLXGetVisualConfigs;
-           req->screen = i;
-           break;
-       }
-
-       if (!_XReply(dpy, (xReply*) &reply, 0, False)) {
-           /* Something is busted. Punt. */
-           UnlockDisplay(dpy);
-           SyncHandle();
-           FreeScreenConfigs(priv);
-           return GL_FALSE;
-       }
-
-       if (!reply.numVisuals) {
-           /* This screen does not support GL rendering */
-           UnlockDisplay(dpy);
-           continue;
-       }
-
-       /* FIXME: Is the __GLX_MIN_CONFIG_PROPS test correct for
-        * FIXME: FBconfigs? 
-        */
-       /* Check number of properties */
-       nprops = reply.numProps;
-       if ((nprops < __GLX_MIN_CONFIG_PROPS) ||
-           (nprops > __GLX_MAX_CONFIG_PROPS)) {
-           /* Huh?  Not in protocol defined limits.  Punt */
-           UnlockDisplay(dpy);
-           SyncHandle();
-           FreeScreenConfigs(priv);
-           return GL_FALSE;
-       }
-
-       /* Allocate memory for our config structure */
-       psc->configs = _gl_context_modes_create(reply.numVisuals,
-                                               sizeof(__GLcontextModes));
-       if (!psc->configs) {
-           UnlockDisplay(dpy);
-           SyncHandle();
-           FreeScreenConfigs(priv);
-           return GL_FALSE;
-       }
-
-       /* Allocate memory for the properties, if needed */
-       if ( supported_request != 3 ) {
-           nprops *= 2;
-       }
-
-       prop_size = nprops * __GLX_SIZE_INT32;
-
-       if (prop_size <= sizeof(buf)) {
-           props = buf;
-       } else {
-           props = (INT32 *) Xmalloc(prop_size);
-       } 
-
-       /* Read each config structure and convert it into our format */
-        config = psc->configs;
-       for (j = 0; j < reply.numVisuals; j++) {
-           assert( config != NULL );
-           _XRead(dpy, (char *)props, prop_size);
-
-           if ( supported_request != 3 ) {
-               config->rgbMode = GL_TRUE;
-               config->drawableType = GLX_WINDOW_BIT;
-           }
-           else {
-               config->drawableType = GLX_WINDOW_BIT | GLX_PIXMAP_BIT;
-           }
-
-           __glXInitializeVisualConfigFromTags( config, nprops, props,
-                                                (supported_request != 3),
-                                                GL_TRUE );
-           if ( config->fbconfigID == GLX_DONT_CARE ) {
-               config->fbconfigID = config->visualID;
-           }
-           config->screen = i;
-           config = config->next;
-       }
-       if (props != buf) {
-           Xfree((char *)props);
-       }
-       UnlockDisplay(dpy);
+       getVisualConfigs(dpy, priv, i);
+       getFBConfigs(dpy, priv, i);
 
+       psc->scr = i;
+       psc->dpy = dpy;
 #ifdef GLX_DIRECT_RENDERING
-        /* Initialize per screen dynamic client GLX extensions */
-       psc->ext_list_first_time = GL_TRUE;
-       /* Initialize the direct rendering per screen data and functions */
-       if (priv->driDisplay.private != NULL) {
-           /* FIXME: Should it be some sort of an error if createNewScreen[i]
-            * FIXME: is NULL?
-            */
-           if (priv->driDisplay.createNewScreen &&
-               priv->driDisplay.createNewScreen[i]) {
-
-               psc->driScreen.screenConfigs = (void *)psc;
-               psc->driScreen.private =
-                   CallCreateNewScreen(dpy, i, & psc->driScreen,
-                                       & priv->driDisplay,
-                                       priv->driDisplay.createNewScreen[i] );
-           }
+       psc->drawHash = __glxHashCreate();
+       if (psc->drawHash == NULL)
+           continue;
+       if (priv->dri2Display)
+           psc->driScreen = (*priv->dri2Display->createScreen)(psc, i, priv);
+       if (psc->driScreen == NULL && priv->driDisplay)
+           psc->driScreen = (*priv->driDisplay->createScreen)(psc, i, priv);
+       if (psc->driScreen == NULL) {
+           __glxHashDestroy(psc->drawHash);
+           psc->drawHash = NULL;
        }
 #endif
     }
@@ -1193,7 +612,7 @@ static Bool AllocAndFetchScreenConfigs(Display *dpy, __GLXdisplayPrivate *priv)
 /*
 ** Initialize the client side extension code.
 */
-__GLXdisplayPrivate *__glXInitialize(Display* dpy)
+_X_HIDDEN __GLXdisplayPrivate *__glXInitialize(Display* dpy)
 {
     XExtDisplayInfo *info = __glXFindDisplay(dpy);
     XExtData **privList, *private, *found;
@@ -1273,8 +692,8 @@ __GLXdisplayPrivate *__glXInitialize(Display* dpy)
     ** (e.g., those called in AllocAndFetchScreenConfigs).
     */
     if (getenv("LIBGL_ALWAYS_INDIRECT") == NULL) {
-        dpyPriv->driDisplay.private =
-            driCreateDisplay(dpy, &dpyPriv->driDisplay);
+        dpyPriv->dri2Display = dri2CreateDisplay(dpy);
+       dpyPriv->driDisplay = driCreateDisplay(dpy);
     }
 #endif
 
@@ -1308,7 +727,7 @@ __GLXdisplayPrivate *__glXInitialize(Display* dpy)
 ** Setup for sending a GLX command on dpy.  Make sure the extension is
 ** initialized.  Try to avoid calling __glXInitialize as its kinda slow.
 */
-CARD8 __glXSetupForCommand(Display *dpy)
+_X_HIDDEN CARD8 __glXSetupForCommand(Display *dpy)
 {
     GLXContext gc;
     __GLXdisplayPrivate *priv;
@@ -1349,7 +768,7 @@ CARD8 __glXSetupForCommand(Display *dpy)
  * Modify this function to use \c ctx->pc instead of the explicit
  * \c pc parameter.
  */
-GLubyte *__glXFlushRenderBuffer(__GLXcontext *ctx, GLubyte *pc)
+_X_HIDDEN GLubyte *__glXFlushRenderBuffer(__GLXcontext *ctx, GLubyte *pc)
 {
     Display * const dpy = ctx->currentDpy;
 #ifdef USE_XCB
@@ -1361,7 +780,8 @@ GLubyte *__glXFlushRenderBuffer(__GLXcontext *ctx, GLubyte *pc)
 
     if ( (dpy != NULL) && (size > 0) ) {
 #ifdef USE_XCB
-       xcb_glx_render(c, ctx->currentContextTag, size, (char *)ctx->buf);
+       xcb_glx_render(c, ctx->currentContextTag, size,
+                      (const uint8_t *)ctx->buf);
 #else
        /* Send the entire buffer as an X request */
        LockDisplay(dpy);
@@ -1398,9 +818,9 @@ GLubyte *__glXFlushRenderBuffer(__GLXcontext *ctx, GLubyte *pc)
  * \param data           Command data.
  * \param dataLen        Size, in bytes, of the command data.
  */
-void __glXSendLargeChunk(__GLXcontext *gc, GLint requestNumber, 
-                        GLint totalRequests,
-                        const GLvoid * data, GLint dataLen)
+_X_HIDDEN void __glXSendLargeChunk(__GLXcontext *gc, GLint requestNumber, 
+                                  GLint totalRequests,
+                                  const GLvoid * data, GLint dataLen)
 {
     Display *dpy = gc->currentDpy;
 #ifdef USE_XCB
@@ -1446,9 +866,9 @@ void __glXSendLargeChunk(__GLXcontext *gc, GLint requestNumber,
  * \param data       Command data.
  * \param dataLen    Size, in bytes, of the command data.
  */
-void __glXSendLargeCommand(__GLXcontext *ctx,
-                          const GLvoid *header, GLint headerLen,
-                          const GLvoid *data, GLint dataLen)
+_X_HIDDEN void __glXSendLargeCommand(__GLXcontext *ctx,
+                                    const GLvoid *header, GLint headerLen,
+                                    const GLvoid *data, GLint dataLen)
 {
     GLint maxSize;
     GLint totalRequests, requestNumber;
@@ -1484,330 +904,8 @@ void __glXSendLargeCommand(__GLXcontext *ctx,
 
 /************************************************************************/
 
-PUBLIC GLXContext glXGetCurrentContext(void)
-{
-    GLXContext cx = __glXGetCurrentContext();
-    
-    if (cx == &dummyContext) {
-       return NULL;
-    } else {
-       return cx;
-    }
-}
-
-PUBLIC GLXDrawable glXGetCurrentDrawable(void)
-{
-    GLXContext gc = __glXGetCurrentContext();
-    return gc->currentDrawable;
-}
-
-
-/************************************************************************/
-
-#ifdef GLX_DIRECT_RENDERING
-/* Return the DRI per screen structure */
-__DRIscreen *__glXFindDRIScreen(__DRInativeDisplay *dpy, int scrn)
-{
-    __DRIscreen *pDRIScreen = NULL;
-    XExtDisplayInfo *info = __glXFindDisplay(dpy);
-    XExtData **privList, *found;
-    __GLXdisplayPrivate *dpyPriv;
-    XEDataObject dataObj;
-
-    __glXLock();
-    dataObj.display = dpy;
-    privList = XEHeadOfExtensionList(dataObj);
-    found = XFindOnExtensionList(privList, info->codes->extension);
-    __glXUnlock();
-
-    if (found) {
-       dpyPriv = (__GLXdisplayPrivate *)found->private_data;
-       pDRIScreen = &dpyPriv->screenConfigs[scrn].driScreen;
-    }
-
-    return pDRIScreen;
-}
-#endif
-
-/************************************************************************/
-
-static Bool SendMakeCurrentRequest( Display *dpy, CARD8 opcode,
-    GLXContextID gc, GLXContextTag old_gc, GLXDrawable draw, GLXDrawable read,
-    xGLXMakeCurrentReply * reply );
-
-/**
- * Sends a GLX protocol message to the specified display to make the context
- * and the drawables current.
- *
- * \param dpy     Display to send the message to.
- * \param opcode  Major opcode value for the display.
- * \param gc_id   Context tag for the context to be made current.
- * \param draw    Drawable ID for the "draw" drawable.
- * \param read    Drawable ID for the "read" drawable.
- * \param reply   Space to store the X-server's reply.
- *
- * \warning
- * This function assumes that \c dpy is locked with \c LockDisplay on entry.
- */
-static Bool SendMakeCurrentRequest(Display *dpy, CARD8 opcode,
-                                  GLXContextID gc_id, GLXContextTag gc_tag,
-                                  GLXDrawable draw, GLXDrawable read,
-                                  xGLXMakeCurrentReply *reply)
-{
-    Bool ret;
-
-
-    LockDisplay(dpy);
-
-    if (draw == read) {
-       xGLXMakeCurrentReq *req;
-
-       GetReq(GLXMakeCurrent,req);
-       req->reqType = opcode;
-       req->glxCode = X_GLXMakeCurrent;
-       req->drawable = draw;
-       req->context = gc_id;
-       req->oldContextTag = gc_tag;
-    }
-    else {
-       __GLXdisplayPrivate *priv = __glXInitialize(dpy);
-
-       /* If the server can support the GLX 1.3 version, we should
-        * perfer that.  Not only that, some servers support GLX 1.3 but
-        * not the SGI extension.
-        */
-
-       if ((priv->majorVersion > 1) || (priv->minorVersion >= 3)) {
-           xGLXMakeContextCurrentReq *req;
-
-           GetReq(GLXMakeContextCurrent,req);
-           req->reqType = opcode;
-           req->glxCode = X_GLXMakeContextCurrent;
-           req->drawable = draw;
-           req->readdrawable = read;
-           req->context = gc_id;
-           req->oldContextTag = gc_tag;
-       }
-       else {
-           xGLXVendorPrivateWithReplyReq *vpreq;
-           xGLXMakeCurrentReadSGIReq *req;
-
-           GetReqExtra(GLXVendorPrivateWithReply,
-                       sz_xGLXMakeCurrentReadSGIReq-sz_xGLXVendorPrivateWithReplyReq,vpreq);
-           req = (xGLXMakeCurrentReadSGIReq *)vpreq;
-           req->reqType = opcode;
-           req->glxCode = X_GLXVendorPrivateWithReply;
-           req->vendorCode = X_GLXvop_MakeCurrentReadSGI;
-           req->drawable = draw;
-           req->readable = read;
-           req->context = gc_id;
-           req->oldContextTag = gc_tag;
-       }
-    }
-
-    ret = _XReply(dpy, (xReply*) reply, 0, False);
-
-    UnlockDisplay(dpy);
-    SyncHandle();
-
-    return ret;
-}
-
-
-#ifdef GLX_DIRECT_RENDERING
-static Bool BindContextWrapper( Display *dpy, GLXContext gc,
-                               GLXDrawable draw, GLXDrawable read )
-{
-    return (*gc->driContext.bindContext)(dpy, gc->screen, draw, read,
-                                        & gc->driContext);
-}
-
-
-static Bool UnbindContextWrapper( GLXContext gc )
-{
-    return (*gc->driContext.unbindContext)(gc->currentDpy, gc->screen, 
-                                          gc->currentDrawable,
-                                          gc->currentReadable,
-                                          & gc->driContext );
-}
-#endif /* GLX_DIRECT_RENDERING */
-
-
-/**
- * Make a particular context current.
- * 
- * \note This is in this file so that it can access dummyContext.
- */
-USED static Bool MakeContextCurrent(Display *dpy, GLXDrawable draw,
-                                    GLXDrawable read, GLXContext gc)
-{
-    xGLXMakeCurrentReply reply;
-    const GLXContext oldGC = __glXGetCurrentContext();
-    const CARD8 opcode = __glXSetupForCommand(dpy);
-    const CARD8 oldOpcode = ((gc == oldGC) || (oldGC == &dummyContext))
-      ? opcode : __glXSetupForCommand(oldGC->currentDpy);
-    Bool bindReturnValue;
-
-
-    if (!opcode || !oldOpcode) {
-       return GL_FALSE;
-    }
-
-    /* Make sure that the new context has a nonzero ID.  In the request,
-     * a zero context ID is used only to mean that we bind to no current
-     * context.
-     */
-    if ((gc != NULL) && (gc->xid == None)) {
-       return GL_FALSE;
-    }
-
-#ifndef GLX_DIRECT_RENDERING
-    if (gc && gc->isDirect) {
-       return GL_FALSE;
-    }
-#endif
-
-    _glapi_check_multithread();
-
-#ifdef GLX_DIRECT_RENDERING
-    /* Bind the direct rendering context to the drawable */
-    if (gc && gc->isDirect) {
-       bindReturnValue = (gc->driContext.private) 
-         ? BindContextWrapper(dpy, gc, draw, read)
-         : False;
-    } else
-#endif
-    {
-       /* Send a glXMakeCurrent request to bind the new context. */
-       bindReturnValue = 
-         SendMakeCurrentRequest(dpy, opcode, gc ? gc->xid : None,
-                                ((dpy != oldGC->currentDpy) || oldGC->isDirect)
-                                ? None : oldGC->currentContextTag,
-                                draw, read, &reply);
-    }
-
-
-    if (!bindReturnValue) {
-       return False;
-    }
-
-    if ((dpy != oldGC->currentDpy || (gc && gc->isDirect)) &&
-       !oldGC->isDirect && oldGC != &dummyContext) {
-       xGLXMakeCurrentReply dummy_reply;
-
-       /* We are either switching from one dpy to another and have to
-        * send a request to the previous dpy to unbind the previous
-        * context, or we are switching away from a indirect context to
-        * a direct context and have to send a request to the dpy to
-        * unbind the previous context.
-        */
-       (void) SendMakeCurrentRequest(oldGC->currentDpy, oldOpcode, None,
-                                     oldGC->currentContextTag, None, None,
-                                     & dummy_reply);
-    }
-#ifdef GLX_DIRECT_RENDERING
-    else if (oldGC->isDirect && oldGC->driContext.private) {
-       (void) UnbindContextWrapper(oldGC);
-    }
-#endif
-
-
-    /* Update our notion of what is current */
-    __glXLock();
-    if (gc == oldGC) {
-       /* Even though the contexts are the same the drawable might have
-        * changed.  Note that gc cannot be the dummy, and that oldGC
-        * cannot be NULL, therefore if they are the same, gc is not
-        * NULL and not the dummy.
-        */
-       gc->currentDrawable = draw;
-       gc->currentReadable = read;
-    } else {
-       if (oldGC != &dummyContext) {
-           /* Old current context is no longer current to anybody */
-           oldGC->currentDpy = 0;
-           oldGC->currentDrawable = None;
-           oldGC->currentReadable = None;
-           oldGC->currentContextTag = 0;
-
-           if (oldGC->xid == None) {
-               /* We are switching away from a context that was
-                * previously destroyed, so we need to free the memory
-                * for the old handle.
-                */
-#ifdef GLX_DIRECT_RENDERING
-               /* Destroy the old direct rendering context */
-               if (oldGC->isDirect) {
-                   if (oldGC->driContext.private) {
-                       (*oldGC->driContext.destroyContext)
-                           (dpy, oldGC->screen, oldGC->driContext.private);
-                       oldGC->driContext.private = NULL;
-                   }
-               }
-#endif
-               __glXFreeContext(oldGC);
-           }
-       }
-       if (gc) {
-           __glXSetCurrentContext(gc);
-
-           gc->currentDpy = dpy;
-           gc->currentDrawable = draw;
-           gc->currentReadable = read;
-
-            if (!gc->isDirect) {
-               if (!IndirectAPI)
-                  IndirectAPI = __glXNewIndirectAPI();
-               _glapi_set_dispatch(IndirectAPI);
-
-#ifdef GLX_USE_APPLEGL
-               do {
-                   extern void XAppleDRIUseIndirectDispatch(void);
-                   XAppleDRIUseIndirectDispatch();
-               } while (0);
-#endif
-
-               __GLXattribute *state = 
-                 (__GLXattribute *)(gc->client_state_private);
-
-               gc->currentContextTag = reply.contextTag;
-               if (state->array_state == NULL) {
-                   (void) glGetString(GL_EXTENSIONS);
-                   (void) glGetString(GL_VERSION);
-                   __glXInitVertexArrayState(gc);
-               }
-           }
-           else {
-               gc->currentContextTag = -1;
-           }
-       } else {
-           __glXSetCurrentContext(&dummyContext);
-#ifdef GLX_DIRECT_RENDERING
-            _glapi_set_dispatch(NULL);  /* no-op functions */
-#endif
-       }
-    }
-    __glXUnlock();
-    return GL_TRUE;
-}
-
-
-PUBLIC Bool glXMakeCurrent(Display *dpy, GLXDrawable draw, GLXContext gc)
-{
-    return MakeContextCurrent( dpy, draw, draw, gc );
-}
-
-PUBLIC GLX_ALIAS(Bool, glXMakeCurrentReadSGI,
-         (Display *dpy, GLXDrawable d, GLXDrawable r, GLXContext ctx),
-         (dpy, d, r, ctx), MakeContextCurrent)
-
-PUBLIC GLX_ALIAS(Bool, glXMakeContextCurrent,
-         (Display *dpy, GLXDrawable d, GLXDrawable r, GLXContext ctx),
-         (dpy, d, r, ctx), MakeContextCurrent)
-
-
 #ifdef DEBUG
-void __glXDumpDrawBuffer(__GLXcontext *ctx)
+_X_HIDDEN void __glXDumpDrawBuffer(__GLXcontext *ctx)
 {
     GLubyte *p = ctx->buf;
     GLubyte *end = ctx->pc;
@@ -1832,9 +930,23 @@ void __glXDumpDrawBuffer(__GLXcontext *ctx)
 
 #ifdef  USE_SPARC_ASM
 /*
- * Used only when we are sparc, using sparc assembler.
+ * This is where our dispatch table's bounds are.
+ * And the static mesa_init is taken directly from
+ * Mesa's 'sparc.c' initializer.
  *
+ * We need something like this here, because this version
+ * of openGL/glx never initializes a Mesa context, and so
+ * the address of the dispatch table pointer never gets stuffed
+ * into the dispatch jump table otherwise.
+ *
+ * It matters only on SPARC, and only if you are using assembler
+ * code instead of C-code indirect dispatch.
+ *
+ * -- FEM, 04.xii.03
  */
+extern unsigned int _mesa_sparc_glapi_begin;
+extern unsigned int _mesa_sparc_glapi_end;
+extern void __glapi_sparc_icache_flush(unsigned int *);
 
 static void
 _glx_mesa_init_sparc_glapi_relocs(void)
index 1d99b61..e843718 100644 (file)
@@ -356,28 +356,15 @@ __glXProcessServerString( const struct extension_info * ext,
    }
 }
 
-
-/**
- * Enable a named GLX extension on a given screen.
- * Drivers should not call this function directly.  They should instead use
- * \c glXGetProcAddress to obtain a pointer to the function.
- *
- * \param psc   Pointer to GLX per-screen record.
- * \param name  Name of the extension to enable.
- *
- * \sa glXGetProcAddress
- *
- * \since Internal API version 20030813.
- */
 void
-__glXScrEnableExtension( __GLXscreenConfigs *psc, const char * name )
+__glXEnableDirectExtension(__GLXscreenConfigs *psc, const char *name)
 {
-   __glXExtensionsCtr();
-   __glXExtensionsCtrScreen(psc);
-   set_glx_extension( known_glx_extensions, name, strlen( name ), GL_TRUE,
-                     psc->direct_support );
-}
+    __glXExtensionsCtr();
+    __glXExtensionsCtrScreen(psc);
 
+    set_glx_extension(known_glx_extensions,
+                     name, strlen(name), GL_TRUE, psc->direct_support);
+}
 
 /**
  * Initialize global extension support tables.
index a4241b6..9cdd05e 100644 (file)
@@ -234,7 +234,7 @@ extern GLboolean __glXExtensionBitIsEnabled( struct __GLXscreenConfigsRec *psc,
 extern const char * __glXGetClientExtensions( void );
 extern void __glXCalculateUsableExtensions( struct __GLXscreenConfigsRec *psc,
     GLboolean display_is_direct_capable, int server_minor_version );
-extern void __glXScrEnableExtension( struct __GLXscreenConfigsRec *psc, const char * name );
+
 extern void __glXCalculateUsableGLExtensions( struct __GLXcontextRec * gc,
     const char * server_string, int major_version, int minor_version );
 extern void __glXGetGLVersion( int * major_version, int * minor_version );
@@ -243,6 +243,8 @@ extern char * __glXGetClientGLExtensionString( void );
 extern GLboolean __glExtensionBitIsEnabled( const struct __GLXcontextRec * gc, 
     unsigned bit );
 
+extern void
+__glXEnableDirectExtension(__GLXscreenConfigs *psc, const char *name);
 
 /* Source-level backwards compatibility with old drivers. They won't
  * find the respective functions, though. 
index fbb2a91..871addd 100644 (file)
@@ -300,7 +300,9 @@ __indirect_glNewList(GLuint list, GLenum mode)
 {
     __GLXcontext *const gc = __glXGetCurrentContext();
     Display *const dpy = gc->currentDpy;
+#ifndef USE_XCB
     const GLuint cmdlen = 8;
+#endif
     if (__builtin_expect(dpy != NULL, 1)) {
 #ifdef USE_XCB
         xcb_connection_t *c = XGetXCBConnection(dpy);
@@ -324,7 +326,9 @@ __indirect_glEndList(void)
 {
     __GLXcontext *const gc = __glXGetCurrentContext();
     Display *const dpy = gc->currentDpy;
+#ifndef USE_XCB
     const GLuint cmdlen = 0;
+#endif
     if (__builtin_expect(dpy != NULL, 1)) {
 #ifdef USE_XCB
         xcb_connection_t *c = XGetXCBConnection(dpy);
@@ -360,6 +364,10 @@ __indirect_glCallLists(GLsizei n, GLenum type, const GLvoid * lists)
     __GLXcontext *const gc = __glXGetCurrentContext();
     const GLuint compsize = __glCallLists_size(type);
     const GLuint cmdlen = 12 + __GLX_PAD((compsize * n));
+    if (n < 0) {
+        __glXSetError(gc, GL_INVALID_VALUE);
+        return;
+    }
     if (__builtin_expect((n >= 0) && (gc->currentDpy != NULL), 1)) {
         if (cmdlen <= gc->maxSmallRenderCommandSize) {
             if ((gc->pc + cmdlen) > gc->bufEnd) {
@@ -393,7 +401,9 @@ __indirect_glDeleteLists(GLuint list, GLsizei range)
 {
     __GLXcontext *const gc = __glXGetCurrentContext();
     Display *const dpy = gc->currentDpy;
+#ifndef USE_XCB
     const GLuint cmdlen = 8;
+#endif
     if (__builtin_expect(dpy != NULL, 1)) {
 #ifdef USE_XCB
         xcb_connection_t *c = XGetXCBConnection(dpy);
@@ -418,7 +428,9 @@ __indirect_glGenLists(GLsizei range)
     __GLXcontext *const gc = __glXGetCurrentContext();
     Display *const dpy = gc->currentDpy;
     GLuint retval = (GLuint) 0;
+#ifndef USE_XCB
     const GLuint cmdlen = 4;
+#endif
     if (__builtin_expect(dpy != NULL, 1)) {
 #ifdef USE_XCB
         xcb_connection_t *c = XGetXCBConnection(dpy);
@@ -3582,6 +3594,10 @@ __indirect_glPixelMapfv(GLenum map, GLsizei mapsize, const GLfloat * values)
 {
     __GLXcontext *const gc = __glXGetCurrentContext();
     const GLuint cmdlen = 12 + __GLX_PAD((mapsize * 4));
+    if (mapsize < 0) {
+        __glXSetError(gc, GL_INVALID_VALUE);
+        return;
+    }
     if (__builtin_expect((mapsize >= 0) && (gc->currentDpy != NULL), 1)) {
         if (cmdlen <= gc->maxSmallRenderCommandSize) {
             if ((gc->pc + cmdlen) > gc->bufEnd) {
@@ -3615,6 +3631,10 @@ __indirect_glPixelMapuiv(GLenum map, GLsizei mapsize, const GLuint * values)
 {
     __GLXcontext *const gc = __glXGetCurrentContext();
     const GLuint cmdlen = 12 + __GLX_PAD((mapsize * 4));
+    if (mapsize < 0) {
+        __glXSetError(gc, GL_INVALID_VALUE);
+        return;
+    }
     if (__builtin_expect((mapsize >= 0) && (gc->currentDpy != NULL), 1)) {
         if (cmdlen <= gc->maxSmallRenderCommandSize) {
             if ((gc->pc + cmdlen) > gc->bufEnd) {
@@ -3648,6 +3668,10 @@ __indirect_glPixelMapusv(GLenum map, GLsizei mapsize, const GLushort * values)
 {
     __GLXcontext *const gc = __glXGetCurrentContext();
     const GLuint cmdlen = 12 + __GLX_PAD((mapsize * 2));
+    if (mapsize < 0) {
+        __glXSetError(gc, GL_INVALID_VALUE);
+        return;
+    }
     if (__builtin_expect((mapsize >= 0) && (gc->currentDpy != NULL), 1)) {
         if (cmdlen <= gc->maxSmallRenderCommandSize) {
             if ((gc->pc + cmdlen) > gc->bufEnd) {
@@ -3716,7 +3740,9 @@ __indirect_glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height,
     __GLXcontext *const gc = __glXGetCurrentContext();
     const __GLXattribute *const state = gc->client_state_private;
     Display *const dpy = gc->currentDpy;
+#ifndef USE_XCB
     const GLuint cmdlen = 28;
+#endif
     if (__builtin_expect(dpy != NULL, 1)) {
 #ifdef USE_XCB
         xcb_connection_t *c = XGetXCBConnection(dpy);
@@ -3808,7 +3834,9 @@ __indirect_glGetClipPlane(GLenum plane, GLdouble * equation)
 {
     __GLXcontext *const gc = __glXGetCurrentContext();
     Display *const dpy = gc->currentDpy;
+#ifndef USE_XCB
     const GLuint cmdlen = 4;
+#endif
     if (__builtin_expect(dpy != NULL, 1)) {
 #ifdef USE_XCB
         xcb_connection_t *c = XGetXCBConnection(dpy);
@@ -3841,7 +3869,9 @@ __indirect_glGetLightfv(GLenum light, GLenum pname, GLfloat * params)
 {
     __GLXcontext *const gc = __glXGetCurrentContext();
     Display *const dpy = gc->currentDpy;
+#ifndef USE_XCB
     const GLuint cmdlen = 8;
+#endif
     if (__builtin_expect(dpy != NULL, 1)) {
 #ifdef USE_XCB
         xcb_connection_t *c = XGetXCBConnection(dpy);
@@ -3879,7 +3909,9 @@ __indirect_glGetLightiv(GLenum light, GLenum pname, GLint * params)
 {
     __GLXcontext *const gc = __glXGetCurrentContext();
     Display *const dpy = gc->currentDpy;
+#ifndef USE_XCB
     const GLuint cmdlen = 8;
+#endif
     if (__builtin_expect(dpy != NULL, 1)) {
 #ifdef USE_XCB
         xcb_connection_t *c = XGetXCBConnection(dpy);
@@ -3917,7 +3949,9 @@ __indirect_glGetMapdv(GLenum target, GLenum query, GLdouble * v)
 {
     __GLXcontext *const gc = __glXGetCurrentContext();
     Display *const dpy = gc->currentDpy;
+#ifndef USE_XCB
     const GLuint cmdlen = 8;
+#endif
     if (__builtin_expect(dpy != NULL, 1)) {
 #ifdef USE_XCB
         xcb_connection_t *c = XGetXCBConnection(dpy);
@@ -3953,7 +3987,9 @@ __indirect_glGetMapfv(GLenum target, GLenum query, GLfloat * v)
 {
     __GLXcontext *const gc = __glXGetCurrentContext();
     Display *const dpy = gc->currentDpy;
+#ifndef USE_XCB
     const GLuint cmdlen = 8;
+#endif
     if (__builtin_expect(dpy != NULL, 1)) {
 #ifdef USE_XCB
         xcb_connection_t *c = XGetXCBConnection(dpy);
@@ -3989,7 +4025,9 @@ __indirect_glGetMapiv(GLenum target, GLenum query, GLint * v)
 {
     __GLXcontext *const gc = __glXGetCurrentContext();
     Display *const dpy = gc->currentDpy;
+#ifndef USE_XCB
     const GLuint cmdlen = 8;
+#endif
     if (__builtin_expect(dpy != NULL, 1)) {
 #ifdef USE_XCB
         xcb_connection_t *c = XGetXCBConnection(dpy);
@@ -4025,7 +4063,9 @@ __indirect_glGetMaterialfv(GLenum face, GLenum pname, GLfloat * params)
 {
     __GLXcontext *const gc = __glXGetCurrentContext();
     Display *const dpy = gc->currentDpy;
+#ifndef USE_XCB
     const GLuint cmdlen = 8;
+#endif
     if (__builtin_expect(dpy != NULL, 1)) {
 #ifdef USE_XCB
         xcb_connection_t *c = XGetXCBConnection(dpy);
@@ -4063,7 +4103,9 @@ __indirect_glGetMaterialiv(GLenum face, GLenum pname, GLint * params)
 {
     __GLXcontext *const gc = __glXGetCurrentContext();
     Display *const dpy = gc->currentDpy;
+#ifndef USE_XCB
     const GLuint cmdlen = 8;
+#endif
     if (__builtin_expect(dpy != NULL, 1)) {
 #ifdef USE_XCB
         xcb_connection_t *c = XGetXCBConnection(dpy);
@@ -4101,7 +4143,9 @@ __indirect_glGetPixelMapfv(GLenum map, GLfloat * values)
 {
     __GLXcontext *const gc = __glXGetCurrentContext();
     Display *const dpy = gc->currentDpy;
+#ifndef USE_XCB
     const GLuint cmdlen = 4;
+#endif
     if (__builtin_expect(dpy != NULL, 1)) {
 #ifdef USE_XCB
         xcb_connection_t *c = XGetXCBConnection(dpy);
@@ -4137,7 +4181,9 @@ __indirect_glGetPixelMapuiv(GLenum map, GLuint * values)
 {
     __GLXcontext *const gc = __glXGetCurrentContext();
     Display *const dpy = gc->currentDpy;
+#ifndef USE_XCB
     const GLuint cmdlen = 4;
+#endif
     if (__builtin_expect(dpy != NULL, 1)) {
 #ifdef USE_XCB
         xcb_connection_t *c = XGetXCBConnection(dpy);
@@ -4174,7 +4220,9 @@ __indirect_glGetPixelMapusv(GLenum map, GLushort * values)
 {
     __GLXcontext *const gc = __glXGetCurrentContext();
     Display *const dpy = gc->currentDpy;
+#ifndef USE_XCB
     const GLuint cmdlen = 4;
+#endif
     if (__builtin_expect(dpy != NULL, 1)) {
 #ifdef USE_XCB
         xcb_connection_t *c = XGetXCBConnection(dpy);
@@ -4210,9 +4258,10 @@ void
 __indirect_glGetPolygonStipple(GLubyte *mask)
 {
     __GLXcontext *const gc = __glXGetCurrentContext();
-    const __GLXattribute *const state = gc->client_state_private;
     Display *const dpy = gc->currentDpy;
+#ifndef USE_XCB
     const GLuint cmdlen = 4;
+#endif
     if (__builtin_expect(dpy != NULL, 1)) {
 #ifdef USE_XCB
         xcb_connection_t *c = XGetXCBConnection(dpy);
@@ -4247,7 +4296,9 @@ __indirect_glGetTexEnvfv(GLenum target, GLenum pname, GLfloat * params)
 {
     __GLXcontext *const gc = __glXGetCurrentContext();
     Display *const dpy = gc->currentDpy;
+#ifndef USE_XCB
     const GLuint cmdlen = 8;
+#endif
     if (__builtin_expect(dpy != NULL, 1)) {
 #ifdef USE_XCB
         xcb_connection_t *c = XGetXCBConnection(dpy);
@@ -4285,7 +4336,9 @@ __indirect_glGetTexEnviv(GLenum target, GLenum pname, GLint * params)
 {
     __GLXcontext *const gc = __glXGetCurrentContext();
     Display *const dpy = gc->currentDpy;
+#ifndef USE_XCB
     const GLuint cmdlen = 8;
+#endif
     if (__builtin_expect(dpy != NULL, 1)) {
 #ifdef USE_XCB
         xcb_connection_t *c = XGetXCBConnection(dpy);
@@ -4323,7 +4376,9 @@ __indirect_glGetTexGendv(GLenum coord, GLenum pname, GLdouble * params)
 {
     __GLXcontext *const gc = __glXGetCurrentContext();
     Display *const dpy = gc->currentDpy;
+#ifndef USE_XCB
     const GLuint cmdlen = 8;
+#endif
     if (__builtin_expect(dpy != NULL, 1)) {
 #ifdef USE_XCB
         xcb_connection_t *c = XGetXCBConnection(dpy);
@@ -4361,7 +4416,9 @@ __indirect_glGetTexGenfv(GLenum coord, GLenum pname, GLfloat * params)
 {
     __GLXcontext *const gc = __glXGetCurrentContext();
     Display *const dpy = gc->currentDpy;
+#ifndef USE_XCB
     const GLuint cmdlen = 8;
+#endif
     if (__builtin_expect(dpy != NULL, 1)) {
 #ifdef USE_XCB
         xcb_connection_t *c = XGetXCBConnection(dpy);
@@ -4399,7 +4456,9 @@ __indirect_glGetTexGeniv(GLenum coord, GLenum pname, GLint * params)
 {
     __GLXcontext *const gc = __glXGetCurrentContext();
     Display *const dpy = gc->currentDpy;
+#ifndef USE_XCB
     const GLuint cmdlen = 8;
+#endif
     if (__builtin_expect(dpy != NULL, 1)) {
 #ifdef USE_XCB
         xcb_connection_t *c = XGetXCBConnection(dpy);
@@ -4439,7 +4498,9 @@ __indirect_glGetTexImage(GLenum target, GLint level, GLenum format,
     __GLXcontext *const gc = __glXGetCurrentContext();
     const __GLXattribute *const state = gc->client_state_private;
     Display *const dpy = gc->currentDpy;
+#ifndef USE_XCB
     const GLuint cmdlen = 20;
+#endif
     if (__builtin_expect(dpy != NULL, 1)) {
 #ifdef USE_XCB
         xcb_connection_t *c = XGetXCBConnection(dpy);
@@ -4483,7 +4544,9 @@ __indirect_glGetTexParameterfv(GLenum target, GLenum pname, GLfloat * params)
 {
     __GLXcontext *const gc = __glXGetCurrentContext();
     Display *const dpy = gc->currentDpy;
+#ifndef USE_XCB
     const GLuint cmdlen = 8;
+#endif
     if (__builtin_expect(dpy != NULL, 1)) {
 #ifdef USE_XCB
         xcb_connection_t *c = XGetXCBConnection(dpy);
@@ -4522,7 +4585,9 @@ __indirect_glGetTexParameteriv(GLenum target, GLenum pname, GLint * params)
 {
     __GLXcontext *const gc = __glXGetCurrentContext();
     Display *const dpy = gc->currentDpy;
+#ifndef USE_XCB
     const GLuint cmdlen = 8;
+#endif
     if (__builtin_expect(dpy != NULL, 1)) {
 #ifdef USE_XCB
         xcb_connection_t *c = XGetXCBConnection(dpy);
@@ -4562,7 +4627,9 @@ __indirect_glGetTexLevelParameterfv(GLenum target, GLint level, GLenum pname,
 {
     __GLXcontext *const gc = __glXGetCurrentContext();
     Display *const dpy = gc->currentDpy;
+#ifndef USE_XCB
     const GLuint cmdlen = 12;
+#endif
     if (__builtin_expect(dpy != NULL, 1)) {
 #ifdef USE_XCB
         xcb_connection_t *c = XGetXCBConnection(dpy);
@@ -4603,7 +4670,9 @@ __indirect_glGetTexLevelParameteriv(GLenum target, GLint level, GLenum pname,
 {
     __GLXcontext *const gc = __glXGetCurrentContext();
     Display *const dpy = gc->currentDpy;
+#ifndef USE_XCB
     const GLuint cmdlen = 12;
+#endif
     if (__builtin_expect(dpy != NULL, 1)) {
 #ifdef USE_XCB
         xcb_connection_t *c = XGetXCBConnection(dpy);
@@ -4644,7 +4713,9 @@ __indirect_glIsList(GLuint list)
     __GLXcontext *const gc = __glXGetCurrentContext();
     Display *const dpy = gc->currentDpy;
     GLboolean retval = (GLboolean) 0;
+#ifndef USE_XCB
     const GLuint cmdlen = 4;
+#endif
     if (__builtin_expect(dpy != NULL, 1)) {
 #ifdef USE_XCB
         xcb_connection_t *c = XGetXCBConnection(dpy);
@@ -5012,7 +5083,13 @@ __indirect_glAreTexturesResident(GLsizei n, const GLuint * textures,
     __GLXcontext *const gc = __glXGetCurrentContext();
     Display *const dpy = gc->currentDpy;
     GLboolean retval = (GLboolean) 0;
+#ifndef USE_XCB
     const GLuint cmdlen = 4 + __GLX_PAD((n * 4));
+#endif
+    if (n < 0) {
+        __glXSetError(gc, GL_INVALID_VALUE);
+        return 0;
+    }
     if (__builtin_expect((n >= 0) && (dpy != NULL), 1)) {
 #ifdef USE_XCB
         xcb_connection_t *c = XGetXCBConnection(dpy);
@@ -5047,7 +5124,7 @@ glAreTexturesResidentEXT(GLsizei n, const GLuint * textures,
 {
     __GLXcontext *const gc = __glXGetCurrentContext();
 
-    if (gc->isDirect) {
+    if (gc->driContext) {
         return CALL_AreTexturesResident(GET_DISPATCH(),
                                         (n, textures, residences));
     } else {
@@ -5055,6 +5132,10 @@ glAreTexturesResidentEXT(GLsizei n, const GLuint * textures,
         Display *const dpy = gc->currentDpy;
         GLboolean retval = (GLboolean) 0;
         const GLuint cmdlen = 4 + __GLX_PAD((n * 4));
+        if (n < 0) {
+            __glXSetError(gc, GL_INVALID_VALUE);
+            return 0;
+        }
         if (__builtin_expect((n >= 0) && (dpy != NULL), 1)) {
             GLubyte const *pc =
                 __glXSetupVendorRequest(gc, X_GLXVendorPrivateWithReply,
@@ -5163,7 +5244,13 @@ __indirect_glDeleteTextures(GLsizei n, const GLuint * textures)
 {
     __GLXcontext *const gc = __glXGetCurrentContext();
     Display *const dpy = gc->currentDpy;
+#ifndef USE_XCB
     const GLuint cmdlen = 4 + __GLX_PAD((n * 4));
+#endif
+    if (n < 0) {
+        __glXSetError(gc, GL_INVALID_VALUE);
+        return;
+    }
     if (__builtin_expect((n >= 0) && (dpy != NULL), 1)) {
 #ifdef USE_XCB
         xcb_connection_t *c = XGetXCBConnection(dpy);
@@ -5187,12 +5274,16 @@ glDeleteTexturesEXT(GLsizei n, const GLuint * textures)
 {
     __GLXcontext *const gc = __glXGetCurrentContext();
 
-    if (gc->isDirect) {
+    if (gc->driContext) {
         CALL_DeleteTextures(GET_DISPATCH(), (n, textures));
     } else {
         __GLXcontext *const gc = __glXGetCurrentContext();
         Display *const dpy = gc->currentDpy;
         const GLuint cmdlen = 4 + __GLX_PAD((n * 4));
+        if (n < 0) {
+            __glXSetError(gc, GL_INVALID_VALUE);
+            return;
+        }
         if (__builtin_expect((n >= 0) && (dpy != NULL), 1)) {
             GLubyte const *pc =
                 __glXSetupVendorRequest(gc, X_GLXVendorPrivate,
@@ -5212,7 +5303,13 @@ __indirect_glGenTextures(GLsizei n, GLuint * textures)
 {
     __GLXcontext *const gc = __glXGetCurrentContext();
     Display *const dpy = gc->currentDpy;
+#ifndef USE_XCB
     const GLuint cmdlen = 4;
+#endif
+    if (n < 0) {
+        __glXSetError(gc, GL_INVALID_VALUE);
+        return;
+    }
     if (__builtin_expect((n >= 0) && (dpy != NULL), 1)) {
 #ifdef USE_XCB
         xcb_connection_t *c = XGetXCBConnection(dpy);
@@ -5245,12 +5342,16 @@ glGenTexturesEXT(GLsizei n, GLuint * textures)
 {
     __GLXcontext *const gc = __glXGetCurrentContext();
 
-    if (gc->isDirect) {
+    if (gc->driContext) {
         CALL_GenTextures(GET_DISPATCH(), (n, textures));
     } else {
         __GLXcontext *const gc = __glXGetCurrentContext();
         Display *const dpy = gc->currentDpy;
         const GLuint cmdlen = 4;
+        if (n < 0) {
+            __glXSetError(gc, GL_INVALID_VALUE);
+            return;
+        }
         if (__builtin_expect((n >= 0) && (dpy != NULL), 1)) {
             GLubyte const *pc =
                 __glXSetupVendorRequest(gc, X_GLXVendorPrivateWithReply,
@@ -5271,7 +5372,9 @@ __indirect_glIsTexture(GLuint texture)
     __GLXcontext *const gc = __glXGetCurrentContext();
     Display *const dpy = gc->currentDpy;
     GLboolean retval = (GLboolean) 0;
+#ifndef USE_XCB
     const GLuint cmdlen = 4;
+#endif
     if (__builtin_expect(dpy != NULL, 1)) {
 #ifdef USE_XCB
         xcb_connection_t *c = XGetXCBConnection(dpy);
@@ -5301,7 +5404,7 @@ glIsTextureEXT(GLuint texture)
 {
     __GLXcontext *const gc = __glXGetCurrentContext();
 
-    if (gc->isDirect) {
+    if (gc->driContext) {
         return CALL_IsTexture(GET_DISPATCH(), (texture));
     } else {
         __GLXcontext *const gc = __glXGetCurrentContext();
@@ -5328,6 +5431,10 @@ __indirect_glPrioritizeTextures(GLsizei n, const GLuint * textures,
 {
     __GLXcontext *const gc = __glXGetCurrentContext();
     const GLuint cmdlen = 8 + __GLX_PAD((n * 4)) + __GLX_PAD((n * 4));
+    if (n < 0) {
+        __glXSetError(gc, GL_INVALID_VALUE);
+        return;
+    }
     if (__builtin_expect(n >= 0, 1)) {
         emit_header(gc->pc, X_GLrop_PrioritizeTextures, cmdlen);
         (void) memcpy((void *) (gc->pc + 4), (void *) (&n), 4);
@@ -5565,7 +5672,9 @@ __indirect_glGetColorTable(GLenum target, GLenum format, GLenum type,
     __GLXcontext *const gc = __glXGetCurrentContext();
     const __GLXattribute *const state = gc->client_state_private;
     Display *const dpy = gc->currentDpy;
+#ifndef USE_XCB
     const GLuint cmdlen = 16;
+#endif
     if (__builtin_expect(dpy != NULL, 1)) {
 #ifdef USE_XCB
         xcb_connection_t *c = XGetXCBConnection(dpy);
@@ -5609,7 +5718,7 @@ glGetColorTableEXT(GLenum target, GLenum format, GLenum type, GLvoid * table)
 {
     __GLXcontext *const gc = __glXGetCurrentContext();
 
-    if (gc->isDirect) {
+    if (gc->driContext) {
         CALL_GetColorTable(GET_DISPATCH(), (target, format, type, table));
     } else {
         __GLXcontext *const gc = __glXGetCurrentContext();
@@ -5641,7 +5750,9 @@ __indirect_glGetColorTableParameterfv(GLenum target, GLenum pname,
 {
     __GLXcontext *const gc = __glXGetCurrentContext();
     Display *const dpy = gc->currentDpy;
+#ifndef USE_XCB
     const GLuint cmdlen = 8;
+#endif
     if (__builtin_expect(dpy != NULL, 1)) {
 #ifdef USE_XCB
         xcb_connection_t *c = XGetXCBConnection(dpy);
@@ -5680,7 +5791,7 @@ glGetColorTableParameterfvEXT(GLenum target, GLenum pname, GLfloat * params)
 {
     __GLXcontext *const gc = __glXGetCurrentContext();
 
-    if (gc->isDirect) {
+    if (gc->driContext) {
         CALL_GetColorTableParameterfv(GET_DISPATCH(),
                                       (target, pname, params));
     } else {
@@ -5709,7 +5820,9 @@ __indirect_glGetColorTableParameteriv(GLenum target, GLenum pname,
 {
     __GLXcontext *const gc = __glXGetCurrentContext();
     Display *const dpy = gc->currentDpy;
+#ifndef USE_XCB
     const GLuint cmdlen = 8;
+#endif
     if (__builtin_expect(dpy != NULL, 1)) {
 #ifdef USE_XCB
         xcb_connection_t *c = XGetXCBConnection(dpy);
@@ -5748,7 +5861,7 @@ glGetColorTableParameterivEXT(GLenum target, GLenum pname, GLint * params)
 {
     __GLXcontext *const gc = __glXGetCurrentContext();
 
-    if (gc->isDirect) {
+    if (gc->driContext) {
         CALL_GetColorTableParameteriv(GET_DISPATCH(),
                                       (target, pname, params));
     } else {
@@ -6029,7 +6142,9 @@ __indirect_glGetConvolutionFilter(GLenum target, GLenum format, GLenum type,
     __GLXcontext *const gc = __glXGetCurrentContext();
     const __GLXattribute *const state = gc->client_state_private;
     Display *const dpy = gc->currentDpy;
+#ifndef USE_XCB
     const GLuint cmdlen = 16;
+#endif
     if (__builtin_expect(dpy != NULL, 1)) {
 #ifdef USE_XCB
         xcb_connection_t *c = XGetXCBConnection(dpy);
@@ -6069,7 +6184,7 @@ gl_dispatch_stub_356(GLenum target, GLenum format, GLenum type,
 {
     __GLXcontext *const gc = __glXGetCurrentContext();
 
-    if (gc->isDirect) {
+    if (gc->driContext) {
         CALL_GetConvolutionFilter(GET_DISPATCH(),
                                   (target, format, type, image));
     } else {
@@ -6103,7 +6218,9 @@ __indirect_glGetConvolutionParameterfv(GLenum target, GLenum pname,
 {
     __GLXcontext *const gc = __glXGetCurrentContext();
     Display *const dpy = gc->currentDpy;
+#ifndef USE_XCB
     const GLuint cmdlen = 8;
+#endif
     if (__builtin_expect(dpy != NULL, 1)) {
 #ifdef USE_XCB
         xcb_connection_t *c = XGetXCBConnection(dpy);
@@ -6142,7 +6259,7 @@ gl_dispatch_stub_357(GLenum target, GLenum pname, GLfloat * params)
 {
     __GLXcontext *const gc = __glXGetCurrentContext();
 
-    if (gc->isDirect) {
+    if (gc->driContext) {
         CALL_GetConvolutionParameterfv(GET_DISPATCH(),
                                        (target, pname, params));
     } else {
@@ -6171,7 +6288,9 @@ __indirect_glGetConvolutionParameteriv(GLenum target, GLenum pname,
 {
     __GLXcontext *const gc = __glXGetCurrentContext();
     Display *const dpy = gc->currentDpy;
+#ifndef USE_XCB
     const GLuint cmdlen = 8;
+#endif
     if (__builtin_expect(dpy != NULL, 1)) {
 #ifdef USE_XCB
         xcb_connection_t *c = XGetXCBConnection(dpy);
@@ -6210,7 +6329,7 @@ gl_dispatch_stub_358(GLenum target, GLenum pname, GLint * params)
 {
     __GLXcontext *const gc = __glXGetCurrentContext();
 
-    if (gc->isDirect) {
+    if (gc->driContext) {
         CALL_GetConvolutionParameteriv(GET_DISPATCH(),
                                        (target, pname, params));
     } else {
@@ -6240,7 +6359,9 @@ __indirect_glGetHistogram(GLenum target, GLboolean reset, GLenum format,
     __GLXcontext *const gc = __glXGetCurrentContext();
     const __GLXattribute *const state = gc->client_state_private;
     Display *const dpy = gc->currentDpy;
+#ifndef USE_XCB
     const GLuint cmdlen = 16;
+#endif
     if (__builtin_expect(dpy != NULL, 1)) {
 #ifdef USE_XCB
         xcb_connection_t *c = XGetXCBConnection(dpy);
@@ -6285,7 +6406,7 @@ gl_dispatch_stub_361(GLenum target, GLboolean reset, GLenum format,
 {
     __GLXcontext *const gc = __glXGetCurrentContext();
 
-    if (gc->isDirect) {
+    if (gc->driContext) {
         CALL_GetHistogram(GET_DISPATCH(),
                           (target, reset, format, type, values));
     } else {
@@ -6319,7 +6440,9 @@ __indirect_glGetHistogramParameterfv(GLenum target, GLenum pname,
 {
     __GLXcontext *const gc = __glXGetCurrentContext();
     Display *const dpy = gc->currentDpy;
+#ifndef USE_XCB
     const GLuint cmdlen = 8;
+#endif
     if (__builtin_expect(dpy != NULL, 1)) {
 #ifdef USE_XCB
         xcb_connection_t *c = XGetXCBConnection(dpy);
@@ -6357,7 +6480,7 @@ gl_dispatch_stub_362(GLenum target, GLenum pname, GLfloat * params)
 {
     __GLXcontext *const gc = __glXGetCurrentContext();
 
-    if (gc->isDirect) {
+    if (gc->driContext) {
         CALL_GetHistogramParameterfv(GET_DISPATCH(), (target, pname, params));
     } else {
         __GLXcontext *const gc = __glXGetCurrentContext();
@@ -6385,7 +6508,9 @@ __indirect_glGetHistogramParameteriv(GLenum target, GLenum pname,
 {
     __GLXcontext *const gc = __glXGetCurrentContext();
     Display *const dpy = gc->currentDpy;
+#ifndef USE_XCB
     const GLuint cmdlen = 8;
+#endif
     if (__builtin_expect(dpy != NULL, 1)) {
 #ifdef USE_XCB
         xcb_connection_t *c = XGetXCBConnection(dpy);
@@ -6423,7 +6548,7 @@ gl_dispatch_stub_363(GLenum target, GLenum pname, GLint * params)
 {
     __GLXcontext *const gc = __glXGetCurrentContext();
 
-    if (gc->isDirect) {
+    if (gc->driContext) {
         CALL_GetHistogramParameteriv(GET_DISPATCH(), (target, pname, params));
     } else {
         __GLXcontext *const gc = __glXGetCurrentContext();
@@ -6452,7 +6577,9 @@ __indirect_glGetMinmax(GLenum target, GLboolean reset, GLenum format,
     __GLXcontext *const gc = __glXGetCurrentContext();
     const __GLXattribute *const state = gc->client_state_private;
     Display *const dpy = gc->currentDpy;
+#ifndef USE_XCB
     const GLuint cmdlen = 16;
+#endif
     if (__builtin_expect(dpy != NULL, 1)) {
 #ifdef USE_XCB
         xcb_connection_t *c = XGetXCBConnection(dpy);
@@ -6493,7 +6620,7 @@ gl_dispatch_stub_364(GLenum target, GLboolean reset, GLenum format,
 {
     __GLXcontext *const gc = __glXGetCurrentContext();
 
-    if (gc->isDirect) {
+    if (gc->driContext) {
         CALL_GetMinmax(GET_DISPATCH(), (target, reset, format, type, values));
     } else {
         __GLXcontext *const gc = __glXGetCurrentContext();
@@ -6526,7 +6653,9 @@ __indirect_glGetMinmaxParameterfv(GLenum target, GLenum pname,
 {
     __GLXcontext *const gc = __glXGetCurrentContext();
     Display *const dpy = gc->currentDpy;
+#ifndef USE_XCB
     const GLuint cmdlen = 8;
+#endif
     if (__builtin_expect(dpy != NULL, 1)) {
 #ifdef USE_XCB
         xcb_connection_t *c = XGetXCBConnection(dpy);
@@ -6562,7 +6691,7 @@ gl_dispatch_stub_365(GLenum target, GLenum pname, GLfloat * params)
 {
     __GLXcontext *const gc = __glXGetCurrentContext();
 
-    if (gc->isDirect) {
+    if (gc->driContext) {
         CALL_GetMinmaxParameterfv(GET_DISPATCH(), (target, pname, params));
     } else {
         __GLXcontext *const gc = __glXGetCurrentContext();
@@ -6589,7 +6718,9 @@ __indirect_glGetMinmaxParameteriv(GLenum target, GLenum pname, GLint * params)
 {
     __GLXcontext *const gc = __glXGetCurrentContext();
     Display *const dpy = gc->currentDpy;
+#ifndef USE_XCB
     const GLuint cmdlen = 8;
+#endif
     if (__builtin_expect(dpy != NULL, 1)) {
 #ifdef USE_XCB
         xcb_connection_t *c = XGetXCBConnection(dpy);
@@ -6625,7 +6756,7 @@ gl_dispatch_stub_366(GLenum target, GLenum pname, GLint * params)
 {
     __GLXcontext *const gc = __glXGetCurrentContext();
 
-    if (gc->isDirect) {
+    if (gc->driContext) {
         CALL_GetMinmaxParameteriv(GET_DISPATCH(), (target, pname, params));
     } else {
         __GLXcontext *const gc = __glXGetCurrentContext();
@@ -7470,6 +7601,26 @@ __indirect_glGetProgramivARB(GLenum target, GLenum pname, GLint * params)
 
 #define X_GLrop_ProgramEnvParameter4dvARB 4185
 void
+__indirect_glProgramEnvParameter4dARB(GLenum target, GLuint index, GLdouble x,
+                                      GLdouble y, GLdouble z, GLdouble w)
+{
+    __GLXcontext *const gc = __glXGetCurrentContext();
+    const GLuint cmdlen = 44;
+    emit_header(gc->pc, X_GLrop_ProgramEnvParameter4dvARB, cmdlen);
+    (void) memcpy((void *) (gc->pc + 4), (void *) (&target), 4);
+    (void) memcpy((void *) (gc->pc + 8), (void *) (&index), 4);
+    (void) memcpy((void *) (gc->pc + 12), (void *) (&x), 8);
+    (void) memcpy((void *) (gc->pc + 20), (void *) (&y), 8);
+    (void) memcpy((void *) (gc->pc + 28), (void *) (&z), 8);
+    (void) memcpy((void *) (gc->pc + 36), (void *) (&w), 8);
+    gc->pc += cmdlen;
+    if (__builtin_expect(gc->pc > gc->limit, 0)) {
+        (void) __glXFlushRenderBuffer(gc, gc->pc);
+    }
+}
+
+#define X_GLrop_ProgramEnvParameter4dvARB 4185
+void
 __indirect_glProgramEnvParameter4dvARB(GLenum target, GLuint index,
                                        const GLdouble * params)
 {
@@ -7487,6 +7638,26 @@ __indirect_glProgramEnvParameter4dvARB(GLenum target, GLuint index,
 
 #define X_GLrop_ProgramEnvParameter4fvARB 4184
 void
+__indirect_glProgramEnvParameter4fARB(GLenum target, GLuint index, GLfloat x,
+                                      GLfloat y, GLfloat z, GLfloat w)
+{
+    __GLXcontext *const gc = __glXGetCurrentContext();
+    const GLuint cmdlen = 28;
+    emit_header(gc->pc, X_GLrop_ProgramEnvParameter4fvARB, cmdlen);
+    (void) memcpy((void *) (gc->pc + 4), (void *) (&target), 4);
+    (void) memcpy((void *) (gc->pc + 8), (void *) (&index), 4);
+    (void) memcpy((void *) (gc->pc + 12), (void *) (&x), 4);
+    (void) memcpy((void *) (gc->pc + 16), (void *) (&y), 4);
+    (void) memcpy((void *) (gc->pc + 20), (void *) (&z), 4);
+    (void) memcpy((void *) (gc->pc + 24), (void *) (&w), 4);
+    gc->pc += cmdlen;
+    if (__builtin_expect(gc->pc > gc->limit, 0)) {
+        (void) __glXFlushRenderBuffer(gc, gc->pc);
+    }
+}
+
+#define X_GLrop_ProgramEnvParameter4fvARB 4184
+void
 __indirect_glProgramEnvParameter4fvARB(GLenum target, GLuint index,
                                        const GLfloat * params)
 {
@@ -7585,6 +7756,10 @@ __indirect_glProgramStringARB(GLenum target, GLenum format, GLsizei len,
 {
     __GLXcontext *const gc = __glXGetCurrentContext();
     const GLuint cmdlen = 16 + __GLX_PAD(len);
+    if (len < 0) {
+        __glXSetError(gc, GL_INVALID_VALUE);
+        return;
+    }
     if (__builtin_expect((len >= 0) && (gc->currentDpy != NULL), 1)) {
         if (cmdlen <= gc->maxSmallRenderCommandSize) {
             if ((gc->pc + cmdlen) > gc->bufEnd) {
@@ -8200,7 +8375,13 @@ __indirect_glDeleteQueriesARB(GLsizei n, const GLuint * ids)
 {
     __GLXcontext *const gc = __glXGetCurrentContext();
     Display *const dpy = gc->currentDpy;
+#ifndef USE_XCB
     const GLuint cmdlen = 4 + __GLX_PAD((n * 4));
+#endif
+    if (n < 0) {
+        __glXSetError(gc, GL_INVALID_VALUE);
+        return;
+    }
     if (__builtin_expect((n >= 0) && (dpy != NULL), 1)) {
 #ifdef USE_XCB
         xcb_connection_t *c = XGetXCBConnection(dpy);
@@ -8238,7 +8419,13 @@ __indirect_glGenQueriesARB(GLsizei n, GLuint * ids)
 {
     __GLXcontext *const gc = __glXGetCurrentContext();
     Display *const dpy = gc->currentDpy;
+#ifndef USE_XCB
     const GLuint cmdlen = 4;
+#endif
+    if (n < 0) {
+        __glXSetError(gc, GL_INVALID_VALUE);
+        return;
+    }
     if (__builtin_expect((n >= 0) && (dpy != NULL), 1)) {
 #ifdef USE_XCB
         xcb_connection_t *c = XGetXCBConnection(dpy);
@@ -8271,7 +8458,9 @@ __indirect_glGetQueryObjectivARB(GLuint id, GLenum pname, GLint * params)
 {
     __GLXcontext *const gc = __glXGetCurrentContext();
     Display *const dpy = gc->currentDpy;
+#ifndef USE_XCB
     const GLuint cmdlen = 8;
+#endif
     if (__builtin_expect(dpy != NULL, 1)) {
 #ifdef USE_XCB
         xcb_connection_t *c = XGetXCBConnection(dpy);
@@ -8307,7 +8496,9 @@ __indirect_glGetQueryObjectuivARB(GLuint id, GLenum pname, GLuint * params)
 {
     __GLXcontext *const gc = __glXGetCurrentContext();
     Display *const dpy = gc->currentDpy;
+#ifndef USE_XCB
     const GLuint cmdlen = 8;
+#endif
     if (__builtin_expect(dpy != NULL, 1)) {
 #ifdef USE_XCB
         xcb_connection_t *c = XGetXCBConnection(dpy);
@@ -8343,7 +8534,9 @@ __indirect_glGetQueryivARB(GLenum target, GLenum pname, GLint * params)
 {
     __GLXcontext *const gc = __glXGetCurrentContext();
     Display *const dpy = gc->currentDpy;
+#ifndef USE_XCB
     const GLuint cmdlen = 8;
+#endif
     if (__builtin_expect(dpy != NULL, 1)) {
 #ifdef USE_XCB
         xcb_connection_t *c = XGetXCBConnection(dpy);
@@ -8383,7 +8576,9 @@ __indirect_glIsQueryARB(GLuint id)
     __GLXcontext *const gc = __glXGetCurrentContext();
     Display *const dpy = gc->currentDpy;
     GLboolean retval = (GLboolean) 0;
+#ifndef USE_XCB
     const GLuint cmdlen = 4;
+#endif
     if (__builtin_expect(dpy != NULL, 1)) {
 #ifdef USE_XCB
         xcb_connection_t *c = XGetXCBConnection(dpy);
@@ -8414,6 +8609,10 @@ __indirect_glDrawBuffersARB(GLsizei n, const GLenum * bufs)
 {
     __GLXcontext *const gc = __glXGetCurrentContext();
     const GLuint cmdlen = 8 + __GLX_PAD((n * 4));
+    if (n < 0) {
+        __glXSetError(gc, GL_INVALID_VALUE);
+        return;
+    }
     if (__builtin_expect((n >= 0) && (gc->currentDpy != NULL), 1)) {
         if (cmdlen <= gc->maxSmallRenderCommandSize) {
             if ((gc->pc + cmdlen) > gc->bufEnd) {
@@ -8774,6 +8973,10 @@ __indirect_glAreProgramsResidentNV(GLsizei n, const GLuint * ids,
     Display *const dpy = gc->currentDpy;
     GLboolean retval = (GLboolean) 0;
     const GLuint cmdlen = 4 + __GLX_PAD((n * 4));
+    if (n < 0) {
+        __glXSetError(gc, GL_INVALID_VALUE);
+        return 0;
+    }
     if (__builtin_expect((n >= 0) && (dpy != NULL), 1)) {
         GLubyte const *pc =
             __glXSetupVendorRequest(gc, X_GLXVendorPrivateWithReply,
@@ -8809,6 +9012,10 @@ __indirect_glDeleteProgramsNV(GLsizei n, const GLuint * programs)
     __GLXcontext *const gc = __glXGetCurrentContext();
     Display *const dpy = gc->currentDpy;
     const GLuint cmdlen = 4 + __GLX_PAD((n * 4));
+    if (n < 0) {
+        __glXSetError(gc, GL_INVALID_VALUE);
+        return;
+    }
     if (__builtin_expect((n >= 0) && (dpy != NULL), 1)) {
         GLubyte const *pc =
             __glXSetupVendorRequest(gc, X_GLXVendorPrivate,
@@ -8845,6 +9052,10 @@ __indirect_glGenProgramsNV(GLsizei n, GLuint * programs)
     __GLXcontext *const gc = __glXGetCurrentContext();
     Display *const dpy = gc->currentDpy;
     const GLuint cmdlen = 4;
+    if (n < 0) {
+        __glXSetError(gc, GL_INVALID_VALUE);
+        return;
+    }
     if (__builtin_expect((n >= 0) && (dpy != NULL), 1)) {
         GLubyte const *pc =
             __glXSetupVendorRequest(gc, X_GLXVendorPrivateWithReply,
@@ -9051,6 +9262,10 @@ __indirect_glLoadProgramNV(GLenum target, GLuint id, GLsizei len,
 {
     __GLXcontext *const gc = __glXGetCurrentContext();
     const GLuint cmdlen = 16 + __GLX_PAD(len);
+    if (len < 0) {
+        __glXSetError(gc, GL_INVALID_VALUE);
+        return;
+    }
     if (__builtin_expect(len >= 0, 1)) {
         emit_header(gc->pc, X_GLrop_LoadProgramNV, cmdlen);
         (void) memcpy((void *) (gc->pc + 4), (void *) (&target), 4);
@@ -9071,6 +9286,10 @@ __indirect_glProgramParameters4dvNV(GLenum target, GLuint index, GLuint num,
 {
     __GLXcontext *const gc = __glXGetCurrentContext();
     const GLuint cmdlen = 16 + __GLX_PAD((num * 32));
+    if (num < 0) {
+        __glXSetError(gc, GL_INVALID_VALUE);
+        return;
+    }
     if (__builtin_expect(num >= 0, 1)) {
         emit_header(gc->pc, X_GLrop_ProgramParameters4dvNV, cmdlen);
         (void) memcpy((void *) (gc->pc + 4), (void *) (&target), 4);
@@ -9091,6 +9310,10 @@ __indirect_glProgramParameters4fvNV(GLenum target, GLuint index, GLuint num,
 {
     __GLXcontext *const gc = __glXGetCurrentContext();
     const GLuint cmdlen = 16 + __GLX_PAD((num * 16));
+    if (num < 0) {
+        __glXSetError(gc, GL_INVALID_VALUE);
+        return;
+    }
     if (__builtin_expect(num >= 0, 1)) {
         emit_header(gc->pc, X_GLrop_ProgramParameters4fvNV, cmdlen);
         (void) memcpy((void *) (gc->pc + 4), (void *) (&target), 4);
@@ -9110,6 +9333,10 @@ __indirect_glRequestResidentProgramsNV(GLsizei n, const GLuint * ids)
 {
     __GLXcontext *const gc = __glXGetCurrentContext();
     const GLuint cmdlen = 8 + __GLX_PAD((n * 4));
+    if (n < 0) {
+        __glXSetError(gc, GL_INVALID_VALUE);
+        return;
+    }
     if (__builtin_expect(n >= 0, 1)) {
         emit_header(gc->pc, X_GLrop_RequestResidentProgramsNV, cmdlen);
         (void) memcpy((void *) (gc->pc + 4), (void *) (&n), 4);
@@ -9561,6 +9788,10 @@ __indirect_glVertexAttribs1dvNV(GLuint index, GLsizei n, const GLdouble * v)
 {
     __GLXcontext *const gc = __glXGetCurrentContext();
     const GLuint cmdlen = 12 + __GLX_PAD((n * 8));
+    if (n < 0) {
+        __glXSetError(gc, GL_INVALID_VALUE);
+        return;
+    }
     if (__builtin_expect(n >= 0, 1)) {
         emit_header(gc->pc, X_GLrop_VertexAttribs1dvNV, cmdlen);
         (void) memcpy((void *) (gc->pc + 4), (void *) (&index), 4);
@@ -9579,6 +9810,10 @@ __indirect_glVertexAttribs1fvNV(GLuint index, GLsizei n, const GLfloat * v)
 {
     __GLXcontext *const gc = __glXGetCurrentContext();
     const GLuint cmdlen = 12 + __GLX_PAD((n * 4));
+    if (n < 0) {
+        __glXSetError(gc, GL_INVALID_VALUE);
+        return;
+    }
     if (__builtin_expect(n >= 0, 1)) {
         emit_header(gc->pc, X_GLrop_VertexAttribs1fvNV, cmdlen);
         (void) memcpy((void *) (gc->pc + 4), (void *) (&index), 4);
@@ -9597,6 +9832,10 @@ __indirect_glVertexAttribs1svNV(GLuint index, GLsizei n, const GLshort * v)
 {
     __GLXcontext *const gc = __glXGetCurrentContext();
     const GLuint cmdlen = 12 + __GLX_PAD((n * 2));
+    if (n < 0) {
+        __glXSetError(gc, GL_INVALID_VALUE);
+        return;
+    }
     if (__builtin_expect(n >= 0, 1)) {
         emit_header(gc->pc, X_GLrop_VertexAttribs1svNV, cmdlen);
         (void) memcpy((void *) (gc->pc + 4), (void *) (&index), 4);
@@ -9615,6 +9854,10 @@ __indirect_glVertexAttribs2dvNV(GLuint index, GLsizei n, const GLdouble * v)
 {
     __GLXcontext *const gc = __glXGetCurrentContext();
     const GLuint cmdlen = 12 + __GLX_PAD((n * 16));
+    if (n < 0) {
+        __glXSetError(gc, GL_INVALID_VALUE);
+        return;
+    }
     if (__builtin_expect(n >= 0, 1)) {
         emit_header(gc->pc, X_GLrop_VertexAttribs2dvNV, cmdlen);
         (void) memcpy((void *) (gc->pc + 4), (void *) (&index), 4);
@@ -9633,6 +9876,10 @@ __indirect_glVertexAttribs2fvNV(GLuint index, GLsizei n, const GLfloat * v)
 {
     __GLXcontext *const gc = __glXGetCurrentContext();
     const GLuint cmdlen = 12 + __GLX_PAD((n * 8));
+    if (n < 0) {
+        __glXSetError(gc, GL_INVALID_VALUE);
+        return;
+    }
     if (__builtin_expect(n >= 0, 1)) {
         emit_header(gc->pc, X_GLrop_VertexAttribs2fvNV, cmdlen);
         (void) memcpy((void *) (gc->pc + 4), (void *) (&index), 4);
@@ -9651,6 +9898,10 @@ __indirect_glVertexAttribs2svNV(GLuint index, GLsizei n, const GLshort * v)
 {
     __GLXcontext *const gc = __glXGetCurrentContext();
     const GLuint cmdlen = 12 + __GLX_PAD((n * 4));
+    if (n < 0) {
+        __glXSetError(gc, GL_INVALID_VALUE);
+        return;
+    }
     if (__builtin_expect(n >= 0, 1)) {
         emit_header(gc->pc, X_GLrop_VertexAttribs2svNV, cmdlen);
         (void) memcpy((void *) (gc->pc + 4), (void *) (&index), 4);
@@ -9669,6 +9920,10 @@ __indirect_glVertexAttribs3dvNV(GLuint index, GLsizei n, const GLdouble * v)
 {
     __GLXcontext *const gc = __glXGetCurrentContext();
     const GLuint cmdlen = 12 + __GLX_PAD((n * 24));
+    if (n < 0) {
+        __glXSetError(gc, GL_INVALID_VALUE);
+        return;
+    }
     if (__builtin_expect(n >= 0, 1)) {
         emit_header(gc->pc, X_GLrop_VertexAttribs3dvNV, cmdlen);
         (void) memcpy((void *) (gc->pc + 4), (void *) (&index), 4);
@@ -9687,6 +9942,10 @@ __indirect_glVertexAttribs3fvNV(GLuint index, GLsizei n, const GLfloat * v)
 {
     __GLXcontext *const gc = __glXGetCurrentContext();
     const GLuint cmdlen = 12 + __GLX_PAD((n * 12));
+    if (n < 0) {
+        __glXSetError(gc, GL_INVALID_VALUE);
+        return;
+    }
     if (__builtin_expect(n >= 0, 1)) {
         emit_header(gc->pc, X_GLrop_VertexAttribs3fvNV, cmdlen);
         (void) memcpy((void *) (gc->pc + 4), (void *) (&index), 4);
@@ -9705,6 +9964,10 @@ __indirect_glVertexAttribs3svNV(GLuint index, GLsizei n, const GLshort * v)
 {
     __GLXcontext *const gc = __glXGetCurrentContext();
     const GLuint cmdlen = 12 + __GLX_PAD((n * 6));
+    if (n < 0) {
+        __glXSetError(gc, GL_INVALID_VALUE);
+        return;
+    }
     if (__builtin_expect(n >= 0, 1)) {
         emit_header(gc->pc, X_GLrop_VertexAttribs3svNV, cmdlen);
         (void) memcpy((void *) (gc->pc + 4), (void *) (&index), 4);
@@ -9723,6 +9986,10 @@ __indirect_glVertexAttribs4dvNV(GLuint index, GLsizei n, const GLdouble * v)
 {
     __GLXcontext *const gc = __glXGetCurrentContext();
     const GLuint cmdlen = 12 + __GLX_PAD((n * 32));
+    if (n < 0) {
+        __glXSetError(gc, GL_INVALID_VALUE);
+        return;
+    }
     if (__builtin_expect(n >= 0, 1)) {
         emit_header(gc->pc, X_GLrop_VertexAttribs4dvNV, cmdlen);
         (void) memcpy((void *) (gc->pc + 4), (void *) (&index), 4);
@@ -9741,6 +10008,10 @@ __indirect_glVertexAttribs4fvNV(GLuint index, GLsizei n, const GLfloat * v)
 {
     __GLXcontext *const gc = __glXGetCurrentContext();
     const GLuint cmdlen = 12 + __GLX_PAD((n * 16));
+    if (n < 0) {
+        __glXSetError(gc, GL_INVALID_VALUE);
+        return;
+    }
     if (__builtin_expect(n >= 0, 1)) {
         emit_header(gc->pc, X_GLrop_VertexAttribs4fvNV, cmdlen);
         (void) memcpy((void *) (gc->pc + 4), (void *) (&index), 4);
@@ -9759,6 +10030,10 @@ __indirect_glVertexAttribs4svNV(GLuint index, GLsizei n, const GLshort * v)
 {
     __GLXcontext *const gc = __glXGetCurrentContext();
     const GLuint cmdlen = 12 + __GLX_PAD((n * 8));
+    if (n < 0) {
+        __glXSetError(gc, GL_INVALID_VALUE);
+        return;
+    }
     if (__builtin_expect(n >= 0, 1)) {
         emit_header(gc->pc, X_GLrop_VertexAttribs4svNV, cmdlen);
         (void) memcpy((void *) (gc->pc + 4), (void *) (&index), 4);
@@ -9777,6 +10052,10 @@ __indirect_glVertexAttribs4ubvNV(GLuint index, GLsizei n, const GLubyte *v)
 {
     __GLXcontext *const gc = __glXGetCurrentContext();
     const GLuint cmdlen = 12 + __GLX_PAD((n * 4));
+    if (n < 0) {
+        __glXSetError(gc, GL_INVALID_VALUE);
+        return;
+    }
     if (__builtin_expect(n >= 0, 1)) {
         emit_header(gc->pc, X_GLrop_VertexAttribs4ubvNV, cmdlen);
         (void) memcpy((void *) (gc->pc + 4), (void *) (&index), 4);
@@ -9843,6 +10122,10 @@ __indirect_glGetProgramNamedParameterdvNV(GLuint id, GLsizei len,
     __GLXcontext *const gc = __glXGetCurrentContext();
     Display *const dpy = gc->currentDpy;
     const GLuint cmdlen = 8 + __GLX_PAD(len);
+    if (len < 0) {
+        __glXSetError(gc, GL_INVALID_VALUE);
+        return;
+    }
     if (__builtin_expect((len >= 0) && (dpy != NULL), 1)) {
         GLubyte const *pc =
             __glXSetupVendorRequest(gc, X_GLXVendorPrivateWithReply,
@@ -9867,6 +10150,10 @@ __indirect_glGetProgramNamedParameterfvNV(GLuint id, GLsizei len,
     __GLXcontext *const gc = __glXGetCurrentContext();
     Display *const dpy = gc->currentDpy;
     const GLuint cmdlen = 8 + __GLX_PAD(len);
+    if (len < 0) {
+        __glXSetError(gc, GL_INVALID_VALUE);
+        return;
+    }
     if (__builtin_expect((len >= 0) && (dpy != NULL), 1)) {
         GLubyte const *pc =
             __glXSetupVendorRequest(gc, X_GLXVendorPrivateWithReply,
@@ -9890,6 +10177,10 @@ __indirect_glProgramNamedParameter4dNV(GLuint id, GLsizei len,
 {
     __GLXcontext *const gc = __glXGetCurrentContext();
     const GLuint cmdlen = 44 + __GLX_PAD(len);
+    if (len < 0) {
+        __glXSetError(gc, GL_INVALID_VALUE);
+        return;
+    }
     if (__builtin_expect(len >= 0, 1)) {
         emit_header(gc->pc, X_GLrop_ProgramNamedParameter4dvNV, cmdlen);
         (void) memcpy((void *) (gc->pc + 4), (void *) (&x), 8);
@@ -9914,6 +10205,10 @@ __indirect_glProgramNamedParameter4dvNV(GLuint id, GLsizei len,
 {
     __GLXcontext *const gc = __glXGetCurrentContext();
     const GLuint cmdlen = 44 + __GLX_PAD(len);
+    if (len < 0) {
+        __glXSetError(gc, GL_INVALID_VALUE);
+        return;
+    }
     if (__builtin_expect(len >= 0, 1)) {
         emit_header(gc->pc, X_GLrop_ProgramNamedParameter4dvNV, cmdlen);
         (void) memcpy((void *) (gc->pc + 4), (void *) (v), 32);
@@ -9935,6 +10230,10 @@ __indirect_glProgramNamedParameter4fNV(GLuint id, GLsizei len,
 {
     __GLXcontext *const gc = __glXGetCurrentContext();
     const GLuint cmdlen = 28 + __GLX_PAD(len);
+    if (len < 0) {
+        __glXSetError(gc, GL_INVALID_VALUE);
+        return;
+    }
     if (__builtin_expect(len >= 0, 1)) {
         emit_header(gc->pc, X_GLrop_ProgramNamedParameter4fvNV, cmdlen);
         (void) memcpy((void *) (gc->pc + 4), (void *) (&id), 4);
@@ -9959,6 +10258,10 @@ __indirect_glProgramNamedParameter4fvNV(GLuint id, GLsizei len,
 {
     __GLXcontext *const gc = __glXGetCurrentContext();
     const GLuint cmdlen = 28 + __GLX_PAD(len);
+    if (len < 0) {
+        __glXSetError(gc, GL_INVALID_VALUE);
+        return;
+    }
     if (__builtin_expect(len >= 0, 1)) {
         emit_header(gc->pc, X_GLrop_ProgramNamedParameter4fvNV, cmdlen);
         (void) memcpy((void *) (gc->pc + 4), (void *) (&id), 4);
@@ -10044,6 +10347,10 @@ __indirect_glDeleteFramebuffersEXT(GLsizei n, const GLuint * framebuffers)
 {
     __GLXcontext *const gc = __glXGetCurrentContext();
     const GLuint cmdlen = 8 + __GLX_PAD((n * 4));
+    if (n < 0) {
+        __glXSetError(gc, GL_INVALID_VALUE);
+        return;
+    }
     if (__builtin_expect(n >= 0, 1)) {
         emit_header(gc->pc, X_GLrop_DeleteFramebuffersEXT, cmdlen);
         (void) memcpy((void *) (gc->pc + 4), (void *) (&n), 4);
@@ -10062,6 +10369,10 @@ __indirect_glDeleteRenderbuffersEXT(GLsizei n, const GLuint * renderbuffers)
 {
     __GLXcontext *const gc = __glXGetCurrentContext();
     const GLuint cmdlen = 8 + __GLX_PAD((n * 4));
+    if (n < 0) {
+        __glXSetError(gc, GL_INVALID_VALUE);
+        return;
+    }
     if (__builtin_expect(n >= 0, 1)) {
         emit_header(gc->pc, X_GLrop_DeleteRenderbuffersEXT, cmdlen);
         (void) memcpy((void *) (gc->pc + 4), (void *) (&n), 4);
@@ -10161,6 +10472,10 @@ __indirect_glGenFramebuffersEXT(GLsizei n, GLuint * framebuffers)
     __GLXcontext *const gc = __glXGetCurrentContext();
     Display *const dpy = gc->currentDpy;
     const GLuint cmdlen = 4;
+    if (n < 0) {
+        __glXSetError(gc, GL_INVALID_VALUE);
+        return;
+    }
     if (__builtin_expect((n >= 0) && (dpy != NULL), 1)) {
         GLubyte const *pc =
             __glXSetupVendorRequest(gc, X_GLXVendorPrivateWithReply,
@@ -10180,6 +10495,10 @@ __indirect_glGenRenderbuffersEXT(GLsizei n, GLuint * renderbuffers)
     __GLXcontext *const gc = __glXGetCurrentContext();
     Display *const dpy = gc->currentDpy;
     const GLuint cmdlen = 4;
+    if (n < 0) {
+        __glXSetError(gc, GL_INVALID_VALUE);
+        return;
+    }
     if (__builtin_expect((n >= 0) && (dpy != NULL), 1)) {
         GLubyte const *pc =
             __glXSetupVendorRequest(gc, X_GLXVendorPrivateWithReply,
index f8c88b3..0719a1b 100644 (file)
@@ -517,7 +517,9 @@ extern HIDDEN void __indirect_glGetProgramivARB(GLenum target, GLenum pname, GLi
 extern HIDDEN void __indirect_glGetVertexAttribdvARB(GLuint index, GLenum pname, GLdouble * params);
 extern HIDDEN void __indirect_glGetVertexAttribfvARB(GLuint index, GLenum pname, GLfloat * params);
 extern HIDDEN void __indirect_glGetVertexAttribivARB(GLuint index, GLenum pname, GLint * params);
+extern HIDDEN void __indirect_glProgramEnvParameter4dARB(GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
 extern HIDDEN void __indirect_glProgramEnvParameter4dvARB(GLenum target, GLuint index, const GLdouble * params);
+extern HIDDEN void __indirect_glProgramEnvParameter4fARB(GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
 extern HIDDEN void __indirect_glProgramEnvParameter4fvARB(GLenum target, GLuint index, const GLfloat * params);
 extern HIDDEN void __indirect_glProgramLocalParameter4dARB(GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
 extern HIDDEN void __indirect_glProgramLocalParameter4dvARB(GLenum target, GLuint index, const GLdouble * params);
index 4791843..852fe71 100644 (file)
@@ -526,7 +526,9 @@ __GLapi * __glXNewIndirectAPI( void )
     glAPI->GetVertexAttribdvARB = __indirect_glGetVertexAttribdvARB;
     glAPI->GetVertexAttribfvARB = __indirect_glGetVertexAttribfvARB;
     glAPI->GetVertexAttribivARB = __indirect_glGetVertexAttribivARB;
+    glAPI->ProgramEnvParameter4dARB = __indirect_glProgramEnvParameter4dARB;
     glAPI->ProgramEnvParameter4dvARB = __indirect_glProgramEnvParameter4dvARB;
+    glAPI->ProgramEnvParameter4fARB = __indirect_glProgramEnvParameter4fARB;
     glAPI->ProgramEnvParameter4fvARB = __indirect_glProgramEnvParameter4fvARB;
     glAPI->ProgramLocalParameter4dARB = __indirect_glProgramLocalParameter4dARB;
     glAPI->ProgramLocalParameter4dvARB = __indirect_glProgramLocalParameter4dvARB;
index 90ec277..09d7244 100644 (file)
@@ -32,7 +32,7 @@
 #include <GL/glxproto.h>
 #include "glxextensions.h"
 #include "indirect_vertex_array.h"
-#include "indirect_va_private.h"
+#include "indirect_vertex_array_priv.h"
 
 #define __GLX_PAD(n) (((n)+3) & ~3)
 
@@ -485,14 +485,14 @@ emit_DrawArrays_none( GLenum mode, GLint first, GLsizei count )
 
     for ( i = 0 ; i < count ; i++ ) {
        if ( (pc + single_vertex_size) >= gc->bufEnd ) {
-           pc = __glXFlushRenderBuffer(gc, gc->pc);
+           pc = __glXFlushRenderBuffer(gc, pc);
        }
 
        pc = emit_element_none( pc, arrays, first + i );
     }
 
     if ( (pc + 4) >= gc->bufEnd ) {
-       pc = __glXFlushRenderBuffer(gc, gc->pc);
+       pc = __glXFlushRenderBuffer(gc, pc);
     }
 
     (void) memcpy( pc, end_cmd, 4 );
@@ -527,7 +527,7 @@ static GLubyte *
 emit_DrawArrays_header_old( __GLXcontext * gc,
                            struct array_state_vector * arrays,
                            size_t * elements_per_request,
-                           size_t * total_requests,
+                           unsigned int * total_requests,
                            GLenum mode, GLsizei count )
 {
     size_t command_size;
@@ -640,7 +640,7 @@ emit_DrawArrays_old( GLenum mode, GLint first, GLsizei count )
 
     GLubyte * pc;
     size_t elements_per_request;
-    size_t total_requests = 0;
+    unsigned total_requests = 0;
     unsigned i;
     size_t total_sent = 0;
 
@@ -726,7 +726,7 @@ emit_DrawElements_none( GLenum mode, GLsizei count, GLenum type,
        unsigned  index = 0;
 
        if ( (pc + single_vertex_size) >= gc->bufEnd ) {
-           pc = __glXFlushRenderBuffer(gc, gc->pc);
+           pc = __glXFlushRenderBuffer(gc, pc);
        }
 
        switch( type ) {
@@ -744,7 +744,7 @@ emit_DrawElements_none( GLenum mode, GLsizei count, GLenum type,
     }
 
     if ( (pc + 4) >= gc->bufEnd ) {
-       pc = __glXFlushRenderBuffer(gc, gc->pc);
+       pc = __glXFlushRenderBuffer(gc, pc);
     }
 
     (void) memcpy( pc, end_cmd, 4 );
@@ -770,9 +770,10 @@ emit_DrawElements_old( GLenum mode, GLsizei count, GLenum type,
 
     GLubyte * pc;
     size_t elements_per_request;
-    size_t total_requests = 0;
+    unsigned total_requests = 0;
     unsigned i;
     unsigned req;
+    unsigned req_element=0;
 
 
     pc = emit_DrawArrays_header_old( gc, arrays, & elements_per_request,
@@ -790,7 +791,7 @@ emit_DrawElements_old( GLenum mode, GLsizei count, GLenum type,
 
        switch( type ) {
        case GL_UNSIGNED_INT: {
-           const GLuint   * ui_ptr = (const GLuint   *) indices;
+           const GLuint   * ui_ptr = (const GLuint   *) indices + req_element;
 
            for ( i = 0 ; i < elements_per_request ; i++ ) {
                const GLint index = (GLint) *(ui_ptr++);
@@ -799,7 +800,7 @@ emit_DrawElements_old( GLenum mode, GLsizei count, GLenum type,
            break;
        }
        case GL_UNSIGNED_SHORT: {
-           const GLushort * us_ptr = (const GLushort *) indices;
+           const GLushort * us_ptr = (const GLushort *) indices + req_element;
 
            for ( i = 0 ; i < elements_per_request ; i++ ) {
                const GLint index = (GLint) *(us_ptr++);
@@ -808,7 +809,7 @@ emit_DrawElements_old( GLenum mode, GLsizei count, GLenum type,
            break;
        }
        case GL_UNSIGNED_BYTE: {
-           const GLubyte  * ub_ptr = (const GLubyte  *) indices;
+           const GLubyte  * ub_ptr = (const GLubyte  *) indices + req_element;
 
            for ( i = 0 ; i < elements_per_request ; i++ ) {
                const GLint index = (GLint) *(ub_ptr++);
@@ -826,6 +827,7 @@ emit_DrawElements_old( GLenum mode, GLsizei count, GLenum type,
        }
 
        count -= elements_per_request;
+       req_element += elements_per_request;
     }
 
 
index cd88684..144e5df 100644 (file)
@@ -117,7 +117,7 @@ void NAME(_gloffset_GetSeparableFilter)(GLenum target, GLenum format, GLenum typ
 {
     __GLXcontext * const gc = __glXGetCurrentContext();
 
-    if (gc->isDirect) {
+    if (gc->driContext) {
        CALL_GetSeparableFilter(GET_DISPATCH(),
                                (target, format, type, row, column, span));
        return;
index c8c878f..a6a57c3 100644 (file)
@@ -64,8 +64,6 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 #ifndef _XF86DRI_SERVER_
 
-#include <GL/internal/dri_interface.h>
-
 _XFUNCPROTOBEGIN
 
 Bool XF86DRIQueryExtension( Display *dpy, int *event_base, int *error_base );
@@ -93,14 +91,14 @@ Bool XF86DRICreateContext( Display *dpy, int screen, Visual *visual,
 Bool XF86DRICreateContextWithConfig( Display *dpy, int screen, int configID,
     XID *ptr_to_returned_context_id, drm_context_t *hHWContext );
 
-extern GLboolean XF86DRIDestroyContext( __DRInativeDisplay *dpy, int screen,
-    __DRIid context_id );
+extern GLboolean XF86DRIDestroyContext( Display *dpy, int screen,
+    XID context_id );
 
-extern GLboolean XF86DRICreateDrawable( __DRInativeDisplay *dpy, int screen,
-    __DRIid drawable, drm_drawable_t *hHWDrawable );
+extern GLboolean XF86DRICreateDrawable( Display *dpy, int screen,
+    XID drawable, drm_drawable_t *hHWDrawable );
 
-extern GLboolean XF86DRIDestroyDrawable( __DRInativeDisplay *dpy, int screen, 
-    __DRIid drawable);
+extern GLboolean XF86DRIDestroyDrawable( Display *dpy, int screen, 
+    XID drawable);
 
 Bool XF86DRIGetDrawableInfo( Display *dpy, int screen, Drawable drawable,
     unsigned int *index, unsigned int *stamp, 
index f3e3da3..6ec8c2d 100644 (file)
@@ -33,6 +33,7 @@
   called by that routine when direct rendering is enabled.
 */
 
+#ifdef GLX_DIRECT_RENDERING
 
 #include "glxclient.h"
 
@@ -208,8 +209,7 @@ static XCharStruct *isvalid(XFontStruct *fs, int which)
   return(NULL);
 }
 
-
-void DRI_glXUseXFont( Font font, int first, int count, int listbase )
+_X_HIDDEN void DRI_glXUseXFont( Font font, int first, int count, int listbase )
 {
   GLXContext CC;
   Display *dpy;
@@ -373,4 +373,4 @@ bm_height);
   glPixelStorei(GL_UNPACK_ALIGNMENT, alignment);
 }
 
-/* The End. */
+#endif
index fff79c3..2013125 100644 (file)
 
 #include "dri_util.h"
 #include "drm_sarea.h"
+#include "utils.h"
 
 #ifndef GLX_OML_sync_control
-typedef GLboolean ( * PFNGLXGETMSCRATEOMLPROC) (__DRInativeDisplay *dpy, __DRIid drawable, int32_t *numerator, int32_t *denominator);
+typedef GLboolean ( * PFNGLXGETMSCRATEOMLPROC) (__DRIdrawable *drawable, int32_t *numerator, int32_t *denominator);
 #endif
 
-/* This pointer *must* be set by the driver's __driCreateNewScreen funciton!
- */
-const __DRIinterfaceMethods * dri_interface = NULL;
-
 /**
- * This is used in a couple of places that call \c driCreateNewDrawable.
+ * This is just a token extension used to signal that the driver
+ * supports setting a read drawable.
  */
-static const int empty_attribute_list[1] = { None };
-
-
-/**
- * Cached copy of the internal API version used by libGL and the client-side
- * DRI driver.
- */
-static int api_ver = 0;
-
-/* forward declarations */
-static int driQueryFrameTracking( __DRInativeDisplay *dpy, void *priv,
-                                  int64_t *sbc, int64_t *missedFrames,
-                                  float *lastMissedUsage, float *usage );
-
-static void *driCreateNewDrawable(__DRInativeDisplay *dpy,
-                                  const __GLcontextModes *modes,
-                                  __DRIid draw, __DRIdrawable *pdraw,
-                                  int renderType, const int *attrs);
-
-static void driDestroyDrawable(__DRInativeDisplay *dpy, void *drawablePrivate);
-
+const __DRIextension driReadDrawableExtension = {
+    __DRI_READ_DRAWABLE, __DRI_READ_DRAWABLE_VERSION
+};
 
 /**
  * Print message to \c stderr if the \c LIBGL_DEBUG environment variable
@@ -111,64 +91,19 @@ __driUtilMessage(const char *f, ...)
     }
 }
 
-
-/*****************************************************************/
-/** \name Drawable list management */
-/*****************************************************************/
-/*@{*/
-
-static GLboolean __driAddDrawable(void *drawHash, __DRIdrawable *pdraw)
+GLint
+driIntersectArea( drm_clip_rect_t rect1, drm_clip_rect_t rect2 )
 {
-    __DRIdrawablePrivate *pdp = (__DRIdrawablePrivate *)pdraw->private;
+   if (rect2.x1 > rect1.x1) rect1.x1 = rect2.x1;
+   if (rect2.x2 < rect1.x2) rect1.x2 = rect2.x2;
+   if (rect2.y1 > rect1.y1) rect1.y1 = rect2.y1;
+   if (rect2.y2 < rect1.y2) rect1.y2 = rect2.y2;
 
-    if (drmHashInsert(drawHash, pdp->draw, pdraw))
-       return GL_FALSE;
+   if (rect1.x1 > rect1.x2 || rect1.y1 > rect1.y2) return 0;
 
-    return GL_TRUE;
-}
-
-static __DRIdrawable *__driFindDrawable(void *drawHash, __DRIid draw)
-{
-    int retcode;
-    __DRIdrawable *pdraw;
-
-    retcode = drmHashLookup(drawHash, draw, (void *)&pdraw);
-    if (retcode)
-       return NULL;
-
-    return pdraw;
-}
-
-
-/**
- * Find drawables in the local hash that have been destroyed on the
- * server.
- * 
- * \param drawHash  Hash-table containing all known drawables.
- */
-static void __driGarbageCollectDrawables(void *drawHash)
-{
-    __DRIid draw;
-    __DRInativeDisplay *dpy;
-    __DRIdrawable *pdraw;
-
-    if (drmHashFirst(drawHash, &draw, (void *)&pdraw) == 1) {
-       do {
-           __DRIdrawablePrivate *pdp = (__DRIdrawablePrivate *)pdraw->private;
-           dpy = pdp->driScreenPriv->display;
-           if (! (*dri_interface->windowExists)(dpy, draw)) {
-               /* Destroy the local drawable data, if the drawable no
-                  longer exists in the Xserver */
-               (*pdraw->destroyDrawable)(dpy, pdraw->private);
-               _mesa_free(pdraw);
-           }
-       } while (drmHashNext(drawHash, &draw, (void *)&pdraw) == 1);
-    }
+   return (rect1.x2 - rect1.x1) * (rect1.y2 - rect1.y1);
 }
 
-/*@}*/
-
-
 /*****************************************************************/
 /** \name Context (un)binding functions                          */
 /*****************************************************************/
@@ -177,10 +112,7 @@ static void __driGarbageCollectDrawables(void *drawHash)
 /**
  * Unbind context.
  * 
- * \param dpy the display handle.
- * \param scrn the screen number.
- * \param draw drawable.
- * \param read Current reading drawable.
+ * \param scrn the screen.
  * \param gc context.
  *
  * \return \c GL_TRUE on success, or \c GL_FALSE on failure.
@@ -193,56 +125,27 @@ static void __driGarbageCollectDrawables(void *drawHash)
  * While casting the opaque private pointers associated with the parameters
  * into their respective real types it also assures they are not \c NULL. 
  */
-static GLboolean driUnbindContext(__DRInativeDisplay *dpy, int scrn,
-                             __DRIid draw, __DRIid read,
-                             __DRIcontext *ctx)
+static int driUnbindContext(__DRIcontext *pcp)
 {
-    __DRIscreen *pDRIScreen;
-    __DRIdrawable *pdraw;
-    __DRIdrawable *pread;
-    __DRIcontextPrivate *pcp;
-    __DRIscreenPrivate *psp;
-    __DRIdrawablePrivate *pdp;
-    __DRIdrawablePrivate *prp;
+    __DRIscreen *psp;
+    __DRIdrawable *pdp;
+    __DRIdrawable *prp;
 
     /*
     ** Assume error checking is done properly in glXMakeCurrent before
     ** calling driUnbindContext.
     */
 
-    if (ctx == NULL || draw == None || read == None) {
-       /* ERROR!!! */
-       return GL_FALSE;
-    }
-
-    pDRIScreen = (*dri_interface->getScreen)(dpy, scrn);
-    if ( (pDRIScreen == NULL) || (pDRIScreen->private == NULL) ) {
-       /* ERROR!!! */
-       return GL_FALSE;
-    }
-
-    psp = (__DRIscreenPrivate *)pDRIScreen->private;
-    pcp = (__DRIcontextPrivate *)ctx->private;
-
-    pdraw = __driFindDrawable(psp->drawHash, draw);
-    if (!pdraw) {
-       /* ERROR!!! */
-       return GL_FALSE;
-    }
-    pdp = (__DRIdrawablePrivate *)pdraw->private;
-
-    pread = __driFindDrawable(psp->drawHash, read);
-    if (!pread) {
-       /* ERROR!!! */
-       return GL_FALSE;
-    }
-    prp = (__DRIdrawablePrivate *)pread->private;
+    if (pcp == NULL)
+        return GL_FALSE;
 
+    psp = pcp->driScreenPriv;
+    pdp = pcp->driDrawablePriv;
+    prp = pcp->driReadablePriv;
 
     /* Let driver unbind drawable from context */
     (*psp->DriverAPI.UnbindContext)(pcp);
 
-
     if (pdp->refcount == 0) {
        /* ERROR!!! */
        return GL_FALSE;
@@ -259,12 +162,6 @@ static GLboolean driUnbindContext(__DRInativeDisplay *dpy, int scrn,
        prp->refcount--;
     }
 
-   /* destroy the drawables if they no longer exist on the server */
-   if ((pdp->refcount == 0) || (prp->refcount == 0)) {
-      /* probably shouldn't need the collector here,
-         as we know the affected drawables (or could there be others?) */
-      __driGarbageCollectDrawables(pdp->driScreenPriv->drawHash);
-   }
 
     /* XXX this is disabled so that if we call SwapBuffers on an unbound
      * window we can determine the last context bound to the window and
@@ -284,72 +181,20 @@ static GLboolean driUnbindContext(__DRInativeDisplay *dpy, int scrn,
  * This function takes both a read buffer and a draw buffer.  This is needed
  * for \c glXMakeCurrentReadSGI or GLX 1.3's \c glXMakeContextCurrent
  * function.
- * 
- * \bug This function calls \c driCreateNewDrawable in two places with the
- *      \c renderType hard-coded to \c GLX_WINDOW_BIT.  Some checking might
- *      be needed in those places when support for pbuffers and / or pixmaps
- *      is added.  Is it safe to assume that the drawable is a window?
  */
-static GLboolean DoBindContext(__DRInativeDisplay *dpy,
-                         __DRIid draw, __DRIid read,
-                         __DRIcontext *ctx, const __GLcontextModes * modes,
-                         __DRIscreenPrivate *psp)
+static int driBindContext(__DRIcontext *pcp,
+                         __DRIdrawable *pdp,
+                         __DRIdrawable *prp)
 {
-    __DRIdrawable *pdraw;
-    __DRIdrawablePrivate *pdp;
-    __DRIdrawable *pread;
-    __DRIdrawablePrivate *prp;
-    __DRIcontextPrivate * const pcp = ctx->private;
-
-
-    /* Find the _DRIdrawable which corresponds to the writing drawable. */
-    pdraw = __driFindDrawable(psp->drawHash, draw);
-    if (!pdraw) {
-       /* Allocate a new drawable */
-       pdraw = (__DRIdrawable *)_mesa_malloc(sizeof(__DRIdrawable));
-       if (!pdraw) {
-           /* ERROR!!! */
-           return GL_FALSE;
-       }
-
-       /* Create a new drawable */
-       driCreateNewDrawable(dpy, modes, draw, pdraw, GLX_WINDOW_BIT,
-                            empty_attribute_list);
-       if (!pdraw->private) {
-           /* ERROR!!! */
-           _mesa_free(pdraw);
-           return GL_FALSE;
-       }
+    __DRIscreenPrivate *psp = pcp->driScreenPriv;
 
-    }
-    pdp = (__DRIdrawablePrivate *) pdraw->private;
+    /*
+    ** Assume error checking is done properly in glXMakeCurrent before
+    ** calling driBindContext.
+    */
 
-    /* Find the _DRIdrawable which corresponds to the reading drawable. */
-    if (read == draw) {
-        /* read buffer == draw buffer */
-        prp = pdp;
-    }
-    else {
-        pread = __driFindDrawable(psp->drawHash, read);
-        if (!pread) {
-            /* Allocate a new drawable */
-            pread = (__DRIdrawable *)_mesa_malloc(sizeof(__DRIdrawable));
-            if (!pread) {
-                /* ERROR!!! */
-                return GL_FALSE;
-            }
-
-            /* Create a new drawable */
-           driCreateNewDrawable(dpy, modes, read, pread, GLX_WINDOW_BIT,
-                                empty_attribute_list);
-            if (!pread->private) {
-                /* ERROR!!! */
-                _mesa_free(pread);
-                return GL_FALSE;
-            }
-        }
-        prp = (__DRIdrawablePrivate *) pread->private;
-    }
+    if (pcp == NULL || pdp == None || prp == None)
+       return GL_FALSE;
 
     /* Bind the drawable to the context */
     pcp->driDrawablePriv = pdp;
@@ -364,16 +209,22 @@ static GLboolean DoBindContext(__DRInativeDisplay *dpy,
     ** Now that we have a context associated with this drawable, we can
     ** initialize the drawable information if has not been done before.
     */
-    if (!pdp->pStamp || *pdp->pStamp != pdp->lastStamp) {
-       DRM_SPINLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID);
-       __driUtilUpdateDrawableInfo(pdp);
-       DRM_SPINUNLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID);
-    }
 
-    if ((pdp != prp) && (!prp->pStamp || *prp->pStamp != prp->lastStamp)) {
-       DRM_SPINLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID);
-       __driUtilUpdateDrawableInfo(prp);
-       DRM_SPINUNLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID);
+    if (psp->dri2.enabled) {
+       __driParseEvents(pcp, pdp);
+       __driParseEvents(pcp, prp);
+    } else {
+       if (!pdp->pStamp || *pdp->pStamp != pdp->lastStamp) {
+           DRM_SPINLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID);
+           __driUtilUpdateDrawableInfo(pdp);
+           DRM_SPINUNLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID);
+       }
+       
+       if ((pdp != prp) && (!prp->pStamp || *prp->pStamp != prp->lastStamp)) {
+           DRM_SPINLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID);
+           __driUtilUpdateDrawableInfo(prp);
+           DRM_SPINUNLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID);
+       }
     }
 
     /* Call device-specific MakeCurrent */
@@ -382,37 +233,6 @@ static GLboolean DoBindContext(__DRInativeDisplay *dpy,
     return GL_TRUE;
 }
 
-
-/**
- * This function takes both a read buffer and a draw buffer.  This is needed
- * for \c glXMakeCurrentReadSGI or GLX 1.3's \c glXMakeContextCurrent
- * function.
- */
-static GLboolean driBindContext(__DRInativeDisplay *dpy, int scrn,
-                            __DRIid draw, __DRIid read,
-                            __DRIcontext * ctx)
-{
-    __DRIscreen *pDRIScreen;
-
-    /*
-    ** Assume error checking is done properly in glXMakeCurrent before
-    ** calling driBindContext.
-    */
-
-    if (ctx == NULL || draw == None || read == None) {
-       /* ERROR!!! */
-       return GL_FALSE;
-    }
-
-    pDRIScreen = (*dri_interface->getScreen)(dpy, scrn);
-    if ( (pDRIScreen == NULL) || (pDRIScreen->private == NULL) ) {
-       /* ERROR!!! */
-       return GL_FALSE;
-    }
-
-    return DoBindContext( dpy, draw, read, ctx, ctx->mode,
-                         (__DRIscreenPrivate *)pDRIScreen->private );
-}
 /*@}*/
 
 
@@ -436,7 +256,7 @@ static GLboolean driBindContext(__DRInativeDisplay *dpy, int scrn,
 void
 __driUtilUpdateDrawableInfo(__DRIdrawablePrivate *pdp)
 {
-    __DRIscreenPrivate *psp;
+    __DRIscreenPrivate *psp = pdp->driScreenPriv;
     __DRIcontextPrivate *pcp = pdp->driContextPriv;
     
     if (!pcp 
@@ -447,15 +267,6 @@ __driUtilUpdateDrawableInfo(__DRIdrawablePrivate *pdp)
         */
     }
 
-    psp = pdp->driScreenPriv;
-    if (!psp) {
-       /* ERROR!!! */
-       _mesa_problem(NULL, "Warning! Possible infinite loop due to bug "
-                    "in file %s, line %d\n",
-                    __FILE__, __LINE__);
-       return;
-    }
-
     if (pdp->pClipRects) {
        _mesa_free(pdp->pClipRects); 
        pdp->pClipRects = NULL;
@@ -468,15 +279,15 @@ __driUtilUpdateDrawableInfo(__DRIdrawablePrivate *pdp)
 
     DRM_SPINUNLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID);
 
-    if (!__driFindDrawable(psp->drawHash, pdp->draw) ||
-       ! (*dri_interface->getDrawableInfo)(pdp->display, pdp->screen, pdp->draw,
+    if (! (*psp->getDrawableInfo->getDrawableInfo)(pdp,
                          &pdp->index, &pdp->lastStamp,
                          &pdp->x, &pdp->y, &pdp->w, &pdp->h,
                          &pdp->numClipRects, &pdp->pClipRects,
                          &pdp->backX,
                          &pdp->backY,
                          &pdp->numBackClipRects,
-                         &pdp->pBackClipRects )) {
+                         &pdp->pBackClipRects,
+                         pdp->loaderPrivate)) {
        /* Error -- eg the window may have been destroyed.  Keep going
         * with no cliprects.
         */
@@ -493,6 +304,138 @@ __driUtilUpdateDrawableInfo(__DRIdrawablePrivate *pdp)
 
 }
 
+int
+__driParseEvents(__DRIcontextPrivate *pcp, __DRIdrawablePrivate *pdp)
+{
+    __DRIscreenPrivate *psp = pcp->driScreenPriv;
+    __DRIDrawableConfigEvent *dc, *last_dc;
+    __DRIBufferAttachEvent *ba, *last_ba;
+    unsigned int tail, mask, *p, end, total, size, changed;
+    unsigned char *data;
+    size_t rect_size;
+
+    /* Check for wraparound. */
+    if (psp->dri2.buffer->prealloc - pdp->dri2.tail > psp->dri2.buffer->size) {
+       /* If prealloc overlaps into what we just parsed, the
+       * server overwrote it and we have to reset our tail
+       * pointer. */
+       DRM_UNLOCK(psp->fd, psp->lock, pcp->hHWContext);
+       (*psp->dri2.loader->reemitDrawableInfo)(pdp, &pdp->dri2.tail,
+                                               pdp->loaderPrivate);
+       DRM_LIGHT_LOCK(psp->fd, psp->lock, pcp->hHWContext);
+    }
+
+    total = psp->dri2.buffer->head - pdp->dri2.tail;
+    mask = psp->dri2.buffer->size - 1;
+    end = psp->dri2.buffer->head;
+    data = psp->dri2.buffer->data;
+
+    changed = 0;
+    last_dc = NULL;
+    last_ba = NULL;
+
+    for (tail = pdp->dri2.tail; tail != end; tail += size) {
+       p = (unsigned int *) (data + (tail & mask));
+       size = DRI2_EVENT_SIZE(*p);
+       if (size > total || (tail & mask) + size > psp->dri2.buffer->size) {
+         /* illegal data, bail out. */
+         fprintf(stderr, "illegal event size\n");
+         break;
+       }
+
+       switch (DRI2_EVENT_TYPE(*p)) {
+       case DRI2_EVENT_DRAWABLE_CONFIG:
+         dc = (__DRIDrawableConfigEvent *) p;
+         if (dc->drawable == pdp->dri2.drawable_id)
+            last_dc = dc;
+         break;
+
+       case DRI2_EVENT_BUFFER_ATTACH:
+         ba = (__DRIBufferAttachEvent *) p;
+         if (ba->drawable == pdp->dri2.drawable_id && 
+             ba->buffer.attachment == DRI_DRAWABLE_BUFFER_FRONT_LEFT)
+            last_ba = ba;
+         break;
+       }
+    }
+         
+    if (last_dc) {
+       if (pdp->w != last_dc->width || pdp->h != last_dc->height)
+         changed = 1;
+
+       pdp->x = last_dc->x;
+       pdp->y = last_dc->y;
+       pdp->w = last_dc->width;
+       pdp->h = last_dc->height;
+
+       pdp->backX = 0;
+       pdp->backY = 0;
+       pdp->numBackClipRects = 1;
+       pdp->pBackClipRects[0].x1 = 0;
+       pdp->pBackClipRects[0].y1 = 0;
+       pdp->pBackClipRects[0].x2 = pdp->w;
+       pdp->pBackClipRects[0].y2 = pdp->h;
+
+       pdp->numClipRects = last_dc->num_rects;
+       _mesa_free(pdp->pClipRects);
+       rect_size = last_dc->num_rects * sizeof last_dc->rects[0];
+       pdp->pClipRects = _mesa_malloc(rect_size);
+       memcpy(pdp->pClipRects, last_dc->rects, rect_size);
+    }
+
+    /* We only care about the most recent drawable config. */
+    if (last_dc && changed)
+       (*psp->DriverAPI.HandleDrawableConfig)(pdp, pcp, last_dc);
+
+    /* Front buffer attachments are special, they typically mean that
+     * we're rendering to a redirected window (or a child window of a
+     * redirected window) and that it got resized.  Resizing the root
+     * window on randr events is a special case of this.  Other causes
+     * may be a window transitioning between redirected and
+     * non-redirected, or a window getting reparented between parents
+     * with different window pixmaps (eg two redirected windows).
+     * These events are special in that the X server allocates the
+     * buffer and that the buffer may be shared by other child
+     * windows.  When our window share the window pixmap with its
+     * parent, drawable config events doesn't affect the front buffer.
+     * We only care about the last such event in the buffer; in fact,
+     * older events will refer to invalid buffer objects.*/
+    if (last_ba)
+       (*psp->DriverAPI.HandleBufferAttach)(pdp, pcp, last_ba);
+
+    /* If there was a drawable config event in the buffer and it
+     * changed the size of the window, all buffer auxillary buffer
+     * attachments prior to that are invalid (as opposed to the front
+     * buffer case discussed above).  In that case we can start
+     * looking for buffer attachment after the last drawable config
+     * event.  If there is no drawable config event in this batch of
+     * events, we have to assume that the last batch might have had
+     * one and process all buffer attach events.*/
+    if (last_dc && changed)
+       tail = (unsigned char *) last_dc - data;
+    else
+       tail = pdp->dri2.tail;
+
+    for ( ; tail != end; tail += size) {
+       ba = (__DRIBufferAttachEvent *) (data + (tail & mask));
+       size = DRI2_EVENT_SIZE(ba->event_header);
+
+       if (DRI2_EVENT_TYPE(ba->event_header) != DRI2_EVENT_BUFFER_ATTACH)
+         continue;
+       if (ba->drawable != pdp->dri2.drawable_id)
+         continue;
+       if (last_ba == ba)
+         continue;
+
+       (*psp->DriverAPI.HandleBufferAttach)(pdp, pcp, ba);
+       changed = 1;
+    }
+
+    pdp->dri2.tail = tail;
+
+    return changed || last_ba;
+}
+
 /*@}*/
 
 /*****************************************************************/
@@ -500,10 +443,33 @@ __driUtilUpdateDrawableInfo(__DRIdrawablePrivate *pdp)
 /*****************************************************************/
 /*@{*/
 
+static void driReportDamage(__DRIdrawable *pdp,
+                           struct drm_clip_rect *pClipRects, int numClipRects)
+{
+    __DRIscreen *psp = pdp->driScreenPriv;
+
+    /* Check that we actually have the new damage report method */
+    if (psp->dri2.enabled) {
+       (*psp->dri2.loader->postDamage)(pdp,
+                                       pClipRects,
+                                       numClipRects,
+                                       pdp->loaderPrivate);
+    } else if (psp->damage) {
+       /* Report the damage.  Currently, all our drivers draw
+        * directly to the front buffer, so we report the damage there
+        * rather than to the backing storein (if any).
+        */
+       (*psp->damage->reportDamage)(pdp,
+                                    pdp->x, pdp->y,
+                                    pClipRects, numClipRects,
+                                    GL_TRUE, pdp->loaderPrivate);
+    }
+}
+
+
 /**
  * Swap buffers.
  *
- * \param dpy the display handle.
  * \param drawablePrivate opaque pointer to the per-drawable private info.
  * 
  * \internal
@@ -511,74 +477,28 @@ __driUtilUpdateDrawableInfo(__DRIdrawablePrivate *pdp)
  * 
  * Is called directly from glXSwapBuffers().
  */
-static void driSwapBuffers( __DRInativeDisplay *dpy, void *drawablePrivate )
-{
-    __DRIdrawablePrivate *dPriv = (__DRIdrawablePrivate *) drawablePrivate;
-    drm_clip_rect_t rect;
-
-    dPriv->swapBuffers(dPriv);
-
-    /* Check that we actually have the new damage report method */
-    if (api_ver < 20070105 || dri_interface->reportDamage == NULL)
-       return;
-
-    /* Assume it's affecting the whole drawable for now */
-    rect.x1 = 0;
-    rect.y1 = 0;
-    rect.x2 = rect.x1 + dPriv->w;
-    rect.y2 = rect.y1 + dPriv->h;
-
-    /* Report the damage.  Currently, all our drivers draw directly to the
-     * front buffer, so we report the damage there rather than to the backing
-     * store (if any).
-     */
-    (*dri_interface->reportDamage)(dpy, dPriv->screen, dPriv->draw,
-                                  dPriv->x, dPriv->y,
-                                  &rect, 1, GL_TRUE);
-}
-
-/**
- * Called directly from a number of higher-level GLX functions.
- */
-static int driGetMSC( void *screenPrivate, int64_t *msc )
-{
-    __DRIscreenPrivate *sPriv = (__DRIscreenPrivate *) screenPrivate;
-
-    return sPriv->DriverAPI.GetMSC( sPriv, msc );
-}
-
-/**
- * Called directly from a number of higher-level GLX functions.
- */
-static int driGetSBC( __DRInativeDisplay *dpy, void *drawablePrivate, int64_t *sbc )
+static void driSwapBuffers(__DRIdrawable *dPriv)
 {
-   __DRIdrawablePrivate *dPriv = (__DRIdrawablePrivate *) drawablePrivate;
-   __DRIswapInfo  sInfo;
-   int  status;
+    __DRIscreen *psp = dPriv->driScreenPriv;
 
+    if (!dPriv->numClipRects)
+        return;
 
-   status = dPriv->driScreenPriv->DriverAPI.GetSwapInfo( dPriv, & sInfo );
-   *sbc = sInfo.swap_count;
+    psp->DriverAPI.SwapBuffers(dPriv);
 
-   return status;
+    driReportDamage(dPriv, dPriv->pClipRects, dPriv->numClipRects);
 }
 
-static int driWaitForSBC( __DRInativeDisplay * dpy, void *drawablePriv,
-                         int64_t target_sbc,
-                         int64_t * msc, int64_t * sbc )
+static int driDrawableGetMSC( __DRIscreen *sPriv, __DRIdrawable *dPriv,
+                             int64_t *msc )
 {
-    __DRIdrawablePrivate *dPriv = (__DRIdrawablePrivate *) drawablePriv;
-
-    return dPriv->driScreenPriv->DriverAPI.WaitForSBC( dPriv, target_sbc,
-                                                       msc, sbc );
+    return sPriv->DriverAPI.GetDrawableMSC(sPriv, dPriv, msc);
 }
 
-static int driWaitForMSC( __DRInativeDisplay * dpy, void *drawablePriv,
-                         int64_t target_msc,
-                         int64_t divisor, int64_t remainder,
-                         int64_t * msc, int64_t * sbc )
+static int driWaitForMSC(__DRIdrawable *dPriv, int64_t target_msc,
+                        int64_t divisor, int64_t remainder,
+                        int64_t * msc, int64_t * sbc)
 {
-    __DRIdrawablePrivate *dPriv = (__DRIdrawablePrivate *) drawablePriv;
     __DRIswapInfo  sInfo;
     int  status;
 
@@ -600,63 +520,70 @@ static int driWaitForMSC( __DRInativeDisplay * dpy, void *drawablePriv,
     return status;
 }
 
-static int64_t driSwapBuffersMSC( __DRInativeDisplay * dpy, void *drawablePriv,
-                                 int64_t target_msc,
-                                 int64_t divisor, int64_t remainder )
+const __DRImediaStreamCounterExtension driMediaStreamCounterExtension = {
+    { __DRI_MEDIA_STREAM_COUNTER, __DRI_MEDIA_STREAM_COUNTER_VERSION },
+    driWaitForMSC,
+    driDrawableGetMSC,
+};
+
+static void driCopySubBuffer(__DRIdrawable *dPriv,
+                             int x, int y, int w, int h)
 {
-    __DRIdrawablePrivate *dPriv = (__DRIdrawablePrivate *) drawablePriv;
+    drm_clip_rect_t rect;
 
-    return dPriv->driScreenPriv->DriverAPI.SwapBuffersMSC( dPriv, target_msc,
-                                                           divisor, 
-                                                           remainder );
+    dPriv->driScreenPriv->DriverAPI.CopySubBuffer(dPriv, x, y, w, h);
+
+    rect.x1 = x;
+    rect.y1 = dPriv->h - y - h;
+    rect.x2 = x + w;
+    rect.y2 = rect.y1 + h;
+    driReportDamage(dPriv, &rect, 1);
 }
 
-static void driCopySubBuffer( __DRInativeDisplay *dpy, void *drawablePrivate,
-                             int x, int y, int w, int h)
+const __DRIcopySubBufferExtension driCopySubBufferExtension = {
+    { __DRI_COPY_SUB_BUFFER, __DRI_COPY_SUB_BUFFER_VERSION },
+    driCopySubBuffer
+};
+
+static void driSetSwapInterval(__DRIdrawable *dPriv, unsigned int interval)
 {
-    __DRIdrawablePrivate *dPriv = (__DRIdrawablePrivate *) drawablePrivate;
-    dPriv->driScreenPriv->DriverAPI.CopySubBuffer(dPriv, x, y, w, h);
-    (void) dpy;
+    dPriv->swap_interval = interval;
 }
 
+static unsigned int driGetSwapInterval(__DRIdrawable *dPriv)
+{
+    return dPriv->swap_interval;
+}
+
+const __DRIswapControlExtension driSwapControlExtension = {
+    { __DRI_SWAP_CONTROL, __DRI_SWAP_CONTROL_VERSION },
+    driSetSwapInterval,
+    driGetSwapInterval
+};
+
+
 /**
  * This is called via __DRIscreenRec's createNewDrawable pointer.
  */
-static void *driCreateNewDrawable(__DRInativeDisplay *dpy,
-                                 const __GLcontextModes *modes,
-                                 __DRIid draw,
-                                 __DRIdrawable *pdraw,
-                                 int renderType,
-                                 const int *attrs)
+static __DRIdrawable *
+driCreateNewDrawable(__DRIscreen *psp, const __DRIconfig *config,
+                    drm_drawable_t hwDrawable, int renderType,
+                    const int *attrs, void *data)
 {
-    __DRIscreen * const pDRIScreen = (*dri_interface->getScreen)(dpy, modes->screen);
-    __DRIscreenPrivate *psp;
-    __DRIdrawablePrivate *pdp;
-
-
-    pdraw->private = NULL;
+    __DRIdrawable *pdp;
 
     /* Since pbuffers are not yet supported, no drawable attributes are
      * supported either.
      */
     (void) attrs;
 
-    if ( (pDRIScreen == NULL) || (pDRIScreen->private == NULL) ) {
-       return NULL;
-    }
-
-    pdp = (__DRIdrawablePrivate *)_mesa_malloc(sizeof(__DRIdrawablePrivate));
+    pdp = _mesa_malloc(sizeof *pdp);
     if (!pdp) {
        return NULL;
     }
 
-    if (!(*dri_interface->createDrawable)(dpy, modes->screen, draw, &pdp->hHWDrawable)) {
-       _mesa_free(pdp);
-       return NULL;
-    }
-
-    pdp->draw = draw;
-    pdp->pdraw = pdraw;
+    pdp->loaderPrivate = data;
+    pdp->hHWDrawable = hwDrawable;
     pdp->refcount = 0;
     pdp->pStamp = NULL;
     pdp->lastStamp = 0;
@@ -669,80 +596,55 @@ static void *driCreateNewDrawable(__DRInativeDisplay *dpy,
     pdp->numBackClipRects = 0;
     pdp->pClipRects = NULL;
     pdp->pBackClipRects = NULL;
-    pdp->display = dpy;
-    pdp->screen = modes->screen;
+    pdp->vblSeq = 0;
+    pdp->vblFlags = 0;
 
-    psp = (__DRIscreenPrivate *)pDRIScreen->private;
     pdp->driScreenPriv = psp;
     pdp->driContextPriv = &psp->dummyContextPriv;
 
-    if (!(*psp->DriverAPI.CreateBuffer)(psp, pdp, modes,
+    if (!(*psp->DriverAPI.CreateBuffer)(psp, pdp, &config->modes,
                                        renderType == GLX_PIXMAP_BIT)) {
-       (void)(*dri_interface->destroyDrawable)(dpy, modes->screen, pdp->draw);
        _mesa_free(pdp);
        return NULL;
     }
 
-    pdraw->private = pdp;
-    pdraw->destroyDrawable = driDestroyDrawable;
-    pdraw->swapBuffers = driSwapBuffers;  /* called by glXSwapBuffers() */
-
-    pdraw->getSBC = driGetSBC;
-    pdraw->waitForSBC = driWaitForSBC;
-    pdraw->waitForMSC = driWaitForMSC;
-    pdraw->swapBuffersMSC = driSwapBuffersMSC;
-    pdraw->frameTracking = NULL;
-    pdraw->queryFrameTracking = driQueryFrameTracking;
-
-    if (driCompareGLXAPIVersion (20060314) >= 0)
-       pdraw->copySubBuffer = driCopySubBuffer;
+    pdp->msc_base = 0;
 
     /* This special default value is replaced with the configured
      * default value when the drawable is first bound to a direct
      * rendering context. 
      */
-    pdraw->swap_interval = (unsigned)-1;
-
-    pdp->swapBuffers = psp->DriverAPI.SwapBuffers;
+    pdp->swap_interval = (unsigned)-1;
 
-    /* Add pdraw to drawable list */
-    if (!__driAddDrawable(psp->drawHash, pdraw)) {
-       /* ERROR!!! */
-       (*pdraw->destroyDrawable)(dpy, pdp);
-       _mesa_free(pdp);
-       pdp = NULL;
-       pdraw->private = NULL;
-    }
-
-   return (void *) pdp;
+    return pdp;
 }
 
 static __DRIdrawable *
-driGetDrawable(__DRInativeDisplay *dpy, __DRIid draw, void *screenPrivate)
+dri2CreateNewDrawable(__DRIscreen *screen, const __DRIconfig *config,
+                     unsigned int drawable_id, unsigned int head, void *data)
 {
-    __DRIscreenPrivate *psp = (__DRIscreenPrivate *) screenPrivate;
+    __DRIdrawable *pdraw;
 
-    /*
-    ** Make sure this routine returns NULL if the drawable is not bound
-    ** to a direct rendering context!
-    */
-    return __driFindDrawable(psp->drawHash, draw);
+    pdraw = driCreateNewDrawable(screen, config, 0, 0, NULL, data);
+    if (!pdraw)
+       return NULL;
+
+    pdraw->dri2.drawable_id = drawable_id;
+    pdraw->dri2.tail = head;
+    pdraw->pBackClipRects = _mesa_malloc(sizeof *pdraw->pBackClipRects);
+
+    return pdraw;
 }
 
+
 static void
-driDestroyDrawable(__DRInativeDisplay *dpy, void *drawablePrivate)
+driDestroyDrawable(__DRIdrawable *pdp)
 {
-    __DRIdrawablePrivate *pdp = (__DRIdrawablePrivate *) drawablePrivate;
     __DRIscreenPrivate *psp;
-    int scrn;
 
     if (pdp) {
        psp = pdp->driScreenPriv;
-       scrn = psp->myNum;
         (*psp->DriverAPI.DestroyBuffer)(pdp);
-       if ((*dri_interface->windowExists)(dpy, pdp->draw))
-           (void)(*dri_interface->destroyDrawable)(dpy, scrn, pdp->draw);
-       drmHashDelete(psp->drawHash, pdp->draw);
        if (pdp->pClipRects) {
            _mesa_free(pdp->pClipRects);
            pdp->pClipRects = NULL;
@@ -766,8 +668,6 @@ driDestroyDrawable(__DRInativeDisplay *dpy, void *drawablePrivate)
 /**
  * Destroy the per-context private information.
  * 
- * \param dpy the display handle.
- * \param scrn the screen number.
  * \param contextPrivate opaque pointer to the per-drawable private info.
  *
  * \internal
@@ -775,14 +675,10 @@ driDestroyDrawable(__DRInativeDisplay *dpy, void *drawablePrivate)
  * drmDestroyContext(), and finally frees \p contextPrivate.
  */
 static void
-driDestroyContext(__DRInativeDisplay *dpy, int scrn, void *contextPrivate)
+driDestroyContext(__DRIcontext *pcp)
 {
-    __DRIcontextPrivate  *pcp   = (__DRIcontextPrivate *) contextPrivate;
-
     if (pcp) {
        (*pcp->driScreenPriv->DriverAPI.DestroyContext)(pcp);
-       __driGarbageCollectDrawables(pcp->driScreenPriv->drawHash);
-       (void) (*dri_interface->destroyContext)(dpy, scrn, pcp->contextID);
        _mesa_free(pcp);
     }
 }
@@ -795,7 +691,7 @@ driDestroyContext(__DRInativeDisplay *dpy, int scrn, void *contextPrivate)
  * \param modes         Mode used to create the new context.
  * \param render_type   Type of rendering target.  \c GLX_RGBA is the only
  *                      type likely to ever be supported for direct-rendering.
- * \param sharedPrivate The shared context dependent methods or \c NULL if
+ * \param shared        The shared context dependent methods or \c NULL if
  *                      non-existent.
  * \param pctx          DRI context to receive the context dependent methods.
  *
@@ -809,36 +705,18 @@ driDestroyContext(__DRInativeDisplay *dpy, int scrn, void *contextPrivate)
  * context.
  *
  */
-static void *
-driCreateNewContext(__DRInativeDisplay *dpy, const __GLcontextModes *modes,
-                   int render_type, void *sharedPrivate, __DRIcontext *pctx)
+static __DRIcontext *
+driCreateNewContext(__DRIscreen *psp, const __DRIconfig *config,
+                   int render_type, __DRIcontext *shared, 
+                   drm_context_t hwContext, void *data)
 {
-    __DRIscreen *pDRIScreen;
-    __DRIcontextPrivate *pcp;
-    __DRIcontextPrivate *pshare = (__DRIcontextPrivate *) sharedPrivate;
-    __DRIscreenPrivate *psp;
-    void * const shareCtx = (pshare != NULL) ? pshare->driverPrivate : NULL;
+    __DRIcontext *pcp;
+    void * const shareCtx = (shared != NULL) ? shared->driverPrivate : NULL;
 
-    pDRIScreen = (*dri_interface->getScreen)(dpy, modes->screen);
-    if ( (pDRIScreen == NULL) || (pDRIScreen->private == NULL) ) {
-       /* ERROR!!! */
+    pcp = _mesa_malloc(sizeof *pcp);
+    if (!pcp)
        return NULL;
-    } 
-
-    psp = (__DRIscreenPrivate *)pDRIScreen->private;
 
-    pcp = (__DRIcontextPrivate *)_mesa_malloc(sizeof(__DRIcontextPrivate));
-    if (!pcp) {
-       return NULL;
-    }
-
-    if (! (*dri_interface->createContext)(dpy, modes->screen, modes->fbconfigID,
-                                       &pcp->contextID, &pcp->hHWContext)) {
-       _mesa_free(pcp);
-       return NULL;
-    }
-
-    pcp->display = dpy;
     pcp->driScreenPriv = psp;
     pcp->driDrawablePriv = NULL;
 
@@ -846,8 +724,7 @@ driCreateNewContext(__DRInativeDisplay *dpy, const __GLcontextModes *modes,
      * context.
      */
 
-    if (!psp->dummyContextPriv.driScreenPriv) {
-        psp->dummyContextPriv.contextID = 0;
+    if (!psp->dri2.enabled && !psp->dummyContextPriv.driScreenPriv) {
         psp->dummyContextPriv.hHWContext = psp->pSAREA->dummy_context;
         psp->dummyContextPriv.driScreenPriv = psp;
         psp->dummyContextPriv.driDrawablePriv = NULL;
@@ -855,21 +732,40 @@ driCreateNewContext(__DRInativeDisplay *dpy, const __GLcontextModes *modes,
        /* No other fields should be used! */
     }
 
-    pctx->destroyContext = driDestroyContext;
-    pctx->bindContext    = driBindContext;
-    pctx->unbindContext  = driUnbindContext;
+    pcp->hHWContext = hwContext;
 
-    if ( !(*psp->DriverAPI.CreateContext)(modes, pcp, shareCtx) ) {
-        (void) (*dri_interface->destroyContext)(dpy, modes->screen,
-                                               pcp->contextID);
+    if ( !(*psp->DriverAPI.CreateContext)(&config->modes, pcp, shareCtx) ) {
         _mesa_free(pcp);
         return NULL;
     }
 
-    __driGarbageCollectDrawables(pcp->driScreenPriv->drawHash);
-
     return pcp;
 }
+
+static __DRIcontext *
+dri2CreateNewContext(__DRIscreen *screen, const __DRIconfig *config,
+                     __DRIcontext *shared, void *data)
+{
+    drm_context_t hwContext;
+    DRM_CAS_RESULT(ret);
+
+    /* DRI2 doesn't use kernel with context IDs, we just need an ID that's
+     * different from the kernel context ID to make drmLock() happy. */
+
+    do {
+       hwContext = screen->dri2.lock->next_id;
+       DRM_CAS(&screen->dri2.lock->next_id, hwContext, hwContext + 1, ret);
+    } while (ret);
+
+    return driCreateNewContext(screen, config, 0, shared, hwContext, data);
+}
+
+static int
+driCopyContext(__DRIcontext *dest, __DRIcontext *src, unsigned long mask)
+{
+    return GL_FALSE;
+}
+
 /*@}*/
 
 
@@ -889,10 +785,8 @@ driCreateNewContext(__DRInativeDisplay *dpy, const __GLcontextModes *modes,
  * This function calls __DriverAPIRec::DestroyScreen on \p screenPrivate, calls
  * drmClose(), and finally frees \p screenPrivate.
  */
-static void driDestroyScreen(__DRInativeDisplay *dpy, int scrn, void *screenPrivate)
+static void driDestroyScreen(__DRIscreen *psp)
 {
-    __DRIscreenPrivate *psp = (__DRIscreenPrivate *) screenPrivate;
-
     if (psp) {
        /* No interaction with the X-server is possible at this point.  This
         * routine is called after XCloseDisplay, so there is no protocol
@@ -902,26 +796,44 @@ static void driDestroyScreen(__DRInativeDisplay *dpy, int scrn, void *screenPriv
        if (psp->DriverAPI.DestroyScreen)
            (*psp->DriverAPI.DestroyScreen)(psp);
 
-       (void)drmUnmap((drmAddress)psp->pSAREA, SAREA_MAX);
-       (void)drmUnmap((drmAddress)psp->pFB, psp->fbSize);
-       _mesa_free(psp->pDevPriv);
-       (void)drmCloseOnce(psp->fd);
-       if ( psp->modes != NULL ) {
-           (*dri_interface->destroyContextModes)( psp->modes );
+       if (psp->dri2.enabled) {
+           drmBOUnmap(psp->fd, &psp->dri2.sareaBO);
+           drmBOUnreference(psp->fd, &psp->dri2.sareaBO);
+       } else {
+          (void)drmUnmap((drmAddress)psp->pSAREA, SAREA_MAX);
+          (void)drmUnmap((drmAddress)psp->pFB, psp->fbSize);
+          (void)drmCloseOnce(psp->fd);
        }
 
-       assert(psp->drawHash);
-       drmHashDestroy(psp->drawHash);
-
        _mesa_free(psp);
     }
 }
 
+static void
+setupLoaderExtensions(__DRIscreen *psp,
+                     const __DRIextension **extensions)
+{
+    int i;
+
+    for (i = 0; extensions[i]; i++) {
+       if (strcmp(extensions[i]->name, __DRI_GET_DRAWABLE_INFO) == 0)
+           psp->getDrawableInfo = (__DRIgetDrawableInfoExtension *) extensions[i];
+       if (strcmp(extensions[i]->name, __DRI_DAMAGE) == 0)
+           psp->damage = (__DRIdamageExtension *) extensions[i];
+       if (strcmp(extensions[i]->name, __DRI_SYSTEM_TIME) == 0)
+           psp->systemTime = (__DRIsystemTimeExtension *) extensions[i];
+       if (strcmp(extensions[i]->name, __DRI_LOADER) == 0)
+           psp->dri2.loader = (__DRIloaderExtension *) extensions[i];
+    }
+}
 
 /**
- * Utility function used to create a new driver-private screen structure.
+ * This is the bootstrap function for the driver.  libGL supplies all of the
+ * requisite information about the system, and the driver initializes itself.
+ * This routine also fills in the linked list pointed to by \c driver_modes
+ * with the \c __GLcontextModes that the driver can support for windows or
+ * pbuffers.
  * 
- * \param dpy   Display pointer
  * \param scrn  Index of the screen
  * \param psc   DRI screen data (not driver private)
  * \param modes Linked list of known display modes.  This list is, at a
@@ -942,44 +854,29 @@ static void driDestroyScreen(__DRInativeDisplay *dpy, int scrn, void *screenPriv
  *                              driver and libGL.
  * \param driverAPI Driver API functions used by other routines in dri_util.c.
  * 
- * \note
- * There is no need to check the minimum API version in this function.  Since
- * the \c __driCreateNewScreen function is versioned, it is impossible for a
- * loader that is too old to even load this driver.
+ * \note There is no need to check the minimum API version in this
+ * function.  Since the name of this function is versioned, it is
+ * impossible for a loader that is too old to even load this driver.
  */
-__DRIscreenPrivate *
-__driUtilCreateNewScreen(__DRInativeDisplay *dpy, int scrn, __DRIscreen *psc,
-                        __GLcontextModes * modes,
-                        const __DRIversion * ddx_version,
-                        const __DRIversion * dri_version,
-                        const __DRIversion * drm_version,
-                        const __DRIframebuffer * frame_buffer,
-                        drm_sarea_t *pSAREA,
-                        int fd,
-                        int internal_api_version,
-                        const struct __DriverAPIRec *driverAPI)
+static __DRIscreen *
+driCreateNewScreen(int scrn,
+                  const __DRIversion *ddx_version,
+                  const __DRIversion *dri_version,
+                  const __DRIversion *drm_version,
+                  const __DRIframebuffer *frame_buffer,
+                  drmAddress pSAREA, int fd, 
+                  const __DRIextension **extensions,
+                  const __DRIconfig ***driver_modes,
+                  void *loaderPrivate)
 {
-    __DRIscreenPrivate *psp;
-
-
-    api_ver = internal_api_version;
-
-    psp = (__DRIscreenPrivate *)_mesa_malloc(sizeof(__DRIscreenPrivate));
-    if (!psp) {
-       return NULL;
-    }
+    static const __DRIextension *emptyExtensionList[] = { NULL };
+    __DRIscreen *psp;
 
-    /* Create the hash table */
-    psp->drawHash = drmHashCreate();
-    if ( psp->drawHash == NULL ) {
-       _mesa_free( psp );
+    psp = _mesa_malloc(sizeof *psp);
+    if (!psp)
        return NULL;
-    }
 
-    psp->display = dpy;
-    psp->myNum = scrn;
-    psp->psc = psc;
-    psp->modes = modes;
+    setupLoaderExtensions(psp, extensions);
 
     /*
     ** NOT_DONE: This is used by the X server to detect when the client
@@ -988,20 +885,12 @@ __driUtilCreateNewScreen(__DRInativeDisplay *dpy, int scrn, __DRIscreen *psc,
     */
     psp->drawLockID = 1;
 
-    psp->drmMajor = drm_version->major;
-    psp->drmMinor = drm_version->minor;
-    psp->drmPatch = drm_version->patch;
-    psp->ddxMajor = ddx_version->major;
-    psp->ddxMinor = ddx_version->minor;
-    psp->ddxPatch = ddx_version->patch;
-    psp->driMajor = dri_version->major;
-    psp->driMinor = dri_version->minor;
-    psp->driPatch = dri_version->patch;
-
-    /* install driver's callback functions */
-    memcpy( &psp->DriverAPI, driverAPI, sizeof(struct __DriverAPIRec) );
+    psp->drm_version = *drm_version;
+    psp->ddx_version = *ddx_version;
+    psp->dri_version = *dri_version;
 
     psp->pSAREA = pSAREA;
+    psp->lock = (drmLock *) &psp->pSAREA->lock;
 
     psp->pFB = frame_buffer->base;
     psp->fbSize = frame_buffer->size;
@@ -1012,7 +901,10 @@ __driUtilCreateNewScreen(__DRInativeDisplay *dpy, int scrn, __DRIscreen *psc,
     psp->pDevPriv = frame_buffer->dev_priv;
     psp->fbBPP = psp->fbStride * 8 / frame_buffer->width;
 
+    psp->extensions = emptyExtensionList;
     psp->fd = fd;
+    psp->myNum = scrn;
+    psp->dri2.enabled = GL_FALSE;
 
     /*
     ** Do not init dummy context here; actual initialization will be
@@ -1021,63 +913,143 @@ __driUtilCreateNewScreen(__DRInativeDisplay *dpy, int scrn, __DRIscreen *psc,
     */
     psp->dummyContextPriv.driScreenPriv = NULL;
 
-    psc->destroyScreen     = driDestroyScreen;
-    psc->createNewDrawable = driCreateNewDrawable;
-    psc->getDrawable       = driGetDrawable;
-    psc->getMSC            = driGetMSC;
-    psc->createNewContext  = driCreateNewContext;
-
-    if (internal_api_version >= 20070121)
-       psc->setTexOffset  = psp->DriverAPI.setTexOffset;
+    psp->DriverAPI = driDriverAPI;
 
-    if ( (psp->DriverAPI.InitDriver != NULL)
-        && !(*psp->DriverAPI.InitDriver)(psp) ) {
-       _mesa_free( psp );
+    *driver_modes = driDriverAPI.InitScreen(psp);
+    if (*driver_modes == NULL) {
+       _mesa_free(psp);
        return NULL;
     }
 
-
     return psp;
 }
 
 
-/**
- * Compare the current GLX API version with a driver supplied required version.
- * 
- * The minimum required version is compared with the API version exported by
- * the \c __glXGetInternalVersion function (in libGL.so).
- * 
- * \param   required_version Minimum required internal GLX API version.
- * \return  A tri-value return, as from strcmp is returned.  A value less
- *          than, equal to, or greater than zero will be returned if the
- *          internal GLX API version is less than, equal to, or greater
- *          than \c required_version.
- *
- * \sa __glXGetInternalVersion().
- */
-int driCompareGLXAPIVersion( GLint required_version )
+static __DRIscreen *
+dri2CreateNewScreen(int scrn, int fd, unsigned int sarea_handle,
+                   const __DRIextension **extensions,
+                   const __DRIconfig ***driver_configs, void *data)
 {
-   if ( api_ver > required_version ) {
-      return 1;
-   }
-   else if ( api_ver == required_version ) {
-      return 0;
-   }
+    static const __DRIextension *emptyExtensionList[] = { NULL };
+    __DRIscreen *psp;
+    unsigned int *p;
+    drmVersionPtr version;
+
+    if (driDriverAPI.InitScreen2 == NULL)
+        return NULL;
+
+    psp = _mesa_malloc(sizeof(*psp));
+    if (!psp)
+       return NULL;
+
+    setupLoaderExtensions(psp, extensions);
+
+    version = drmGetVersion(fd);
+    if (version) {
+       psp->drm_version.major = version->version_major;
+       psp->drm_version.minor = version->version_minor;
+       psp->drm_version.patch = version->version_patchlevel;
+       drmFreeVersion(version);
+    }
+
+    psp->extensions = emptyExtensionList;
+    psp->fd = fd;
+    psp->myNum = scrn;
+    psp->dri2.enabled = GL_TRUE;
+
+    if (drmBOReference(psp->fd, sarea_handle, &psp->dri2.sareaBO)) {
+       fprintf(stderr, "Failed to reference DRI2 sarea BO\n");
+       _mesa_free(psp);
+       return NULL;
+    }
+
+    if (drmBOMap(psp->fd, &psp->dri2.sareaBO,
+                DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, 0, &psp->dri2.sarea)) {
+       drmBOUnreference(psp->fd, &psp->dri2.sareaBO);
+       _mesa_free(psp);
+       return NULL;
+    }
+
+    p = psp->dri2.sarea;
+    while (DRI2_SAREA_BLOCK_TYPE(*p)) {
+       switch (DRI2_SAREA_BLOCK_TYPE(*p)) {
+       case DRI2_SAREA_BLOCK_LOCK:
+           psp->dri2.lock = (__DRILock *) p;
+           break;
+       case DRI2_SAREA_BLOCK_EVENT_BUFFER:
+           psp->dri2.buffer = (__DRIEventBuffer *) p;
+           break;
+       }
+       p = DRI2_SAREA_BLOCK_NEXT(p);
+    }
+
+    psp->lock = (drmLock *) &psp->dri2.lock->lock;
 
-   return -1;
+    psp->DriverAPI = driDriverAPI;
+    *driver_configs = driDriverAPI.InitScreen2(psp);
+    if (*driver_configs == NULL) {
+       drmBOUnmap(psp->fd, &psp->dri2.sareaBO);
+       drmBOUnreference(psp->fd, &psp->dri2.sareaBO);
+       _mesa_free(psp);
+       return NULL;
+    }
+
+    psp->DriverAPI = driDriverAPI;
+
+    return psp;
 }
 
+static const __DRIextension **driGetExtensions(__DRIscreen *psp)
+{
+    return psp->extensions;
+}
+
+const __DRIlegacyExtension driLegacyExtension = {
+    { __DRI_LEGACY, __DRI_LEGACY_VERSION },
+    driCreateNewScreen,
+    driCreateNewDrawable,
+    driCreateNewContext
+};
+
+const __DRIcoreExtension driCoreExtension = {
+    { __DRI_CORE, __DRI_CORE_VERSION },
+    dri2CreateNewScreen,
+    driDestroyScreen,
+    driGetExtensions,
+    driGetConfigAttrib,
+    driIndexConfigAttrib,
+    dri2CreateNewDrawable,
+    driDestroyDrawable,
+    driSwapBuffers,
+    dri2CreateNewContext,
+    driCopyContext,
+    driDestroyContext,
+    driBindContext,
+    driUnbindContext
+};
+
+/* This is the table of extensions that the loader will dlsym() for. */
+PUBLIC const __DRIextension *__driDriverExtensions[] = {
+    &driCoreExtension.base,
+    &driLegacyExtension.base,
+    NULL
+};
+
+static int
+driFrameTracking(__DRIdrawable *drawable, GLboolean enable)
+{
+    return GLX_BAD_CONTEXT;
+}
 
 static int
-driQueryFrameTracking( __DRInativeDisplay * dpy, void * priv,
-                      int64_t * sbc, int64_t * missedFrames,
-                      float * lastMissedUsage, float * usage )
+driQueryFrameTracking(__DRIdrawable *dpriv,
+                     int64_t * sbc, int64_t * missedFrames,
+                     float * lastMissedUsage, float * usage)
 {
    __DRIswapInfo   sInfo;
    int             status;
    int64_t         ust;
-   __DRIdrawablePrivate * dpriv = (__DRIdrawablePrivate *) priv;
-
+   __DRIscreenPrivate *psp = dpriv->driScreenPriv;
 
    status = dpriv->driScreenPriv->DriverAPI.GetSwapInfo( dpriv, & sInfo );
    if ( status == 0 ) {
@@ -1085,13 +1057,18 @@ driQueryFrameTracking( __DRInativeDisplay * dpy, void * priv,
       *missedFrames = sInfo.swap_missed_count;
       *lastMissedUsage = sInfo.swap_missed_usage;
 
-      (*dri_interface->getUST)( & ust );
+      (*psp->systemTime->getUST)( & ust );
       *usage = driCalculateSwapUsage( dpriv, sInfo.swap_ust, ust );
    }
 
    return status;
 }
 
+const __DRIframeTrackingExtension driFrameTrackingExtension = {
+    { __DRI_FRAME_TRACKING, __DRI_FRAME_TRACKING_VERSION },
+    driFrameTracking,
+    driQueryFrameTracking    
+};
 
 /**
  * Calculate amount of swap interval used between GLX buffer swaps.
@@ -1129,11 +1106,10 @@ driCalculateSwapUsage( __DRIdrawablePrivate *dPriv, int64_t last_swap_ust,
    int32_t   d;
    int       interval;
    float     usage = 1.0;
+   __DRIscreenPrivate *psp = dPriv->driScreenPriv;
 
-
-   if ( (*dri_interface->getMSCRate)( dPriv->display, dPriv->draw, &n, &d ) ) {
-      interval = (dPriv->pdraw->swap_interval != 0)
-         ? dPriv->pdraw->swap_interval : 1;
+   if ( (*psp->systemTime->getMSCRate)(dPriv, &n, &d, dPriv->loaderPrivate) ) {
+      interval = (dPriv->swap_interval != 0) ? dPriv->swap_interval : 1;
 
 
       /* We want to calculate
index 027cb7f..f2bc456 100644 (file)
@@ -1,3 +1,24 @@
+/**
+ * \file dri_util.h
+ * DRI utility functions definitions.
+ *
+ * This module acts as glue between GLX and the actual hardware driver.  A DRI
+ * driver doesn't really \e have to use any of this - it's optional.  But, some
+ * useful stuff is done here that otherwise would have to be duplicated in most
+ * drivers.
+ * 
+ * Basically, these utility functions take care of some of the dirty details of
+ * screen initialization, context creation, context binding, DRM setup, etc.
+ *
+ * These functions are compiled into each DRI driver so libGL.so knows nothing
+ * about them.
+ *
+ * \sa dri_util.c.
+ * 
+ * \author Kevin E. Martin <kevin@precisioninsight.com>
+ * \author Brian Paul <brian@precisioninsight.com>
+ */
+
 /*
  * Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
  * All Rights Reserved.
  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  */
 
-/**
- * \file dri_util.h
- * DRI utility functions definitions.
- *
- * This module acts as glue between GLX and the actual hardware driver.  A DRI
- * driver doesn't really \e have to use any of this - it's optional.  But, some
- * useful stuff is done here that otherwise would have to be duplicated in most
- * drivers.
- * 
- * Basically, these utility functions take care of some of the dirty details of
- * screen initialization, context creation, context binding, DRM setup, etc.
- *
- * These functions are compiled into each DRI driver so libGL.so knows nothing
- * about them.
- *
- * \sa dri_util.c.
- * 
- * \author Kevin E. Martin <kevin@precisioninsight.com>
- * \author Brian Paul <brian@precisioninsight.com>
- */
 
 #ifndef _DRI_UTIL_H_
 #define _DRI_UTIL_H_
 
 #include <GL/gl.h>
-#include "drm.h"
-#include "drm_sarea.h"
-#include "xf86drm.h"
+#include <drm.h>
+#include <drm_sarea.h>
+#include <xf86drm.h>
 #include "GL/internal/glcore.h"
 #include "GL/internal/dri_interface.h"
+#include "GL/internal/dri_sarea.h"
 
 #define GLX_BAD_CONTEXT                    5
 
-typedef struct __DRIdisplayPrivateRec  __DRIdisplayPrivate;
-typedef struct __DRIscreenPrivateRec   __DRIscreenPrivate;
-typedef struct __DRIcontextPrivateRec  __DRIcontextPrivate;
-typedef struct __DRIdrawablePrivateRec __DRIdrawablePrivate;
 typedef struct __DRIswapInfoRec        __DRIswapInfo;
-typedef struct __DRIutilversionRec2    __DRIutilversion2;
 
+/* Typedefs to avoid rewriting the world. */
+typedef struct __DRIscreenRec  __DRIscreenPrivate;
+typedef struct __DRIdrawableRec        __DRIdrawablePrivate;
+typedef struct __DRIcontextRec __DRIcontextPrivate;
+
+/**
+ * Extensions.
+ */
+extern const __DRIlegacyExtension driLegacyExtension;
+extern const __DRIcoreExtension driCoreExtension;
+extern const __DRIextension driReadDrawableExtension;
+extern const __DRIcopySubBufferExtension driCopySubBufferExtension;
+extern const __DRIswapControlExtension driSwapControlExtension;
+extern const __DRIframeTrackingExtension driFrameTrackingExtension;
+extern const __DRImediaStreamCounterExtension driMediaStreamCounterExtension;
 
 /**
  * Used by DRI_VALIDATE_DRAWABLE_INFO
@@ -78,7 +90,7 @@ typedef struct __DRIutilversionRec2    __DRIutilversion2;
 /**
  * Utility macro to validate the drawable information.
  *
- * See __DRIdrawablePrivate::pStamp and __DRIdrawablePrivate::lastStamp.
+ * See __DRIdrawable::pStamp and __DRIdrawable::lastStamp.
  */
 #define DRI_VALIDATE_DRAWABLE_INFO(psp, pdp)                            \
 do {                                                                    \
@@ -107,94 +119,103 @@ do {                                                                    \
  * this structure.
  */
 struct __DriverAPIRec {
-    /** 
-     * Driver initialization callback
-     */
-    GLboolean (*InitDriver)(__DRIscreenPrivate *driScrnPriv);
-    
+    const __DRIconfig **(*InitScreen) (__DRIscreen * priv);
+
     /**
      * Screen destruction callback
      */
-    void (*DestroyScreen)(__DRIscreenPrivate *driScrnPriv);
+    void (*DestroyScreen)(__DRIscreen *driScrnPriv);
 
     /**
      * Context creation callback
      */                    
     GLboolean (*CreateContext)(const __GLcontextModes *glVis,
-                               __DRIcontextPrivate *driContextPriv,
+                               __DRIcontext *driContextPriv,
                                void *sharedContextPrivate);
 
     /**
      * Context destruction callback
      */
-    void (*DestroyContext)(__DRIcontextPrivate *driContextPriv);
+    void (*DestroyContext)(__DRIcontext *driContextPriv);
 
     /**
      * Buffer (drawable) creation callback
      */
-    GLboolean (*CreateBuffer)(__DRIscreenPrivate *driScrnPriv,
-                              __DRIdrawablePrivate *driDrawPriv,
+    GLboolean (*CreateBuffer)(__DRIscreen *driScrnPriv,
+                              __DRIdrawable *driDrawPriv,
                               const __GLcontextModes *glVis,
                               GLboolean pixmapBuffer);
     
     /**
      * Buffer (drawable) destruction callback
      */
-    void (*DestroyBuffer)(__DRIdrawablePrivate *driDrawPriv);
+    void (*DestroyBuffer)(__DRIdrawable *driDrawPriv);
 
     /**
      * Buffer swapping callback 
      */
-    void (*SwapBuffers)(__DRIdrawablePrivate *driDrawPriv);
+    void (*SwapBuffers)(__DRIdrawable *driDrawPriv);
 
     /**
      * Context activation callback
      */
-    GLboolean (*MakeCurrent)(__DRIcontextPrivate *driContextPriv,
-                             __DRIdrawablePrivate *driDrawPriv,
-                             __DRIdrawablePrivate *driReadPriv);
+    GLboolean (*MakeCurrent)(__DRIcontext *driContextPriv,
+                             __DRIdrawable *driDrawPriv,
+                             __DRIdrawable *driReadPriv);
 
     /**
      * Context unbinding callback
      */
-    GLboolean (*UnbindContext)(__DRIcontextPrivate *driContextPriv);
+    GLboolean (*UnbindContext)(__DRIcontext *driContextPriv);
   
     /**
      * Retrieves statistics about buffer swap operations.  Required if
      * GLX_OML_sync_control or GLX_MESA_swap_frame_usage is supported.
      */
-    int (*GetSwapInfo)( __DRIdrawablePrivate *dPriv, __DRIswapInfo * sInfo );
-
+    int (*GetSwapInfo)( __DRIdrawable *dPriv, __DRIswapInfo * sInfo );
 
-    /**
-     * Required if GLX_SGI_video_sync or GLX_OML_sync_control is
-     * supported.
-     */
-    int (*GetMSC)( __DRIscreenPrivate * priv, int64_t * count );
 
     /**
      * These are required if GLX_OML_sync_control is supported.
      */
     /*@{*/
-    int (*WaitForMSC)( __DRIdrawablePrivate *priv, int64_t target_msc, 
+    int (*WaitForMSC)( __DRIdrawable *priv, int64_t target_msc, 
                       int64_t divisor, int64_t remainder,
                       int64_t * msc );
-    int (*WaitForSBC)( __DRIdrawablePrivate *priv, int64_t target_sbc,
+    int (*WaitForSBC)( __DRIdrawable *priv, int64_t target_sbc,
                       int64_t * msc, int64_t * sbc );
 
-    int64_t (*SwapBuffersMSC)( __DRIdrawablePrivate *priv, int64_t target_msc,
+    int64_t (*SwapBuffersMSC)( __DRIdrawable *priv, int64_t target_msc,
                               int64_t divisor, int64_t remainder );
     /*@}*/
-    void (*CopySubBuffer)(__DRIdrawablePrivate *driDrawPriv,
+    void (*CopySubBuffer)(__DRIdrawable *driDrawPriv,
                          int x, int y, int w, int h);
 
     /**
-     * See corresponding field in \c __DRIscreenRec.
+     * New version of GetMSC so we can pass drawable data to the low
+     * level DRM driver (e.g. pipe info).  Required if
+     * GLX_SGI_video_sync or GLX_OML_sync_control is supported.
      */
-    void (*setTexOffset)(__DRIcontext *pDRICtx, GLint texname,
-                        unsigned long long offset, GLint depth, GLuint pitch);
+    int (*GetDrawableMSC) ( __DRIscreen * priv,
+                           __DRIdrawable *drawablePrivate,
+                           int64_t *count);
+
+
+
+    /* DRI2 Entry points */
+    const __DRIconfig **(*InitScreen2) (__DRIscreen * priv);
+    void (*HandleDrawableConfig)(__DRIdrawable *dPriv,
+                               __DRIcontext *pcp,
+                               __DRIDrawableConfigEvent *event);
+
+    void (*HandleBufferAttach)(__DRIdrawable *dPriv,
+                              __DRIcontext *pcp,
+                              __DRIBufferAttachEvent *ba);
+
 };
 
+extern const struct __DriverAPIRec driDriverAPI;
+
 
 struct __DRIswapInfoRec {
     /** 
@@ -230,7 +251,7 @@ struct __DRIswapInfoRec {
 /**
  * Per-drawable private DRI driver information.
  */
-struct __DRIdrawablePrivateRec {
+struct __DRIdrawableRec {
     /**
      * Kernel drawable handle
      */
@@ -244,10 +265,10 @@ struct __DRIdrawablePrivateRec {
     void *driverPrivate;
 
     /**
-     * X's drawable ID associated with this private drawable.
+     * Private data from the loader.  We just hold on to it and pass
+     * it back when calling into loader provided functions.
      */
-    __DRIid draw;
-    __DRIdrawable *pdraw;
+    void *loaderPrivate;
 
     /**
      * Reference count for number of context's currently bound to this
@@ -272,7 +293,7 @@ struct __DRIdrawablePrivateRec {
     /**
      * Last value of the stamp.
      *
-     * If this differs from the value stored at __DRIdrawablePrivate::pStamp,
+     * If this differs from the value stored at __DRIdrawable::pStamp,
      * then the drawable information has been modified by the X server, and the
      * drawable information (below) should be retrieved from the X server.
      */
@@ -306,41 +327,56 @@ struct __DRIdrawablePrivateRec {
     /*@}*/
 
     /**
-     * Pointer to context to which this drawable is currently bound.
+     * \name Vertical blank tracking information
+     * Used for waiting on vertical blank events.
      */
-    __DRIcontextPrivate *driContextPriv;
+    /*@{*/
+    unsigned int vblSeq;
+    unsigned int vblFlags;
+    /*@}*/
 
     /**
-     * Pointer to screen on which this drawable was created.
+     * \name Monotonic MSC tracking
+     *
+     * Low level driver is responsible for updating msc_base and
+     * vblSeq values so that higher level code can calculate
+     * a new msc value or msc target for a WaitMSC call.  The new value
+     * will be:
+     *   msc = msc_base + get_vblank_count() - vblank_base;
+     *
+     * And for waiting on a value, core code will use:
+     *   actual_target = target_msc - msc_base + vblank_base;
+     */
+    /*@{*/
+    int64_t vblank_base;
+    int64_t msc_base;
+    /*@}*/
+
+    /**
+     * Pointer to context to which this drawable is currently bound.
      */
-    __DRIscreenPrivate *driScreenPriv;
+    __DRIcontext *driContextPriv;
 
     /**
-     * \name Display and screen information.
-     * 
-     * Basically just need these for when the locking code needs to call
-     * \c __driUtilUpdateDrawableInfo.
+     * Pointer to screen on which this drawable was created.
      */
-    /*@{*/
-    __DRInativeDisplay *display;
-    int screen;
-    /*@}*/
+    __DRIscreen *driScreenPriv;
 
     /**
-     * Called via glXSwapBuffers().
+     * Controls swap interval as used by GLX_SGI_swap_control and
+     * GLX_MESA_swap_control.
      */
-    void (*swapBuffers)( __DRIdrawablePrivate *dPriv );
+    unsigned int swap_interval;
+    struct {
+       unsigned int tail;
+       unsigned int drawable_id;
+    } dri2;
 };
 
 /**
  * Per-context private driver information.
  */
-struct __DRIcontextPrivateRec {
-    /**
-     * Kernel context handle used to access the device lock.
-     */
-    __DRIid contextID;
-
+struct __DRIcontextRec {
     /**
      * Kernel context handle used to access the device lock.
      */
@@ -352,35 +388,30 @@ struct __DRIcontextPrivateRec {
     void *driverPrivate;
 
     /**
-     * This context's display pointer.
+     * Pointer back to the \c __DRIcontext that contains this structure.
      */
-    __DRInativeDisplay *display;
+    __DRIcontext *pctx;
 
     /**
      * Pointer to drawable currently bound to this context for drawing.
      */
-    __DRIdrawablePrivate *driDrawablePriv;
+    __DRIdrawable *driDrawablePriv;
 
     /**
      * Pointer to drawable currently bound to this context for reading.
      */
-    __DRIdrawablePrivate *driReadablePriv;
+    __DRIdrawable *driReadablePriv;
 
     /**
      * Pointer to screen on which this context was created.
      */
-    __DRIscreenPrivate *driScreenPriv;
+    __DRIscreen *driScreenPriv;
 };
 
 /**
  * Per-screen private driver information.
  */
-struct __DRIscreenPrivateRec {
-    /**
-     * Display for this screen
-     */
-    __DRInativeDisplay *display;
-
+struct __DRIscreenRec {
     /**
      * Current screen's number
      */
@@ -391,38 +422,21 @@ struct __DRIscreenPrivateRec {
      */
     struct __DriverAPIRec DriverAPI;
 
+    const __DRIextension **extensions;
     /**
-     * \name DDX version
      * DDX / 2D driver version information.
-     * \todo Replace these fields with a \c __DRIversionRec.
      */
-    /*@{*/
-    int ddxMajor;
-    int ddxMinor;
-    int ddxPatch;
-    /*@}*/
+    __DRIversion ddx_version;
 
     /**
-     * \name DRI version
      * DRI X extension version information.
-     * \todo Replace these fields with a \c __DRIversionRec.
      */
-    /*@{*/
-    int driMajor;
-    int driMinor;
-    int driPatch;
-    /*@}*/
+    __DRIversion dri_version;
 
     /**
-     * \name DRM version
      * DRM (kernel module) version information.
-     * \todo Replace these fields with a \c __DRIversionRec.
      */
-    /*@{*/
-    int drmMajor;
-    int drmMinor;
-    int drmPatch;
-    /*@}*/
+    __DRIversion drm_version;
 
     /**
      * ID used when the client sets the drawable lock.
@@ -485,12 +499,7 @@ struct __DRIscreenPrivateRec {
      * context is created when the first "real" context is created on this
      * screen.
      */
-    __DRIcontextPrivate dummyContextPriv;
-
-    /**
-     * Hash table to hold the drawable information for this screen.
-     */
-    void *drawHash;
+    __DRIcontext dummyContextPriv;
 
     /**
      * Device-dependent private information (not stored in the SAREA).
@@ -500,65 +509,45 @@ struct __DRIscreenPrivateRec {
     void *private;
 
     /**
-     * GLX visuals / FBConfigs for this screen.  These are stored as a
-     * linked list.
-     * 
-     * \note
-     * This field is \b only used in conjunction with the old interfaces.  If
-     * the new interfaces are used, this field will be set to \c NULL and will
-     * not be dereferenced.
-     */
-    __GLcontextModes *modes;
-
-    /**
      * Pointer back to the \c __DRIscreen that contains this structure.
      */
-
     __DRIscreen *psc;
-};
 
-
-/**
- * Used to store a version which includes a major range instead of a single
- * major version number.
- */
-struct __DRIutilversionRec2 {
-    int    major_min;    /** min allowed Major version number. */
-    int    major_max;    /** max allowed Major version number. */
-    int    minor;        /**< Minor version number. */
-    int    patch;        /**< Patch-level. */
+    /* Extensions provided by the loader. */
+    const __DRIgetDrawableInfoExtension *getDrawableInfo;
+    const __DRIsystemTimeExtension *systemTime;
+    const __DRIdamageExtension *damage;
+
+    struct {
+       /* Flag to indicate that this is a DRI2 screen.  Many of the above
+        * fields will not be valid or initializaed in that case. */
+       int enabled;
+       drmBO sareaBO;
+       void *sarea;
+       __DRIEventBuffer *buffer;
+       __DRILock *lock;
+       __DRIloaderExtension *loader;
+    } dri2;
+
+    /* The lock actually in use, old sarea or DRI2 */
+    drmLock *lock;
 };
 
-
 extern void
 __driUtilMessage(const char *f, ...);
 
 
 extern void
-__driUtilUpdateDrawableInfo(__DRIdrawablePrivate *pdp);
-
-
-extern __DRIscreenPrivate * __driUtilCreateNewScreen( __DRInativeDisplay *dpy,
-    int scrn, __DRIscreen *psc, __GLcontextModes * modes,
-    const __DRIversion * ddx_version, const __DRIversion * dri_version,
-    const __DRIversion * drm_version, const __DRIframebuffer * frame_buffer,
-    drm_sarea_t *pSAREA, int fd, int internal_api_version,
-    const struct __DriverAPIRec *driverAPI );
+__driUtilUpdateDrawableInfo(__DRIdrawable *pdp);
 
-/* Test the version of the internal GLX API.  Returns a value like strcmp. */
 extern int
-driCompareGLXAPIVersion( GLint required_version );
+__driParseEvents(__DRIcontext *psp, __DRIdrawable *pdp);
 
 extern float
-driCalculateSwapUsage( __DRIdrawablePrivate *dPriv,
+driCalculateSwapUsage( __DRIdrawable *dPriv,
                       int64_t last_swap_ust, int64_t current_ust );
 
-/**
- * Pointer to the \c __DRIinterfaceMethods passed to the driver by the loader.
- * 
- * This pointer is set in the driver's \c __driCreateNewScreen function and
- * is defined in dri_util.c.
- */
-extern const __DRIinterfaceMethods * dri_interface;
+extern GLint
+driIntersectArea( drm_clip_rect_t rect1, drm_clip_rect_t rect2 );
 
 #endif /* _DRI_UTIL_H_ */
index d34da53..d36af3e 100644 (file)
@@ -209,8 +209,6 @@ driUpdateFramebufferSize(GLcontext *ctx, const __DRIdrawablePrivate *dPriv)
    struct gl_framebuffer *fb = (struct gl_framebuffer *) dPriv->driverPrivate;
    if (fb && (dPriv->w != fb->Width || dPriv->h != fb->Height)) {
       ctx->Driver.ResizeBuffers(ctx, fb, dPriv->w, dPriv->h);
-      /* if the driver needs the hw lock for ResizeBuffers, the drawable
-         might have changed again by now */
       assert(fb->Width == dPriv->w);
       assert(fb->Height == dPriv->h);
    }
index 50f3cf5..53f5f84 100644 (file)
     do {                                                                \
         GLuint p = *(volatile GLuint *) GET_PTR(_x, _y);                \
        __asm__ __volatile__( "bswap    %0; rorl $8, %0"                \
-                               : "=r" (p) : "r" (p) );                 \
+                               : "=r" (p) : "0" (p) );                 \
        ((GLuint *)rgba)[0] = p;                                         \
     } while (0)
 # elif defined( MESA_BIG_ENDIAN )
index 6a189e7..7fbe0d8 100644 (file)
@@ -419,21 +419,6 @@ driCheckDriDdxDrmVersions2(const char * driver_name,
                                drmActual, drmExpected);
 }
 
-
-
-GLint
-driIntersectArea( drm_clip_rect_t rect1, drm_clip_rect_t rect2 )
-{
-   if (rect2.x1 > rect1.x1) rect1.x1 = rect2.x1;
-   if (rect2.x2 < rect1.x2) rect1.x2 = rect2.x2;
-   if (rect2.y1 > rect1.y1) rect1.y1 = rect2.y1;
-   if (rect2.y2 < rect1.y2) rect1.y2 = rect2.y2;
-
-   if (rect1.x1 > rect1.x2 || rect1.y1 > rect1.y2) return 0;
-
-   return (rect1.x2 - rect1.x1) * (rect1.y2 - rect1.y1);
-}
-
 GLboolean driClipRectToFramebuffer( const GLframebuffer *buffer,
                                    GLint *x, GLint *y,
                                    GLsizei *width, GLsizei *height )
@@ -467,8 +452,6 @@ GLboolean driClipRectToFramebuffer( const GLframebuffer *buffer,
    return GL_TRUE;
 }
 
-
-
 /**
  * Creates a set of \c __GLcontextModes that a driver will expose.
  * 
@@ -536,86 +519,99 @@ GLboolean driClipRectToFramebuffer( const GLframebuffer *buffer,
  * \c GL_UNSIGNED_3BYTE_8_8_8, \c GL_4FLOAT_32_32_32_32, 
  * \c GL_4HALF_16_16_16_16, etc.  We can cross that bridge when we come to it.
  */
-GLboolean
-driFillInModes( __GLcontextModes ** ptr_to_modes,
-               GLenum fb_format, GLenum fb_type,
-               const u_int8_t * depth_bits, const u_int8_t * stencil_bits,
-               unsigned num_depth_stencil_bits,
-               const GLenum * db_modes, unsigned num_db_modes,
-               int visType )
+__DRIconfig **
+driCreateConfigs(GLenum fb_format, GLenum fb_type,
+                const u_int8_t * depth_bits, const u_int8_t * stencil_bits,
+                unsigned num_depth_stencil_bits,
+                const GLenum * db_modes, unsigned num_db_modes)
 {
-   static const u_int8_t bits_table[3][4] = {
+   static const u_int8_t bits_table[4][4] = {
      /* R  G  B  A */
+      { 3, 3, 2, 0 }, /* Any GL_UNSIGNED_BYTE_3_3_2 */
       { 5, 6, 5, 0 }, /* Any GL_UNSIGNED_SHORT_5_6_5 */
       { 8, 8, 8, 0 }, /* Any RGB with any GL_UNSIGNED_INT_8_8_8_8 */
       { 8, 8, 8, 8 }  /* Any RGBA with any GL_UNSIGNED_INT_8_8_8_8 */
    };
 
-   /* The following arrays are all indexed by the fb_type masked with 0x07.
-    * Given the four supported fb_type values, this results in valid array
-    * indices of 3, 4, 5, and 7.
-    */
-   static const u_int32_t masks_table_rgb[8][4] = {
-      { 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
-      { 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
-      { 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+   static const u_int32_t masks_table_rgb[6][4] = {
+      { 0x000000E0, 0x0000001C, 0x00000003, 0x00000000 }, /* 3_3_2       */
+      { 0x00000007, 0x00000038, 0x000000C0, 0x00000000 }, /* 2_3_3_REV   */
       { 0x0000F800, 0x000007E0, 0x0000001F, 0x00000000 }, /* 5_6_5       */
       { 0x0000001F, 0x000007E0, 0x0000F800, 0x00000000 }, /* 5_6_5_REV   */
       { 0xFF000000, 0x00FF0000, 0x0000FF00, 0x00000000 }, /* 8_8_8_8     */
-      { 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
       { 0x000000FF, 0x0000FF00, 0x00FF0000, 0x00000000 }  /* 8_8_8_8_REV */
    };
 
-   static const u_int32_t masks_table_rgba[8][4] = {
-      { 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
-      { 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
-      { 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+   static const u_int32_t masks_table_rgba[6][4] = {
+      { 0x000000E0, 0x0000001C, 0x00000003, 0x00000000 }, /* 3_3_2       */
+      { 0x00000007, 0x00000038, 0x000000C0, 0x00000000 }, /* 2_3_3_REV   */
       { 0x0000F800, 0x000007E0, 0x0000001F, 0x00000000 }, /* 5_6_5       */
       { 0x0000001F, 0x000007E0, 0x0000F800, 0x00000000 }, /* 5_6_5_REV   */
       { 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF }, /* 8_8_8_8     */
-      { 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
       { 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000 }, /* 8_8_8_8_REV */
    };
 
-   static const u_int32_t masks_table_bgr[8][4] = {
-      { 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
-      { 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
-      { 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+   static const u_int32_t masks_table_bgr[6][4] = {
+      { 0x00000007, 0x00000038, 0x000000C0, 0x00000000 }, /* 3_3_2       */
+      { 0x000000E0, 0x0000001C, 0x00000003, 0x00000000 }, /* 2_3_3_REV   */
       { 0x0000001F, 0x000007E0, 0x0000F800, 0x00000000 }, /* 5_6_5       */
       { 0x0000F800, 0x000007E0, 0x0000001F, 0x00000000 }, /* 5_6_5_REV   */
       { 0x0000FF00, 0x00FF0000, 0xFF000000, 0x00000000 }, /* 8_8_8_8     */
-      { 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
       { 0x00FF0000, 0x0000FF00, 0x000000FF, 0x00000000 }, /* 8_8_8_8_REV */
    };
 
-   static const u_int32_t masks_table_bgra[8][4] = {
-      { 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
-      { 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
-      { 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+   static const u_int32_t masks_table_bgra[6][4] = {
+      { 0x00000007, 0x00000038, 0x000000C0, 0x00000000 }, /* 3_3_2       */
+      { 0x000000E0, 0x0000001C, 0x00000003, 0x00000000 }, /* 2_3_3_REV   */
       { 0x0000001F, 0x000007E0, 0x0000F800, 0x00000000 }, /* 5_6_5       */
       { 0x0000F800, 0x000007E0, 0x0000001F, 0x00000000 }, /* 5_6_5_REV   */
       { 0x0000FF00, 0x00FF0000, 0xFF000000, 0x000000FF }, /* 8_8_8_8     */
-      { 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
       { 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000 }, /* 8_8_8_8_REV */
    };
 
-   static const u_int8_t bytes_per_pixel[8] = {
-      0, 0, 0, 2, 2, 4, 0, 4
+   static const u_int8_t bytes_per_pixel[6] = {
+      1, /* 3_3_2       */
+      1, /* 2_3_3_REV   */
+      2, /* 5_6_5       */
+      2, /* 5_6_5_REV   */
+      4, /* 8_8_8_8     */
+      4  /* 8_8_8_8_REV */
    };
 
    const u_int8_t  * bits;
    const u_int32_t * masks;
-   const int index = fb_type & 0x07;
-   __GLcontextModes * modes = *ptr_to_modes;
+   int index;
+   __DRIconfig **configs, **c;
+   __GLcontextModes *modes;
    unsigned i;
    unsigned j;
    unsigned k;
-
-
-   if ( bytes_per_pixel[ index ] == 0 ) {
-      fprintf( stderr, "[%s:%u] Framebuffer type 0x%04x has 0 bytes per pixel.\n",
-              __FUNCTION__, __LINE__, fb_type );
-      return GL_FALSE;
+   unsigned num_modes;
+   unsigned num_accum_bits = 2;
+
+   switch ( fb_type ) {
+      case GL_UNSIGNED_BYTE_3_3_2:
+        index = 0;
+        break;
+      case GL_UNSIGNED_BYTE_2_3_3_REV:
+        index = 1;
+        break;
+      case GL_UNSIGNED_SHORT_5_6_5:
+        index = 2;
+        break;
+      case GL_UNSIGNED_SHORT_5_6_5_REV:
+        index = 3;
+        break;
+      case GL_UNSIGNED_INT_8_8_8_8:
+        index = 4;
+        break;
+      case GL_UNSIGNED_INT_8_8_8_8_REV:
+        index = 5;
+        break;
+      default:
+        fprintf( stderr, "[%s:%u] Unknown framebuffer type 0x%04x.\n",
+               __FUNCTION__, __LINE__, fb_type );
+        return NULL;
    }
 
 
@@ -627,40 +623,55 @@ driFillInModes( __GLcontextModes ** ptr_to_modes,
 
    switch ( fb_format ) {
       case GL_RGB:
-         bits = (bytes_per_pixel[ index ] == 2)
-            ? bits_table[0] : bits_table[1];
          masks = masks_table_rgb[ index ];
          break;
 
       case GL_RGBA:
-         bits = (bytes_per_pixel[ index ] == 2)
-            ? bits_table[0] : bits_table[2];
          masks = masks_table_rgba[ index ];
          break;
 
       case GL_BGR:
-         bits = (bytes_per_pixel[ index ] == 2)
-            ? bits_table[0] : bits_table[1];
          masks = masks_table_bgr[ index ];
          break;
 
       case GL_BGRA:
-         bits = (bytes_per_pixel[ index ] == 2)
-            ? bits_table[0] : bits_table[2];
          masks = masks_table_bgra[ index ];
          break;
 
       default:
-         fprintf( stderr, "[%s:%u] Framebuffer format 0x%04x is not GL_RGB, GL_RGBA, GL_BGR, or GL_BGRA.\n",
-              __FUNCTION__, __LINE__, fb_format );
-         return GL_FALSE;
+         fprintf( stderr, "[%s:%u] Unknown framebuffer format 0x%04x.\n",
+               __FUNCTION__, __LINE__, fb_format );
+         return NULL;
+   }
+
+   switch ( bytes_per_pixel[ index ] ) {
+      case 1:
+        bits = bits_table[0];
+        break;
+      case 2:
+        bits = bits_table[1];
+        break;
+      default:
+        bits = ((fb_format == GL_RGB) || (fb_format == GL_BGR))
+           ? bits_table[2]
+           : bits_table[3];
+        break;
    }
 
+   num_modes = num_depth_stencil_bits * num_db_modes * num_accum_bits;
+   configs = _mesa_calloc((num_modes + 1) * sizeof *configs);
+   if (configs == NULL)
+       return NULL;
 
+    c = configs;
     for ( k = 0 ; k < num_depth_stencil_bits ; k++ ) {
        for ( i = 0 ; i < num_db_modes ; i++ ) {
-           for ( j = 0 ; j < 2 ; j++ ) {
+           for ( j = 0 ; j < num_accum_bits ; j++ ) {
+               *c = _mesa_malloc (sizeof **c);
+               modes = &(*c)->modes;
+               c++;
 
+               memset(modes, 0, sizeof *modes);
                modes->redBits   = bits[0];
                modes->greenBits = bits[1];
                modes->blueBits  = bits[2];
@@ -681,7 +692,13 @@ driFillInModes( __GLcontextModes ** ptr_to_modes,
                modes->stencilBits = stencil_bits[k];
                modes->depthBits = depth_bits[k];
 
-               modes->visualType = visType;
+               modes->transparentPixel = GLX_NONE;
+               modes->transparentRed = GLX_DONT_CARE;
+               modes->transparentGreen = GLX_DONT_CARE;
+               modes->transparentBlue = GLX_DONT_CARE;
+               modes->transparentAlpha = GLX_DONT_CARE;
+               modes->transparentIndex = GLX_DONT_CARE;
+               modes->visualType = GLX_DONT_CARE;
                modes->renderType = GLX_RGBA_BIT;
                modes->drawableType = GLX_WINDOW_BIT;
                modes->rgbMode = GL_TRUE;
@@ -701,11 +718,155 @@ driFillInModes( __GLcontextModes ** ptr_to_modes,
                modes->haveDepthBuffer = (modes->depthBits > 0);
                modes->haveStencilBuffer = (modes->stencilBits > 0);
 
-               modes = modes->next;
+               modes->bindToTextureRgb = GL_TRUE;
+               modes->bindToTextureRgba = GL_TRUE;
+               modes->bindToMipmapTexture = GL_FALSE;
+               modes->bindToTextureTargets = modes->rgbMode ?
+                   __DRI_ATTRIB_TEXTURE_1D_BIT |
+                   __DRI_ATTRIB_TEXTURE_2D_BIT |
+                   __DRI_ATTRIB_TEXTURE_RECTANGLE_BIT :
+                   0;
            }
        }
     }
+    *c = NULL;
+
+    return configs;
+}
+
+const __DRIconfig **driConcatConfigs(__DRIconfig **a, __DRIconfig **b)
+{
+    const __DRIconfig **all;
+    int i, j, index;
+
+    i = 0;
+    while (a[i] != NULL)
+       i++;
+    j = 0;
+    while (b[j] != NULL)
+       j++;
+   
+    all = _mesa_malloc((i + j + 1) * sizeof *all);
+    index = 0;
+    for (i = 0; a[i] != NULL; i++)
+       all[index++] = a[i];
+    for (j = 0; b[j] != NULL; j++)
+       all[index++] = b[j];
+    all[index++] = NULL;
+
+    _mesa_free(a);
+    _mesa_free(b);
+
+    return all;
+}
+
+#define __ATTRIB(attrib, field) \
+    { attrib, offsetof(__GLcontextModes, field) }
+
+static const struct { unsigned int attrib, offset; } attribMap[] = {
+    __ATTRIB(__DRI_ATTRIB_BUFFER_SIZE,                 rgbBits),
+    __ATTRIB(__DRI_ATTRIB_LEVEL,                       level),
+    __ATTRIB(__DRI_ATTRIB_RED_SIZE,                    redBits),
+    __ATTRIB(__DRI_ATTRIB_GREEN_SIZE,                  greenBits),
+    __ATTRIB(__DRI_ATTRIB_BLUE_SIZE,                   blueBits),
+    __ATTRIB(__DRI_ATTRIB_ALPHA_SIZE,                  alphaBits),
+    __ATTRIB(__DRI_ATTRIB_DEPTH_SIZE,                  depthBits),
+    __ATTRIB(__DRI_ATTRIB_STENCIL_SIZE,                        stencilBits),
+    __ATTRIB(__DRI_ATTRIB_ACCUM_RED_SIZE,              accumRedBits),
+    __ATTRIB(__DRI_ATTRIB_ACCUM_GREEN_SIZE,            accumGreenBits),
+    __ATTRIB(__DRI_ATTRIB_ACCUM_BLUE_SIZE,             accumBlueBits),
+    __ATTRIB(__DRI_ATTRIB_ACCUM_ALPHA_SIZE,            accumAlphaBits),
+    __ATTRIB(__DRI_ATTRIB_SAMPLE_BUFFERS,              sampleBuffers),
+    __ATTRIB(__DRI_ATTRIB_SAMPLES,                     samples),
+    __ATTRIB(__DRI_ATTRIB_DOUBLE_BUFFER,               doubleBufferMode),
+    __ATTRIB(__DRI_ATTRIB_STEREO,                      stereoMode),
+    __ATTRIB(__DRI_ATTRIB_AUX_BUFFERS,                 numAuxBuffers),
+    __ATTRIB(__DRI_ATTRIB_TRANSPARENT_TYPE,            transparentPixel),
+    __ATTRIB(__DRI_ATTRIB_TRANSPARENT_INDEX_VALUE,     transparentPixel),
+    __ATTRIB(__DRI_ATTRIB_TRANSPARENT_RED_VALUE,       transparentRed),
+    __ATTRIB(__DRI_ATTRIB_TRANSPARENT_GREEN_VALUE,     transparentGreen),
+    __ATTRIB(__DRI_ATTRIB_TRANSPARENT_BLUE_VALUE,      transparentBlue),
+    __ATTRIB(__DRI_ATTRIB_TRANSPARENT_ALPHA_VALUE,     transparentAlpha),
+    __ATTRIB(__DRI_ATTRIB_FLOAT_MODE,                  floatMode),
+    __ATTRIB(__DRI_ATTRIB_RED_MASK,                    redMask),
+    __ATTRIB(__DRI_ATTRIB_GREEN_MASK,                  greenMask),
+    __ATTRIB(__DRI_ATTRIB_BLUE_MASK,                   blueMask),
+    __ATTRIB(__DRI_ATTRIB_ALPHA_MASK,                  alphaMask),
+    __ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_WIDTH,           maxPbufferWidth),
+    __ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_HEIGHT,          maxPbufferHeight),
+    __ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_PIXELS,          maxPbufferPixels),
+    __ATTRIB(__DRI_ATTRIB_OPTIMAL_PBUFFER_WIDTH,       optimalPbufferWidth),
+    __ATTRIB(__DRI_ATTRIB_OPTIMAL_PBUFFER_HEIGHT,      optimalPbufferHeight),
+    __ATTRIB(__DRI_ATTRIB_SWAP_METHOD,                 swapMethod),
+    __ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_RGB,         bindToTextureRgb),
+    __ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_RGBA,                bindToTextureRgba),
+    __ATTRIB(__DRI_ATTRIB_BIND_TO_MIPMAP_TEXTURE,      bindToMipmapTexture),
+    __ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_TARGETS,     bindToTextureTargets),
+    __ATTRIB(__DRI_ATTRIB_YINVERTED,                   yInverted),
+
+    /* The struct field doesn't matter here, these are handled by the
+     * switch in driGetConfigAttribIndex.  We need them in the array
+     * so the iterator includes them though.*/
+    __ATTRIB(__DRI_ATTRIB_RENDER_TYPE,                 level),
+    __ATTRIB(__DRI_ATTRIB_CONFIG_CAVEAT,               level),
+    __ATTRIB(__DRI_ATTRIB_SWAP_METHOD,                 level)
+};
+
+#define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0]))
+
+static int
+driGetConfigAttribIndex(const __DRIconfig *config,
+                       unsigned int index, unsigned int *value)
+{
+    switch (attribMap[index].attrib) {
+    case __DRI_ATTRIB_RENDER_TYPE:
+       if (config->modes.rgbMode)
+           *value = __DRI_ATTRIB_RGBA_BIT;
+       else
+           *value = __DRI_ATTRIB_COLOR_INDEX_BIT;
+       break;
+    case __DRI_ATTRIB_CONFIG_CAVEAT:
+       if (config->modes.visualRating == GLX_NON_CONFORMANT_CONFIG)
+           *value = __DRI_ATTRIB_NON_CONFORMANT_CONFIG;
+       else if (config->modes.visualRating == GLX_SLOW_CONFIG)
+           *value = __DRI_ATTRIB_SLOW_BIT;
+       else
+           *value = 0;
+       break;
+    case __DRI_ATTRIB_SWAP_METHOD:
+       break;
+
+    default:
+       *value = *(unsigned int *)
+           ((char *) &config->modes + attribMap[index].offset);
+       
+       break;
+    }
 
-    *ptr_to_modes = modes;
     return GL_TRUE;
 }
+
+int
+driGetConfigAttrib(const __DRIconfig *config,
+                  unsigned int attrib, unsigned int *value)
+{
+    int i;
+
+    for (i = 0; i < ARRAY_SIZE(attribMap); i++)
+       if (attribMap[i].attrib == attrib)
+           return driGetConfigAttribIndex(config, i, value);
+
+    return GL_FALSE;
+}
+
+int
+driIndexConfigAttrib(const __DRIconfig *config, int index,
+                    unsigned int *attrib, unsigned int *value)
+{
+    if (index >= 0 && index < ARRAY_SIZE(attribMap)) {
+       *attrib = attribMap[index].attrib;
+       return driGetConfigAttribIndex(config, index, value);
+    }
+
+    return GL_FALSE;
+}
index b28b895..9ac3b51 100644 (file)
 #ifndef DRI_DEBUG_H
 #define DRI_DEBUG_H
 
+#include <GL/gl.h>
+#include <GL/internal/dri_interface.h>
 #include "context.h"
-#include "dri_util.h"
+
+typedef struct __DRIutilversionRec2    __DRIutilversion2;
 
 struct dri_debug_control {
     const char * string;
@@ -83,6 +86,17 @@ struct dri_extension {
     const struct dri_extension_function * functions;
 };
 
+/**
+ * Used to store a version which includes a major range instead of a single
+ * major version number.
+ */
+struct __DRIutilversionRec2 {
+    int    major_min;    /** min allowed Major version number. */
+    int    major_max;    /** max allowed Major version number. */
+    int    minor;        /**< Minor version number. */
+    int    patch;        /**< Patch-level. */
+};
+
 extern unsigned driParseDebugString( const char * debug,
     const struct dri_debug_control * control );
 
@@ -105,16 +119,27 @@ extern GLboolean driCheckDriDdxDrmVersions3(const char * driver_name,
     const __DRIversion * ddxActual, const __DRIutilversion2 * ddxExpected,
     const __DRIversion * drmActual, const __DRIversion * drmExpected);
 
-extern GLint driIntersectArea( drm_clip_rect_t rect1, drm_clip_rect_t rect2 );
-
 extern GLboolean driClipRectToFramebuffer( const GLframebuffer *buffer,
                                           GLint *x, GLint *y,
                                           GLsizei *width, GLsizei *height );
 
-extern GLboolean driFillInModes( __GLcontextModes ** modes,
-    GLenum fb_format, GLenum fb_type,
-    const u_int8_t * depth_bits, const u_int8_t * stencil_bits,
-    unsigned num_depth_stencil_bits,
-    const GLenum * db_modes, unsigned num_db_modes, int visType );
+struct __DRIconfigRec {
+    __GLcontextModes modes;
+};
+
+extern __DRIconfig **
+driCreateConfigs(GLenum fb_format, GLenum fb_type,
+                const u_int8_t * depth_bits, const u_int8_t * stencil_bits,
+                unsigned num_depth_stencil_bits,
+                const GLenum * db_modes, unsigned num_db_modes);
+
+const __DRIconfig **driConcatConfigs(__DRIconfig **a, __DRIconfig **b);
+
+int
+driGetConfigAttrib(const __DRIconfig *config,
+                  unsigned int attrib, unsigned int *value);
+int
+driIndexConfigAttrib(const __DRIconfig *config, int index,
+                    unsigned int *attrib, unsigned int *value);
 
 #endif /* DRI_DEBUG_H */
index 094950d..0008ab1 100644 (file)
 #include "vblank.h"
 #include "xmlpool.h"
 
+static unsigned int msc_to_vblank(__DRIdrawablePrivate * dPriv, int64_t msc)
+{
+   return (unsigned int)(msc - dPriv->msc_base + dPriv->vblank_base);
+}
+
+static int64_t vblank_to_msc(__DRIdrawablePrivate * dPriv, unsigned int vblank)
+{
+   return (int64_t)(vblank - dPriv->vblank_base + dPriv->msc_base);
+}
+
 
 /****************************************************************************/
 /**
@@ -41,7 +51,7 @@
  *
  * Stores the 64-bit count of vertical refreshes since some (arbitrary)
  * point in time in \c count.  Unless the value wraps around, which it
- * may, it will never decrease.
+ * may, it will never decrease for a given drawable.
  *
  * \warning This function is called from \c glXGetVideoSyncSGI, which expects
  * a \c count of type \c unsigned (32-bit), and \c glXGetSyncValuesOML, which 
  * currently always returns a \c sequence of type \c unsigned.
  *
  * \param priv   Pointer to the DRI screen private struct.
+ * \param dPriv  Pointer to the DRI drawable private struct
  * \param count  Storage to hold MSC counter.
  * \return       Zero is returned on success.  A negative errno value
  *               is returned on failure.
  */
-int driGetMSC32( __DRIscreenPrivate * priv, int64_t * count )
+int driDrawableGetMSC32( __DRIscreenPrivate * priv,
+                        __DRIdrawablePrivate * dPriv,
+                        int64_t * count)
 {
    drmVBlank vbl;
    int ret;
@@ -62,14 +75,21 @@ int driGetMSC32( __DRIscreenPrivate * priv, int64_t * count )
 
    vbl.request.type = DRM_VBLANK_RELATIVE;
    vbl.request.sequence = 0;
+   if ( dPriv && dPriv->vblFlags & VBLANK_FLAG_SECONDARY )
+      vbl.request.type |= DRM_VBLANK_SECONDARY;
 
    ret = drmWaitVBlank( priv->fd, &vbl );
-   *count = (int64_t)vbl.reply.sequence;
+
+   if (dPriv) {
+      *count = vblank_to_msc(dPriv, vbl.reply.sequence);
+   } else {
+      /* Old driver (no knowledge of drawable MSC callback) */
+      *count = vbl.reply.sequence;
+   }
 
    return ret;
 }
 
-
 /****************************************************************************/
 /**
  * Wait for a specified refresh count.  This implements most of the
@@ -122,7 +142,9 @@ int driWaitForMSC32( __DRIdrawablePrivate *priv,
           */
          vbl.request.type = dont_wait ? DRM_VBLANK_RELATIVE :
                                         DRM_VBLANK_ABSOLUTE;
-         vbl.request.sequence = next;
+         vbl.request.sequence = next ? msc_to_vblank(priv, next) : 0;
+        if ( priv->vblFlags & VBLANK_FLAG_SECONDARY )
+           vbl.request.type |= DRM_VBLANK_SECONDARY;
 
         if ( drmWaitVBlank( priv->driScreenPriv->fd, &vbl ) != 0 ) {
            /* FIXME: This doesn't seem like the right thing to return here.
@@ -130,8 +152,10 @@ int driWaitForMSC32( __DRIdrawablePrivate *priv,
            return GLX_BAD_CONTEXT;
         }
 
+        *msc = vblank_to_msc(priv, vbl.reply.sequence);
+
          dont_wait = 0;
-         if (target_msc != 0 && vbl.reply.sequence == target)
+         if (target_msc != 0 && *msc == target)
             break;
 
          /* Assuming the wait-done test fails, the next refresh to wait for
@@ -141,9 +165,9 @@ int driWaitForMSC32( __DRIdrawablePrivate *priv,
           * If this refresh has already happened, we add divisor to obtain 
           * the next refresh after the current one that will satisfy it.
           */
-         r = (vbl.reply.sequence % (unsigned int)divisor);
-         next = (vbl.reply.sequence - r + (unsigned int)remainder);
-         if (next <= vbl.reply.sequence) next += (unsigned int)divisor;
+         r = (*msc % (unsigned int)divisor);
+         next = (*msc - r + (unsigned int)remainder);
+         if (next <= *msc) next += (unsigned int)divisor;
 
       } while ( r != (unsigned int)remainder );
    }
@@ -153,7 +177,10 @@ int driWaitForMSC32( __DRIdrawablePrivate *priv,
        */
 
       vbl.request.type = DRM_VBLANK_ABSOLUTE;
-      vbl.request.sequence = target_msc;
+      vbl.request.sequence = target_msc ? msc_to_vblank(priv, target_msc) : 0;
+
+      if ( priv->vblFlags & VBLANK_FLAG_SECONDARY )
+        vbl.request.type |= DRM_VBLANK_SECONDARY;
 
       if ( drmWaitVBlank( priv->driScreenPriv->fd, &vbl ) != 0 ) {
         /* FIXME: This doesn't seem like the right thing to return here.
@@ -162,8 +189,8 @@ int driWaitForMSC32( __DRIdrawablePrivate *priv,
       }
    }
 
-   *msc  = (target_msc & 0xffffffff00000000LL);
-   *msc |= vbl.reply.sequence;
+   *msc = vblank_to_msc(priv, vbl.reply.sequence);
+
    if ( *msc < target_msc ) {
       *msc += 0x0000000100000000LL;
    }
@@ -232,8 +259,8 @@ static int do_wait( drmVBlank * vbl, GLuint * vbl_seq, int fd )
       if ( first_time ) {
         fprintf(stderr, 
                 "%s: drmWaitVBlank returned %d, IRQs don't seem to be"
-                " working correctly.\nTry running with LIBGL_THROTTLE_REFRESH"
-                " and LIBL_SYNC_REFRESH unset.\n", __FUNCTION__, ret);
+                " working correctly.\nTry adjusting the vblank_mode"
+                " configuration parameter.\n", __FUNCTION__, ret);
         first_time = GL_FALSE;
       }
 
@@ -247,20 +274,42 @@ static int do_wait( drmVBlank * vbl, GLuint * vbl_seq, int fd )
 
 /****************************************************************************/
 /**
+ * Returns the default swap interval of the given drawable.
+ */
+
+static unsigned
+driGetDefaultVBlankInterval( const  __DRIdrawablePrivate *priv )
+{
+   if ( (priv->vblFlags & (VBLANK_FLAG_THROTTLE | VBLANK_FLAG_SYNC)) != 0 ) {
+      return 1;
+   }
+   else {
+      return 0;
+   }
+}
+
+
+/****************************************************************************/
+/**
  * Sets the default swap interval when the drawable is first bound to a
  * direct rendering context.
  */
 
-void driDrawableInitVBlank( __DRIdrawablePrivate *priv, GLuint flags,
-                           GLuint *vbl_seq )
+void driDrawableInitVBlank( __DRIdrawablePrivate *priv )
 {
-   if ( priv->pdraw->swap_interval == (unsigned)-1 ) {
+   if ( priv->swap_interval == (unsigned)-1 &&
+       !( priv->vblFlags & VBLANK_FLAG_NO_IRQ ) ) {
       /* Get current vertical blank sequence */
-      drmVBlank vbl = { .request={ .type = DRM_VBLANK_RELATIVE, .sequence = 0 } };
-      do_wait( &vbl, vbl_seq, priv->driScreenPriv->fd );
-
-      priv->pdraw->swap_interval = (flags & (VBLANK_FLAG_THROTTLE |
-                                            VBLANK_FLAG_SYNC)) != 0 ? 1 : 0;
+      drmVBlank vbl;
+      vbl.request.type = DRM_VBLANK_RELATIVE;
+      if ( priv->vblFlags & VBLANK_FLAG_SECONDARY )
+        vbl.request.type |= DRM_VBLANK_SECONDARY;
+      vbl.request.sequence = 0;
+      do_wait( &vbl, &priv->vblSeq, priv->driScreenPriv->fd );
+      priv->vblank_base = priv->vblSeq;
+
+      priv->swap_interval = driGetDefaultVBlankInterval( priv );
    }
 }
 
@@ -271,21 +320,17 @@ void driDrawableInitVBlank( __DRIdrawablePrivate *priv, GLuint flags,
  */
 
 unsigned
-driGetVBlankInterval( const  __DRIdrawablePrivate *priv, GLuint flags )
+driGetVBlankInterval( const  __DRIdrawablePrivate *priv )
 {
-   if ( (flags & VBLANK_FLAG_INTERVAL) != 0 ) {
+   if ( (priv->vblFlags & VBLANK_FLAG_INTERVAL) != 0 ) {
       /* this must have been initialized when the drawable was first bound
        * to a direct rendering context. */
-      assert ( priv->pdraw->swap_interval != (unsigned)-1 );
+      assert ( priv->swap_interval != (unsigned)-1 );
 
-      return priv->pdraw->swap_interval;
-   }
-   else if ( (flags & (VBLANK_FLAG_THROTTLE | VBLANK_FLAG_SYNC)) != 0 ) {
-      return 1;
-   }
-   else {
-      return 0;
+      return priv->swap_interval;
    }
+   else 
+      return driGetDefaultVBlankInterval( priv );
 }
 
 
@@ -295,18 +340,17 @@ driGetVBlankInterval( const  __DRIdrawablePrivate *priv, GLuint flags )
  */
 
 void
-driGetCurrentVBlank( const  __DRIdrawablePrivate *priv, GLuint flags,
-                    GLuint *vbl_seq )
+driGetCurrentVBlank( __DRIdrawablePrivate *priv )
 {
    drmVBlank vbl;
 
    vbl.request.type = DRM_VBLANK_RELATIVE;
-   if ( flags & VBLANK_FLAG_SECONDARY ) {
+   if ( priv->vblFlags & VBLANK_FLAG_SECONDARY ) {
       vbl.request.type |= DRM_VBLANK_SECONDARY;
    }
    vbl.request.sequence = 0;
 
-   (void) do_wait( &vbl, vbl_seq, priv->driScreenPriv->fd );
+   (void) do_wait( &vbl, &priv->vblSeq, priv->driScreenPriv->fd );
 }
 
 
@@ -314,19 +358,15 @@ driGetCurrentVBlank( const  __DRIdrawablePrivate *priv, GLuint flags,
 /**
  * Waits for the vertical blank for use with glXSwapBuffers.
  * 
- * \param vbl_seq  Vertical blank sequence number (MSC) after the last buffer
- *                 swap.  Updated after this wait.
- * \param flags    \c VBLANK_FLAG bits that control how long to wait.
  * \param missed_deadline  Set to \c GL_TRUE if the MSC after waiting is later
- *                 than the "target" based on \c flags.  The idea is that if
- *                 \c missed_deadline is set, then the application is not 
- *                 achieving its desired framerate.
+ *                 than the "target" based on \c priv->vblFlags.  The idea is
+ *                 that if \c missed_deadline is set, then the application is
+ *                 not achieving its desired framerate.
  * \return         Zero on success, -1 on error.
  */
 
 int
-driWaitForVBlank( const  __DRIdrawablePrivate *priv, GLuint * vbl_seq,
-                 GLuint flags, GLboolean * missed_deadline )
+driWaitForVBlank( __DRIdrawablePrivate *priv, GLboolean * missed_deadline )
 {
    drmVBlank vbl;
    unsigned   original_seq;
@@ -335,10 +375,10 @@ driWaitForVBlank( const  __DRIdrawablePrivate *priv, GLuint * vbl_seq,
    unsigned   diff;
 
    *missed_deadline = GL_FALSE;
-   if ( (flags & (VBLANK_FLAG_INTERVAL |
-                 VBLANK_FLAG_THROTTLE |
-                 VBLANK_FLAG_SYNC)) == 0 ||
-       (flags & VBLANK_FLAG_NO_IRQ) != 0 ) {
+   if ( (priv->vblFlags & (VBLANK_FLAG_INTERVAL |
+                          VBLANK_FLAG_THROTTLE |
+                          VBLANK_FLAG_SYNC)) == 0 ||
+       (priv->vblFlags & VBLANK_FLAG_NO_IRQ) != 0 ) {
       return 0;
    }
 
@@ -349,44 +389,45 @@ driWaitForVBlank( const  __DRIdrawablePrivate *priv, GLuint * vbl_seq,
     *
     * VBLANK_FLAG_INTERVAL and VBLANK_FLAG_THROTTLE mean to wait for at
     * least one vertical blank since the last wait.  Since do_wait modifies
-    * vbl_seq, we have to save the original value of vbl_seq for the
+    * priv->vblSeq, we have to save the original value of priv->vblSeq for the
     * VBLANK_FLAG_INTERVAL / VBLANK_FLAG_THROTTLE calculation later.
     */
 
-   original_seq = *vbl_seq;
-   interval = driGetVBlankInterval(priv, flags);
+   original_seq = priv->vblSeq;
+   interval = driGetVBlankInterval(priv);
    deadline = original_seq + interval;
 
    vbl.request.type = DRM_VBLANK_RELATIVE;
-   if ( flags & VBLANK_FLAG_SECONDARY ) {
+   if ( priv->vblFlags & VBLANK_FLAG_SECONDARY ) {
       vbl.request.type |= DRM_VBLANK_SECONDARY;
    }
-   vbl.request.sequence = ((flags & VBLANK_FLAG_SYNC) != 0) ? 1 : 0;
+   vbl.request.sequence = ((priv->vblFlags & VBLANK_FLAG_SYNC) != 0) ? 1 : 0;
 
-   if ( do_wait( & vbl, vbl_seq, priv->driScreenPriv->fd ) != 0 ) {
+   if ( do_wait( & vbl, &priv->vblSeq, priv->driScreenPriv->fd ) != 0 ) {
       return -1;
    }
 
-   diff = *vbl_seq - deadline;
+   diff = priv->vblSeq - deadline;
 
    /* No need to wait again if we've already reached the target */
    if (diff <= (1 << 23)) {
-      *missed_deadline = (flags & VBLANK_FLAG_SYNC) ? (diff > 0) : GL_TRUE;
+      *missed_deadline = (priv->vblFlags & VBLANK_FLAG_SYNC) ? (diff > 0) :
+                        GL_TRUE;
       return 0;
    }
 
    /* Wait until the target vertical blank. */
    vbl.request.type = DRM_VBLANK_ABSOLUTE;
-   if ( flags & VBLANK_FLAG_SECONDARY ) {
+   if ( priv->vblFlags & VBLANK_FLAG_SECONDARY ) {
       vbl.request.type |= DRM_VBLANK_SECONDARY;
    }
    vbl.request.sequence = deadline;
 
-   if ( do_wait( & vbl, vbl_seq, priv->driScreenPriv->fd ) != 0 ) {
+   if ( do_wait( & vbl, &priv->vblSeq, priv->driScreenPriv->fd ) != 0 ) {
       return -1;
    }
 
-   diff = *vbl_seq - deadline;
+   diff = priv->vblSeq - deadline;
    *missed_deadline = diff > 0 && diff <= (1 << 23);
 
    return 0;
index 52c1933..b3a0dad 100644 (file)
                                          */
 
 extern int driGetMSC32( __DRIscreenPrivate * priv, int64_t * count );
+extern int driDrawableGetMSC32( __DRIscreenPrivate * priv,
+                               __DRIdrawablePrivate * drawablePrivate,
+                               int64_t * count);
 extern int driWaitForMSC32( __DRIdrawablePrivate *priv,
     int64_t target_msc, int64_t divisor, int64_t remainder, int64_t * msc );
 extern GLuint driGetDefaultVBlankFlags( const driOptionCache *optionCache );
-extern void driDrawableInitVBlank ( __DRIdrawablePrivate *priv, GLuint flags,
-                                   GLuint *vbl_seq );
-extern unsigned driGetVBlankInterval( const  __DRIdrawablePrivate *priv,
-                                     GLuint flags );
-extern void driGetCurrentVBlank( const  __DRIdrawablePrivate *priv,
-                                GLuint flags, GLuint *vbl_seq );
-extern int driWaitForVBlank( const __DRIdrawablePrivate *priv,
-    GLuint * vbl_seq, GLuint flags, GLboolean * missed_deadline );
+extern void driDrawableInitVBlank ( __DRIdrawablePrivate *priv );
+extern unsigned driGetVBlankInterval( const  __DRIdrawablePrivate *priv );
+extern void driGetCurrentVBlank( __DRIdrawablePrivate *priv );
+extern int driWaitForVBlank( __DRIdrawablePrivate *priv,
+                            GLboolean * missed_deadline );
 
 #undef usleep
 #include <unistd.h>  /* for usleep() */
index b635894..8602d47 100644 (file)
@@ -279,7 +279,7 @@ static GLfloat strToF (const XML_Char *string, const XML_Char **tail) {
 /** \brief Parse a value of a given type. */
 static GLboolean parseValue (driOptionValue *v, driOptionType type,
                             const XML_Char *string) {
-    const XML_Char *tail;
+    const XML_Char *tail = NULL;
   /* skip leading white-space */
     string += strspn (string, " \f\n\r\t\v");
     switch (type) {
@@ -403,40 +403,40 @@ static GLboolean checkValue (const driOptionValue *v, const driOptionInfo *info)
 /** \brief Output a warning message. */
 #define XML_WARNING1(msg) do {\
     __driUtilMessage ("Warning in %s line %d, column %d: "msg, data->name, \
-                      XML_GetCurrentLineNumber(data->parser), \
-                      XML_GetCurrentColumnNumber(data->parser)); \
+                      (int) XML_GetCurrentLineNumber(data->parser), \
+                      (int) XML_GetCurrentColumnNumber(data->parser)); \
 } while (0)
 #define XML_WARNING(msg,args...) do { \
     __driUtilMessage ("Warning in %s line %d, column %d: "msg, data->name, \
-                      XML_GetCurrentLineNumber(data->parser), \
-                      XML_GetCurrentColumnNumber(data->parser), \
+                      (int) XML_GetCurrentLineNumber(data->parser), \
+                      (int) XML_GetCurrentColumnNumber(data->parser), \
                       args); \
 } while (0)
 /** \brief Output an error message. */
 #define XML_ERROR1(msg) do { \
     __driUtilMessage ("Error in %s line %d, column %d: "msg, data->name, \
-                      XML_GetCurrentLineNumber(data->parser), \
-                      XML_GetCurrentColumnNumber(data->parser)); \
+                      (int) XML_GetCurrentLineNumber(data->parser), \
+                      (int) XML_GetCurrentColumnNumber(data->parser)); \
 } while (0)
 #define XML_ERROR(msg,args...) do { \
     __driUtilMessage ("Error in %s line %d, column %d: "msg, data->name, \
-                      XML_GetCurrentLineNumber(data->parser), \
-                      XML_GetCurrentColumnNumber(data->parser), \
+                      (int) XML_GetCurrentLineNumber(data->parser), \
+                      (int) XML_GetCurrentColumnNumber(data->parser), \
                       args); \
 } while (0)
 /** \brief Output a fatal error message and abort. */
 #define XML_FATAL1(msg) do { \
     fprintf (stderr, "Fatal error in %s line %d, column %d: "msg"\n", \
              data->name, \
-             XML_GetCurrentLineNumber(data->parser), \
-             XML_GetCurrentColumnNumber(data->parser)); \
+             (int) XML_GetCurrentLineNumber(data->parser),     \
+             (int) XML_GetCurrentColumnNumber(data->parser)); \
     abort();\
 } while (0)
 #define XML_FATAL(msg,args...) do { \
     fprintf (stderr, "Fatal error in %s line %d, column %d: "msg"\n", \
              data->name, \
-             XML_GetCurrentLineNumber(data->parser), \
-             XML_GetCurrentColumnNumber(data->parser), \
+             (int) XML_GetCurrentLineNumber(data->parser),     \
+             (int) XML_GetCurrentColumnNumber(data->parser),           \
              args); \
     abort();\
 } while (0)