From 4566b006f1a6bbdb96871e511e10e16f18bad23e Mon Sep 17 00:00:00 2001 From: Alan Hourihane Date: Tue, 10 Jun 2008 20:17:16 +0100 Subject: Bring in DRI2 changes --- include/GL/internal/glcore.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/GL/internal/glcore.h') diff --git a/include/GL/internal/glcore.h b/include/GL/internal/glcore.h index fc0aaf3d5e..1bb63c1aee 100644 --- a/include/GL/internal/glcore.h +++ b/include/GL/internal/glcore.h @@ -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; -- cgit v1.2.3 From 6f7ed99b306990f284f9d57c0b66efaa7f2277e1 Mon Sep 17 00:00:00 2001 From: Alan Hourihane Date: Thu, 12 Jun 2008 00:11:54 +0100 Subject: revert the DRI2 commits --- bin/mklib | 125 +-- include/GL/internal/dri_interface.h | 794 ++++++-------- include/GL/internal/dri_sarea.h | 134 --- include/GL/internal/glcore.h | 1 - src/gallium/winsys/dri/intel/intel_context.c | 81 +- src/gallium/winsys/dri/intel/intel_lock.c | 7 +- src/gallium/winsys/dri/intel/intel_screen.c | 375 +++---- src/gallium/winsys/dri/intel/intel_screen.h | 4 +- src/gallium/winsys/dri/intel/intel_swapbuffers.c | 3 +- src/glx/x11/Makefile | 27 +- src/glx/x11/XF86dri.c | 39 +- src/glx/x11/dri2.c | 252 ----- src/glx/x11/dri2.h | 53 - src/glx/x11/dri2_glx.c | 371 ------- src/glx/x11/dri_common.c | 399 ------- src/glx/x11/dri_common.h | 60 -- src/glx/x11/dri_glx.c | 885 +++++++--------- src/glx/x11/glcontextmodes.c | 30 +- src/glx/x11/glcontextmodes.h | 6 +- src/glx/x11/glx_pbuffer.c | 100 +- src/glx/x11/glx_texture_compression.c | 347 +++++++ src/glx/x11/glxclient.h | 171 ++- src/glx/x11/glxcmds.c | 707 +++++++------ src/glx/x11/glxcurrent.c | 510 --------- src/glx/x11/glxext.c | 1198 +++++++++++++++++++--- src/glx/x11/glxextensions.c | 25 +- src/glx/x11/glxextensions.h | 4 +- src/glx/x11/glxhash.c | 416 -------- src/glx/x11/glxhash.h | 16 - src/glx/x11/indirect.c | 353 +------ src/glx/x11/indirect.h | 2 - src/glx/x11/indirect_init.c | 2 - src/glx/x11/indirect_texture_compression.c | 347 ------- src/glx/x11/indirect_vertex_array.c | 24 +- src/glx/x11/indirect_vertex_array_priv.h | 308 ------ src/glx/x11/singlepix.c | 2 +- src/glx/x11/xf86dri.h | 14 +- src/glx/x11/xfont.c | 6 +- src/mesa/drivers/dri/common/dri_util.c | 1036 ++++++++++--------- src/mesa/drivers/dri/common/dri_util.h | 319 +++--- src/mesa/drivers/dri/common/drirenderbuffer.c | 2 + src/mesa/drivers/dri/common/spantmp2.h | 2 +- src/mesa/drivers/dri/common/utils.c | 309 ++---- src/mesa/drivers/dri/common/utils.h | 41 +- src/mesa/drivers/dri/common/vblank.c | 159 ++- src/mesa/drivers/dri/common/vblank.h | 16 +- src/mesa/drivers/dri/common/xmlconfig.c | 26 +- 47 files changed, 3654 insertions(+), 6454 deletions(-) delete mode 100644 include/GL/internal/dri_sarea.h delete mode 100644 src/glx/x11/dri2.c delete mode 100644 src/glx/x11/dri2.h delete mode 100644 src/glx/x11/dri2_glx.c delete mode 100644 src/glx/x11/dri_common.c delete mode 100644 src/glx/x11/dri_common.h create mode 100644 src/glx/x11/glx_texture_compression.c delete mode 100644 src/glx/x11/glxcurrent.c delete mode 100644 src/glx/x11/glxhash.c delete mode 100644 src/glx/x11/glxhash.h delete mode 100644 src/glx/x11/indirect_texture_compression.c delete mode 100644 src/glx/x11/indirect_vertex_array_priv.h (limited to 'include/GL/internal/glcore.h') diff --git a/bin/mklib b/bin/mklib index 2fb215e7d7..e17e2fee0b 100755 --- a/bin/mklib +++ b/bin/mklib @@ -34,7 +34,6 @@ MINOR=0 PATCH="" DEPS="" LINK="" -LDFLAGS="" CPLUSPLUS=0 STATIC=0 DLOPEN=0 @@ -64,14 +63,12 @@ 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' @@ -97,19 +94,12 @@ 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" @@ -138,10 +128,6 @@ do shift 1; ARCHOPT=$1 ;; - '-altopts') - shift 1; - ALTOPTS=$1 - ;; '-noprefix') NOPREFIX=1 ;; @@ -201,7 +187,7 @@ fi # case $ARCH in - 'Linux' | 'OpenBSD' | 'DragonFly' | 'GNU' | GNU/*) + 'Linux' | 'OpenBSD' | 'GNU' | GNU/*) # we assume gcc if [ "x$LINK" = "x" ] ; then @@ -232,13 +218,9 @@ case $ARCH in OPTS="-m32 ${OPTS}" fi - if [ "${ALTOPTS}" ] ; then - OPTS=${ALTOPTS} - fi - rm -f ${LIBNAME} # make lib - ${LINK} ${OPTS} ${LDFLAGS} -o ${LIBNAME} ${OBJECTS} ${DEPS} + ${LINK} ${OPTS} -o ${LIBNAME} ${OBJECTS} ${DEPS} # finish up FINAL_LIBS="${LIBNAME}" elif [ $STATIC = 1 ] ; then @@ -246,9 +228,6 @@ 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} @@ -284,9 +263,6 @@ 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}" @@ -302,7 +278,7 @@ case $ARCH in rm -f ${LIBNAME}.so # make lib - ${LINK} ${OPTS} ${LDFLAGS} -o ${LIBNAME}.so.${VERSION} ${OBJECTS} ${DEPS} + ${LINK} ${OPTS} -o ${LIBNAME}.so.${VERSION} ${OBJECTS} ${DEPS} # make usual symlinks ln -s ${LIBNAME}.so.${VERSION} ${LIBNAME}.so.${MAJOR} ln -s ${LIBNAME}.so.${MAJOR} ${LIBNAME}.so @@ -369,17 +345,15 @@ 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} ${LDFLAGS} -o ${LIBNAME} ${OBJECTS} ${DEPS} + ${LINK} ${OPTS} -o ${LIBNAME} ${OBJECTS} ${DEPS} else rm -f ${LIBNAME}.${MAJOR} ${LIBNAME} - ${LINK} ${OPTS} ${LDFLAGS} -o ${LIBNAME}.${MAJOR} ${OBJECTS} ${DEPS} + ${LINK} ${OPTS} -o ${LIBNAME}.${MAJOR} ${OBJECTS} ${DEPS} ln -s ${LIBNAME}.${MAJOR} ${LIBNAME} fi FINAL_LIBS="${LIBNAME}.${MAJOR} ${LIBNAME}" @@ -402,11 +376,8 @@ 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} ${LDFLAGS} -o ${LIBNAME} ${OBJECTS} ${DEPS} + ${LINK} ${OPTS} -o ${LIBNAME} ${OBJECTS} ${DEPS} FINAL_LIBS=${LIBNAME} elif [ $STATIC = 1 ] ; then STLIB="lib${LIBNAME}.a" @@ -418,12 +389,9 @@ 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} ${LDFLAGS} -o ${SHLIB} ${OBJECTS} ${DEPS} + ${LINK} ${OPTS} -o ${SHLIB} ${OBJECTS} ${DEPS} ln -sf ${SHLIB} "lib${LIBNAME}.so" FINAL_LIBS="${SHLIB} lib${LIBNAME}.so" fi @@ -474,10 +442,6 @@ case $ARCH in exit 1 fi - if [ "${ALTOPTS}" ] ; then - OPTS=${ALTOPTS} - fi - if [ $CPLUSPLUS = 1 ] ; then LINK="CC" else @@ -485,7 +449,7 @@ case $ARCH in fi echo "mklib: Making IRIX " ${ABI} " shared library: " ${LIBNAME} - ${LINK} ${OPTS} ${LDFLAGS} -o ${LIBNAME} ${OBJECTS} ${DEPS} + ${LINK} ${OPTS} -o ${LIBNAME} ${OBJECTS} ${DEPS} FINAL_LIBS=${LIBNAME} fi ;; @@ -558,16 +522,12 @@ 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} ${LDFLAGS} -o ${LIBNAME} ${OBJECTS} ${DEPS} + cc -G ${OPTS} -o ${LIBNAME} ${OBJECTS} ${DEPS} else - cc ${OPTS} ${LDFLAGS} -o ${OFILE} ${OBJECTS} ${DEPS} + cc ${OPTS} -o ${OFILE} ${OBJECTS} ${DEPS} ar ${X64} -r ${LIBNAME} ${OFILE} fi @@ -613,9 +573,6 @@ 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 @@ -627,37 +584,19 @@ 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 - - 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}" + LINKNAME="lib${LIBNAME}.${LIBSUFFIX}" + LIBNAME="lib${LIBNAME}.${MAJOR}.${LIBSUFFIX}" # examine first object to determine ABI set ${OBJECTS} - 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 + 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 # XXX can we always add -isysroot /Developer/SDKs/MacOSX10.4u.sdk # to OPTS here? @@ -670,11 +609,9 @@ case $ARCH in fi echo "mklib: Making Darwin shared library: " ${LIBNAME} - - ${LINK} ${OPTS} ${LDFLAGS} -o ${LIBNAME} ${OBJECTS} ${DEPS} + ${LINK} ${OPTS} -o ${LIBNAME} ${OBJECTS} ${DEPS} ln -s ${LIBNAME} ${LINKNAME} - ln -s ${LIBNAME} ${LINKNAME2} - FINAL_LIBS="${LIBNAME} ${LINKNAME} ${LINKNAME2}" + FINAL_LIBS="${LIBNAME} ${LINKNAME}" fi ;; @@ -726,9 +663,6 @@ 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 @@ -739,9 +673,6 @@ 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} @@ -755,7 +686,7 @@ case $ARCH in rm -f ${LIBNAME}.so.${MAJOR} rm -f ${LIBNAME}.so # make lib - ${LINK} ${OPTS} ${LDFLAGS} -o ${LIBNAME}.so.${VERSION} ${OBJECTS} ${DEPS} + ${LINK} ${OPTS} -o ${LIBNAME}.so.${VERSION} ${OBJECTS} ${DEPS} # make usual symlinks ln -s ${LIBNAME}.so.${VERSION} ${LIBNAME}.so.${MAJOR} ln -s ${LIBNAME}.so.${MAJOR} ${LIBNAME}.so @@ -806,9 +737,6 @@ 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 @@ -816,9 +744,6 @@ 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 @@ -833,7 +758,7 @@ case $ARCH in rm -f ${LIBNAME}.a # make lib - ${LINK} ${OPTS} ${LDFLAGS} -o ${CYGNAME}-${MAJOR}.dll ${OBJECTS} ${DEPS} + ${LINK} ${OPTS} -o ${CYGNAME}-${MAJOR}.dll ${OBJECTS} ${DEPS} # make usual symlinks ln -s ${LIBNAME}-${MAJOR}.dll.a ${LIBNAME}.dll.a # finish up diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h index 033d7a4ae4..8d24e311f8 100644 --- a/include/GL/internal/dri_interface.h +++ b/include/GL/internal/dri_interface.h @@ -1,6 +1,5 @@ /* * Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. - * Copyright 2007-2008 Red Hat, Inc. * (C) Copyright IBM Corporation 2004 * All Rights Reserved. * @@ -34,12 +33,12 @@ * * \author Kevin E. Martin * \author Ian Romanick - * \author Kristian Høgsberg */ #ifndef DRI_INTERFACE_H #define DRI_INTERFACE_H +#include #include /** @@ -49,246 +48,180 @@ * 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 __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; +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; /*@}*/ /** - * Extension struct. Drivers 'inherit' from this struct by embedding - * it as the first element in the extension struct. - * - * 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. + * \name Functions provided by the driver loader. */ -struct __DRIextensionRec { - const char *name; - int version; -}; - +/*@{*/ /** - * 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. + * 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. + * + * \sa glXGetScreenDriver, glXGetProcAddress, glXGetDriverConfig */ +typedef const char * (* PFNGLXGETSCREENDRIVERPROC) (__DRInativeDisplay *dpy, int scrNum); /** - * Used by drivers to indicate support for setting the read drawable. + * 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 */ -#define __DRI_READ_DRAWABLE "DRI_ReadDrawable" -#define __DRI_READ_DRAWABLE_VERSION 1 +typedef const char * (* PFNGLXGETDRIVERCONFIGPROC) (const char *driverName); /** - * Used by drivers that implement the GLX_MESA_copy_sub_buffer extension. + * 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. */ -#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); -}; +typedef void (* PFNGLXSCRENABLEEXTENSIONPROC) ( void *psc, const char * name ); +/*@}*/ -/** - * Used by drivers that implement the GLX_SGI_swap_control or - * GLX_MESA_swap_control extension. - */ -#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); -}; /** - * Used by drivers that implement the GLX_MESA_allocate_memory. + * \name Functions and data provided by the driver. */ -#define __DRI_ALLOCATE "DRI_Allocate" -#define __DRI_ALLOCATE_VERSION 1 -struct __DRIallocateExtensionRec { - __DRIextension base; +/*@{*/ + +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; - 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); -}; /** - * Used by drivers that implement the GLX_MESA_swap_frame_usage extension. + * XML document describing the configuration options supported by the + * driver. */ -#define __DRI_FRAME_TRACKING "DRI_FrameTracking" -#define __DRI_FRAME_TRACKING_VERSION 1 -struct __DRIframeTrackingExtensionRec { - __DRIextension base; - - /** - * Enable or disable frame usage tracking. - * - * \since Internal API version 20030317. - */ - int (*frameTracking)(__DRIdrawable *drawable, GLboolean enable); +extern const char __driConfigOptions[]; - /** - * Retrieve frame usage information. - * - * \since Internal API version 20030317. - */ - 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. + * 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. */ -#define __DRI_MEDIA_STREAM_COUNTER "DRI_MediaStreamCounter" -#define __DRI_MEDIA_STREAM_COUNTER_VERSION 1 -struct __DRImediaStreamCounterExtensionRec { - __DRIextension base; +struct __DRIversionRec { + int major; /**< Major version number. */ + int minor; /**< Minor version number. */ + int patch; /**< Patch-level. */ +}; + + +typedef void (*__DRIfuncPtr)(void); +struct __DRIinterfaceMethodsRec { /** - * 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. + * Get pointer to named function. */ - int (*waitForMSC)(__DRIdrawable *drawable, - int64_t target_msc, int64_t divisor, int64_t remainder, - int64_t * msc, int64_t * sbc); + __DRIfuncPtr (*getProcAddress)( const char * proc_name ); /** - * Get the number of vertical refreshes since some point in time before - * this function was first called (i.e., system start up). + * Create a list of \c __GLcontextModes structures. */ - 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; + __GLcontextModes * (*createContextModes)(unsigned count, + size_t minimum_bytes_per_struct); /** - * 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. + * Destroy a list of \c __GLcontextModes structures. * - * For GLX_EXT_texture_from_pixmap with AIGLX. + * \todo + * Determine if the drivers actually need to call this. */ - void (*setTexOffset)(__DRIcontext *pDRICtx, GLint texname, - unsigned long long offset, GLint depth, GLuint pitch); -}; + void (*destroyContextModes)( __GLcontextModes * modes ); + /** + * Get the \c __DRIscreen for a given display and screen number. + */ + __DRIscreen *(*getScreen)(__DRInativeDisplay *dpy, int screenNum); -#define __DRI_TEX_BUFFER "DRI_TexBuffer" -#define __DRI_TEX_BUFFER_VERSION 1 -struct __DRItexBufferExtensionRec { - __DRIextension base; /** - * Method to override base texture image with the contents of a - * __DRIdrawable. + * \name Client/server protocol functions. * - * For GLX_EXT_texture_from_pixmap with AIGLX. + * 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. */ - void (*setTexBuffer)(__DRIcontext *pDRICtx, - GLint target, - __DRIdrawable *pDraw); -}; - - -/** - * XML document describing the configuration options supported by the - * driver. - */ -extern const char __driConfigOptions[]; - -/*@}*/ + /*@{*/ + /** + * 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. + */ + GLboolean (*windowExists)(__DRInativeDisplay *dpy, __DRIid draw); -/** - * 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. - */ + /** + * Create the server-side portion of the GL context. + */ + GLboolean (* createContext)( __DRInativeDisplay *dpy, int screenNum, + int configID, void * contextID, drm_context_t * hw_context ); -typedef struct __DRIgetDrawableInfoExtensionRec __DRIgetDrawableInfoExtension; -typedef struct __DRIsystemTimeExtensionRec __DRIsystemTimeExtension; -typedef struct __DRIdamageExtensionRec __DRIdamageExtension; -typedef struct __DRIloaderExtensionRec __DRIloaderExtension; -typedef struct __DRIswrastLoaderExtensionRec __DRIswrastLoaderExtension; + /** + * Destroy the server-side portion of the GL context. + */ + GLboolean (* destroyContext)( __DRInativeDisplay *dpy, int screenNum, + __DRIid context ); + /** + * Create the server-side portion of the drawable. + */ + GLboolean (*createDrawable)( __DRInativeDisplay * ndpy, int screen, + __DRIid drawable, drm_drawable_t * hHWDrawable ); -/** - * Callback to getDrawableInfo protocol - */ -#define __DRI_GET_DRAWABLE_INFO "DRI_GetDrawableInfo" -#define __DRI_GET_DRAWABLE_INFO_VERSION 1 -struct __DRIgetDrawableInfoExtensionRec { - __DRIextension base; + /** + * Destroy the server-side portion of the drawable. + */ + GLboolean (*destroyDrawable)( __DRInativeDisplay * ndpy, int screen, + __DRIid drawable ); /** * This function is used to get information about the position, size, and * clip rects of a drawable. */ - GLboolean (* getDrawableInfo) ( __DRIdrawable *drawable, - unsigned int * index, unsigned int * stamp, + GLboolean (* getDrawableInfo) ( __DRInativeDisplay *dpy, int scrn, + __DRIid draw, 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, - void *loaderPrivate); -}; + int * numBackClipRects, drm_clip_rect_t ** pBackClipRects ); + /*@}*/ -/** - * 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). */ @@ -301,18 +234,9 @@ struct __DRIsystemTimeExtensionRec { * the rate of the "media stream counter". In practical terms, this is * the frame refresh rate of the display. */ - 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; + GLboolean (*getMSCRate)(__DRInativeDisplay * dpy, __DRIid drawable, + int32_t * numerator, int32_t * denominator); + /*@}*/ /** * Reports areas of the given drawable which have been modified by the @@ -327,221 +251,15 @@ struct __DRIdamageExtensionRec { * \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)(__DRIdrawable *draw, + void (*reportDamage)(__DRInativeDisplay * dpy, int screen, + __DRIid drawable, int x, int y, drm_clip_rect_t *rects, int num_rects, - 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. */ + int front_buffer); }; + /** * Framebuffer information record. Used by libGL to communicate information * about the framebuffer to the driver's \c __driCreateNewScreen function. @@ -571,59 +289,229 @@ struct __DRIframebufferRec { /** - * This extension provides alternative screen, drawable and context - * constructors for legacy DRI functionality. This is used in - * conjunction with the core extension. + * Screen dependent methods. This structure is initialized during the + * \c __DRIdisplayRec::createScreen call. */ -#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); +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); }; /** - * This extension provides alternative screen, drawable and context - * constructors for swrast DRI functionality. This is used in - * conjunction with the core extension. + * Context dependent methods. This structure is initialized during the + * \c __DRIscreenRec::createContext call. */ -#define __DRI_SWRAST "DRI_SWRast" -#define __DRI_SWRAST_VERSION 1 +struct __DRIcontextRec { + /** + * Method to destroy the private DRI context data. + */ + void (*destroyContext)(__DRInativeDisplay *dpy, int scrn, void *contextPrivate); -struct __DRIswrastExtensionRec { - __DRIextension base; + /** + * 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 ); - __DRIscreen *(*createNewScreen)(int screen, - const __DRIextension **extensions, - const __DRIconfig ***driver_configs, - void *loaderPrivate); + /** + * 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); - __DRIdrawable *(*createNewDrawable)(__DRIscreen *screen, - const __DRIconfig *config, - 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); }; #endif diff --git a/include/GL/internal/dri_sarea.h b/include/GL/internal/dri_sarea.h deleted file mode 100644 index 849161fbc1..0000000000 --- a/include/GL/internal/dri_sarea.h +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright 2007 Red Hat, Inc - * 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. - */ - -#ifndef DRI_SAREA_H -#define DRI_SAREA_H - -#include - -/* The DRI2 SAREA holds a list of self-describing blocks. Each block - * is 8 byte aligned and has a common 32-bit header word. The upper - * 16 bits describe the type of the block and the lower 16 bits the - * size. DRI2 only defines a couple of blocks and allows drivers to - * define driver specific blocks using type codes from 0x8000 and up. - * The type code 0x0000 defines the end of the sarea. */ - -#define DRI2_SAREA_BLOCK_HEADER(type, size) (((type) << 16) | (size)) -#define DRI2_SAREA_BLOCK_TYPE(b) ((b) >> 16) -#define DRI2_SAREA_BLOCK_SIZE(b) ((b) & 0xffff) -#define DRI2_SAREA_BLOCK_NEXT(p) \ - ((void *) ((unsigned char *) (p) + \ - DRI2_SAREA_BLOCK_SIZE(*(unsigned int *) p))) - -#define DRI2_SAREA_BLOCK_END 0x0000 -#define DRI2_SAREA_BLOCK_LOCK 0x0001 -#define DRI2_SAREA_BLOCK_EVENT_BUFFER 0x0002 - -/* Chipset specific blocks start at 0x8000, 0xffff is reserved. */ - -typedef struct __DRILock __DRILock; -typedef struct __DRIEventBuffer __DRIEventBuffer; -typedef struct __DRIDrawableBuffer __DRIDrawableBuffer; -typedef struct __DRIDrawableConfigEvent __DRIDrawableConfigEvent; -typedef struct __DRIBufferAttachEvent __DRIBufferAttachEvent; - -struct __DRILock { - unsigned int block_header; - drm_hw_lock_t lock; - - /* We use this with DRM_CAS to allocate lock IDs for the real lock.*/ - unsigned int next_id; -}; - -struct __DRIEventBuffer { - unsigned int block_header; - unsigned int head; /* last valid event */ - unsigned int prealloc; /* event currently being written */ - unsigned int size; /* size of data */ - unsigned char data[0]; -}; - -enum { - /* the four standard color buffers */ - DRI_DRAWABLE_BUFFER_FRONT_LEFT = 0, - DRI_DRAWABLE_BUFFER_BACK_LEFT = 1, - DRI_DRAWABLE_BUFFER_FRONT_RIGHT = 2, - DRI_DRAWABLE_BUFFER_BACK_RIGHT = 3, - /* optional aux buffer */ - DRI_DRAWABLE_BUFFER_AUX0 = 4, - DRI_DRAWABLE_BUFFER_AUX1 = 5, - DRI_DRAWABLE_BUFFER_AUX2 = 6, - DRI_DRAWABLE_BUFFER_AUX3 = 7, - DRI_DRAWABLE_BUFFER_DEPTH = 8, - DRI_DRAWABLE_BUFFER_STENCIL = 9, - DRI_DRAWABLE_BUFFER_ACCUM = 10, - /* generic renderbuffers */ - DRI_DRAWABLE_BUFFER_COLOR0 = 11, - DRI_DRAWABLE_BUFFER_COLOR1 = 12, - DRI_DRAWABLE_BUFFER_COLOR2 = 13, - DRI_DRAWABLE_BUFFER_COLOR3 = 14, - DRI_DRAWABLE_BUFFER_COLOR4 = 15, - DRI_DRAWABLE_BUFFER_COLOR5 = 16, - DRI_DRAWABLE_BUFFER_COLOR6 = 17, - DRI_DRAWABLE_BUFFER_COLOR7 = 18, - DRI_DRAWABLE_BUFFER_COUNT = 19 -}; - -struct __DRIDrawableBuffer { - unsigned int attachment; - unsigned int handle; - unsigned int pitch; - unsigned short cpp; - - /* Upper 8 bits are driver specific, lower 8 bits generic. The - * bits can inidicate buffer properties such as tiled, swizzled etc. */ - unsigned short flags; -}; - -#define DRI2_EVENT_HEADER(type, size) (((type) << 16) | (size)) -#define DRI2_EVENT_TYPE(b) ((b) >> 16) -#define DRI2_EVENT_SIZE(b) ((b) & 0xffff) - -#define DRI2_EVENT_PAD 0x0000 -#define DRI2_EVENT_DRAWABLE_CONFIG 0x0001 -#define DRI2_EVENT_BUFFER_ATTACH 0x0002 - -struct __DRIDrawableConfigEvent { - unsigned int event_header; - unsigned int drawable; - short x; - short y; - unsigned int width; - unsigned int height; - unsigned int num_rects; - struct drm_clip_rect rects[0]; -}; - -struct __DRIBufferAttachEvent { - unsigned int event_header; - unsigned int drawable; - __DRIDrawableBuffer buffer; -}; - -#endif /* DRI_SAREA_H */ diff --git a/include/GL/internal/glcore.h b/include/GL/internal/glcore.h index 1bb63c1aee..fc0aaf3d5e 100644 --- a/include/GL/internal/glcore.h +++ b/include/GL/internal/glcore.h @@ -41,7 +41,6 @@ #define GL_CORE_SGI 1 #define GL_CORE_MESA 2 #define GL_CORE_APPLE 4 -#define GL_CORE_WINDOWS 8 typedef struct __GLcontextRec __GLcontext; diff --git a/src/gallium/winsys/dri/intel/intel_context.c b/src/gallium/winsys/dri/intel/intel_context.c index 9d78e9ebf8..8284e0edbb 100644 --- a/src/gallium/winsys/dri/intel/intel_context.c +++ b/src/gallium/winsys/dri/intel/intel_context.c @@ -28,8 +28,6 @@ #include "i830_dri.h" -#include "state_tracker/st_public.h" -#include "state_tracker/st_context.h" #include "intel_screen.h" #include "intel_context.h" #include "intel_swapbuffers.h" @@ -38,6 +36,8 @@ #include "i915simple/i915_screen.h" +#include "state_tracker/st_public.h" +#include "state_tracker/st_context.h" #include "pipe/p_defines.h" #include "pipe/p_context.h" @@ -67,6 +67,7 @@ int __intel_debug = 0; #define need_GL_NV_vertex_program #include "extension_helper.h" + /** * Extension strings exported by the intel driver. * @@ -74,7 +75,7 @@ int __intel_debug = 0; * It appears that ARB_texture_env_crossbar has "disappeared" compared to the * old i830-specific driver. */ -static const struct dri_extension card_extensions[] = { +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}, @@ -85,27 +86,22 @@ static 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}, -#endif + {"GL_EXT_pixel_buffer_object", NULL}, {"GL_EXT_secondary_color", GL_EXT_secondary_color_functions}, {"GL_EXT_stencil_wrap", NULL}, {"GL_EXT_texture_edge_clamp", NULL}, @@ -120,61 +116,10 @@ static 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}, - { "GL_EXT_framebuffer_object", GL_EXT_framebuffer_object_functions}, - { "GL_ARB_pixel_buffer_object", NULL}, - { NULL, NULL } -}; - -static const struct dri_extension arb_oc_extensions[] = { - {"GL_ARB_occlusion_query", GL_ARB_occlusion_query_functions}, - {NULL, NULL} -}; -#endif - -/** - * Initializes potential list of extensions if ctx == NULL, or actually enables - * extensions for a context. - */ -void intelInitExtensions(struct intel_context *intel, GLboolean enable_imaging) -{ - GLcontext *ctx = intel ? intel->st->ctx : NULL; - /* 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 || - (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 @@ -259,10 +204,10 @@ intelCreateContext(const __GLcontextModes * visual, /* * memory pools */ - DRM_LIGHT_LOCK(sPriv->fd, &sPriv->lock, driContextPriv->hHWContext); + DRM_LIGHT_LOCK(sPriv->fd, &sPriv->pSAREA->lock, driContextPriv->hHWContext); // ZZZ JB should be per screen and not be done per context havePools = intelCreatePools(sPriv); - DRM_UNLOCK(sPriv->fd, &sPriv->lock, driContextPriv->hHWContext); + DRM_UNLOCK(sPriv->fd, &sPriv->pSAREA->lock, driContextPriv->hHWContext); if (!havePools) return GL_FALSE; @@ -270,7 +215,7 @@ intelCreateContext(const __GLcontextModes * visual, /* Dri stuff */ intel->hHWContext = driContextPriv->hHWContext; intel->driFd = sPriv->fd; - intel->driHwLock = (drmLock *) & sPriv->lock; + intel->driHwLock = (drmLock *) & sPriv->pSAREA->lock; fthrottle_mode = driQueryOptioni(&intel->optionCache, "fthrottle_mode"); intel->iw.irq_seq = -1; @@ -320,7 +265,7 @@ intelCreateContext(const __GLcontextModes * visual, intel->st = st_create_context(pipe, visual, st_share); - intelInitExtensions( intel, GL_TRUE ); + driInitExtensions( intel->st->ctx, card_extensions, GL_TRUE ); return GL_TRUE; } diff --git a/src/gallium/winsys/dri/intel/intel_lock.c b/src/gallium/winsys/dri/intel/intel_lock.c index 469090c0e1..406284c98f 100644 --- a/src/gallium/winsys/dri/intel/intel_lock.c +++ b/src/gallium/winsys/dri/intel/intel_lock.c @@ -50,9 +50,6 @@ intelContendedLock(struct intel_context *intel, uint flags) DBG(LOCK, "%s - got contended lock\n", __progname); - if (sPriv->dri2.enabled) - return; - /* If the window moved, may need to set a new cliprect now. * * NOTE: This releases and regains the hw lock, so all state @@ -61,8 +58,8 @@ intelContendedLock(struct intel_context *intel, uint flags) if (dPriv) DRI_VALIDATE_DRAWABLE_INFO(sPriv, dPriv); - if (sarea && (sarea->width != intelScreen->front.width || - sarea->height != intelScreen->front.height)) { + if (sarea->width != intelScreen->front.width || + sarea->height != intelScreen->front.height) { intelUpdateScreenRotation(sPriv, sarea); } diff --git a/src/gallium/winsys/dri/intel/intel_screen.c b/src/gallium/winsys/dri/intel/intel_screen.c index e456c28d0d..8817a80a5a 100644 --- a/src/gallium/winsys/dri/intel/intel_screen.c +++ b/src/gallium/winsys/dri/intel/intel_screen.c @@ -60,114 +60,7 @@ 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) -{ - (void) dPriv; - (void) pcp; - (void) event; -} - -static void -intelHandleBufferAttach(__DRIdrawablePrivate *dPriv, - __DRIcontextPrivate *pcp, - __DRIBufferAttachEvent *ba) -{ - struct intel_screen *intelScreen = intel_screen(dPriv->driScreenPriv); - - switch (ba->buffer.attachment) { - case DRI_DRAWABLE_BUFFER_FRONT_LEFT: - intelScreen->front.width = dPriv->w; - intelScreen->front.height = dPriv->h; - intelScreen->front.cpp = ba->buffer.cpp; - intelScreen->front.pitch = ba->buffer.pitch; - driGenBuffers(intelScreen->base.staticPool, "front", 1, &intelScreen->front.buffer, 0, 0, 0); - driBOSetReferenced(intelScreen->front.buffer, ba->buffer.handle); - break; - - case DRI_DRAWABLE_BUFFER_BACK_LEFT: - case DRI_DRAWABLE_BUFFER_DEPTH: - case DRI_DRAWABLE_BUFFER_STENCIL: - case DRI_DRAWABLE_BUFFER_ACCUM: - /* anything ?? */ - break; - - default: - fprintf(stderr, "unhandled buffer attach event, attachment type %d\n", - ba->buffer.attachment); - return; - } -} - -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 @@ -284,8 +177,7 @@ intelCreatePools(__DRIscreenPrivate * sPriv) intelScreen->havePools = GL_TRUE; - if (intelScreen->sarea) - intelUpdateScreenRotation(sPriv, intelScreen->sarea); + intelUpdateScreenRotation(sPriv, intelScreen->sarea); return GL_TRUE; } @@ -318,6 +210,11 @@ 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"); @@ -334,19 +231,28 @@ intelInitDriver(__DRIscreenPrivate * sPriv) __driConfigOptions, __driNConfigOptions); sPriv->private = (void *) intelScreen; - intelScreen->sarea = (drmI830Sarea *) (((GLubyte *) sPriv->pSAREA) + - gDRIPriv->sarea_priv_offset); + intelScreen->sarea = (drmI830Sarea *) (((GLubyte *) sPriv->pSAREA) + + gDRIPriv->sarea_priv_offset); intelScreen->deviceID = gDRIPriv->deviceID; - intelScreen->front.cpp = gDRIPriv->cpp; - intelScreen->drmMinor = sPriv->drm_version.minor; + intelScreen->drmMinor = sPriv->drmMinor; + + assert(gDRIPriv->bitsPerPixel == 16 || + gDRIPriv->bitsPerPixel == 32); + intelUpdateScreenRotation(sPriv, intelScreen->sarea); if (0) intelPrintDRIInfo(intelScreen, sPriv, gDRIPriv); - sPriv->extensions = intelScreenExtensions; + 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"); + } intel_be_init_device(&intelScreen->base, sPriv->fd); intelScreen->base.base.flush_frontbuffer = intel_flush_frontbuffer; @@ -445,19 +351,65 @@ intelGetSwapInfo(__DRIdrawablePrivate * dPriv, __DRIswapInfo * sInfo) return 0; } -static __DRIconfig ** -intelFillInModes(__DRIscreenPrivate *psp, - unsigned pixel_bits, unsigned depth_bits, - unsigned stencil_bits, GLboolean have_back_buffer) + +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 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) { - __DRIconfig **configs; + __GLcontextModes *modes; __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. @@ -499,143 +451,100 @@ intelFillInModes(__DRIscreenPrivate *psp, fb_type = GL_UNSIGNED_INT_8_8_8_8_REV; } - 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__, + 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__, __LINE__); return NULL; } /* Mark the visual as slow if there are "fake" stencil bits. */ - for (i = 0; configs[i]; i++) { - m = &configs[i]->modes; + for (m = modes; m != NULL; m = m->next) { if ((m->stencilBits != 0) && (m->stencilBits != stencil_bits)) { m->visualRating = GLX_SLOW_CONFIG; } } - return configs; + return modes; } + /** - * This is the driver specific part of the createNewScreen entry point. - * - * \todo maybe fold this into intelInitDriver + * 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. * - * \return the __GLcontextModes supported by this driver + * \return A pointer to a \c __DRIscreenPrivate on success, or \c NULL on + * failure. */ -static const __DRIconfig **intelInitScreen(__DRIscreenPrivate *psp) +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) { -#ifdef I915 - static const __DRIversion ddx_expected = { 1, 5, 0 }; -#else - static const __DRIversion ddx_expected = { 1, 6, 0 }; -#endif + __DRIscreenPrivate *psp; + static const __DRIversion ddx_expected = { 1, 7, 0 }; static const __DRIversion dri_expected = { 4, 0, 0 }; - static const __DRIversion drm_expected = { 1, 5, 0 }; - I830DRIPtr dri_priv = (I830DRIPtr) psp->pDevPriv; + static const __DRIversion drm_expected = { 1, 7, 0 }; + + dri_interface = interface; if (!driCheckDriDdxDrmVersions2("i915", - &psp->dri_version, &dri_expected, - &psp->ddx_version, &ddx_expected, - &psp->drm_version, &drm_expected)) { + dri_version, &dri_expected, + ddx_version, &ddx_expected, + drm_version, &drm_expected)) { return NULL; } - /* 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; + 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); } - /* parse information in __driConfigOptions */ - driParseOptionInfo(&intelScreen->optionCache, - __driConfigOptions, __driNConfigOptions); - - 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)); + return (void *) psp; } -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, -}; diff --git a/src/gallium/winsys/dri/intel/intel_screen.h b/src/gallium/winsys/dri/intel/intel_screen.h index 5a3ae1dc0f..8036917903 100644 --- a/src/gallium/winsys/dri/intel/intel_screen.h +++ b/src/gallium/winsys/dri/intel/intel_screen.h @@ -32,7 +32,7 @@ #include "i830_common.h" #include "xmlconfig.h" #include "intel_drm/ws_dri_bufpool.h" -#include "state_tracker/st_context.h" + #include "pipe/p_compiler.h" #include "intel_drm/intel_be_device.h" @@ -116,7 +116,5 @@ intelCreateContext(const __GLcontextModes * visual, __DRIcontextPrivate * driContextPriv, void *sharedContextPrivate); -extern void -intelInitExtensions(struct intel_context *intel, GLboolean enable_imaging); #endif diff --git a/src/gallium/winsys/dri/intel/intel_swapbuffers.c b/src/gallium/winsys/dri/intel/intel_swapbuffers.c index 8b17154cf9..7f3babd98e 100644 --- a/src/gallium/winsys/dri/intel/intel_swapbuffers.c +++ b/src/gallium/winsys/dri/intel/intel_swapbuffers.c @@ -78,8 +78,7 @@ intelDisplaySurface(__DRIdrawablePrivate *dPriv, * current context (which is what intelScreenContext should return) might * not get a contended lock and thus cliprects not updated (tests/manywin) */ - if (!intel->driScreen->dri2.enabled && - intel_context(dPriv->driContextPriv) != intel) + if (intel_context(dPriv->driContextPriv) != intel) DRI_VALIDATE_DRAWABLE_INFO(intel->driScreen, dPriv); diff --git a/src/glx/x11/Makefile b/src/glx/x11/Makefile index bb4d3cc5ee..b404727f08 100644 --- a/src/glx/x11/Makefile +++ b/src/glx/x11/Makefile @@ -10,14 +10,12 @@ 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 \ @@ -31,16 +29,13 @@ SOURCES = \ xfont.c \ glx_pbuffer.c \ glx_query.c \ - dri_common.c \ + glx_texture_compression.c \ dri_glx.c \ - XF86dri.c \ - glxhash.c \ - dri2_glx.c \ - dri2.c + XF86dri.c include $(TOP)/src/mesa/sources -MESA_ASM_API = $(addprefix $(TOP)/src/mesa/, $(ASM_API)) +MESA_GLAPI_ASM_SOURCES = $(addprefix $(TOP)/src/mesa/, $(GLAPI_ASM_SOURCES)) MESA_GLAPI_SOURCES = $(addprefix $(TOP)/src/mesa/, $(GLAPI_SOURCES)) MESA_GLAPI_OBJECTS = $(addprefix $(TOP)/src/mesa/, $(GLAPI_OBJECTS)) @@ -50,10 +45,9 @@ INCLUDES = -I. \ -I$(TOP)/include \ -I$(TOP)/include/GL/internal \ -I$(TOP)/src/mesa \ - -I$(TOP)/src/mesa/glapi \ -I$(TOP)/src/mesa/main \ + -I$(TOP)/src/mesa/glapi \ $(LIBDRM_CFLAGS) \ - $(DRI2PROTO_CFLAGS) \ $(X11_INCLUDES) @@ -71,28 +65,29 @@ 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)' -ldflags '$(LDFLAGS)' \ + $(TOP)/bin/mklib -o $(GL_LIB) -linker '$(CC)' \ -major 1 -minor 2 $(MKLIB_OPTIONS) \ -install $(TOP)/$(LIB_DIR) $(GL_LIB_DEPS) $(OBJECTS) -depend: $(SOURCES) $(MESA_GLAPI_SOURCES) $(MESA_ASM_API) Makefile +depend: $(SOURCES) $(MESA_GLAPI_SOURCES) $(MESA_GLAPI_ASM_SOURCES) Makefile + rm -f depend touch depend $(MKDEP) $(MKDEP_OPTIONS) $(INCLUDES) $(SOURCES) \ - $(MESA_GLAPI_SOURCES) $(MESA_ASM_API) + $(MESA_GLAPI_SOURCES) $(MESA_GLAPI_ASM_SOURCES) # Emacs tags tags: etags `find . -name \*.[ch]` `find $(TOP)/include` -install: $(TOP)/$(LIB_DIR)/$(GL_LIB_NAME) - $(MAKE) -C $(TOP)/src/mesa install-libgl +# Dummy install target +install: # Remove .o and backup files clean: -rm -f $(TOP)/$(LIB_DIR)/libGL.so* -rm -f *.o *~ - -rm -f depend depend.bak + -rm -f depend include depend diff --git a/src/glx/x11/XF86dri.c b/src/glx/x11/XF86dri.c index ba38949c0b..9919a40977 100644 --- a/src/glx/x11/XF86dri.c +++ b/src/glx/x11/XF86dri.c @@ -374,9 +374,10 @@ PUBLIC Bool XF86DRICreateContext(dpy, screen, visual, context, hHWContext) context, hHWContext ); } -PUBLIC GLboolean XF86DRIDestroyContext(Display *dpy, int screen, - XID context ) +PUBLIC GLboolean XF86DRIDestroyContext( __DRInativeDisplay * ndpy, int screen, + __DRIid context ) { + Display * const dpy = (Display *) ndpy; XExtDisplayInfo *info = find_display (dpy); xXF86DRIDestroyContextReq *req; @@ -395,9 +396,10 @@ PUBLIC GLboolean XF86DRIDestroyContext(Display *dpy, int screen, return True; } -PUBLIC GLboolean XF86DRICreateDrawable(Display *dpy, int screen, - XID drawable, drm_drawable_t * hHWDrawable ) +PUBLIC GLboolean XF86DRICreateDrawable( __DRInativeDisplay * ndpy, int screen, + __DRIid drawable, drm_drawable_t * hHWDrawable ) { + Display * const dpy = (Display *) ndpy; XExtDisplayInfo *info = find_display (dpy); xXF86DRICreateDrawableReply rep; xXF86DRICreateDrawableReq *req; @@ -424,36 +426,16 @@ PUBLIC GLboolean XF86DRICreateDrawable(Display *dpy, int screen, return True; } -static int noopErrorHandler(Display *dpy, XErrorEvent *xerr) -{ - return 0; -} - -PUBLIC GLboolean XF86DRIDestroyDrawable(Display *dpy, int screen, - XID drawable ) +PUBLIC GLboolean XF86DRIDestroyDrawable( __DRInativeDisplay * ndpy, int screen, + __DRIid 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; @@ -462,9 +444,6 @@ PUBLIC GLboolean XF86DRIDestroyDrawable(Display *dpy, int screen, req->drawable = drawable; UnlockDisplay(dpy); SyncHandle(); - - XSetErrorHandler(oldXErrorHandler); - TRACE("DestroyDrawable... return True"); return True; } diff --git a/src/glx/x11/dri2.c b/src/glx/x11/dri2.c deleted file mode 100644 index e7044ab424..0000000000 --- a/src/glx/x11/dri2.c +++ /dev/null @@ -1,252 +0,0 @@ -/* - * Copyright © 2008 Red Hat, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Soft- - * ware"), to deal in the Software without restriction, including without - * limitation the rights to use, copy, modify, merge, publish, distribute, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, provided that the above copyright - * notice(s) and this permission notice appear in all copies of the Soft- - * ware and that both the above copyright notice(s) and this permission - * notice appear in supporting documentation. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL- - * ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY - * RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN - * THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSE- - * QUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, - * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER - * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFOR- - * MANCE OF THIS SOFTWARE. - * - * Except as contained in this notice, the name of a copyright holder shall - * not be used in advertising or otherwise to promote the sale, use or - * other dealings in this Software without prior written authorization of - * the copyright holder. - * - * Authors: - * Kristian Høgsberg (krh@redhat.com) - */ - - -#define NEED_REPLIES -#include -#include -#include -#include -#include "glheader.h" -#include "xf86drm.h" -#include "dri2.h" - -static char dri2ExtensionName[] = DRI2_NAME; -static XExtensionInfo *dri2Info; -static XEXT_GENERATE_CLOSE_DISPLAY (DRI2CloseDisplay, dri2Info) -static /* const */ XExtensionHooks dri2ExtensionHooks = { - NULL, /* create_gc */ - NULL, /* copy_gc */ - NULL, /* flush_gc */ - NULL, /* free_gc */ - NULL, /* create_font */ - NULL, /* free_font */ - DRI2CloseDisplay, /* close_display */ - NULL, /* wire_to_event */ - NULL, /* event_to_wire */ - NULL, /* error */ - NULL, /* error_string */ -}; - -static XEXT_GENERATE_FIND_DISPLAY (DRI2FindDisplay, dri2Info, - dri2ExtensionName, - &dri2ExtensionHooks, - 0, NULL) - -Bool DRI2QueryExtension(Display *dpy, int *eventBase, int *errorBase) -{ - XExtDisplayInfo *info = DRI2FindDisplay(dpy); - - if (XextHasExtension(info)) { - *eventBase = info->codes->first_event; - *errorBase = info->codes->first_error; - return True; - } - - return False; -} - -Bool DRI2QueryVersion(Display *dpy, int *major, int *minor) -{ - XExtDisplayInfo *info = DRI2FindDisplay (dpy); - xDRI2QueryVersionReply rep; - xDRI2QueryVersionReq *req; - - XextCheckExtension (dpy, info, dri2ExtensionName, False); - - LockDisplay(dpy); - GetReq(DRI2QueryVersion, req); - req->reqType = info->codes->major_opcode; - req->dri2ReqType = X_DRI2QueryVersion; - req->majorVersion = DRI2_MAJOR; - req->minorVersion = DRI2_MINOR; - if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { - UnlockDisplay(dpy); - SyncHandle(); - return False; - } - *major = rep.majorVersion; - *minor = rep.minorVersion; - UnlockDisplay(dpy); - SyncHandle(); - - return True; -} - -Bool DRI2Connect(Display *dpy, int screen, - char **driverName, char **busId, unsigned int *sareaHandle) -{ - XExtDisplayInfo *info = DRI2FindDisplay(dpy); - xDRI2ConnectReply rep; - xDRI2ConnectReq *req; - - XextCheckExtension (dpy, info, dri2ExtensionName, False); - - LockDisplay(dpy); - GetReq(DRI2Connect, req); - req->reqType = info->codes->major_opcode; - req->dri2ReqType = X_DRI2Connect; - req->screen = screen; - if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { - UnlockDisplay(dpy); - SyncHandle(); - return False; - } - - *sareaHandle = rep.sareaHandle; - - *driverName = Xmalloc(rep.driverNameLength + 1); - if (*driverName == NULL) { - _XEatData(dpy, - ((rep.driverNameLength + 3) & ~3) + - ((rep.busIdLength + 3) & ~3)); - UnlockDisplay(dpy); - SyncHandle(); - return False; - } - _XReadPad(dpy, *driverName, rep.driverNameLength); - (*driverName)[rep.driverNameLength] = '\0'; - - *busId = Xmalloc(rep.busIdLength + 1); - if (*busId == NULL) { - Xfree(*driverName); - _XEatData(dpy, ((rep.busIdLength + 3) & ~3)); - UnlockDisplay(dpy); - SyncHandle(); - return False; - } - _XReadPad(dpy, *busId, rep.busIdLength); - (*busId)[rep.busIdLength] = '\0'; - - UnlockDisplay(dpy); - SyncHandle(); - - return rep.sareaHandle != 0; -} - -Bool DRI2AuthConnection(Display *dpy, int screen, drm_magic_t magic) -{ - XExtDisplayInfo *info = DRI2FindDisplay(dpy); - xDRI2AuthConnectionReq *req; - xDRI2AuthConnectionReply rep; - - XextCheckExtension (dpy, info, dri2ExtensionName, False); - - LockDisplay(dpy); - GetReq(DRI2AuthConnection, req); - req->reqType = info->codes->major_opcode; - req->dri2ReqType = X_DRI2AuthConnection; - req->screen = screen; - req->magic = magic; - rep.authenticated = 0; - if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { - UnlockDisplay(dpy); - SyncHandle(); - return False; - } - UnlockDisplay(dpy); - SyncHandle(); - - return rep.authenticated; -} - -Bool DRI2CreateDrawable(Display *dpy, XID drawable, - unsigned int *handle, unsigned int *head) -{ - XExtDisplayInfo *info = DRI2FindDisplay(dpy); - xDRI2CreateDrawableReply rep; - xDRI2CreateDrawableReq *req; - - XextCheckExtension (dpy, info, dri2ExtensionName, False); - - LockDisplay(dpy); - GetReq(DRI2CreateDrawable, req); - req->reqType = info->codes->major_opcode; - req->dri2ReqType = X_DRI2CreateDrawable; - req->drawable = drawable; - if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { - UnlockDisplay(dpy); - SyncHandle(); - return False; - } - UnlockDisplay(dpy); - SyncHandle(); - - *handle = rep.handle; - *head = rep.head; - - return True; -} - -void DRI2DestroyDrawable(Display *dpy, XID drawable) -{ - XExtDisplayInfo *info = DRI2FindDisplay(dpy); - xDRI2DestroyDrawableReq *req; - - XextSimpleCheckExtension (dpy, info, dri2ExtensionName); - - XSync(dpy, GL_FALSE); - - LockDisplay(dpy); - GetReq(DRI2DestroyDrawable, req); - req->reqType = info->codes->major_opcode; - req->dri2ReqType = X_DRI2DestroyDrawable; - req->drawable = drawable; - UnlockDisplay(dpy); - SyncHandle(); -} - -Bool DRI2ReemitDrawableInfo(Display *dpy, XID drawable, unsigned int *head) -{ - XExtDisplayInfo *info = DRI2FindDisplay(dpy); - xDRI2ReemitDrawableInfoReply rep; - xDRI2ReemitDrawableInfoReq *req; - - XextCheckExtension (dpy, info, dri2ExtensionName, False); - - LockDisplay(dpy); - GetReq(DRI2ReemitDrawableInfo, req); - req->reqType = info->codes->major_opcode; - req->dri2ReqType = X_DRI2ReemitDrawableInfo; - req->drawable = drawable; - if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { - UnlockDisplay(dpy); - SyncHandle(); - return False; - } - UnlockDisplay(dpy); - SyncHandle(); - - *head = rep.head; - - return True; -} diff --git a/src/glx/x11/dri2.h b/src/glx/x11/dri2.h deleted file mode 100644 index 1dfd0448b2..0000000000 --- a/src/glx/x11/dri2.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright © 2007,2008 Red Hat, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Soft- - * ware"), to deal in the Software without restriction, including without - * limitation the rights to use, copy, modify, merge, publish, distribute, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, provided that the above copyright - * notice(s) and this permission notice appear in all copies of the Soft- - * ware and that both the above copyright notice(s) and this permission - * notice appear in supporting documentation. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL- - * ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY - * RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN - * THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSE- - * QUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, - * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER - * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFOR- - * MANCE OF THIS SOFTWARE. - * - * Except as contained in this notice, the name of a copyright holder shall - * not be used in advertising or otherwise to promote the sale, use or - * other dealings in this Software without prior written authorization of - * the copyright holder. - * - * Authors: - * Kristian Høgsberg (krh@redhat.com) - */ - -#ifndef _DRI2_H_ -#define _DRI2_H_ - -extern Bool -DRI2QueryExtension(Display *display, int *eventBase, int *errorBase); -extern Bool -DRI2QueryVersion(Display *display, int *major, int *minor); -extern Bool -DRI2Connect(Display *display, int screen, - char **driverName, char **busId, unsigned int *sareaHandle); -extern Bool -DRI2AuthConnection(Display *display, int screen, drm_magic_t magic); -extern Bool -DRI2CreateDrawable(Display *display, XID drawable, - unsigned int *handle, unsigned int *head); -extern void -DRI2DestroyDrawable(Display *display, XID handle); -extern Bool -DRI2ReemitDrawableInfo(Display *dpy, XID handle, unsigned int *head); - -#endif diff --git a/src/glx/x11/dri2_glx.c b/src/glx/x11/dri2_glx.c deleted file mode 100644 index b679c72c10..0000000000 --- a/src/glx/x11/dri2_glx.c +++ /dev/null @@ -1,371 +0,0 @@ -/* - * Copyright © 2008 Red Hat, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Soft- - * ware"), to deal in the Software without restriction, including without - * limitation the rights to use, copy, modify, merge, publish, distribute, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, provided that the above copyright - * notice(s) and this permission notice appear in all copies of the Soft- - * ware and that both the above copyright notice(s) and this permission - * notice appear in supporting documentation. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL- - * ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY - * RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN - * THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSE- - * QUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, - * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER - * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFOR- - * MANCE OF THIS SOFTWARE. - * - * Except as contained in this notice, the name of a copyright holder shall - * not be used in advertising or otherwise to promote the sale, use or - * other dealings in this Software without prior written authorization of - * the copyright holder. - * - * Authors: - * Kristian Høgsberg (krh@redhat.com) - */ - -#ifdef GLX_DIRECT_RENDERING - -#include -#include -#include -#include "glheader.h" -#include "glxclient.h" -#include "glcontextmodes.h" -#include "xf86dri.h" -#include "sarea.h" -#include -#include -#include -#include "xf86drm.h" -#include "dri2.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; - __GLXscreenConfigs *psc; -}; - -static void dri2DestroyContext(__GLXDRIcontext *context, - __GLXscreenConfigs *psc, Display *dpy) -{ - __GLXDRIcontextPrivate *pcp = (__GLXDRIcontextPrivate *) context; - const __DRIcoreExtension *core = pcp->psc->core; - - (*core->destroyContext)(pcp->driContext); - - Xfree(pcp); -} - -static Bool dri2BindContext(__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 dri2UnbindContext(__GLXDRIcontext *context) -{ - __GLXDRIcontextPrivate *pcp = (__GLXDRIcontextPrivate *) context; - const __DRIcoreExtension *core = pcp->psc->core; - - (*core->unbindContext)(pcp->driContext); -} - -static __GLXDRIcontext *dri2CreateContext(__GLXscreenConfigs *psc, - const __GLcontextModes *mode, - GLXContext gc, - GLXContext shareList, int renderType) -{ - __GLXDRIcontextPrivate *pcp, *pcp_shared; - __GLXDRIconfigPrivate *config = (__GLXDRIconfigPrivate *) mode; - const __DRIcoreExtension *core = psc->core; - __DRIcontext *shared = NULL; - - if (shareList) { - pcp_shared = (__GLXDRIcontextPrivate *) shareList->driContext; - shared = pcp_shared->driContext; - } - - pcp = Xmalloc(sizeof *pcp); - if (pcp == NULL) - return NULL; - - pcp->psc = psc; - pcp->driContext = - (*core->createNewContext)(psc->__driScreen, - config->driConfig, shared, pcp); - gc->__driContext = pcp->driContext; - - if (pcp->driContext == NULL) { - Xfree(pcp); - return NULL; - } - - pcp->base.destroyContext = dri2DestroyContext; - pcp->base.bindContext = dri2BindContext; - pcp->base.unbindContext = dri2UnbindContext; - - return &pcp->base; -} - -static void dri2DestroyDrawable(__GLXDRIdrawable *pdraw) -{ - const __DRIcoreExtension *core = pdraw->psc->core; - - (*core->destroyDrawable)(pdraw->driDrawable); - DRI2DestroyDrawable(pdraw->psc->dpy, pdraw->drawable); - Xfree(pdraw); -} - -static __GLXDRIdrawable *dri2CreateDrawable(__GLXscreenConfigs *psc, - XID xDrawable, - GLXDrawable drawable, - const __GLcontextModes *modes) -{ - __GLXDRIdrawable *pdraw; - __GLXDRIconfigPrivate *config = (__GLXDRIconfigPrivate *) modes; - unsigned int handle, head; - const __DRIcoreExtension *core = psc->core; - - pdraw = Xmalloc(sizeof(*pdraw)); - if (!pdraw) - return NULL; - - pdraw->destroyDrawable = dri2DestroyDrawable; - pdraw->xDrawable = xDrawable; - pdraw->drawable = drawable; - pdraw->psc = psc; - - fprintf(stderr, "calling DRI2CreateDrawable, XID 0x%lx, GLX ID 0x%lx\n", - xDrawable, drawable); - - if (!DRI2CreateDrawable(psc->dpy, xDrawable, &handle, &head)) { - Xfree(pdraw); - return NULL; - } - - fprintf(stderr, "success, head 0x%x, handle 0x%x\n", head, handle); - - /* Create a new drawable */ - pdraw->driDrawable = - (*core->createNewDrawable)(psc->__driScreen, - config->driConfig, - handle, - head, - pdraw); - - if (!pdraw->driDrawable) { - DRI2DestroyDrawable(psc->dpy, drawable); - Xfree(pdraw); - return NULL; - } - - return pdraw; -} - -static void dri2DestroyScreen(__GLXscreenConfigs *psc) -{ - /* Free the direct rendering per screen data */ - (*psc->core->destroyScreen)(psc->__driScreen); - drmClose(psc->fd); - psc->__driScreen = NULL; -} - - -static void dri2ReemitDrawableInfo(__DRIdrawable *draw, unsigned int *tail, - void *loaderPrivate) -{ - __GLXDRIdrawable *pdraw = loaderPrivate; - - DRI2ReemitDrawableInfo(pdraw->psc->dpy, pdraw->drawable, tail); -} - -static void dri2PostDamage(__DRIdrawable *draw, - struct drm_clip_rect *rects, - int numRects, void *loaderPrivate) -{ - XRectangle *xrects; - XserverRegion region; - __GLXDRIdrawable *glxDraw = loaderPrivate; - __GLXscreenConfigs *psc = glxDraw->psc; - Display *dpy = psc->dpy; - int i; - - xrects = malloc(sizeof(XRectangle) * numRects); - if (xrects == NULL) - return; - - for (i = 0; i < numRects; i++) { - xrects[i].x = rects[i].x1; - xrects[i].y = rects[i].y1; - xrects[i].width = rects[i].x2 - rects[i].x1; - xrects[i].height = rects[i].y2 - rects[i].y1; - } - region = XFixesCreateRegion(dpy, xrects, numRects); - free(xrects); - XDamageAdd(dpy, glxDraw->xDrawable, region); - XFixesDestroyRegion(dpy, region); -} - -static const __DRIloaderExtension dri2LoaderExtension = { - { __DRI_LOADER, __DRI_LOADER_VERSION }, - dri2ReemitDrawableInfo, - dri2PostDamage -}; - -static const __DRIextension *loader_extensions[] = { - &dri2LoaderExtension.base, - &systemTimeExtension.base, - NULL -}; - -static __GLXDRIscreen *dri2CreateScreen(__GLXscreenConfigs *psc, int screen, - __GLXdisplayPrivate *priv) -{ - const __DRIconfig **driver_configs; - const __DRIextension **extensions; - __GLXDRIscreen *psp; - unsigned int sareaHandle; - char *driverName, *busID; - drm_magic_t magic; - 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 (!DRI2Connect(psc->dpy, screen, &driverName, &busID, &sareaHandle)) - return NULL; - - psc->driver = driOpenDriver(driverName); - if (psc->driver == NULL) - goto handle_error; - - extensions = dlsym(psc->driver, __DRI_DRIVER_EXTENSIONS); - if (extensions == NULL) { - ErrorMessageF("driver exports no extensions (%s)\n", dlerror()); - goto handle_error; - } - - for (i = 0; extensions[i]; i++) { - if (strcmp(extensions[i]->name, __DRI_CORE) == 0) - psc->core = (__DRIcoreExtension *) extensions[i]; - } - - if (psc->core == NULL) { - ErrorMessageF("core dri extension not found\n"); - goto handle_error; - } - - psc->fd = drmOpen(NULL, busID); - if (psc->fd < 0) { - ErrorMessageF("failed to open drm device: %s\n", strerror(errno)); - return NULL; - } - - if (drmGetMagic(psc->fd, &magic)) - return NULL; - - if (!DRI2AuthConnection(psc->dpy, screen, magic)) { - ErrorMessageF("failed to authenticate drm access\n"); - return NULL; - } - - psc->__driScreen = - psc->core->createNewScreen(screen, psc->fd, sareaHandle, - loader_extensions, &driver_configs, psc); - if (psc->__driScreen == NULL) { - ErrorMessageF("failed to create dri screen\n"); - return NULL; - } - - driBindExtensions(psc); - - psc->configs = driConvertConfigs(psc->core, psc->configs, driver_configs); - psc->visuals = driConvertConfigs(psc->core, psc->visuals, driver_configs); - - psp->destroyScreen = dri2DestroyScreen; - psp->createContext = dri2CreateContext; - psp->createDrawable = dri2CreateDrawable; - - Xfree(driverName); - Xfree(busID); - - return psp; - - handle_error: - Xfree(driverName); - Xfree(busID); - - /* FIXME: clean up here */ - - return NULL; -} - -/* Called from __glXFreeDisplayPrivate. - */ -static void dri2DestroyDisplay(__GLXDRIdisplay *dpy) -{ - Xfree(dpy); -} - -/* - * Allocate, initialize and return a __DRIdisplayPrivate object. - * This is called from __glXInitialize() when we are given a new - * display pointer. - */ -_X_HIDDEN __GLXDRIdisplay *dri2CreateDisplay(Display *dpy) -{ - __GLXDRIdisplayPrivate *pdp; - int eventBase, errorBase; - - if (!DRI2QueryExtension(dpy, &eventBase, &errorBase)) - return NULL; - - pdp = Xmalloc(sizeof *pdp); - if (pdp == NULL) - return NULL; - - if (!DRI2QueryVersion(dpy, &pdp->driMajor, &pdp->driMinor)) { - Xfree(pdp); - return NULL; - } - - pdp->driPatch = 0; - - pdp->base.destroyDisplay = dri2DestroyDisplay; - pdp->base.createScreen = dri2CreateScreen; - - return &pdp->base; -} - -#endif /* GLX_DIRECT_RENDERING */ diff --git a/src/glx/x11/dri_common.c b/src/glx/x11/dri_common.c deleted file mode 100644 index b159d193a5..0000000000 --- a/src/glx/x11/dri_common.c +++ /dev/null @@ -1,399 +0,0 @@ -/* - * Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. - * Copyright © 2008 Red Hat, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Soft- - * ware"), to deal in the Software without restriction, including without - * limitation the rights to use, copy, modify, merge, publish, distribute, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, provided that the above copyright - * notice(s) and this permission notice appear in all copies of the Soft- - * ware and that both the above copyright notice(s) and this permission - * notice appear in supporting documentation. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL- - * ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY - * RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN - * THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSE- - * QUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, - * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER - * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFOR- - * MANCE OF THIS SOFTWARE. - * - * Except as contained in this notice, the name of a copyright holder shall - * not be used in advertising or otherwise to promote the sale, use or - * other dealings in this Software without prior written authorization of - * the copyright holder. - * - * Authors: - * Kevin E. Martin - * Brian Paul - * Kristian Høgsberg (krh@redhat.com) - */ - -#ifdef GLX_DIRECT_RENDERING - -#include -#include -#include "glheader.h" -#include "glxclient.h" -#include "glcontextmodes.h" -#include "dri_common.h" - -#ifndef RTLD_NOW -#define RTLD_NOW 0 -#endif -#ifndef RTLD_GLOBAL -#define RTLD_GLOBAL 0 -#endif - -_X_HIDDEN 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". - */ -_X_HIDDEN 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); - } -} - -#ifndef DEFAULT_DRIVER_DIR -/* this is normally defined in Mesa/configs/default with DRI_DRIVER_SEARCH_PATH */ -#define DEFAULT_DRIVER_DIR "/usr/local/lib/dri" -#endif - -/** - * 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. - */ -_X_HIDDEN void *driOpenDriver(const char *driverName) -{ - void *glhandle, *handle; - const char *libPaths, *p, *next; - char realDriverName[200]; - int len; - - /* Attempt to make sure libGL symbols will be visible to the driver */ - glhandle = dlopen("libGL.so.1", RTLD_NOW | RTLD_GLOBAL); - - libPaths = NULL; - 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 == NULL) - libPaths = DEFAULT_DRIVER_DIR; - - handle = NULL; - for (p = libPaths; *p; p = next) { - next = strchr(p, ':'); - if (next == NULL) { - len = strlen(p); - next = p + len; - } else { - len = next - p; - next++; - } - -#ifdef GLX_USE_TLS - snprintf(realDriverName, sizeof realDriverName, - "%.*s/tls/%s_dri.so", len, p, driverName); - InfoMessageF("OpenDriver: trying %s\n", realDriverName); - handle = dlopen(realDriverName, RTLD_NOW | RTLD_GLOBAL); -#endif - - if ( handle == NULL ) { - snprintf(realDriverName, sizeof realDriverName, - "%.*s/%s_dri.so", len, p, driverName); - InfoMessageF("OpenDriver: trying %s\n", realDriverName); - handle = dlopen(realDriverName, RTLD_NOW | RTLD_GLOBAL); - } - - if ( handle != NULL ) - break; - else - ErrorMessageF("dlopen %s failed (%s)\n", realDriverName, dlerror()); - } - - if (!handle) - ErrorMessageF("unable to load driver: %s_dri.so\n", driverName); - - if (glhandle) - dlclose(glhandle); - - return handle; -} - -_X_HIDDEN const __DRIsystemTimeExtension systemTimeExtension = { - { __DRI_SYSTEM_TIME, __DRI_SYSTEM_TIME_VERSION }, - __glXGetUST, - __driGetMscRateOML -}; - -#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), -#if 0 - __ATTRIB(__DRI_ATTRIB_TRANSPARENT_TYPE, transparentPixel), - __ATTRIB(__DRI_ATTRIB_TRANSPARENT_INDEX_VALUE, transparentIndex), - __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_RED_MASK, redMask), - __ATTRIB(__DRI_ATTRIB_GREEN_MASK, greenMask), - __ATTRIB(__DRI_ATTRIB_BLUE_MASK, blueMask), - __ATTRIB(__DRI_ATTRIB_ALPHA_MASK, alphaMask), -#endif - __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), -#if 0 - __ATTRIB(__DRI_ATTRIB_SWAP_METHOD, swapMethod), -#endif - __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_YINVERTED, yInverted), -}; - -#define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0])) - -static int -scalarEqual(__GLcontextModes *mode, unsigned int attrib, unsigned int value) -{ - unsigned int glxValue; - int i; - - for (i = 0; i < ARRAY_SIZE(attribMap); i++) - if (attribMap[i].attrib == attrib) { - glxValue = *(unsigned int *) ((char *) mode + attribMap[i].offset); - return glxValue == GLX_DONT_CARE || glxValue == value; - } - - return GL_TRUE; /* Is a non-existing attribute equal to value? */ -} - -static int -driConfigEqual(const __DRIcoreExtension *core, - __GLcontextModes *modes, const __DRIconfig *driConfig) -{ - unsigned int attrib, value, glxValue; - int i; - - i = 0; - while (core->indexConfigAttrib(driConfig, i++, &attrib, &value)) { - switch (attrib) { - case __DRI_ATTRIB_RENDER_TYPE: - glxValue = 0; - if (value & __DRI_ATTRIB_RGBA_BIT) { - glxValue |= GLX_RGBA_BIT; - } else if (value & __DRI_ATTRIB_COLOR_INDEX_BIT) { - glxValue |= GLX_COLOR_INDEX_BIT; - } - if (glxValue != modes->renderType) - return GL_FALSE; - break; - - case __DRI_ATTRIB_CONFIG_CAVEAT: - if (value & __DRI_ATTRIB_NON_CONFORMANT_CONFIG) - glxValue = GLX_NON_CONFORMANT_CONFIG; - else if (value & __DRI_ATTRIB_SLOW_BIT) - glxValue = GLX_SLOW_CONFIG; - else - glxValue = GLX_NONE; - if (glxValue != modes->visualRating) - return GL_FALSE; - break; - - case __DRI_ATTRIB_BIND_TO_TEXTURE_TARGETS: - glxValue = 0; - if (value & __DRI_ATTRIB_TEXTURE_1D_BIT) - glxValue |= GLX_TEXTURE_1D_BIT_EXT; - if (value & __DRI_ATTRIB_TEXTURE_2D_BIT) - glxValue |= GLX_TEXTURE_2D_BIT_EXT; - if (value & __DRI_ATTRIB_TEXTURE_RECTANGLE_BIT) - glxValue |= GLX_TEXTURE_RECTANGLE_BIT_EXT; - if (modes->bindToTextureTargets != GLX_DONT_CARE && - glxValue != modes->bindToTextureTargets) - return GL_FALSE; - break; - - default: - if (!scalarEqual(modes, attrib, value)) - return GL_FALSE; - } - } - - return GL_TRUE; -} - -static __GLcontextModes * -createDriMode(const __DRIcoreExtension *core, - __GLcontextModes *modes, const __DRIconfig **driConfigs) -{ - __GLXDRIconfigPrivate *config; - int i; - - for (i = 0; driConfigs[i]; i++) { - if (driConfigEqual(core, modes, driConfigs[i])) - break; - } - - if (driConfigs[i] == NULL) - return NULL; - - config = Xmalloc(sizeof *config); - if (config == NULL) - return NULL; - - config->modes = *modes; - config->driConfig = driConfigs[i]; - - return &config->modes; -} - -_X_HIDDEN __GLcontextModes * -driConvertConfigs(const __DRIcoreExtension *core, - __GLcontextModes *modes, const __DRIconfig **configs) -{ - __GLcontextModes head, *tail, *m; - - tail = &head; - head.next = NULL; - for (m = modes; m; m = m->next) { - tail->next = createDriMode(core, m, configs); - if (tail->next == NULL) { - /* no matching dri config for m */ - continue; - } - - - tail = tail->next; - } - - _gl_context_modes_destroy(modes); - - return head.next; -} - -_X_HIDDEN void -driBindExtensions(__GLXscreenConfigs *psc) -{ - const __DRIextension **extensions; - int i; - - extensions = psc->core->getExtensions(psc->__driScreen); - - for (i = 0; extensions[i]; i++) { -#ifdef __DRI_COPY_SUB_BUFFER - if (strcmp(extensions[i]->name, __DRI_COPY_SUB_BUFFER) == 0) { - psc->copySubBuffer = (__DRIcopySubBufferExtension *) extensions[i]; - __glXEnableDirectExtension(psc, "GLX_MESA_copy_sub_buffer_bit"); - } -#endif - -#ifdef __DRI_SWAP_CONTROL - if (strcmp(extensions[i]->name, __DRI_SWAP_CONTROL) == 0) { - psc->swapControl = (__DRIswapControlExtension *) extensions[i]; - __glXEnableDirectExtension(psc, "GLX_SGI_swap_control"); - __glXEnableDirectExtension(psc, "GLX_MESA_swap_control"); - } -#endif - -#ifdef __DRI_ALLOCATE - if (strcmp(extensions[i]->name, __DRI_ALLOCATE) == 0) { - psc->allocate = (__DRIallocateExtension *) extensions[i]; - __glXEnableDirectExtension(psc, "GLX_MESA_allocate_memory"); - } -#endif - -#ifdef __DRI_FRAME_TRACKING - if (strcmp(extensions[i]->name, __DRI_FRAME_TRACKING) == 0) { - psc->frameTracking = (__DRIframeTrackingExtension *) extensions[i]; - __glXEnableDirectExtension(psc, "GLX_MESA_swap_frame_usage"); - } -#endif - -#ifdef __DRI_MEDIA_STREAM_COUNTER - if (strcmp(extensions[i]->name, __DRI_MEDIA_STREAM_COUNTER) == 0) { - psc->msc = (__DRImediaStreamCounterExtension *) extensions[i]; - __glXEnableDirectExtension(psc, "GLX_SGI_video_sync"); - } -#endif - -#ifdef __DRI_SWAP_BUFFER_COUNTER - /* No driver supports this at this time and the extension is - * not defined in dri_interface.h. Will enable - * GLX_OML_sync_control if implemented. */ -#endif - -#ifdef __DRI_READ_DRAWABLE - if (strcmp(extensions[i]->name, __DRI_READ_DRAWABLE) == 0) { - __glXEnableDirectExtension(psc, "GLX_SGI_make_current_read"); - } -#endif - -#ifdef __DRI_TEX_BUFFER - if (strcmp(extensions[i]->name, __DRI_TEX_BUFFER) == 0) { - psc->texBuffer = (__DRItexBufferExtension *) extensions[i]; - __glXEnableDirectExtension(psc, "GLX_EXT_texture_from_pixmap"); - } -#endif - - /* Ignore unknown extensions */ - } -} - -#endif /* GLX_DIRECT_RENDERING */ diff --git a/src/glx/x11/dri_common.h b/src/glx/x11/dri_common.h deleted file mode 100644 index 3556510335..0000000000 --- a/src/glx/x11/dri_common.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. - * Copyright © 2008 Red Hat, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Soft- - * ware"), to deal in the Software without restriction, including without - * limitation the rights to use, copy, modify, merge, publish, distribute, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, provided that the above copyright - * notice(s) and this permission notice appear in all copies of the Soft- - * ware and that both the above copyright notice(s) and this permission - * notice appear in supporting documentation. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL- - * ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY - * RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN - * THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSE- - * QUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, - * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER - * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFOR- - * MANCE OF THIS SOFTWARE. - * - * Except as contained in this notice, the name of a copyright holder shall - * not be used in advertising or otherwise to promote the sale, use or - * other dealings in this Software without prior written authorization of - * the copyright holder. - * - * Authors: - * Kevin E. Martin - * Brian Paul - * Kristian Høgsberg (krh@redhat.com) - */ - -#ifndef _DRI_COMMON_H -#define _DRI_COMMON_H - -typedef struct __GLXDRIconfigPrivateRec __GLXDRIconfigPrivate; - -struct __GLXDRIconfigPrivateRec { - __GLcontextModes modes; - const __DRIconfig *driConfig; -}; - -extern __GLcontextModes * -driConvertConfigs(const __DRIcoreExtension *core, - __GLcontextModes *modes, const __DRIconfig **configs); - -extern const __DRIsystemTimeExtension systemTimeExtension; - -extern void InfoMessageF(const char *f, ...); - -extern void ErrorMessageF(const char *f, ...); - -extern void *driOpenDriver(const char *driverName); - -extern void driBindExtensions(__GLXscreenConfigs *psc); - -#endif /* _DRI_COMMON_H */ diff --git a/src/glx/x11/dri_glx.c b/src/glx/x11/dri_glx.c index 1cb3204d4c..21e07c1935 100644 --- a/src/glx/x11/dri_glx.c +++ b/src/glx/x11/dri_glx.c @@ -34,47 +34,260 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #ifdef GLX_DIRECT_RENDERING -#include -#include -#include +#include +#include +#include +#include #include "glheader.h" #include "glxclient.h" -#include "glcontextmodes.h" #include "xf86dri.h" #include "sarea.h" +#include #include +#include "dri_glx.h" #include -#include -#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; -}; +#include + +#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 and 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; +} + /* * 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 driGetDriverName(Display *dpy, int scrNum, char **driverName) +static Bool GetDriverName(Display *dpy, int scrNum, char **driverName) { int directCapable; Bool b; @@ -104,6 +317,25 @@ static Bool driGetDriverName(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. * @@ -113,7 +345,7 @@ static Bool driGetDriverName(Display *dpy, int scrNum, char **driverName) PUBLIC const char *glXGetScreenDriver (Display *dpy, int scrNum) { static char ret[32]; char *driverName; - if (driGetDriverName(dpy, scrNum, &driverName)) { + if (GetDriverName(dpy, scrNum, &driverName)) { int len; if (!driverName) return NULL; @@ -127,6 +359,7 @@ PUBLIC const char *glXGetScreenDriver (Display *dpy, int scrNum) { return NULL; } + /* * Exported function for obtaining a driver's option list (UTF-8 encoded XML). * @@ -138,532 +371,71 @@ PUBLIC const char *glXGetScreenDriver (Display *dpy, int scrNum) { * * Note: The driver remains opened after this function returns. */ -PUBLIC const char *glXGetDriverConfig (const char *driverName) -{ - void *handle = driOpenDriver (driverName); - if (handle) - return dlsym (handle, "__driConfigOptions"); +PUBLIC const char *glXGetDriverConfig (const char *driverName) { + __DRIdriver *driver = OpenDriver (driverName); + if (driver) + return dlsym (driver->handle, "__driConfigOptions"); else return NULL; } -#ifdef XDAMAGE_1_1_INTERFACE - -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. +/* Called from __glXFreeDisplayPrivate. */ -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) +static void driDestroyDisplay(Display *dpy, void *private) { - 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; + __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); } - - 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. */ -_X_HIDDEN __GLXDRIdisplay *driCreateDisplay(Display *dpy) +void *driCreateDisplay(Display *dpy, __DRIdisplay *pdisp) { - __GLXDRIdisplayPrivate *pdpyp; + const int numScreens = ScreenCount(dpy); + __DRIdisplayPrivate *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; @@ -673,7 +445,7 @@ _X_HIDDEN __GLXDRIdisplay *driCreateDisplay(Display *dpy) return NULL; } - pdpyp = Xmalloc(sizeof *pdpyp); + pdpyp = (__DRIdisplayPrivate *)Xmalloc(sizeof(__DRIdisplayPrivate)); if (!pdpyp) { return NULL; } @@ -682,10 +454,41 @@ _X_HIDDEN __GLXDRIdisplay *driCreateDisplay(Display *dpy) pdpyp->driMinor = minor; pdpyp->driPatch = patch; - pdpyp->base.destroyDisplay = driDestroyDisplay; - pdpyp->base.createScreen = driCreateScreen; + 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; + } + } - return &pdpyp->base; + return (void *)pdpyp; } #endif /* GLX_DIRECT_RENDERING */ diff --git a/src/glx/x11/glcontextmodes.c b/src/glx/x11/glcontextmodes.c index 326c8b2357..788ecf6a3a 100644 --- a/src/glx/x11/glcontextmodes.c +++ b/src/glx/x11/glcontextmodes.c @@ -336,8 +336,7 @@ _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 == GL_TRUE ? GL_TRUE : - GL_FALSE; + *value_return = mode->bindToMipmapTexture; return 0; case GLX_BIND_TO_TEXTURE_TARGETS_EXT: *value_return = mode->bindToTextureTargets; @@ -418,7 +417,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 = GLX_DONT_CARE; + (*next)->bindToTextureTargets = 0; (*next)->yInverted = GLX_DONT_CARE; next = & ((*next)->next); @@ -457,28 +456,19 @@ _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 ) { - __GLcontextModes *m; + while ( modes != NULL ) { + if ( modes->visualID == vid ) { + break; + } - for (m = modes; m != NULL; m = m->next) - if (m->visualID == vid) - return m; + modes = modes->next; + } - return NULL; + return modes; } -__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 diff --git a/src/glx/x11/glcontextmodes.h b/src/glx/x11/glcontextmodes.h index afd09cd7fb..4b5c6f68b8 100644 --- a/src/glx/x11/glcontextmodes.h +++ b/src/glx/x11/glcontextmodes.h @@ -44,10 +44,8 @@ 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_fbconfig(__GLcontextModes *modes, int fbid); +extern __GLcontextModes * _gl_context_modes_find_visual( + __GLcontextModes * modes, int vid ); extern GLboolean _gl_context_modes_are_same( const __GLcontextModes * a, const __GLcontextModes * b ); diff --git a/src/glx/x11/glx_pbuffer.c b/src/glx/x11/glx_pbuffer.c index 0f878f223f..1df2d0f342 100644 --- a/src/glx/x11/glx_pbuffer.c +++ b/src/glx/x11/glx_pbuffer.c @@ -164,33 +164,6 @@ 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. * @@ -288,16 +261,6 @@ 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 ); } } @@ -308,6 +271,7 @@ GetDrawableAttribute( Display *dpy, GLXDrawable drawable, return 0; } + /** * Create a non-pbuffer GLX drawable. * @@ -342,7 +306,7 @@ CreateDrawable( Display *dpy, const __GLcontextModes * fbconfig, req->glxCode = glxCode; req->screen = (CARD32) fbconfig->screen; req->fbconfig = fbconfig->fbconfigID; - req->window = (CARD32) drawable; + req->window = (GLXPbuffer) drawable; req->glxwindow = (GLXWindow) XAllocID(dpy); req->numAttribs = (CARD32) i; @@ -351,34 +315,6 @@ 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; } @@ -414,20 +350,6 @@ 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; } @@ -538,24 +460,8 @@ 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, - width, height, + 0, 0, attrib_list, GL_TRUE ); } diff --git a/src/glx/x11/glx_texture_compression.c b/src/glx/x11/glx_texture_compression.c new file mode 100644 index 0000000000..5676858017 --- /dev/null +++ b/src/glx/x11/glx_texture_compression.c @@ -0,0 +1,347 @@ +/* + * (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 + */ + +#include "packrender.h" +#include "packsingle.h" +#include "indirect.h" + +#include + + +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 ); + } +} diff --git a/src/glx/x11/glxclient.h b/src/glx/x11/glxclient.h index 73c278ee38..03e44e5d04 100644 --- a/src/glx/x11/glxclient.h +++ b/src/glx/x11/glxclient.h @@ -58,7 +58,7 @@ #include "GL/glxproto.h" #include "GL/internal/glcore.h" #include "glapitable.h" -#include "glxhash.h" +#include "glxextensions.h" #if defined( USE_XTHREADS ) # include #elif defined( PTHREADS ) @@ -70,9 +70,7 @@ #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; @@ -80,9 +78,6 @@ typedef struct _glapi_table __GLapi; #ifdef GLX_DIRECT_RENDERING -#define containerOf(ptr, type, member) \ - (type *)( (char *)ptr - offsetof(type,member) ) - #include @@ -90,64 +85,43 @@ typedef struct _glapi_table __GLapi; * Display dependent methods. This structure is initialized during the * \c driCreateDisplay call. */ -typedef struct __GLXDRIdisplayRec __GLXDRIdisplay; -typedef struct __GLXDRIscreenRec __GLXDRIscreen; -typedef struct __GLXDRIdrawableRec __GLXDRIdrawable; -typedef struct __GLXDRIcontextRec __GLXDRIcontext; - -#include "glxextensions.h" - -struct __GLXDRIdisplayRec { +struct __DRIdisplayRec { /** * Method to destroy the private DRI display data. */ - void (*destroyDisplay)(__GLXDRIdisplay *display); - - __GLXDRIscreen *(*createScreen)(__GLXscreenConfigs *psc, int screen, - __GLXdisplayPrivate *priv); -}; + void (*destroyDisplay)(Display *dpy, void *displayPrivate); -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); -}; + /** + * Opaque pointer to private per display direct rendering data. + * \c NULL if direct rendering is not supported on this display. + */ + struct __DRIdisplayPrivateRec *private; -struct __GLXDRIcontextRec { - void (*destroyContext)(__GLXDRIcontext *context, __GLXscreenConfigs *psc, - Display *dpy); - Bool (*bindContext)(__GLXDRIcontext *context, - __GLXDRIdrawable *pdraw, - __GLXDRIdrawable *pread); - - void (*unbindContext)(__GLXDRIcontext *context); + /** + * Array of pointers to methods to create and initialize the private DRI + * screen data. + */ + PFNCREATENEWSCREENFUNC * createNewScreen; }; -struct __GLXDRIdrawableRec { - void (*destroyDrawable)(__GLXDRIdrawable *drawable); - XID xDrawable; - XID drawable; - __GLXscreenConfigs *psc; - __DRIdrawable *driDrawable; - GLenum textureTarget; +/* +** 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; }; /* ** Function to create and DRI display data and initialize the display ** dependent methods. */ -extern __GLXDRIdisplay *driCreateDisplay(Display *dpy); -extern __GLXDRIdisplay *dri2CreateDisplay(Display *dpy); +extern void *driCreateDisplay(Display *dpy, __DRIdisplay *pdisp); + +extern __DRIdriver *driGetDriver(Display *dpy, int scrNum); extern void DRI_glXUseXFont( Font font, int first, int count, int listbase ); @@ -159,6 +133,8 @@ extern const char *glXGetScreenDriver (Display *dpy, int scrNum); extern const char *glXGetDriverConfig (const char *driverName); +extern Bool __glXWindowExists(Display *dpy, GLXDrawable draw); + #endif /************************************************************************/ @@ -249,11 +225,19 @@ 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 @@ -359,15 +343,24 @@ struct __GLXcontextRec { */ GLint majorOpcode; +#ifdef GLX_DIRECT_RENDERING /** - * Pointer to the mode used to create this context. + * Per context direct rendering interface functions and data. */ - const __GLcontextModes * mode; - -#ifdef GLX_DIRECT_RENDERING - __GLXDRIcontext *driContext; - __DRIcontext *__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 @@ -445,7 +438,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). */ -struct __GLXscreenConfigsRec { +typedef struct __GLXscreenConfigsRec { /** * GLX extension string reported by the X-server. */ @@ -461,46 +454,13 @@ struct __GLXscreenConfigsRec { /** * Per screen direct rendering interface functions and data. */ - __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 - + __DRIscreen driScreen; #endif /** - * Linked list of glx visuals and fbconfigs for this screen. + * Linked list of configurations for this screen. */ - __GLcontextModes *visuals, *configs; + __GLcontextModes *configs; /** * Per-screen dynamic GLX extension tracking. The \c direct_support @@ -514,7 +474,7 @@ struct __GLXscreenConfigsRec { GLboolean ext_list_first_time; /*@}*/ -}; +} __GLXscreenConfigs; /** * Per display private data. One of these records exists for each display @@ -563,11 +523,11 @@ struct __GLXdisplayPrivateRec { /** * Per display direct rendering interface functions and data. */ - __GLXDRIdisplay *driDisplay; - __GLXDRIdisplay *dri2Display; + __DRIdisplay driDisplay; #endif }; +void __glXFreeContext(__GLXcontext*); extern GLubyte *__glXFlushRenderBuffer(__GLXcontext*, GLubyte*); @@ -611,10 +571,6 @@ 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 @@ -724,16 +680,13 @@ 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 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 +extern Bool __glXGetMscRateOML(Display * dpy, GLXDrawable drawable, + int32_t * numerator, int32_t * denominator); #endif /* !__GLX_client_h__ */ diff --git a/src/glx/x11/glxcmds.c b/src/glx/x11/glxcmds.c index 4345678a98..80281896f6 100644 --- a/src/glx/x11/glxcmds.c +++ b/src/glx/x11/glxcmds.c @@ -38,110 +38,63 @@ * Client-side GLX interface. */ +#include #include "glxclient.h" +#include +#include +#include +#include #include "glapi.h" -#include "glxextensions.h" -#include "glcontextmodes.h" -#include "glheader.h" - #ifdef GLX_DIRECT_RENDERING -#include +#include "indirect_init.h" #include #include "xf86dri.h" #endif +#include "glxextensions.h" +#include "glcontextmodes.h" +#include "glheader.h" +#include 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. */ -_X_HIDDEN __GLXDRIdrawable * -GetGLXDRIDrawable(Display *dpy, GLXDrawable drawable, int * const scrn_num) + +#ifdef GLX_DIRECT_RENDERING +static __DRIdrawable * +GetDRIDrawable( Display *dpy, GLXDrawable drawable, int * const scrn_num ) { - __GLXdisplayPrivate *priv = __glXInitialize(dpy); - __GLXDRIdrawable *pdraw; - const unsigned screen_count = ScreenCount(dpy); - unsigned i; - __GLXscreenConfigs *psc; + __GLXdisplayPrivate * const priv = __glXInitialize(dpy); - 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; + 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; + + if ( pdraw != NULL ) { + if ( scrn_num != NULL ) { + *scrn_num = i; + } + return pdraw; + } } } return NULL; } - #endif @@ -311,9 +264,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 @@ -359,10 +312,6 @@ 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; @@ -376,36 +325,41 @@ CreateContext(Display *dpy, XVisualInfo *vis, return NULL; #ifdef GLX_DIRECT_RENDERING - if (allowDirect && psc->driScreen) { + if (allowDirect) { + int screen = (fbconfig == NULL) ? vis->screen : fbconfig->screen; + __GLXscreenConfigs * const psc = GetGLXScreenConfigs(dpy, screen); const __GLcontextModes * mode; - 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; - } + /* 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 ); } else { mode = fbconfig; } - 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; + 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; + } } } #endif @@ -422,7 +376,7 @@ CreateContext(Display *dpy, XVisualInfo *vis, req->visual = vis->visualid; req->screen = vis->screen; req->shareList = shareList ? shareList->xid : None; - req->isDirect = gc->driContext != NULL; + req->isDirect = gc->isDirect; } else if ( use_glx_1_3 ) { xGLXCreateNewContextReq *req; @@ -436,7 +390,7 @@ CreateContext(Display *dpy, XVisualInfo *vis, req->screen = fbconfig->screen; req->renderType = renderType; req->shareList = shareList ? shareList->xid : None; - req->isDirect = gc->driContext != NULL; + req->isDirect = gc->isDirect; } else { xGLXVendorPrivateWithReplyReq *vpreq; @@ -454,7 +408,7 @@ CreateContext(Display *dpy, XVisualInfo *vis, req->screen = fbconfig->screen; req->renderType = renderType; req->shareList = shareList ? shareList->xid : None; - req->isDirect = gc->driContext != NULL; + req->isDirect = gc->isDirect; } UnlockDisplay(dpy); @@ -476,7 +430,7 @@ PUBLIC GLXContext glXCreateContext(Display *dpy, XVisualInfo *vis, False, 0); } -_X_HIDDEN void __glXFreeContext(__GLXcontext *gc) +void __glXFreeContext(__GLXcontext *gc) { if (gc->vendor) XFree((char *) gc->vendor); if (gc->renderer) XFree((char *) gc->renderer); @@ -512,10 +466,12 @@ DestroyContext(Display *dpy, GLXContext gc) #ifdef GLX_DIRECT_RENDERING /* Destroy the direct rendering context */ - if (gc->driContext) { - (*gc->driContext->destroyContext)(gc->driContext, gc->psc, dpy); - gc->driContext = NULL; - GarbageCollectDRIDrawables(dpy, gc->psc); + if (gc->isDirect) { + if (gc->driContext.private) { + (*gc->driContext.destroyContext)(dpy, gc->screen, + gc->driContext.private); + gc->driContext.private = NULL; + } } #endif @@ -596,7 +552,7 @@ PUBLIC void glXWaitGL(void) __glXFlushRenderBuffer(gc, gc->pc); #ifdef GLX_DIRECT_RENDERING - if (gc->driContext) { + if (gc->isDirect) { /* This bit of ugliness unwraps the glFinish function */ #ifdef glFinish #undef glFinish @@ -632,7 +588,7 @@ PUBLIC void glXWaitX(void) __glXFlushRenderBuffer(gc, gc->pc); #ifdef GLX_DIRECT_RENDERING - if (gc->driContext) { + if (gc->isDirect) { XSync(dpy, False); return; } @@ -662,7 +618,7 @@ PUBLIC void glXUseXFont(Font font, int first, int count, int listBase) (void) __glXFlushRenderBuffer(gc, gc->pc); #ifdef GLX_DIRECT_RENDERING - if (gc->driContext) { + if (gc->isDirect) { DRI_glXUseXFont(font, first, count, listBase); return; } @@ -702,7 +658,7 @@ PUBLIC void glXCopyContext(Display *dpy, GLXContext source, } #ifdef GLX_DIRECT_RENDERING - if (gc->driContext) { + if (gc->isDirect) { /* NOT_DONE: This does not work yet */ } #endif @@ -774,7 +730,7 @@ PUBLIC Bool glXIsDirect(Display *dpy, GLXContext gc) if (!gc) { return GL_FALSE; #ifdef GLX_DIRECT_RENDERING - } else if (gc->driContext) { + } else if (gc->isDirect) { return GL_TRUE; #endif } @@ -837,10 +793,10 @@ PUBLIC void glXSwapBuffers(Display *dpy, GLXDrawable drawable) GLXContextTag tag; CARD8 opcode; #ifdef GLX_DIRECT_RENDERING - __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, NULL); + __DRIdrawable *pdraw = GetDRIDrawable( dpy, drawable, NULL ); - if (pdraw != NULL) { - (*pdraw->psc->core->swapBuffers)(pdraw->driDrawable); + if ( pdraw != NULL ) { + (*pdraw->swapBuffers)(dpy, pdraw->private); return; } #endif @@ -884,12 +840,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 ) { - modes = _gl_context_modes_find_visual(psc->visuals, vis->visualid); + const __GLcontextModes * const modes = _gl_context_modes_find_visual( + psc->configs, vis->visualid ); /* Lookup attribute after first finding a match on the visual */ if ( modes != NULL ) { @@ -1267,7 +1223,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->visuals ; modes != NULL ; modes = modes->next ) { + for ( modes = psc->configs ; modes != NULL ; modes = modes->next ) { if ( fbconfigs_compatible( & test_config, modes ) && ((best_config == NULL) || (fbconfig_compare( (const __GLcontextModes * const * const)&modes, &best_config ) < 0)) ) { @@ -1312,7 +1268,7 @@ PUBLIC const char *glXQueryExtensionsString( Display *dpy, int screen ) __glXCalculateUsableExtensions(psc, #ifdef GLX_DIRECT_RENDERING - (psc->driScreen != NULL), + (psc->driScreen.private != NULL), #else GL_FALSE, #endif @@ -1491,15 +1447,13 @@ static int __glXQueryContextInfo(Display *dpy, GLXContext ctx) ctx->share_xid = *pProp++; break; case GLX_VISUAL_ID_EXT: - ctx->mode = - _gl_context_modes_find_visual(ctx->psc->visuals, *pProp++); + ctx->vid = *pProp++; break; case GLX_SCREEN: ctx->screen = *pProp++; break; case GLX_FBCONFIG_ID: - ctx->mode = - _gl_context_modes_find_fbconfig(ctx->psc->configs, *pProp++); + ctx->fbconfigID = *pProp++; break; case GLX_RENDER_TYPE: ctx->renderType = *pProp++; @@ -1524,7 +1478,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->driContext && (ctx->mode == NULL)) { + if (!ctx->isDirect && (ctx->vid == None)) { retVal = __glXQueryContextInfo(dpy, ctx); if (Success != retVal) return retVal; } @@ -1533,13 +1487,13 @@ glXQueryContext(Display *dpy, GLXContext ctx, int attribute, int *value) *value = (int)(ctx->share_xid); break; case GLX_VISUAL_ID_EXT: - *value = ctx->mode ? ctx->mode->visualID : None; + *value = (int)(ctx->vid); break; case GLX_SCREEN: *value = (int)(ctx->screen); break; case GLX_FBCONFIG_ID: - *value = ctx->mode ? ctx->mode->fbconfigID : None; + *value = (int)(ctx->fbconfigID); break; case GLX_RENDER_TYPE: *value = (int)(ctx->renderType); @@ -1637,7 +1591,6 @@ 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) @@ -1662,10 +1615,8 @@ PUBLIC GLXFBConfig *glXGetFBConfigs(Display *dpy, int screen, int *nelements) for ( modes = priv->screenConfigs[screen].configs ; modes != NULL ; modes = modes->next ) { - if ( modes->fbconfigID != GLX_DONT_CARE ) { - config[i] = modes; - i++; - } + config[i] = modes; + i++; } } } @@ -1717,15 +1668,16 @@ static int __glXSwapIntervalSGI(int interval) return GLX_BAD_VALUE; } -#ifdef __DRI_SWAP_CONTROL - if (gc->driContext) { +#ifdef GLX_DIRECT_RENDERING + if ( gc->isDirect ) { __GLXscreenConfigs * const psc = GetGLXScreenConfigs( gc->currentDpy, gc->screen ); - __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(gc->currentDpy, - gc->currentDrawable, - NULL); - if (psc->swapControl != NULL && pdraw != NULL) { - psc->swapControl->setSwapInterval(pdraw->driDrawable, interval); + __DRIdrawable * const pdraw = GetDRIDrawable( gc->currentDpy, + gc->currentDrawable, + NULL ); + if ( __glXExtensionBitIsEnabled( psc, SGI_swap_control_bit ) + && (pdraw != NULL) ) { + pdraw->swap_interval = interval; return 0; } else { @@ -1763,22 +1715,25 @@ static int __glXSwapIntervalSGI(int interval) */ static int __glXSwapIntervalMESA(unsigned int interval) { -#ifdef __DRI_SWAP_CONTROL +#ifdef GLX_DIRECT_RENDERING GLXContext gc = __glXGetCurrentContext(); if ( interval < 0 ) { return GLX_BAD_VALUE; } - if (gc != NULL && gc->driContext) { + if ( (gc != NULL) && gc->isDirect ) { __GLXscreenConfigs * const psc = GetGLXScreenConfigs( gc->currentDpy, gc->screen ); - 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); + 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; return 0; } } @@ -1793,18 +1748,21 @@ static int __glXSwapIntervalMESA(unsigned int interval) static int __glXGetSwapIntervalMESA(void) { -#ifdef __DRI_SWAP_CONTROL +#ifdef GLX_DIRECT_RENDERING GLXContext gc = __glXGetCurrentContext(); - if (gc != NULL && gc->driContext) { + if ( (gc != NULL) && gc->isDirect ) { __GLXscreenConfigs * const psc = GetGLXScreenConfigs( gc->currentDpy, gc->screen ); - 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); + 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; } } } @@ -1821,13 +1779,15 @@ static int __glXGetSwapIntervalMESA(void) static GLint __glXBeginFrameTrackingMESA(Display *dpy, GLXDrawable drawable) { int status = GLX_BAD_CONTEXT; -#ifdef __DRI_FRAME_TRACKING +#ifdef GLX_DIRECT_RENDERING int screen; - __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, &screen); + __DRIdrawable * const pdraw = GetDRIDrawable(dpy, drawable, & screen); __GLXscreenConfigs * const psc = GetGLXScreenConfigs(dpy, screen); - if (pdraw != NULL && psc->frameTracking != NULL) - status = psc->frameTracking->frameTracking(pdraw->driDrawable, GL_TRUE); + if ( (pdraw != NULL) && (pdraw->frameTracking != NULL) + && __glXExtensionBitIsEnabled( psc, MESA_swap_frame_usage_bit ) ) { + status = pdraw->frameTracking( dpy, pdraw->private, GL_TRUE ); + } #else (void) dpy; (void) drawable; @@ -1839,14 +1799,15 @@ static GLint __glXBeginFrameTrackingMESA(Display *dpy, GLXDrawable drawable) static GLint __glXEndFrameTrackingMESA(Display *dpy, GLXDrawable drawable) { int status = GLX_BAD_CONTEXT; -#ifdef __DRI_FRAME_TRACKING +#ifdef GLX_DIRECT_RENDERING int screen; - __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, & screen); - __GLXscreenConfigs *psc = GetGLXScreenConfigs(dpy, screen); + __DRIdrawable * const pdraw = GetDRIDrawable(dpy, drawable, & screen); + __GLXscreenConfigs * const psc = GetGLXScreenConfigs(dpy, screen); - if (pdraw != NULL && psc->frameTracking != NULL) - status = psc->frameTracking->frameTracking(pdraw->driDrawable, - GL_FALSE); + if ( (pdraw != NULL) && (pdraw->frameTracking != NULL) + && __glXExtensionBitIsEnabled( psc, MESA_swap_frame_usage_bit ) ) { + status = pdraw->frameTracking( dpy, pdraw->private, GL_FALSE ); + } #else (void) dpy; (void) drawable; @@ -1859,20 +1820,19 @@ static GLint __glXGetFrameUsageMESA(Display *dpy, GLXDrawable drawable, GLfloat *usage) { int status = GLX_BAD_CONTEXT; -#ifdef __DRI_FRAME_TRACKING +#ifdef GLX_DIRECT_RENDERING int screen; - __GLXDRIdrawable * const pdraw = GetGLXDRIDrawable(dpy, drawable, & screen); + __DRIdrawable * const pdraw = GetDRIDrawable(dpy, drawable, & screen); __GLXscreenConfigs * const psc = GetGLXScreenConfigs(dpy, screen); - if (pdraw != NULL && psc->frameTracking != NULL) { - int64_t sbc, missedFrames; - float lastMissedUsage; + if ( (pdraw != NULL ) && (pdraw->queryFrameTracking != NULL) + && __glXExtensionBitIsEnabled( psc, MESA_swap_frame_usage_bit ) ) { + int64_t sbc, missedFrames; + float lastMissedUsage; - status = psc->frameTracking->queryFrameTracking(pdraw->driDrawable, - &sbc, - &missedFrames, - &lastMissedUsage, - usage); + status = pdraw->queryFrameTracking( dpy, pdraw->private, &sbc, + &missedFrames, &lastMissedUsage, + usage ); } #else (void) dpy; @@ -1888,17 +1848,18 @@ static GLint __glXQueryFrameTrackingMESA(Display *dpy, GLXDrawable drawable, GLfloat *lastMissedUsage) { int status = GLX_BAD_CONTEXT; -#ifdef __DRI_FRAME_TRACKING +#ifdef GLX_DIRECT_RENDERING int screen; - __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, & screen); + __DRIdrawable * const pdraw = GetDRIDrawable(dpy, drawable, & screen); __GLXscreenConfigs * const psc = GetGLXScreenConfigs(dpy, screen); - if (pdraw != NULL && psc->frameTracking != NULL) { + if ( (pdraw != NULL ) && (pdraw->queryFrameTracking != NULL) + && __glXExtensionBitIsEnabled( psc, MESA_swap_frame_usage_bit ) ) { float usage; - status = psc->frameTracking->queryFrameTracking(pdraw->driDrawable, - sbc, missedFrames, - lastMissedUsage, &usage); + status = pdraw->queryFrameTracking( dpy, pdraw->private, sbc, + missedFrames, lastMissedUsage, + & usage ); } #else (void) dpy; @@ -1920,24 +1881,21 @@ 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 __DRI_MEDIA_STREAM_COUNTER +#ifdef GLX_DIRECT_RENDERING GLXContext gc = __glXGetCurrentContext(); - if (gc != NULL && gc->driContext) { + if ( (gc != NULL) && gc->isDirect ) { __GLXscreenConfigs * const psc = GetGLXScreenConfigs( gc->currentDpy, gc->screen ); - 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; + if ( __glXExtensionBitIsEnabled( psc, SGI_video_sync_bit ) + && psc->driScreen.private && psc->driScreen.getMSC) { + int ret; + int64_t temp; - return (ret == 0) ? 0 : GLX_BAD_CONTEXT; + ret = psc->driScreen.getMSC( psc->driScreen.private, & temp ); + *count = (unsigned) temp; + return (ret == 0) ? 0 : GLX_BAD_CONTEXT; } } #else @@ -1948,26 +1906,32 @@ static int __glXGetVideoSyncSGI(unsigned int *count) static int __glXWaitVideoSyncSGI(int divisor, int remainder, unsigned int *count) { -#ifdef __DRI_MEDIA_STREAM_COUNTER +#ifdef GLX_DIRECT_RENDERING GLXContext gc = __glXGetCurrentContext(); if ( divisor <= 0 || remainder < 0 ) return GLX_BAD_VALUE; - if (gc != NULL && gc->driContext) { + if ( (gc != NULL) && gc->isDirect ) { __GLXscreenConfigs * const psc = GetGLXScreenConfigs( gc->currentDpy, gc->screen ); - 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; + 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; + } } } #else @@ -2119,19 +2083,20 @@ 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) { -#if defined(__DRI_SWAP_BUFFER_COUNTER) && defined(__DRI_MEDIA_STREAM_COUNTER) +#ifdef GLX_DIRECT_RENDERING __GLXdisplayPrivate * const priv = __glXInitialize(dpy); if ( priv != NULL ) { int i; - __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, &i); + __DRIdrawable * const pdraw = GetDRIDrawable( dpy, drawable, & i ); __GLXscreenConfigs * const psc = &priv->screenConfigs[i]; assert( (pdraw == NULL) || (i != -1) ); - return ( (pdraw && psc->sbc && psc->msc) - && ((*psc->msc->getMSC)(psc->driScreen, msc) == 0) - && ((*psc->sbc->getSBC)(pdraw->driDrawable, sbc) == 0) - && (__glXGetUST(ust) == 0) ); + 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) ); } #else (void) dpy; @@ -2143,68 +2108,6 @@ 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. @@ -2222,17 +2125,70 @@ __driGetMscRateOML(__DRIdrawable *draw, * when GLX_OML_sync_control appears in the client extension string. */ -_X_HIDDEN GLboolean __glXGetMscRateOML(Display * dpy, GLXDrawable drawable, - int32_t * numerator, - int32_t * denominator) +Bool __glXGetMscRateOML(Display * dpy, GLXDrawable drawable, + int32_t * numerator, int32_t * denominator) { #if defined( GLX_DIRECT_RENDERING ) && defined( XF86VIDMODE ) - __GLXDRIdrawable *draw = GetGLXDRIDrawable(dpy, drawable, NULL); + __GLXdisplayPrivate * const priv = __glXInitialize(dpy); - if (draw == NULL) - return False; - return __driGetMscRateOML(draw->driDrawable, numerator, denominator, draw); + 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. + */ + + 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; + + (void) drawable; + return True; + } + } #else (void) dpy; (void) drawable; @@ -2247,9 +2203,9 @@ static int64_t __glXSwapBuffersMscOML(Display *dpy, GLXDrawable drawable, int64_t target_msc, int64_t divisor, int64_t remainder) { -#ifdef __DRI_SWAP_BUFFER_COUNTER +#ifdef GLX_DIRECT_RENDERING int screen; - __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, &screen); + __DRIdrawable *pdraw = GetDRIDrawable( dpy, drawable, & screen ); __GLXscreenConfigs * const psc = GetGLXScreenConfigs( dpy, screen ); /* The OML_sync_control spec says these should "generate a GLX_BAD_VALUE @@ -2262,10 +2218,11 @@ static int64_t __glXSwapBuffersMscOML(Display *dpy, GLXDrawable drawable, if ( divisor > 0 && remainder >= divisor ) return -1; - if (pdraw != NULL && psc->counters != NULL) - return (*psc->sbc->swapBuffersMSC)(pdraw->driDrawable, target_msc, - divisor, remainder); - + if ( (pdraw != NULL) && (pdraw->swapBuffersMSC != NULL) + && __glXExtensionBitIsEnabled( psc, OML_sync_control_bit ) ) { + return (*pdraw->swapBuffersMSC)(dpy, pdraw->private, target_msc, + divisor, remainder); + } #else (void) dpy; (void) drawable; @@ -2282,9 +2239,9 @@ static Bool __glXWaitForMscOML(Display * dpy, GLXDrawable drawable, int64_t remainder, int64_t *ust, int64_t *msc, int64_t *sbc) { -#ifdef __DRI_MEDIA_STREAM_COUNTER +#ifdef GLX_DIRECT_RENDERING int screen; - __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, &screen); + __DRIdrawable *pdraw = GetDRIDrawable( dpy, drawable, & screen ); __GLXscreenConfigs * const psc = GetGLXScreenConfigs( dpy, screen ); int ret; @@ -2296,9 +2253,10 @@ static Bool __glXWaitForMscOML(Display * dpy, GLXDrawable drawable, if ( divisor > 0 && remainder >= divisor ) return False; - if (pdraw != NULL && psc->msc != NULL) { - ret = (*psc->msc->waitForMSC)(pdraw->driDrawable, target_msc, - divisor, remainder, msc, sbc); + if ( (pdraw != NULL) && (pdraw->waitForMSC != NULL) + && __glXExtensionBitIsEnabled( psc, OML_sync_control_bit ) ) { + ret = (*pdraw->waitForMSC)( dpy, pdraw->private, 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. @@ -2323,9 +2281,9 @@ static Bool __glXWaitForSbcOML(Display * dpy, GLXDrawable drawable, int64_t target_sbc, int64_t *ust, int64_t *msc, int64_t *sbc ) { -#ifdef __DRI_SWAP_BUFFER_COUNTER +#ifdef GLX_DIRECT_RENDERING int screen; - __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, &screen); + __DRIdrawable *pdraw = GetDRIDrawable( dpy, drawable, & screen ); __GLXscreenConfigs * const psc = GetGLXScreenConfigs( dpy, screen ); int ret; @@ -2335,8 +2293,9 @@ static Bool __glXWaitForSbcOML(Display * dpy, GLXDrawable drawable, if ( target_sbc < 0 ) return False; - if (pdraw != NULL && psc->sbc != NULL) { - ret = (*psc->sbc->waitForSBC)(pdraw->driDrawable, target_sbc, msc, sbc); + if ( (pdraw != NULL) && (pdraw->waitForSBC != NULL) + && __glXExtensionBitIsEnabled( psc, OML_sync_control_bit )) { + ret = (*pdraw->waitForSBC)( dpy, pdraw->private, target_sbc, msc, sbc ); /* __glXGetUST returns zero on success and non-zero on failure. * This function returns True on success and False on failure. @@ -2364,13 +2323,16 @@ PUBLIC void *glXAllocateMemoryMESA(Display *dpy, int scrn, size_t size, float readFreq, float writeFreq, float priority) { -#ifdef __DRI_ALLOCATE +#ifdef GLX_DIRECT_RENDERING __GLXscreenConfigs * const psc = GetGLXScreenConfigs( dpy, scrn ); - if (psc && psc->allocate) - return (*psc->allocate->allocateMemory)(psc->__driScreen, size, - readFreq, writeFreq, priority); - + 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 ); + } + } #else (void) dpy; (void) scrn; @@ -2386,12 +2348,14 @@ PUBLIC void *glXAllocateMemoryMESA(Display *dpy, int scrn, PUBLIC void glXFreeMemoryMESA(Display *dpy, int scrn, void *pointer) { -#ifdef __DRI_ALLOCATE +#ifdef GLX_DIRECT_RENDERING __GLXscreenConfigs * const psc = GetGLXScreenConfigs( dpy, scrn ); - if (psc && psc->allocate) - (*psc->allocate->freeMemory)(psc->__driScreen, pointer); - + if ( __glXExtensionBitIsEnabled( psc, MESA_allocate_memory_bit ) ) { + if (psc && psc->driScreen.private && psc->driScreen.freeMemory) { + (*psc->driScreen.freeMemory)( dpy, scrn, pointer ); + } + } #else (void) dpy; (void) scrn; @@ -2403,12 +2367,14 @@ PUBLIC void glXFreeMemoryMESA(Display *dpy, int scrn, void *pointer) PUBLIC GLuint glXGetMemoryOffsetMESA( Display *dpy, int scrn, const void *pointer ) { -#ifdef __DRI_ALLOCATE +#ifdef GLX_DIRECT_RENDERING __GLXscreenConfigs * const psc = GetGLXScreenConfigs( dpy, scrn ); - if (psc && psc->allocate) - return (*psc->allocate->memoryOffset)(psc->__driScreen, pointer); - + if ( __glXExtensionBitIsEnabled( psc, MESA_allocate_memory_bit ) ) { + if (psc && psc->driScreen.private && psc->driScreen.memoryOffset) { + return (*psc->driScreen.memoryOffset)( dpy, scrn, pointer ); + } + } #else (void) dpy; (void) scrn; @@ -2481,14 +2447,13 @@ static void __glXCopySubBufferMESA(Display *dpy, GLXDrawable drawable, INT32 *x_ptr, *y_ptr, *w_ptr, *h_ptr; CARD8 opcode; -#ifdef __DRI_COPY_SUB_BUFFER +#ifdef GLX_DIRECT_RENDERING int screen; - __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, &screen); + __DRIdrawable *pdraw = GetDRIDrawable( dpy, drawable, & screen ); if ( pdraw != NULL ) { __GLXscreenConfigs * const psc = GetGLXScreenConfigs( dpy, screen ); - if (psc->copySubBuffer != NULL) { - (*psc->copySubBuffer->copySubBuffer)(pdraw->driDrawable, - x, y, width, height); + if ( __glXExtensionBitIsEnabled( psc, MESA_copy_sub_buffer_bit ) ) { + (*pdraw->copySubBuffer)(dpy, pdraw->private, x, y, width, height); } return; @@ -2564,16 +2529,8 @@ static void __glXBindTexImageEXT(Display *dpy, } #ifdef GLX_DIRECT_RENDERING - if (gc->driContext) { - __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, NULL); - - if (pdraw != NULL) - (*pdraw->psc->texBuffer->setTexBuffer)(gc->__driContext, - pdraw->textureTarget, - pdraw->driDrawable); - + if (gc->isDirect) return; - } #endif opcode = __glXSetupForCommand(dpy); @@ -2624,7 +2581,7 @@ static void __glXReleaseTexImageEXT(Display *dpy, return; #ifdef GLX_DIRECT_RENDERING - if (gc->driContext) + if (gc->isDirect) return; #endif @@ -2656,7 +2613,7 @@ static void __glXReleaseTexImageEXT(Display *dpy, * * \sa strdup */ -_X_HIDDEN char * +char * __glXstrdup(const char *str) { char *copy; @@ -2883,6 +2840,98 @@ 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 @@ -2897,7 +2946,7 @@ PUBLIC void (*glXGetProcAddress(const GLubyte *procName))( void ) * * \since Internal API version 20030317. */ -_X_HIDDEN int __glXGetUST( int64_t * ust ) +int __glXGetUST( int64_t * ust ) { struct timeval tv; diff --git a/src/glx/x11/glxcurrent.c b/src/glx/x11/glxcurrent.c deleted file mode 100644 index ad648fd438..0000000000 --- a/src/glx/x11/glxcurrent.c +++ /dev/null @@ -1,510 +0,0 @@ -/* -** License Applicability. Except to the extent portions of this file are -** made subject to an alternative license as permitted in the SGI Free -** Software License B, Version 1.1 (the "License"), the contents of this -** file are subject only to the provisions of the License. You may not use -** this file except in compliance with the License. You may obtain a copy -** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 -** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: -** -** http://oss.sgi.com/projects/FreeB -** -** Note that, as provided in the License, the Software is distributed on an -** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS -** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND -** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A -** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. -** -** Original Code. The Original Code is: OpenGL Sample Implementation, -** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, -** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. -** Copyright in any portions created by third parties is as indicated -** elsewhere herein. All Rights Reserved. -** -** Additional Notice Provisions: The application programming interfaces -** established by SGI in conjunction with the Original Code are The -** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released -** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version -** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X -** Window System(R) (Version 1.3), released October 19, 1998. This software -** was created using the OpenGL(R) version 1.2.1 Sample Implementation -** published by SGI, but has not been independently verified as being -** compliant with the OpenGL(R) version 1.2.1 Specification. -** -*/ - -/** - * \file glxcurrent.c - * Client-side GLX interface for current context management. - */ - -#include "glxclient.h" -#include "glapi.h" -#include "glheader.h" -#include "indirect_init.h" - -#ifdef GLX_DIRECT_RENDERING -#include "xf86dri.h" -#endif - -/* -** 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; - -_X_HIDDEN __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; - } -} - -_X_HIDDEN 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 */ -_X_HIDDEN xmutex_rec __glXmutex; - -#elif defined( PTHREADS ) - -_X_HIDDEN 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; - -_X_HIDDEN 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 ); - } -} - -_X_HIDDEN void __glXSetCurrentContext( __GLXcontext * c ) -{ - pthread_once( & once_control, init_thread_data ); - pthread_setspecific( ContextTSD, c ); -} - -_X_HIDDEN __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 */ -_X_HIDDEN __GLXcontext *__glXcurrentContext = &dummyContext; - -#endif - - -_X_HIDDEN void __glXSetCurrentContextNull(void) -{ - __glXSetCurrentContext(&dummyContext); -#ifdef GLX_DIRECT_RENDERING - _glapi_set_dispatch(NULL); /* no-op functions */ -#endif -} - - -/************************************************************************/ - -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; -} - - -/************************************************************************/ - -/** - * 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 __GLXDRIdrawable * -FetchDRIDrawable(Display *dpy, - GLXDrawable glxDrawable, GLXContext gc, Bool pre13) -{ - __GLXdisplayPrivate * const priv = __glXInitialize(dpy); - __GLXDRIdrawable *pdraw; - __GLXscreenConfigs *psc; - XID drawable; - - if (priv == NULL) - return NULL; - - psc = &priv->screenConfigs[gc->screen]; - if (psc->drawHash == NULL) - return NULL; - - if (__glxHashLookup(psc->drawHash, glxDrawable, (void *) &pdraw) == 0) - return pdraw; - - /* If this is glXMakeCurrent (pre GLX 1.3) we allow creating the - * GLX drawable on the fly. Otherwise we pass None as the X - * drawable */ - if (pre13) - drawable = glxDrawable; - else - drawable = None; - - pdraw = psc->driScreen->createDrawable(psc, drawable, - glxDrawable, gc->mode); - if (__glxHashInsert(psc->drawHash, glxDrawable, pdraw)) { - (*pdraw->destroyDrawable)(pdraw); - return NULL; - } - - return pdraw; -} -#endif /* GLX_DIRECT_RENDERING */ - - -/** - * Make a particular context current. - * - * \note This is in this file so that it can access dummyContext. - */ -static Bool MakeContextCurrent(Display *dpy, GLXDrawable draw, - GLXDrawable read, GLXContext gc, - Bool pre13) -{ - 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; - } - - _glapi_check_multithread(); - -#ifdef GLX_DIRECT_RENDERING - /* Bind the direct rendering context to the drawable */ - if (gc && gc->driContext) { - __GLXDRIdrawable *pdraw = FetchDRIDrawable(dpy, draw, gc, pre13); - __GLXDRIdrawable *pread = FetchDRIDrawable(dpy, read, gc, pre13); - - bindReturnValue = - (gc->driContext->bindContext) (gc->driContext, pdraw, pread); - } 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->driContext)) && - !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->driContext) { - oldGC->driContext->unbindContext(oldGC->driContext); - } -#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->driContext) { - oldGC->driContext->destroyContext(oldGC->driContext, - oldGC->psc, - oldGC->createDpy); - oldGC->driContext = NULL; - } -#endif - __glXFreeContext(oldGC); - } - } - if (gc) { - __glXSetCurrentContext(gc); - - gc->currentDpy = dpy; - gc->currentDrawable = draw; - gc->currentReadable = read; - - if (!gc->driContext) { - 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 { - __glXSetCurrentContextNull(); - } - } - __glXUnlock(); - return GL_TRUE; -} - - -PUBLIC Bool glXMakeCurrent(Display *dpy, GLXDrawable draw, GLXContext gc) -{ - return MakeContextCurrent(dpy, draw, draw, gc, True); -} - -PUBLIC GLX_ALIAS(Bool, glXMakeCurrentReadSGI, - (Display *dpy, GLXDrawable d, GLXDrawable r, GLXContext ctx), - (dpy, d, r, ctx, False), MakeContextCurrent) - -PUBLIC GLX_ALIAS(Bool, glXMakeContextCurrent, - (Display *dpy, GLXDrawable d, GLXDrawable r, GLXContext ctx), - (dpy, d, r, ctx, False), MakeContextCurrent) diff --git a/src/glx/x11/glxext.c b/src/glx/x11/glxext.c index 4d814744cd..6403cbd56d 100644 --- a/src/glx/x11/glxext.c +++ b/src/glx/x11/glxext.c @@ -44,25 +44,57 @@ */ #include "glxclient.h" +#include #include #include +#include +#include +#include +#include "indirect_init.h" #include "glapi.h" #include "glxextensions.h" #include "glcontextmodes.h" #include "glheader.h" +#ifdef GLX_DIRECT_RENDERING +#include +#include +#include "xf86dri.h" +#include "sarea.h" +#include "dri_glx.h" +#endif + #ifdef USE_XCB #include #include #include #endif +#include #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 { \ @@ -75,11 +107,173 @@ 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 */ -_X_HIDDEN int __glXDebug = 0; +int __glXDebug = 0; + +/* +** forward prototype declarations +*/ +int __glXCloseDisplay(Display *dpy, XExtCodes *codes); + + +/************************************************************************/ /* Extension required boiler plate */ @@ -102,13 +296,16 @@ static /* const */ char *error_list[] = { "GLXBadWindow", }; -static int __glXCloseDisplay(Display *dpy, XExtCodes *codes) +int __glXCloseDisplay(Display *dpy, XExtCodes *codes) { GLXContext gc; gc = __glXGetCurrentContext(); if (dpy == gc->currentDpy) { - __glXSetCurrentContextNull(); + __glXSetCurrentContext(&dummyContext); +#ifdef GLX_DIRECT_RENDERING + _glapi_set_dispatch(NULL); /* no-op functions */ +#endif __glXFreeContext(gc); } @@ -163,10 +360,11 @@ static void FreeScreenConfigs(__GLXdisplayPrivate *priv) Xfree((char*) psc->serverGLXexts); #ifdef GLX_DIRECT_RENDERING - if (psc->driScreen) { - psc->driScreen->destroyScreen(psc); - __glxHashDestroy(psc->drawHash); - } + /* Free the direct rendering per screen data */ + if (psc->driScreen.private) + (*psc->driScreen.destroyScreen)(priv->dpy, i, + psc->driScreen.private); + psc->driScreen.private = NULL; #endif } XFree((char*) priv->screenConfigs); @@ -193,12 +391,14 @@ static int __glXFreeDisplayPrivate(XExtData *extension) #ifdef GLX_DIRECT_RENDERING /* Free the direct rendering per display data */ - if (priv->driDisplay) - (*priv->driDisplay->destroyDisplay)(priv->driDisplay); - priv->driDisplay = NULL; - if (priv->dri2Display) - (*priv->dri2Display->destroyDisplay)(priv->dri2Display); - priv->dri2Display = NULL; + 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; + } #endif Xfree((char*) priv); @@ -240,7 +440,7 @@ static Bool QueryVersion(Display *dpy, int opcode, int *major, int *minor) } -_X_HIDDEN void +void __glXInitializeVisualConfigFromTags( __GLcontextModes *config, int count, const INT32 *bp, Bool tagged_only, Bool fbconfig_style_tags ) @@ -434,128 +634,371 @@ __glXInitializeVisualConfigFromTags( __GLcontextModes *config, int count, config->haveStencilBuffer = (config->stencilBits > 0); } -static __GLcontextModes * -createConfigsFromProperties(Display *dpy, int nvisuals, int nprops, - int screen, GLboolean tagged_only) + +#ifdef GLX_DIRECT_RENDERING +static unsigned +filter_modes( __GLcontextModes ** server_modes, + const __GLcontextModes * driver_modes ) { - INT32 buf[__GLX_TOTAL_CONFIG], *props; - unsigned prop_size; - __GLcontextModes *modes, *m; - int i; + __GLcontextModes * m; + __GLcontextModes ** prev_next; + const __GLcontextModes * check; + unsigned modes_count = 0; - if (nprops == 0) - return NULL; + if ( driver_modes == NULL ) { + fprintf(stderr, "libGL warning: 3D driver returned no fbconfigs.\n"); + return 0; + } - /* FIXME: Is the __GLX_MIN_CONFIG_PROPS test correct for FBconfigs? */ + /* 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. + */ - /* Check number of properties */ - if (nprops < __GLX_MIN_CONFIG_PROPS || nprops > __GLX_MAX_CONFIG_PROPS) - return NULL; + prev_next = server_modes; + for ( m = *prev_next ; m != NULL ; m = *prev_next ) { + GLboolean do_delete = GL_TRUE; - /* Allocate memory for our config structure */ - modes = _gl_context_modes_create(nvisuals, sizeof(__GLcontextModes)); - if (!modes) - return NULL; + for ( check = driver_modes ; check != NULL ; check = check->next ) { + if ( _gl_context_modes_are_same( m, check ) ) { + do_delete = GL_FALSE; + break; + } + } - prop_size = nprops * __GLX_SIZE_INT32; - if (prop_size <= sizeof(buf)) - props = buf; - else - props = Xmalloc(prop_size); + /* 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; - /* 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; - } + if (getenv("LIBGL_DEBUG")) { + fprintf(stderr, "libGL warning: 3D driver claims to not support " + "visual 0x%02x\n", m->visualID); + } + } - if (props != buf) - Xfree(props); + if ( do_delete ) { + *prev_next = m->next; - return modes; + m->next = NULL; + _gl_context_modes_destroy( m ); + } + else { + modes_count++; + prev_next = & m->next; + } + } + + return modes_count; } -static GLboolean -getVisualConfigs(Display *dpy, __GLXdisplayPrivate *priv, int screen) + +/** + * Implement \c __DRIinterfaceMethods::getProcAddress. + */ +static __DRIfuncPtr get_proc_address( const char * proc_name ) { - xGLXGetVisualConfigsReq *req; - __GLXscreenConfigs *psc; - xGLXGetVisualConfigsReply reply; + if (strcmp( proc_name, "glxEnableExtension" ) == 0) { + return (__DRIfuncPtr) __glXScrEnableExtension; + } - LockDisplay(dpy); + return NULL; +} + +#ifdef XDAMAGE_1_1_INTERFACE +static GLboolean has_damage_post(__DRInativeDisplay *dpy) +{ + static GLboolean inited = GL_FALSE; + static GLboolean has_damage; + + if (!inited) { + int major, minor; - psc = priv->screenConfigs + screen; - psc->visuals = NULL; - GetReq(GLXGetVisualConfigs, req); - req->reqType = priv->majorOpcode; - req->glxCode = X_GLXGetVisualConfigs; - req->screen = screen; + if (XDamageQueryVersion(dpy, &major, &minor) && + major == 1 && minor >= 1) + { + has_damage = GL_TRUE; + } else { + has_damage = GL_FALSE; + } + inited = GL_TRUE; + } - if (!_XReply(dpy, (xReply*) &reply, 0, False)) - goto out; + return has_damage; +} +#endif /* XDAMAGE_1_1_INTERFACE */ - psc->visuals = createConfigsFromProperties(dpy, - reply.numVisuals, - reply.numProps, - screen, GL_FALSE); +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; + } - out: - UnlockDisplay(dpy); - return psc->visuals != NULL; + 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); +#endif } -static GLboolean -getFBConfigs(Display *dpy, __GLXdisplayPrivate *priv, int screen) +/** + * 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) { - xGLXGetFBConfigsReq *fb_req; - xGLXGetFBConfigsSGIXReq *sgi_req; - xGLXVendorPrivateWithReplyReq *vpreq; - xGLXGetFBConfigsReply reply; - __GLXscreenConfigs *psc; + __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 ); + } + } + } + } + } + } + } + } - psc = priv->screenConfigs + screen; - psc->serverGLXexts = __glXGetStringFromServer(dpy, priv->majorOpcode, - X_GLXQueryServerString, - screen, GLX_EXTENSIONS); + if ( psp == NULL ) { + if ( pSAREA != MAP_FAILED ) { + (void)drmUnmap(pSAREA, SAREA_MAX); + } - LockDisplay(dpy); + if ( framebuffer.base != MAP_FAILED ) { + (void)drmUnmap((drmAddress)framebuffer.base, framebuffer.size); + } - 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 ( framebuffer.dev_priv != NULL ) { + Xfree(framebuffer.dev_priv); + } - if (!_XReply(dpy, (xReply*) &reply, 0, False)) - goto out; + if ( fd >= 0 ) { + (void)drmCloseOnce(fd); + } - psc->configs = createConfigsFromProperties(dpy, - reply.numFBConfigs, - reply.numAttribs * 2, - screen, GL_TRUE); + (void)XF86DRICloseConnection(dpy, scrn); - out: - UnlockDisplay(dpy); - return psc->configs != NULL; + 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 ); + } + + fprintf(stderr, "libGL error: reverting to (slow) indirect rendering\n"); + } +#endif /* !GLX_USE_APPLEGL */ + + return psp; } +#endif /* GLX_DIRECT_RENDERING */ + /* ** Allocate the memory for the per screen configs for each screen. @@ -563,8 +1006,17 @@ getFBConfigs(Display *dpy, __GLXdisplayPrivate *priv, int screen) */ static Bool AllocAndFetchScreenConfigs(Display *dpy, __GLXdisplayPrivate *priv) { + xGLXGetVisualConfigsReq *req; + xGLXGetFBConfigsReq *fb_req; + xGLXVendorPrivateWithReplyReq *vpreq; + xGLXGetFBConfigsSGIXReq *sgi_req; + xGLXGetVisualConfigsReply reply; __GLXscreenConfigs *psc; - GLint i, screens; + __GLcontextModes *config; + GLint i, j, nprops, screens; + INT32 buf[__GLX_TOTAL_CONFIG], *props; + unsigned supported_request = 0; + unsigned prop_size; /* ** First allocate memory for the array of per screen configs. @@ -578,30 +1030,159 @@ 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++) { - getVisualConfigs(dpy, priv, i); - getFBConfigs(dpy, priv, i); + 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; + } + } - psc->scr = i; - psc->dpy = dpy; -#ifdef GLX_DIRECT_RENDERING - psc->drawHash = __glxHashCreate(); - if (psc->drawHash == NULL) + + 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; - 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; + } + + /* 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); + +#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] ); + } } #endif } @@ -612,7 +1193,7 @@ static Bool AllocAndFetchScreenConfigs(Display *dpy, __GLXdisplayPrivate *priv) /* ** Initialize the client side extension code. */ -_X_HIDDEN __GLXdisplayPrivate *__glXInitialize(Display* dpy) +__GLXdisplayPrivate *__glXInitialize(Display* dpy) { XExtDisplayInfo *info = __glXFindDisplay(dpy); XExtData **privList, *private, *found; @@ -692,8 +1273,8 @@ _X_HIDDEN __GLXdisplayPrivate *__glXInitialize(Display* dpy) ** (e.g., those called in AllocAndFetchScreenConfigs). */ if (getenv("LIBGL_ALWAYS_INDIRECT") == NULL) { - dpyPriv->dri2Display = dri2CreateDisplay(dpy); - dpyPriv->driDisplay = driCreateDisplay(dpy); + dpyPriv->driDisplay.private = + driCreateDisplay(dpy, &dpyPriv->driDisplay); } #endif @@ -727,7 +1308,7 @@ _X_HIDDEN __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. */ -_X_HIDDEN CARD8 __glXSetupForCommand(Display *dpy) +CARD8 __glXSetupForCommand(Display *dpy) { GLXContext gc; __GLXdisplayPrivate *priv; @@ -768,7 +1349,7 @@ _X_HIDDEN CARD8 __glXSetupForCommand(Display *dpy) * Modify this function to use \c ctx->pc instead of the explicit * \c pc parameter. */ -_X_HIDDEN GLubyte *__glXFlushRenderBuffer(__GLXcontext *ctx, GLubyte *pc) +GLubyte *__glXFlushRenderBuffer(__GLXcontext *ctx, GLubyte *pc) { Display * const dpy = ctx->currentDpy; #ifdef USE_XCB @@ -780,8 +1361,7 @@ _X_HIDDEN GLubyte *__glXFlushRenderBuffer(__GLXcontext *ctx, GLubyte *pc) if ( (dpy != NULL) && (size > 0) ) { #ifdef USE_XCB - xcb_glx_render(c, ctx->currentContextTag, size, - (const uint8_t *)ctx->buf); + xcb_glx_render(c, ctx->currentContextTag, size, (char *)ctx->buf); #else /* Send the entire buffer as an X request */ LockDisplay(dpy); @@ -818,9 +1398,9 @@ _X_HIDDEN GLubyte *__glXFlushRenderBuffer(__GLXcontext *ctx, GLubyte *pc) * \param data Command data. * \param dataLen Size, in bytes, of the command data. */ -_X_HIDDEN void __glXSendLargeChunk(__GLXcontext *gc, GLint requestNumber, - GLint totalRequests, - const GLvoid * data, GLint dataLen) +void __glXSendLargeChunk(__GLXcontext *gc, GLint requestNumber, + GLint totalRequests, + const GLvoid * data, GLint dataLen) { Display *dpy = gc->currentDpy; #ifdef USE_XCB @@ -866,9 +1446,9 @@ _X_HIDDEN void __glXSendLargeChunk(__GLXcontext *gc, GLint requestNumber, * \param data Command data. * \param dataLen Size, in bytes, of the command data. */ -_X_HIDDEN void __glXSendLargeCommand(__GLXcontext *ctx, - const GLvoid *header, GLint headerLen, - const GLvoid *data, GLint dataLen) +void __glXSendLargeCommand(__GLXcontext *ctx, + const GLvoid *header, GLint headerLen, + const GLvoid *data, GLint dataLen) { GLint maxSize; GLint totalRequests, requestNumber; @@ -904,8 +1484,330 @@ _X_HIDDEN 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 -_X_HIDDEN void __glXDumpDrawBuffer(__GLXcontext *ctx) +void __glXDumpDrawBuffer(__GLXcontext *ctx) { GLubyte *p = ctx->buf; GLubyte *end = ctx->pc; @@ -930,23 +1832,9 @@ _X_HIDDEN void __glXDumpDrawBuffer(__GLXcontext *ctx) #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. + * Used only when we are sparc, using sparc assembler. * - * 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) diff --git a/src/glx/x11/glxextensions.c b/src/glx/x11/glxextensions.c index e843718472..1d99b61db0 100644 --- a/src/glx/x11/glxextensions.c +++ b/src/glx/x11/glxextensions.c @@ -356,16 +356,29 @@ __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 -__glXEnableDirectExtension(__GLXscreenConfigs *psc, const char *name) +__glXScrEnableExtension( __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. */ diff --git a/src/glx/x11/glxextensions.h b/src/glx/x11/glxextensions.h index 9cdd05ed76..a4241b6b7f 100644 --- a/src/glx/x11/glxextensions.h +++ b/src/glx/x11/glxextensions.h @@ -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,8 +243,6 @@ 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. diff --git a/src/glx/x11/glxhash.c b/src/glx/x11/glxhash.c deleted file mode 100644 index 9ed0429032..0000000000 --- a/src/glx/x11/glxhash.c +++ /dev/null @@ -1,416 +0,0 @@ -/* glxhash.c -- Small hash table support for integer -> integer mapping - * Taken from libdrm. - * - * Created: Sun Apr 18 09:35:45 1999 by faith@precisioninsight.com - * - * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. - * 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 - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * PRECISION INSIGHT AND/OR ITS 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. - * - * Authors: Rickard E. (Rik) Faith - * - * DESCRIPTION - * - * This file contains a straightforward implementation of a fixed-sized - * hash table using self-organizing linked lists [Knuth73, pp. 398-399] for - * collision resolution. There are two potentially interesting things - * about this implementation: - * - * 1) The table is power-of-two sized. Prime sized tables are more - * traditional, but do not have a significant advantage over power-of-two - * sized table, especially when double hashing is not used for collision - * resolution. - * - * 2) The hash computation uses a table of random integers [Hanson97, - * pp. 39-41]. - * - * FUTURE ENHANCEMENTS - * - * With a table size of 512, the current implementation is sufficient for a - * few hundred keys. Since this is well above the expected size of the - * tables for which this implementation was designed, the implementation of - * dynamic hash tables was postponed until the need arises. A common (and - * naive) approach to dynamic hash table implementation simply creates a - * new hash table when necessary, rehashes all the data into the new table, - * and destroys the old table. The approach in [Larson88] is superior in - * two ways: 1) only a portion of the table is expanded when needed, - * distributing the expansion cost over several insertions, and 2) portions - * of the table can be locked, enabling a scalable thread-safe - * implementation. - * - * REFERENCES - * - * [Hanson97] David R. Hanson. C Interfaces and Implementations: - * Techniques for Creating Reusable Software. Reading, Massachusetts: - * Addison-Wesley, 1997. - * - * [Knuth73] Donald E. Knuth. The Art of Computer Programming. Volume 3: - * Sorting and Searching. Reading, Massachusetts: Addison-Wesley, 1973. - * - * [Larson88] Per-Ake Larson. "Dynamic Hash Tables". CACM 31(4), April - * 1988, pp. 446-457. - * - */ - -#include "glxhash.h" -#include - -#define HASH_MAIN 0 - -#include -#include - -#define HASH_MAGIC 0xdeadbeef -#define HASH_DEBUG 0 -#define HASH_SIZE 512 /* Good for about 100 entries */ - /* If you change this value, you probably - have to change the HashHash hashing - function! */ - -#define HASH_ALLOC malloc -#define HASH_FREE free -#define HASH_RANDOM_DECL -#define HASH_RANDOM_INIT(seed) srandom(seed) -#define HASH_RANDOM random() -#define HASH_RANDOM_DESTROY - -typedef struct __glxHashBucket { - unsigned long key; - void *value; - struct __glxHashBucket *next; -} __glxHashBucket, *__glxHashBucketPtr; - -typedef struct __glxHashTable *__glxHashTablePtr; -struct __glxHashTable { - unsigned long magic; - unsigned long entries; - unsigned long hits; /* At top of linked list */ - unsigned long partials; /* Not at top of linked list */ - unsigned long misses; /* Not in table */ - __glxHashBucketPtr buckets[HASH_SIZE]; - int p0; - __glxHashBucketPtr p1; -}; - -static unsigned long HashHash(unsigned long key) -{ - unsigned long hash = 0; - unsigned long tmp = key; - static int init = 0; - static unsigned long scatter[256]; - int i; - - if (!init) { - HASH_RANDOM_DECL; - HASH_RANDOM_INIT(37); - for (i = 0; i < 256; i++) scatter[i] = HASH_RANDOM; - HASH_RANDOM_DESTROY; - ++init; - } - - while (tmp) { - hash = (hash << 1) + scatter[tmp & 0xff]; - tmp >>= 8; - } - - hash %= HASH_SIZE; -#if HASH_DEBUG - printf( "Hash(%d) = %d\n", key, hash); -#endif - return hash; -} - -_X_HIDDEN __glxHashTable *__glxHashCreate(void) -{ - __glxHashTablePtr table; - int i; - - table = HASH_ALLOC(sizeof(*table)); - if (!table) return NULL; - table->magic = HASH_MAGIC; - table->entries = 0; - table->hits = 0; - table->partials = 0; - table->misses = 0; - - for (i = 0; i < HASH_SIZE; i++) table->buckets[i] = NULL; - return table; -} - -_X_HIDDEN int __glxHashDestroy(__glxHashTable *t) -{ - __glxHashTablePtr table = (__glxHashTablePtr)t; - __glxHashBucketPtr bucket; - __glxHashBucketPtr next; - int i; - - if (table->magic != HASH_MAGIC) return -1; /* Bad magic */ - - for (i = 0; i < HASH_SIZE; i++) { - for (bucket = table->buckets[i]; bucket;) { - next = bucket->next; - HASH_FREE(bucket); - bucket = next; - } - } - HASH_FREE(table); - return 0; -} - -/* Find the bucket and organize the list so that this bucket is at the - top. */ - -static __glxHashBucketPtr HashFind(__glxHashTablePtr table, - unsigned long key, unsigned long *h) -{ - unsigned long hash = HashHash(key); - __glxHashBucketPtr prev = NULL; - __glxHashBucketPtr bucket; - - if (h) *h = hash; - - for (bucket = table->buckets[hash]; bucket; bucket = bucket->next) { - if (bucket->key == key) { - if (prev) { - /* Organize */ - prev->next = bucket->next; - bucket->next = table->buckets[hash]; - table->buckets[hash] = bucket; - ++table->partials; - } else { - ++table->hits; - } - return bucket; - } - prev = bucket; - } - ++table->misses; - return NULL; -} - -_X_HIDDEN int __glxHashLookup(__glxHashTable *t, - unsigned long key, void **value) -{ - __glxHashTablePtr table = (__glxHashTablePtr)t; - __glxHashBucketPtr bucket; - - if (!table || table->magic != HASH_MAGIC) return -1; /* Bad magic */ - - bucket = HashFind(table, key, NULL); - if (!bucket) return 1; /* Not found */ - *value = bucket->value; - return 0; /* Found */ -} - -_X_HIDDEN int __glxHashInsert(__glxHashTable *t, - unsigned long key, void *value) -{ - __glxHashTablePtr table = (__glxHashTablePtr)t; - __glxHashBucketPtr bucket; - unsigned long hash; - - if (table->magic != HASH_MAGIC) return -1; /* Bad magic */ - - if (HashFind(table, key, &hash)) return 1; /* Already in table */ - - bucket = HASH_ALLOC(sizeof(*bucket)); - if (!bucket) return -1; /* Error */ - bucket->key = key; - bucket->value = value; - bucket->next = table->buckets[hash]; - table->buckets[hash] = bucket; -#if HASH_DEBUG - printf("Inserted %d at %d/%p\n", key, hash, bucket); -#endif - return 0; /* Added to table */ -} - -_X_HIDDEN int __glxHashDelete(__glxHashTable *t, unsigned long key) -{ - __glxHashTablePtr table = (__glxHashTablePtr)t; - unsigned long hash; - __glxHashBucketPtr bucket; - - if (table->magic != HASH_MAGIC) return -1; /* Bad magic */ - - bucket = HashFind(table, key, &hash); - - if (!bucket) return 1; /* Not found */ - - table->buckets[hash] = bucket->next; - HASH_FREE(bucket); - return 0; -} - -_X_HIDDEN int __glxHashNext(__glxHashTable *t, - unsigned long *key, void **value) -{ - __glxHashTablePtr table = (__glxHashTablePtr)t; - - while (table->p0 < HASH_SIZE) { - if (table->p1) { - *key = table->p1->key; - *value = table->p1->value; - table->p1 = table->p1->next; - return 1; - } - table->p1 = table->buckets[table->p0]; - ++table->p0; - } - return 0; -} - -_X_HIDDEN int __glxHashFirst(__glxHashTable *t, - unsigned long *key, void **value) -{ - __glxHashTablePtr table = (__glxHashTablePtr)t; - - if (table->magic != HASH_MAGIC) return -1; /* Bad magic */ - - table->p0 = 0; - table->p1 = table->buckets[0]; - return __glxHashNext(table, key, value); -} - -#if HASH_MAIN -#define DIST_LIMIT 10 -static int dist[DIST_LIMIT]; - -static void clear_dist(void) { - int i; - - for (i = 0; i < DIST_LIMIT; i++) dist[i] = 0; -} - -static int count_entries(__glxHashBucketPtr bucket) -{ - int count = 0; - - for (; bucket; bucket = bucket->next) ++count; - return count; -} - -static void update_dist(int count) -{ - if (count >= DIST_LIMIT) ++dist[DIST_LIMIT-1]; - else ++dist[count]; -} - -static void compute_dist(__glxHashTablePtr table) -{ - int i; - __glxHashBucketPtr bucket; - - printf("Entries = %ld, hits = %ld, partials = %ld, misses = %ld\n", - table->entries, table->hits, table->partials, table->misses); - clear_dist(); - for (i = 0; i < HASH_SIZE; i++) { - bucket = table->buckets[i]; - update_dist(count_entries(bucket)); - } - for (i = 0; i < DIST_LIMIT; i++) { - if (i != DIST_LIMIT-1) printf("%5d %10d\n", i, dist[i]); - else printf("other %10d\n", dist[i]); - } -} - -static void check_table(__glxHashTablePtr table, - unsigned long key, unsigned long value) -{ - unsigned long retval = 0; - int retcode = __glxHashLookup(table, key, &retval); - - switch (retcode) { - case -1: - printf("Bad magic = 0x%08lx:" - " key = %lu, expected = %lu, returned = %lu\n", - table->magic, key, value, retval); - break; - case 1: - printf("Not found: key = %lu, expected = %lu returned = %lu\n", - key, value, retval); - break; - case 0: - if (value != retval) - printf("Bad value: key = %lu, expected = %lu, returned = %lu\n", - key, value, retval); - break; - default: - printf("Bad retcode = %d: key = %lu, expected = %lu, returned = %lu\n", - retcode, key, value, retval); - break; - } -} - -int main(void) -{ - __glxHashTablePtr table; - int i; - - printf("\n***** 256 consecutive integers ****\n"); - table = __glxHashCreate(); - for (i = 0; i < 256; i++) __glxHashInsert(table, i, i); - for (i = 0; i < 256; i++) check_table(table, i, i); - for (i = 256; i >= 0; i--) check_table(table, i, i); - compute_dist(table); - __glxHashDestroy(table); - - printf("\n***** 1024 consecutive integers ****\n"); - table = __glxHashCreate(); - for (i = 0; i < 1024; i++) __glxHashInsert(table, i, i); - for (i = 0; i < 1024; i++) check_table(table, i, i); - for (i = 1024; i >= 0; i--) check_table(table, i, i); - compute_dist(table); - __glxHashDestroy(table); - - printf("\n***** 1024 consecutive page addresses (4k pages) ****\n"); - table = __glxHashCreate(); - for (i = 0; i < 1024; i++) __glxHashInsert(table, i*4096, i); - for (i = 0; i < 1024; i++) check_table(table, i*4096, i); - for (i = 1024; i >= 0; i--) check_table(table, i*4096, i); - compute_dist(table); - __glxHashDestroy(table); - - printf("\n***** 1024 random integers ****\n"); - table = __glxHashCreate(); - srandom(0xbeefbeef); - for (i = 0; i < 1024; i++) __glxHashInsert(table, random(), i); - srandom(0xbeefbeef); - for (i = 0; i < 1024; i++) check_table(table, random(), i); - srandom(0xbeefbeef); - for (i = 0; i < 1024; i++) check_table(table, random(), i); - compute_dist(table); - __glxHashDestroy(table); - - printf("\n***** 5000 random integers ****\n"); - table = __glxHashCreate(); - srandom(0xbeefbeef); - for (i = 0; i < 5000; i++) __glxHashInsert(table, random(), i); - srandom(0xbeefbeef); - for (i = 0; i < 5000; i++) check_table(table, random(), i); - srandom(0xbeefbeef); - for (i = 0; i < 5000; i++) check_table(table, random(), i); - compute_dist(table); - __glxHashDestroy(table); - - return 0; -} -#endif diff --git a/src/glx/x11/glxhash.h b/src/glx/x11/glxhash.h deleted file mode 100644 index 66012fb889..0000000000 --- a/src/glx/x11/glxhash.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef _GLX_HASH_H_ -#define _GLX_HASH_H_ - - -typedef struct __glxHashTable __glxHashTable; - -/* Hash table routines */ -extern __glxHashTable *__glxHashCreate(void); -extern int __glxHashDestroy(__glxHashTable *t); -extern int __glxHashLookup(__glxHashTable *t, unsigned long key, void **value); -extern int __glxHashInsert(__glxHashTable *t, unsigned long key, void *value); -extern int __glxHashDelete(__glxHashTable *t, unsigned long key); -extern int __glxHashFirst(__glxHashTable *t, unsigned long *key, void **value); -extern int __glxHashNext(__glxHashTable *t, unsigned long *key, void **value); - -#endif /* _GLX_HASH_H_ */ diff --git a/src/glx/x11/indirect.c b/src/glx/x11/indirect.c index 871adddb95..fbb2a91956 100644 --- a/src/glx/x11/indirect.c +++ b/src/glx/x11/indirect.c @@ -300,9 +300,7 @@ __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); @@ -326,9 +324,7 @@ __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); @@ -364,10 +360,6 @@ __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) { @@ -401,9 +393,7 @@ __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); @@ -428,9 +418,7 @@ __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); @@ -3594,10 +3582,6 @@ __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) { @@ -3631,10 +3615,6 @@ __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) { @@ -3668,10 +3648,6 @@ __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) { @@ -3740,9 +3716,7 @@ __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); @@ -3834,9 +3808,7 @@ __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); @@ -3869,9 +3841,7 @@ __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); @@ -3909,9 +3879,7 @@ __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); @@ -3949,9 +3917,7 @@ __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); @@ -3987,9 +3953,7 @@ __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); @@ -4025,9 +3989,7 @@ __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); @@ -4063,9 +4025,7 @@ __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); @@ -4103,9 +4063,7 @@ __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); @@ -4143,9 +4101,7 @@ __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); @@ -4181,9 +4137,7 @@ __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); @@ -4220,9 +4174,7 @@ __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); @@ -4258,10 +4210,9 @@ 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); @@ -4296,9 +4247,7 @@ __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); @@ -4336,9 +4285,7 @@ __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); @@ -4376,9 +4323,7 @@ __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); @@ -4416,9 +4361,7 @@ __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); @@ -4456,9 +4399,7 @@ __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); @@ -4498,9 +4439,7 @@ __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); @@ -4544,9 +4483,7 @@ __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); @@ -4585,9 +4522,7 @@ __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); @@ -4627,9 +4562,7 @@ __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); @@ -4670,9 +4603,7 @@ __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); @@ -4713,9 +4644,7 @@ __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); @@ -5083,13 +5012,7 @@ __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); @@ -5124,7 +5047,7 @@ glAreTexturesResidentEXT(GLsizei n, const GLuint * textures, { __GLXcontext *const gc = __glXGetCurrentContext(); - if (gc->driContext) { + if (gc->isDirect) { return CALL_AreTexturesResident(GET_DISPATCH(), (n, textures, residences)); } else { @@ -5132,10 +5055,6 @@ 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, @@ -5244,13 +5163,7 @@ __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); @@ -5274,16 +5187,12 @@ glDeleteTexturesEXT(GLsizei n, const GLuint * textures) { __GLXcontext *const gc = __glXGetCurrentContext(); - if (gc->driContext) { + if (gc->isDirect) { 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, @@ -5303,13 +5212,7 @@ __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); @@ -5342,16 +5245,12 @@ glGenTexturesEXT(GLsizei n, GLuint * textures) { __GLXcontext *const gc = __glXGetCurrentContext(); - if (gc->driContext) { + if (gc->isDirect) { 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, @@ -5372,9 +5271,7 @@ __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); @@ -5404,7 +5301,7 @@ glIsTextureEXT(GLuint texture) { __GLXcontext *const gc = __glXGetCurrentContext(); - if (gc->driContext) { + if (gc->isDirect) { return CALL_IsTexture(GET_DISPATCH(), (texture)); } else { __GLXcontext *const gc = __glXGetCurrentContext(); @@ -5431,10 +5328,6 @@ __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); @@ -5672,9 +5565,7 @@ __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); @@ -5718,7 +5609,7 @@ glGetColorTableEXT(GLenum target, GLenum format, GLenum type, GLvoid * table) { __GLXcontext *const gc = __glXGetCurrentContext(); - if (gc->driContext) { + if (gc->isDirect) { CALL_GetColorTable(GET_DISPATCH(), (target, format, type, table)); } else { __GLXcontext *const gc = __glXGetCurrentContext(); @@ -5750,9 +5641,7 @@ __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); @@ -5791,7 +5680,7 @@ glGetColorTableParameterfvEXT(GLenum target, GLenum pname, GLfloat * params) { __GLXcontext *const gc = __glXGetCurrentContext(); - if (gc->driContext) { + if (gc->isDirect) { CALL_GetColorTableParameterfv(GET_DISPATCH(), (target, pname, params)); } else { @@ -5820,9 +5709,7 @@ __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); @@ -5861,7 +5748,7 @@ glGetColorTableParameterivEXT(GLenum target, GLenum pname, GLint * params) { __GLXcontext *const gc = __glXGetCurrentContext(); - if (gc->driContext) { + if (gc->isDirect) { CALL_GetColorTableParameteriv(GET_DISPATCH(), (target, pname, params)); } else { @@ -6142,9 +6029,7 @@ __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); @@ -6184,7 +6069,7 @@ gl_dispatch_stub_356(GLenum target, GLenum format, GLenum type, { __GLXcontext *const gc = __glXGetCurrentContext(); - if (gc->driContext) { + if (gc->isDirect) { CALL_GetConvolutionFilter(GET_DISPATCH(), (target, format, type, image)); } else { @@ -6218,9 +6103,7 @@ __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); @@ -6259,7 +6142,7 @@ gl_dispatch_stub_357(GLenum target, GLenum pname, GLfloat * params) { __GLXcontext *const gc = __glXGetCurrentContext(); - if (gc->driContext) { + if (gc->isDirect) { CALL_GetConvolutionParameterfv(GET_DISPATCH(), (target, pname, params)); } else { @@ -6288,9 +6171,7 @@ __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); @@ -6329,7 +6210,7 @@ gl_dispatch_stub_358(GLenum target, GLenum pname, GLint * params) { __GLXcontext *const gc = __glXGetCurrentContext(); - if (gc->driContext) { + if (gc->isDirect) { CALL_GetConvolutionParameteriv(GET_DISPATCH(), (target, pname, params)); } else { @@ -6359,9 +6240,7 @@ __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); @@ -6406,7 +6285,7 @@ gl_dispatch_stub_361(GLenum target, GLboolean reset, GLenum format, { __GLXcontext *const gc = __glXGetCurrentContext(); - if (gc->driContext) { + if (gc->isDirect) { CALL_GetHistogram(GET_DISPATCH(), (target, reset, format, type, values)); } else { @@ -6440,9 +6319,7 @@ __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); @@ -6480,7 +6357,7 @@ gl_dispatch_stub_362(GLenum target, GLenum pname, GLfloat * params) { __GLXcontext *const gc = __glXGetCurrentContext(); - if (gc->driContext) { + if (gc->isDirect) { CALL_GetHistogramParameterfv(GET_DISPATCH(), (target, pname, params)); } else { __GLXcontext *const gc = __glXGetCurrentContext(); @@ -6508,9 +6385,7 @@ __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); @@ -6548,7 +6423,7 @@ gl_dispatch_stub_363(GLenum target, GLenum pname, GLint * params) { __GLXcontext *const gc = __glXGetCurrentContext(); - if (gc->driContext) { + if (gc->isDirect) { CALL_GetHistogramParameteriv(GET_DISPATCH(), (target, pname, params)); } else { __GLXcontext *const gc = __glXGetCurrentContext(); @@ -6577,9 +6452,7 @@ __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); @@ -6620,7 +6493,7 @@ gl_dispatch_stub_364(GLenum target, GLboolean reset, GLenum format, { __GLXcontext *const gc = __glXGetCurrentContext(); - if (gc->driContext) { + if (gc->isDirect) { CALL_GetMinmax(GET_DISPATCH(), (target, reset, format, type, values)); } else { __GLXcontext *const gc = __glXGetCurrentContext(); @@ -6653,9 +6526,7 @@ __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); @@ -6691,7 +6562,7 @@ gl_dispatch_stub_365(GLenum target, GLenum pname, GLfloat * params) { __GLXcontext *const gc = __glXGetCurrentContext(); - if (gc->driContext) { + if (gc->isDirect) { CALL_GetMinmaxParameterfv(GET_DISPATCH(), (target, pname, params)); } else { __GLXcontext *const gc = __glXGetCurrentContext(); @@ -6718,9 +6589,7 @@ __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); @@ -6756,7 +6625,7 @@ gl_dispatch_stub_366(GLenum target, GLenum pname, GLint * params) { __GLXcontext *const gc = __glXGetCurrentContext(); - if (gc->driContext) { + if (gc->isDirect) { CALL_GetMinmaxParameteriv(GET_DISPATCH(), (target, pname, params)); } else { __GLXcontext *const gc = __glXGetCurrentContext(); @@ -7599,26 +7468,6 @@ __indirect_glGetProgramivARB(GLenum target, GLenum pname, GLint * params) return; } -#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, @@ -7636,26 +7485,6 @@ __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, @@ -7756,10 +7585,6 @@ __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) { @@ -8375,13 +8200,7 @@ __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); @@ -8419,13 +8238,7 @@ __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); @@ -8458,9 +8271,7 @@ __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); @@ -8496,9 +8307,7 @@ __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); @@ -8534,9 +8343,7 @@ __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); @@ -8576,9 +8383,7 @@ __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); @@ -8609,10 +8414,6 @@ __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) { @@ -8973,10 +8774,6 @@ __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, @@ -9012,10 +8809,6 @@ __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, @@ -9052,10 +8845,6 @@ __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, @@ -9262,10 +9051,6 @@ __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); @@ -9286,10 +9071,6 @@ __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); @@ -9310,10 +9091,6 @@ __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); @@ -9333,10 +9110,6 @@ __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); @@ -9788,10 +9561,6 @@ __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); @@ -9810,10 +9579,6 @@ __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); @@ -9832,10 +9597,6 @@ __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); @@ -9854,10 +9615,6 @@ __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); @@ -9876,10 +9633,6 @@ __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); @@ -9898,10 +9651,6 @@ __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); @@ -9920,10 +9669,6 @@ __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); @@ -9942,10 +9687,6 @@ __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); @@ -9964,10 +9705,6 @@ __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); @@ -9986,10 +9723,6 @@ __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); @@ -10008,10 +9741,6 @@ __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); @@ -10030,10 +9759,6 @@ __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); @@ -10052,10 +9777,6 @@ __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); @@ -10122,10 +9843,6 @@ __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, @@ -10150,10 +9867,6 @@ __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, @@ -10177,10 +9890,6 @@ __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); @@ -10205,10 +9914,6 @@ __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); @@ -10230,10 +9935,6 @@ __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); @@ -10258,10 +9959,6 @@ __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); @@ -10347,10 +10044,6 @@ __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); @@ -10369,10 +10062,6 @@ __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); @@ -10472,10 +10161,6 @@ __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, @@ -10495,10 +10180,6 @@ __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, diff --git a/src/glx/x11/indirect.h b/src/glx/x11/indirect.h index 0719a1b302..f8c88b36bb 100644 --- a/src/glx/x11/indirect.h +++ b/src/glx/x11/indirect.h @@ -517,9 +517,7 @@ 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); diff --git a/src/glx/x11/indirect_init.c b/src/glx/x11/indirect_init.c index 852fe712c6..479184337c 100644 --- a/src/glx/x11/indirect_init.c +++ b/src/glx/x11/indirect_init.c @@ -526,9 +526,7 @@ __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; diff --git a/src/glx/x11/indirect_texture_compression.c b/src/glx/x11/indirect_texture_compression.c deleted file mode 100644 index 5676858017..0000000000 --- a/src/glx/x11/indirect_texture_compression.c +++ /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 - */ - -#include "packrender.h" -#include "packsingle.h" -#include "indirect.h" - -#include - - -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 ); - } -} diff --git a/src/glx/x11/indirect_vertex_array.c b/src/glx/x11/indirect_vertex_array.c index 09d7244ba9..90ec277c41 100644 --- a/src/glx/x11/indirect_vertex_array.c +++ b/src/glx/x11/indirect_vertex_array.c @@ -32,7 +32,7 @@ #include #include "glxextensions.h" #include "indirect_vertex_array.h" -#include "indirect_vertex_array_priv.h" +#include "indirect_va_private.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, pc); + pc = __glXFlushRenderBuffer(gc, gc->pc); } pc = emit_element_none( pc, arrays, first + i ); } if ( (pc + 4) >= gc->bufEnd ) { - pc = __glXFlushRenderBuffer(gc, pc); + pc = __glXFlushRenderBuffer(gc, 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, - unsigned int * total_requests, + size_t * 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; - unsigned total_requests = 0; + size_t 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, pc); + pc = __glXFlushRenderBuffer(gc, 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, pc); + pc = __glXFlushRenderBuffer(gc, gc->pc); } (void) memcpy( pc, end_cmd, 4 ); @@ -770,10 +770,9 @@ emit_DrawElements_old( GLenum mode, GLsizei count, GLenum type, GLubyte * pc; size_t elements_per_request; - unsigned total_requests = 0; + size_t total_requests = 0; unsigned i; unsigned req; - unsigned req_element=0; pc = emit_DrawArrays_header_old( gc, arrays, & elements_per_request, @@ -791,7 +790,7 @@ emit_DrawElements_old( GLenum mode, GLsizei count, GLenum type, switch( type ) { case GL_UNSIGNED_INT: { - const GLuint * ui_ptr = (const GLuint *) indices + req_element; + const GLuint * ui_ptr = (const GLuint *) indices; for ( i = 0 ; i < elements_per_request ; i++ ) { const GLint index = (GLint) *(ui_ptr++); @@ -800,7 +799,7 @@ emit_DrawElements_old( GLenum mode, GLsizei count, GLenum type, break; } case GL_UNSIGNED_SHORT: { - const GLushort * us_ptr = (const GLushort *) indices + req_element; + const GLushort * us_ptr = (const GLushort *) indices; for ( i = 0 ; i < elements_per_request ; i++ ) { const GLint index = (GLint) *(us_ptr++); @@ -809,7 +808,7 @@ emit_DrawElements_old( GLenum mode, GLsizei count, GLenum type, break; } case GL_UNSIGNED_BYTE: { - const GLubyte * ub_ptr = (const GLubyte *) indices + req_element; + const GLubyte * ub_ptr = (const GLubyte *) indices; for ( i = 0 ; i < elements_per_request ; i++ ) { const GLint index = (GLint) *(ub_ptr++); @@ -827,7 +826,6 @@ emit_DrawElements_old( GLenum mode, GLsizei count, GLenum type, } count -= elements_per_request; - req_element += elements_per_request; } diff --git a/src/glx/x11/indirect_vertex_array_priv.h b/src/glx/x11/indirect_vertex_array_priv.h deleted file mode 100644 index ab97dc645f..0000000000 --- a/src/glx/x11/indirect_vertex_array_priv.h +++ /dev/null @@ -1,308 +0,0 @@ -/* - * (C) Copyright IBM Corporation 2004, 2005 - * 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 - * 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 - * IBM, - * 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. - */ - -#ifndef _INDIRECT_VA_PRIVATE_ -#define _INDIRECT_VA_PRIVATE_ - -/** - * \file indirect_va_private.h - * - * \author Ian Romanick - */ - -#include - -#include "glxclient.h" -#include "indirect.h" -#include - - -/** - * State descriptor for a single array of vertex data. - */ -struct array_state { - /** - * Pointer to the application supplied data. - */ - const void * data; - - /** - * Enum representing the type of the application supplied data. - */ - GLenum data_type; - - /** - * Stride value supplied by the application. This value is not used - * internally. It is only kept so that it can be queried by the - * application using glGet*v. - */ - GLsizei user_stride; - - /** - * Calculated size, in bytes, of a single element in the array. This - * is calculated based on \c count and the size of the data type - * represented by \c data_type. - */ - GLsizei element_size; - - /** - * Actual byte-stride from one element to the next. This value will - * be equal to either \c user_stride or \c element_stride. - */ - GLsizei true_stride; - - /** - * Number of data values in each element. - */ - GLint count; - - /** - * "Normalized" data is on the range [0,1] (unsigned) or [-1,1] (signed). - * This is used for mapping integral types to floating point types. - */ - GLboolean normalized; - - /** - * Pre-calculated GLX protocol command header. - */ - uint32_t header[2]; - - /** - * Size of the header data. For simple data, like glColorPointerfv, - * this is 4. For complex data that requires either a count (e.g., - * glWeightfvARB), an index (e.g., glVertexAttrib1fvARB), or a - * selector enum (e.g., glMultiTexCoord2fv) this is 8. - */ - unsigned header_size; - - /** - * Set to \c GL_TRUE if this array is enabled. Otherwise, it is set - * to \c GL_FALSE. - */ - GLboolean enabled; - - /** - * For multi-arrayed data (e.g., texture coordinates, generic vertex - * program attributes, etc.), this specifies which array this is. - */ - unsigned index; - - /** - * Per-array-type key. For most arrays, this will be the GL enum for - * that array (e.g., GL_VERTEX_ARRAY for vertex data, GL_NORMAL_ARRAY - * for normal data, GL_TEXTURE_COORD_ARRAY for texture coordinate data, - * etc.). - */ - GLenum key; - - /** - * If this array can be used with the "classic" \c glDrawArrays protocol, - * this is set to \c GL_TRUE. Otherwise, it is set to \c GL_FALSE. - */ - GLboolean old_DrawArrays_possible; -}; - - -/** - * Array state that is pushed / poped by \c glPushClientAttrib and - * \c glPopClientAttrib. - */ -struct array_stack_state { - /** - * Pointer to the application supplied data. - */ - const void * data; - - /** - * Enum representing the type of the application supplied data. - */ - GLenum data_type; - - /** - * Stride value supplied by the application. This value is not used - * internally. It is only kept so that it can be queried by the - * application using glGet*v. - */ - GLsizei user_stride; - - /** - * Number of data values in each element. - */ - GLint count; - - /** - * Per-array-type key. For most arrays, this will be the GL enum for - * that array (e.g., GL_VERTEX_ARRAY for vertex data, GL_NORMAL_ARRAY - * for normal data, GL_TEXTURE_COORD_ARRAY for texture coordinate data, - * etc.). - */ - GLenum key; - - /** - * For multi-arrayed data (e.g., texture coordinates, generic vertex - * program attributes, etc.), this specifies which array this is. - */ - unsigned index; - - /** - * Set to \c GL_TRUE if this array is enabled. Otherwise, it is set - * to \c GL_FALSE. - */ - GLboolean enabled; -}; - - -/** - * Collection of all the vertex array state. - */ -struct array_state_vector { - /** - * Number of arrays tracked by \c ::arrays. - */ - size_t num_arrays; - - /** - * Array of vertex array state. This array contains all of the valid - * vertex arrays. If a vertex array isn't in this array, then it isn't - * valid. For example, if an implementation does not support - * EXT_fog_coord, there won't be a GL_FOG_COORD_ARRAY entry in this - * array. - */ - struct array_state * arrays; - - /** - * Number of currently enabled client-side arrays. The value of this - * field is only valid if \c array_info_cache_valid is true. - */ - size_t enabled_client_array_count; - - /** - * \name ARRAY_INFO cache. - * - * These fields track the state of the ARRAY_INFO cache. The - * \c array_info_cache_size is the size of the actual data stored in - * \c array_info_cache. \c array_info_cache_buffer_size is the size of - * the buffer. This will always be greater than or equal to - * \c array_info_cache_size. - * - * \note - * There are some bytes of extra data before \c array_info_cache that is - * used to hold the header for RenderLarge commands. This is - * \b not included in \c array_info_cache_size or - * \c array_info_cache_buffer_size. \c array_info_cache_base stores a - * pointer to the true start of the buffer (i.e., what malloc returned). - */ - /*@{*/ - size_t array_info_cache_size; - size_t array_info_cache_buffer_size; - void * array_info_cache; - void * array_info_cache_base; - /*@}*/ - - - /** - * Is the cache of ARRAY_INFO data valid? The cache can become invalid - * when one of several state changes occur. Among these chages are - * modifying the array settings for an enabled array and enabling / - * disabling an array. - */ - GLboolean array_info_cache_valid; - - /** - * Is it possible to use the GL 1.1 / EXT_vertex_arrays protocol? Use - * of this protocol is disabled with really old servers (i.e., servers - * that don't support GL 1.1 or EXT_vertex_arrays) or when an environment - * variable is set. - * - * \todo - * GL 1.1 and EXT_vertex_arrays use identical protocol, but have different - * opcodes for \c glDrawArrays. For servers that advertise one or the - * other, there should be a way to select which opcode to use. - */ - GLboolean old_DrawArrays_possible; - - /** - * Is it possible to use the new GL X.X / ARB_vertex_buffer_object - * protocol? - * - * \todo - * This protocol has not yet been defined by the ARB, but is currently a - * work in progress. This field is a place-holder. - */ - GLboolean new_DrawArrays_possible; - - /** - * Active texture unit set by \c glClientActiveTexture. - * - * \sa __glXGetActiveTextureUnit - */ - unsigned active_texture_unit; - - /** - * Number of supported texture units. Even if ARB_multitexture / - * GL 1.3 are not supported, this will be at least 1. When multitexture - * is supported, this will be the value queried by calling - * \c glGetIntegerv with \c GL_MAX_TEXTURE_UNITS. - * - * \todo - * Investigate if this should be the value of \c GL_MAX_TEXTURE_COORDS - * instead (if GL 2.0 / ARB_fragment_shader / ARB_fragment_program / - * NV_fragment_program are supported). - */ - unsigned num_texture_units; - - /** - * Number of generic vertex program attribs. If GL_ARB_vertex_program - * is not supported, this will be zero. Otherwise it will be the value - * queries by calling \c glGetProgramiv with \c GL_VERTEX_PROGRAM_ARB - * and \c GL_MAX_PROGRAM_ATTRIBS_ARB. - */ - unsigned num_vertex_program_attribs; - - /** - * \n Methods for implementing various GL functions. - * - * These method pointers are only valid \c array_info_cache_valid is set. - * When each function starts, it much check \c array_info_cache_valid. - * If it is not set, it must call \c fill_array_info_cache and call - * the new method. - * - * \sa fill_array_info_cache - * - * \todo - * Write code to plug these functions directly into the dispatch table. - */ - /*@{*/ - void (*DrawArrays)( GLenum, GLint, GLsizei ); - void (*DrawElements)( GLenum mode, GLsizei count, GLenum type, - const GLvoid *indices ); - /*@}*/ - - struct array_stack_state * stack; - unsigned active_texture_unit_stack[ __GL_CLIENT_ATTRIB_STACK_DEPTH ]; - unsigned stack_index; -}; - -#endif /* _INDIRECT_VA_PRIVATE_ */ diff --git a/src/glx/x11/singlepix.c b/src/glx/x11/singlepix.c index 144e5df743..cd88684f70 100644 --- a/src/glx/x11/singlepix.c +++ b/src/glx/x11/singlepix.c @@ -117,7 +117,7 @@ void NAME(_gloffset_GetSeparableFilter)(GLenum target, GLenum format, GLenum typ { __GLXcontext * const gc = __glXGetCurrentContext(); - if (gc->driContext) { + if (gc->isDirect) { CALL_GetSeparableFilter(GET_DISPATCH(), (target, format, type, row, column, span)); return; diff --git a/src/glx/x11/xf86dri.h b/src/glx/x11/xf86dri.h index a6a57c3135..c8c878f127 100644 --- a/src/glx/x11/xf86dri.h +++ b/src/glx/x11/xf86dri.h @@ -64,6 +64,8 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #ifndef _XF86DRI_SERVER_ +#include + _XFUNCPROTOBEGIN Bool XF86DRIQueryExtension( Display *dpy, int *event_base, int *error_base ); @@ -91,14 +93,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( Display *dpy, int screen, - XID context_id ); +extern GLboolean XF86DRIDestroyContext( __DRInativeDisplay *dpy, int screen, + __DRIid context_id ); -extern GLboolean XF86DRICreateDrawable( Display *dpy, int screen, - XID drawable, drm_drawable_t *hHWDrawable ); +extern GLboolean XF86DRICreateDrawable( __DRInativeDisplay *dpy, int screen, + __DRIid drawable, drm_drawable_t *hHWDrawable ); -extern GLboolean XF86DRIDestroyDrawable( Display *dpy, int screen, - XID drawable); +extern GLboolean XF86DRIDestroyDrawable( __DRInativeDisplay *dpy, int screen, + __DRIid drawable); Bool XF86DRIGetDrawableInfo( Display *dpy, int screen, Drawable drawable, unsigned int *index, unsigned int *stamp, diff --git a/src/glx/x11/xfont.c b/src/glx/x11/xfont.c index 6ec8c2d6bf..f3e3da3e79 100644 --- a/src/glx/x11/xfont.c +++ b/src/glx/x11/xfont.c @@ -33,7 +33,6 @@ called by that routine when direct rendering is enabled. */ -#ifdef GLX_DIRECT_RENDERING #include "glxclient.h" @@ -209,7 +208,8 @@ static XCharStruct *isvalid(XFontStruct *fs, int which) return(NULL); } -_X_HIDDEN void DRI_glXUseXFont( Font font, int first, int count, int listbase ) + +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); } -#endif +/* The End. */ diff --git a/src/mesa/drivers/dri/common/dri_util.c b/src/mesa/drivers/dri/common/dri_util.c index 2013125efe..fff79c36ad 100644 --- a/src/mesa/drivers/dri/common/dri_util.c +++ b/src/mesa/drivers/dri/common/dri_util.c @@ -55,19 +55,39 @@ #include "dri_util.h" #include "drm_sarea.h" -#include "utils.h" #ifndef GLX_OML_sync_control -typedef GLboolean ( * PFNGLXGETMSCRATEOMLPROC) (__DRIdrawable *drawable, int32_t *numerator, int32_t *denominator); +typedef GLboolean ( * PFNGLXGETMSCRATEOMLPROC) (__DRInativeDisplay *dpy, __DRIid 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 just a token extension used to signal that the driver - * supports setting a read drawable. + * This is used in a couple of places that call \c driCreateNewDrawable. */ -const __DRIextension driReadDrawableExtension = { - __DRI_READ_DRAWABLE, __DRI_READ_DRAWABLE_VERSION -}; +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); + /** * Print message to \c stderr if the \c LIBGL_DEBUG environment variable @@ -91,19 +111,64 @@ __driUtilMessage(const char *f, ...) } } -GLint -driIntersectArea( drm_clip_rect_t rect1, drm_clip_rect_t rect2 ) + +/*****************************************************************/ +/** \name Drawable list management */ +/*****************************************************************/ +/*@{*/ + +static GLboolean __driAddDrawable(void *drawHash, __DRIdrawable *pdraw) { - 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; + __DRIdrawablePrivate *pdp = (__DRIdrawablePrivate *)pdraw->private; - if (rect1.x1 > rect1.x2 || rect1.y1 > rect1.y2) return 0; + if (drmHashInsert(drawHash, pdp->draw, pdraw)) + return GL_FALSE; - return (rect1.x2 - rect1.x1) * (rect1.y2 - rect1.y1); + 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); + } } +/*@}*/ + + /*****************************************************************/ /** \name Context (un)binding functions */ /*****************************************************************/ @@ -112,7 +177,10 @@ driIntersectArea( drm_clip_rect_t rect1, drm_clip_rect_t rect2 ) /** * Unbind context. * - * \param scrn the screen. + * \param dpy the display handle. + * \param scrn the screen number. + * \param draw drawable. + * \param read Current reading drawable. * \param gc context. * * \return \c GL_TRUE on success, or \c GL_FALSE on failure. @@ -125,27 +193,56 @@ driIntersectArea( drm_clip_rect_t rect1, drm_clip_rect_t rect2 ) * While casting the opaque private pointers associated with the parameters * into their respective real types it also assures they are not \c NULL. */ -static int driUnbindContext(__DRIcontext *pcp) +static GLboolean driUnbindContext(__DRInativeDisplay *dpy, int scrn, + __DRIid draw, __DRIid read, + __DRIcontext *ctx) { - __DRIscreen *psp; - __DRIdrawable *pdp; - __DRIdrawable *prp; + __DRIscreen *pDRIScreen; + __DRIdrawable *pdraw; + __DRIdrawable *pread; + __DRIcontextPrivate *pcp; + __DRIscreenPrivate *psp; + __DRIdrawablePrivate *pdp; + __DRIdrawablePrivate *prp; /* ** Assume error checking is done properly in glXMakeCurrent before ** calling driUnbindContext. */ - if (pcp == NULL) - return GL_FALSE; + 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; - 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; @@ -162,6 +259,12 @@ static int driUnbindContext(__DRIcontext *pcp) 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 @@ -181,20 +284,72 @@ static int driUnbindContext(__DRIcontext *pcp) * 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 int driBindContext(__DRIcontext *pcp, - __DRIdrawable *pdp, - __DRIdrawable *prp) +static GLboolean DoBindContext(__DRInativeDisplay *dpy, + __DRIid draw, __DRIid read, + __DRIcontext *ctx, const __GLcontextModes * modes, + __DRIscreenPrivate *psp) { - __DRIscreenPrivate *psp = pcp->driScreenPriv; + __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; + } - /* - ** Assume error checking is done properly in glXMakeCurrent before - ** calling driBindContext. - */ + /* 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; + } - if (pcp == NULL || pdp == None || prp == None) - return GL_FALSE; + } + pdp = (__DRIdrawablePrivate *) pdraw->private; + + /* 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; + } /* Bind the drawable to the context */ pcp->driDrawablePriv = pdp; @@ -209,22 +364,16 @@ static int driBindContext(__DRIcontext *pcp, ** 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 (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); - } + 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 */ @@ -233,6 +382,37 @@ static int driBindContext(__DRIcontext *pcp, 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 ); +} /*@}*/ @@ -256,7 +436,7 @@ static int driBindContext(__DRIcontext *pcp, void __driUtilUpdateDrawableInfo(__DRIdrawablePrivate *pdp) { - __DRIscreenPrivate *psp = pdp->driScreenPriv; + __DRIscreenPrivate *psp; __DRIcontextPrivate *pcp = pdp->driContextPriv; if (!pcp @@ -267,6 +447,15 @@ __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; @@ -279,15 +468,15 @@ __driUtilUpdateDrawableInfo(__DRIdrawablePrivate *pdp) DRM_SPINUNLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID); - if (! (*psp->getDrawableInfo->getDrawableInfo)(pdp, + if (!__driFindDrawable(psp->drawHash, pdp->draw) || + ! (*dri_interface->getDrawableInfo)(pdp->display, pdp->screen, pdp->draw, &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->loaderPrivate)) { + &pdp->pBackClipRects )) { /* Error -- eg the window may have been destroyed. Keep going * with no cliprects. */ @@ -304,138 +493,6 @@ __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; -} - /*@}*/ /*****************************************************************/ @@ -443,33 +500,10 @@ __driParseEvents(__DRIcontextPrivate *pcp, __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 @@ -477,28 +511,74 @@ static void driReportDamage(__DRIdrawable *pdp, * * Is called directly from glXSwapBuffers(). */ -static void driSwapBuffers(__DRIdrawable *dPriv) +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 ) { - __DRIscreen *psp = dPriv->driScreenPriv; + __DRIdrawablePrivate *dPriv = (__DRIdrawablePrivate *) drawablePrivate; + __DRIswapInfo sInfo; + int status; - if (!dPriv->numClipRects) - return; - psp->DriverAPI.SwapBuffers(dPriv); + status = dPriv->driScreenPriv->DriverAPI.GetSwapInfo( dPriv, & sInfo ); + *sbc = sInfo.swap_count; - driReportDamage(dPriv, dPriv->pClipRects, dPriv->numClipRects); + return status; } -static int driDrawableGetMSC( __DRIscreen *sPriv, __DRIdrawable *dPriv, - int64_t *msc ) +static int driWaitForSBC( __DRInativeDisplay * dpy, void *drawablePriv, + int64_t target_sbc, + int64_t * msc, int64_t * sbc ) { - return sPriv->DriverAPI.GetDrawableMSC(sPriv, dPriv, msc); + __DRIdrawablePrivate *dPriv = (__DRIdrawablePrivate *) drawablePriv; + + return dPriv->driScreenPriv->DriverAPI.WaitForSBC( dPriv, target_sbc, + msc, sbc ); } -static int driWaitForMSC(__DRIdrawable *dPriv, int64_t target_msc, - int64_t divisor, int64_t remainder, - int64_t * msc, int64_t * sbc) +static int driWaitForMSC( __DRInativeDisplay * dpy, void *drawablePriv, + int64_t target_msc, + int64_t divisor, int64_t remainder, + int64_t * msc, int64_t * sbc ) { + __DRIdrawablePrivate *dPriv = (__DRIdrawablePrivate *) drawablePriv; __DRIswapInfo sInfo; int status; @@ -520,70 +600,63 @@ static int driWaitForMSC(__DRIdrawable *dPriv, int64_t target_msc, return status; } -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) +static int64_t driSwapBuffersMSC( __DRInativeDisplay * dpy, void *drawablePriv, + int64_t target_msc, + int64_t divisor, int64_t remainder ) { - drm_clip_rect_t rect; + __DRIdrawablePrivate *dPriv = (__DRIdrawablePrivate *) drawablePriv; - 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); + return dPriv->driScreenPriv->DriverAPI.SwapBuffersMSC( dPriv, target_msc, + divisor, + remainder ); } -const __DRIcopySubBufferExtension driCopySubBufferExtension = { - { __DRI_COPY_SUB_BUFFER, __DRI_COPY_SUB_BUFFER_VERSION }, - driCopySubBuffer -}; - -static void driSetSwapInterval(__DRIdrawable *dPriv, unsigned int interval) -{ - dPriv->swap_interval = interval; -} - -static unsigned int driGetSwapInterval(__DRIdrawable *dPriv) +static void driCopySubBuffer( __DRInativeDisplay *dpy, void *drawablePrivate, + int x, int y, int w, int h) { - return dPriv->swap_interval; + __DRIdrawablePrivate *dPriv = (__DRIdrawablePrivate *) drawablePrivate; + dPriv->driScreenPriv->DriverAPI.CopySubBuffer(dPriv, x, y, w, h); + (void) dpy; } -const __DRIswapControlExtension driSwapControlExtension = { - { __DRI_SWAP_CONTROL, __DRI_SWAP_CONTROL_VERSION }, - driSetSwapInterval, - driGetSwapInterval -}; - - /** * This is called via __DRIscreenRec's createNewDrawable pointer. */ -static __DRIdrawable * -driCreateNewDrawable(__DRIscreen *psp, const __DRIconfig *config, - drm_drawable_t hwDrawable, int renderType, - const int *attrs, void *data) +static void *driCreateNewDrawable(__DRInativeDisplay *dpy, + const __GLcontextModes *modes, + __DRIid draw, + __DRIdrawable *pdraw, + int renderType, + const int *attrs) { - __DRIdrawable *pdp; + __DRIscreen * const pDRIScreen = (*dri_interface->getScreen)(dpy, modes->screen); + __DRIscreenPrivate *psp; + __DRIdrawablePrivate *pdp; + + + pdraw->private = NULL; /* Since pbuffers are not yet supported, no drawable attributes are * supported either. */ (void) attrs; - pdp = _mesa_malloc(sizeof *pdp); + if ( (pDRIScreen == NULL) || (pDRIScreen->private == NULL) ) { + return NULL; + } + + pdp = (__DRIdrawablePrivate *)_mesa_malloc(sizeof(__DRIdrawablePrivate)); if (!pdp) { return NULL; } - pdp->loaderPrivate = data; - pdp->hHWDrawable = hwDrawable; + if (!(*dri_interface->createDrawable)(dpy, modes->screen, draw, &pdp->hHWDrawable)) { + _mesa_free(pdp); + return NULL; + } + + pdp->draw = draw; + pdp->pdraw = pdraw; pdp->refcount = 0; pdp->pStamp = NULL; pdp->lastStamp = 0; @@ -596,55 +669,80 @@ driCreateNewDrawable(__DRIscreen *psp, const __DRIconfig *config, pdp->numBackClipRects = 0; pdp->pClipRects = NULL; pdp->pBackClipRects = NULL; - pdp->vblSeq = 0; - pdp->vblFlags = 0; + pdp->display = dpy; + pdp->screen = modes->screen; + psp = (__DRIscreenPrivate *)pDRIScreen->private; pdp->driScreenPriv = psp; pdp->driContextPriv = &psp->dummyContextPriv; - if (!(*psp->DriverAPI.CreateBuffer)(psp, pdp, &config->modes, + if (!(*psp->DriverAPI.CreateBuffer)(psp, pdp, modes, renderType == GLX_PIXMAP_BIT)) { + (void)(*dri_interface->destroyDrawable)(dpy, modes->screen, pdp->draw); _mesa_free(pdp); return NULL; } - pdp->msc_base = 0; + 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; /* This special default value is replaced with the configured * default value when the drawable is first bound to a direct * rendering context. */ - pdp->swap_interval = (unsigned)-1; + pdraw->swap_interval = (unsigned)-1; + + pdp->swapBuffers = psp->DriverAPI.SwapBuffers; - return pdp; + /* 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; } static __DRIdrawable * -dri2CreateNewDrawable(__DRIscreen *screen, const __DRIconfig *config, - unsigned int drawable_id, unsigned int head, void *data) +driGetDrawable(__DRInativeDisplay *dpy, __DRIid draw, void *screenPrivate) { - __DRIdrawable *pdraw; - - pdraw = driCreateNewDrawable(screen, config, 0, 0, NULL, data); - if (!pdraw) - return NULL; + __DRIscreenPrivate *psp = (__DRIscreenPrivate *) screenPrivate; - pdraw->dri2.drawable_id = drawable_id; - pdraw->dri2.tail = head; - pdraw->pBackClipRects = _mesa_malloc(sizeof *pdraw->pBackClipRects); - - return pdraw; + /* + ** Make sure this routine returns NULL if the drawable is not bound + ** to a direct rendering context! + */ + return __driFindDrawable(psp->drawHash, draw); } - static void -driDestroyDrawable(__DRIdrawable *pdp) +driDestroyDrawable(__DRInativeDisplay *dpy, void *drawablePrivate) { + __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; @@ -668,6 +766,8 @@ driDestroyDrawable(__DRIdrawable *pdp) /** * 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 @@ -675,10 +775,14 @@ driDestroyDrawable(__DRIdrawable *pdp) * drmDestroyContext(), and finally frees \p contextPrivate. */ static void -driDestroyContext(__DRIcontext *pcp) +driDestroyContext(__DRInativeDisplay *dpy, int scrn, void *contextPrivate) { + __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); } } @@ -691,7 +795,7 @@ driDestroyContext(__DRIcontext *pcp) * \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 shared The shared context dependent methods or \c NULL if + * \param sharedPrivate The shared context dependent methods or \c NULL if * non-existent. * \param pctx DRI context to receive the context dependent methods. * @@ -705,18 +809,36 @@ driDestroyContext(__DRIcontext *pcp) * context. * */ -static __DRIcontext * -driCreateNewContext(__DRIscreen *psp, const __DRIconfig *config, - int render_type, __DRIcontext *shared, - drm_context_t hwContext, void *data) +static void * +driCreateNewContext(__DRInativeDisplay *dpy, const __GLcontextModes *modes, + int render_type, void *sharedPrivate, __DRIcontext *pctx) { - __DRIcontext *pcp; - void * const shareCtx = (shared != NULL) ? shared->driverPrivate : NULL; + __DRIscreen *pDRIScreen; + __DRIcontextPrivate *pcp; + __DRIcontextPrivate *pshare = (__DRIcontextPrivate *) sharedPrivate; + __DRIscreenPrivate *psp; + void * const shareCtx = (pshare != NULL) ? pshare->driverPrivate : NULL; - pcp = _mesa_malloc(sizeof *pcp); - if (!pcp) + pDRIScreen = (*dri_interface->getScreen)(dpy, modes->screen); + if ( (pDRIScreen == NULL) || (pDRIScreen->private == NULL) ) { + /* ERROR!!! */ 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; @@ -724,7 +846,8 @@ driCreateNewContext(__DRIscreen *psp, const __DRIconfig *config, * context. */ - if (!psp->dri2.enabled && !psp->dummyContextPriv.driScreenPriv) { + if (!psp->dummyContextPriv.driScreenPriv) { + psp->dummyContextPriv.contextID = 0; psp->dummyContextPriv.hHWContext = psp->pSAREA->dummy_context; psp->dummyContextPriv.driScreenPriv = psp; psp->dummyContextPriv.driDrawablePriv = NULL; @@ -732,40 +855,21 @@ driCreateNewContext(__DRIscreen *psp, const __DRIconfig *config, /* No other fields should be used! */ } - pcp->hHWContext = hwContext; + pctx->destroyContext = driDestroyContext; + pctx->bindContext = driBindContext; + pctx->unbindContext = driUnbindContext; - if ( !(*psp->DriverAPI.CreateContext)(&config->modes, pcp, shareCtx) ) { + if ( !(*psp->DriverAPI.CreateContext)(modes, pcp, shareCtx) ) { + (void) (*dri_interface->destroyContext)(dpy, modes->screen, + pcp->contextID); _mesa_free(pcp); return NULL; } - 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. */ + __driGarbageCollectDrawables(pcp->driScreenPriv->drawHash); - 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; + return pcp; } - /*@}*/ @@ -785,8 +889,10 @@ driCopyContext(__DRIcontext *dest, __DRIcontext *src, unsigned long mask) * This function calls __DriverAPIRec::DestroyScreen on \p screenPrivate, calls * drmClose(), and finally frees \p screenPrivate. */ -static void driDestroyScreen(__DRIscreen *psp) +static void driDestroyScreen(__DRInativeDisplay *dpy, int scrn, void *screenPrivate) { + __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 @@ -796,44 +902,26 @@ static void driDestroyScreen(__DRIscreen *psp) if (psp->DriverAPI.DestroyScreen) (*psp->DriverAPI.DestroyScreen)(psp); - 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); + (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 ); } + 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]; - } -} /** - * 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. + * Utility function used to create a new driver-private screen structure. * + * \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 @@ -854,29 +942,44 @@ setupLoaderExtensions(__DRIscreen *psp, * 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 name of this 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 \c __driCreateNewScreen function is versioned, it is impossible for a + * loader that is too old to even load this driver. */ -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 * +__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 const __DRIextension *emptyExtensionList[] = { NULL }; - __DRIscreen *psp; + __DRIscreenPrivate *psp; + + + api_ver = internal_api_version; + + psp = (__DRIscreenPrivate *)_mesa_malloc(sizeof(__DRIscreenPrivate)); + if (!psp) { + return NULL; + } - psp = _mesa_malloc(sizeof *psp); - if (!psp) + /* Create the hash table */ + psp->drawHash = drmHashCreate(); + if ( psp->drawHash == NULL ) { + _mesa_free( psp ); return NULL; + } - setupLoaderExtensions(psp, extensions); + psp->display = dpy; + psp->myNum = scrn; + psp->psc = psc; + psp->modes = modes; /* ** NOT_DONE: This is used by the X server to detect when the client @@ -885,12 +988,20 @@ driCreateNewScreen(int scrn, */ psp->drawLockID = 1; - psp->drm_version = *drm_version; - psp->ddx_version = *ddx_version; - psp->dri_version = *dri_version; + 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->pSAREA = pSAREA; - psp->lock = (drmLock *) &psp->pSAREA->lock; psp->pFB = frame_buffer->base; psp->fbSize = frame_buffer->size; @@ -901,10 +1012,7 @@ driCreateNewScreen(int scrn, 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 @@ -913,143 +1021,63 @@ driCreateNewScreen(int scrn, */ psp->dummyContextPriv.driScreenPriv = NULL; - psp->DriverAPI = driDriverAPI; - - *driver_modes = driDriverAPI.InitScreen(psp); - if (*driver_modes == NULL) { - _mesa_free(psp); - return NULL; - } - - return psp; -} - - -static __DRIscreen * -dri2CreateNewScreen(int scrn, int fd, unsigned int sarea_handle, - const __DRIextension **extensions, - const __DRIconfig ***driver_configs, void *data) -{ - 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); - } + psc->destroyScreen = driDestroyScreen; + psc->createNewDrawable = driCreateNewDrawable; + psc->getDrawable = driGetDrawable; + psc->getMSC = driGetMSC; + psc->createNewContext = driCreateNewContext; - psp->lock = (drmLock *) &psp->dri2.lock->lock; + if (internal_api_version >= 20070121) + psc->setTexOffset = psp->DriverAPI.setTexOffset; - 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); + if ( (psp->DriverAPI.InitDriver != NULL) + && !(*psp->DriverAPI.InitDriver)(psp) ) { + _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) +/** + * 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 ) { - return GLX_BAD_CONTEXT; + if ( api_ver > required_version ) { + return 1; + } + else if ( api_ver == required_version ) { + return 0; + } + + return -1; } + static int -driQueryFrameTracking(__DRIdrawable *dpriv, - int64_t * sbc, int64_t * missedFrames, - float * lastMissedUsage, float * usage) +driQueryFrameTracking( __DRInativeDisplay * dpy, void * priv, + int64_t * sbc, int64_t * missedFrames, + float * lastMissedUsage, float * usage ) { __DRIswapInfo sInfo; int status; int64_t ust; - __DRIscreenPrivate *psp = dpriv->driScreenPriv; + __DRIdrawablePrivate * dpriv = (__DRIdrawablePrivate *) priv; + status = dpriv->driScreenPriv->DriverAPI.GetSwapInfo( dpriv, & sInfo ); if ( status == 0 ) { @@ -1057,18 +1085,13 @@ driQueryFrameTracking(__DRIdrawable *dpriv, *missedFrames = sInfo.swap_missed_count; *lastMissedUsage = sInfo.swap_missed_usage; - (*psp->systemTime->getUST)( & ust ); + (*dri_interface->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. @@ -1106,10 +1129,11 @@ driCalculateSwapUsage( __DRIdrawablePrivate *dPriv, int64_t last_swap_ust, int32_t d; int interval; float usage = 1.0; - __DRIscreenPrivate *psp = dPriv->driScreenPriv; - if ( (*psp->systemTime->getMSCRate)(dPriv, &n, &d, dPriv->loaderPrivate) ) { - interval = (dPriv->swap_interval != 0) ? dPriv->swap_interval : 1; + + if ( (*dri_interface->getMSCRate)( dPriv->display, dPriv->draw, &n, &d ) ) { + interval = (dPriv->pdraw->swap_interval != 0) + ? dPriv->pdraw->swap_interval : 1; /* We want to calculate diff --git a/src/mesa/drivers/dri/common/dri_util.h b/src/mesa/drivers/dri/common/dri_util.h index f2bc456307..027cb7f461 100644 --- a/src/mesa/drivers/dri/common/dri_util.h +++ b/src/mesa/drivers/dri/common/dri_util.h @@ -1,24 +1,3 @@ -/** - * \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 - * \author Brian Paul - */ - /* * Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. * All Rights Reserved. @@ -44,37 +23,46 @@ * 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 + * \author Brian Paul + */ #ifndef _DRI_UTIL_H_ #define _DRI_UTIL_H_ #include -#include -#include -#include +#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 @@ -90,7 +78,7 @@ extern const __DRImediaStreamCounterExtension driMediaStreamCounterExtension; /** * Utility macro to validate the drawable information. * - * See __DRIdrawable::pStamp and __DRIdrawable::lastStamp. + * See __DRIdrawablePrivate::pStamp and __DRIdrawablePrivate::lastStamp. */ #define DRI_VALIDATE_DRAWABLE_INFO(psp, pdp) \ do { \ @@ -119,103 +107,94 @@ do { \ * this structure. */ struct __DriverAPIRec { - const __DRIconfig **(*InitScreen) (__DRIscreen * priv); - + /** + * Driver initialization callback + */ + GLboolean (*InitDriver)(__DRIscreenPrivate *driScrnPriv); + /** * Screen destruction callback */ - void (*DestroyScreen)(__DRIscreen *driScrnPriv); + void (*DestroyScreen)(__DRIscreenPrivate *driScrnPriv); /** * Context creation callback */ GLboolean (*CreateContext)(const __GLcontextModes *glVis, - __DRIcontext *driContextPriv, + __DRIcontextPrivate *driContextPriv, void *sharedContextPrivate); /** * Context destruction callback */ - void (*DestroyContext)(__DRIcontext *driContextPriv); + void (*DestroyContext)(__DRIcontextPrivate *driContextPriv); /** * Buffer (drawable) creation callback */ - GLboolean (*CreateBuffer)(__DRIscreen *driScrnPriv, - __DRIdrawable *driDrawPriv, + GLboolean (*CreateBuffer)(__DRIscreenPrivate *driScrnPriv, + __DRIdrawablePrivate *driDrawPriv, const __GLcontextModes *glVis, GLboolean pixmapBuffer); /** * Buffer (drawable) destruction callback */ - void (*DestroyBuffer)(__DRIdrawable *driDrawPriv); + void (*DestroyBuffer)(__DRIdrawablePrivate *driDrawPriv); /** * Buffer swapping callback */ - void (*SwapBuffers)(__DRIdrawable *driDrawPriv); + void (*SwapBuffers)(__DRIdrawablePrivate *driDrawPriv); /** * Context activation callback */ - GLboolean (*MakeCurrent)(__DRIcontext *driContextPriv, - __DRIdrawable *driDrawPriv, - __DRIdrawable *driReadPriv); + GLboolean (*MakeCurrent)(__DRIcontextPrivate *driContextPriv, + __DRIdrawablePrivate *driDrawPriv, + __DRIdrawablePrivate *driReadPriv); /** * Context unbinding callback */ - GLboolean (*UnbindContext)(__DRIcontext *driContextPriv); + GLboolean (*UnbindContext)(__DRIcontextPrivate *driContextPriv); /** * Retrieves statistics about buffer swap operations. Required if * GLX_OML_sync_control or GLX_MESA_swap_frame_usage is supported. */ - int (*GetSwapInfo)( __DRIdrawable *dPriv, __DRIswapInfo * sInfo ); + int (*GetSwapInfo)( __DRIdrawablePrivate *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)( __DRIdrawable *priv, int64_t target_msc, + int (*WaitForMSC)( __DRIdrawablePrivate *priv, int64_t target_msc, int64_t divisor, int64_t remainder, int64_t * msc ); - int (*WaitForSBC)( __DRIdrawable *priv, int64_t target_sbc, + int (*WaitForSBC)( __DRIdrawablePrivate *priv, int64_t target_sbc, int64_t * msc, int64_t * sbc ); - int64_t (*SwapBuffersMSC)( __DRIdrawable *priv, int64_t target_msc, + int64_t (*SwapBuffersMSC)( __DRIdrawablePrivate *priv, int64_t target_msc, int64_t divisor, int64_t remainder ); /*@}*/ - void (*CopySubBuffer)(__DRIdrawable *driDrawPriv, + void (*CopySubBuffer)(__DRIdrawablePrivate *driDrawPriv, int x, int y, int w, int h); /** - * 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. + * See corresponding field in \c __DRIscreenRec. */ - 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); - + void (*setTexOffset)(__DRIcontext *pDRICtx, GLint texname, + unsigned long long offset, GLint depth, GLuint pitch); }; -extern const struct __DriverAPIRec driDriverAPI; - struct __DRIswapInfoRec { /** @@ -251,7 +230,7 @@ struct __DRIswapInfoRec { /** * Per-drawable private DRI driver information. */ -struct __DRIdrawableRec { +struct __DRIdrawablePrivateRec { /** * Kernel drawable handle */ @@ -265,10 +244,10 @@ struct __DRIdrawableRec { void *driverPrivate; /** - * Private data from the loader. We just hold on to it and pass - * it back when calling into loader provided functions. + * X's drawable ID associated with this private drawable. */ - void *loaderPrivate; + __DRIid draw; + __DRIdrawable *pdraw; /** * Reference count for number of context's currently bound to this @@ -293,7 +272,7 @@ struct __DRIdrawableRec { /** * Last value of the stamp. * - * If this differs from the value stored at __DRIdrawable::pStamp, + * If this differs from the value stored at __DRIdrawablePrivate::pStamp, * then the drawable information has been modified by the X server, and the * drawable information (below) should be retrieved from the X server. */ @@ -327,56 +306,41 @@ struct __DRIdrawableRec { /*@}*/ /** - * \name Vertical blank tracking information - * Used for waiting on vertical blank events. - */ - /*@{*/ - unsigned int vblSeq; - unsigned int vblFlags; - /*@}*/ - - /** - * \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; + * Pointer to context to which this drawable is currently bound. */ - /*@{*/ - int64_t vblank_base; - int64_t msc_base; - /*@}*/ + __DRIcontextPrivate *driContextPriv; /** - * Pointer to context to which this drawable is currently bound. + * Pointer to screen on which this drawable was created. */ - __DRIcontext *driContextPriv; + __DRIscreenPrivate *driScreenPriv; /** - * Pointer to screen on which this drawable was created. + * \name Display and screen information. + * + * Basically just need these for when the locking code needs to call + * \c __driUtilUpdateDrawableInfo. */ - __DRIscreen *driScreenPriv; + /*@{*/ + __DRInativeDisplay *display; + int screen; + /*@}*/ /** - * Controls swap interval as used by GLX_SGI_swap_control and - * GLX_MESA_swap_control. + * Called via glXSwapBuffers(). */ - unsigned int swap_interval; - struct { - unsigned int tail; - unsigned int drawable_id; - } dri2; + void (*swapBuffers)( __DRIdrawablePrivate *dPriv ); }; /** * Per-context private driver information. */ -struct __DRIcontextRec { +struct __DRIcontextPrivateRec { + /** + * Kernel context handle used to access the device lock. + */ + __DRIid contextID; + /** * Kernel context handle used to access the device lock. */ @@ -388,30 +352,35 @@ struct __DRIcontextRec { void *driverPrivate; /** - * Pointer back to the \c __DRIcontext that contains this structure. + * This context's display pointer. */ - __DRIcontext *pctx; + __DRInativeDisplay *display; /** * Pointer to drawable currently bound to this context for drawing. */ - __DRIdrawable *driDrawablePriv; + __DRIdrawablePrivate *driDrawablePriv; /** * Pointer to drawable currently bound to this context for reading. */ - __DRIdrawable *driReadablePriv; + __DRIdrawablePrivate *driReadablePriv; /** * Pointer to screen on which this context was created. */ - __DRIscreen *driScreenPriv; + __DRIscreenPrivate *driScreenPriv; }; /** * Per-screen private driver information. */ -struct __DRIscreenRec { +struct __DRIscreenPrivateRec { + /** + * Display for this screen + */ + __DRInativeDisplay *display; + /** * Current screen's number */ @@ -422,21 +391,38 @@ struct __DRIscreenRec { */ struct __DriverAPIRec DriverAPI; - const __DRIextension **extensions; /** + * \name DDX version * DDX / 2D driver version information. + * \todo Replace these fields with a \c __DRIversionRec. */ - __DRIversion ddx_version; + /*@{*/ + int ddxMajor; + int ddxMinor; + int ddxPatch; + /*@}*/ /** + * \name DRI version * DRI X extension version information. + * \todo Replace these fields with a \c __DRIversionRec. */ - __DRIversion dri_version; + /*@{*/ + int driMajor; + int driMinor; + int driPatch; + /*@}*/ /** + * \name DRM version * DRM (kernel module) version information. + * \todo Replace these fields with a \c __DRIversionRec. */ - __DRIversion drm_version; + /*@{*/ + int drmMajor; + int drmMinor; + int drmPatch; + /*@}*/ /** * ID used when the client sets the drawable lock. @@ -499,7 +485,12 @@ struct __DRIscreenRec { * context is created when the first "real" context is created on this * screen. */ - __DRIcontext dummyContextPriv; + __DRIcontextPrivate dummyContextPriv; + + /** + * Hash table to hold the drawable information for this screen. + */ + void *drawHash; /** * Device-dependent private information (not stored in the SAREA). @@ -508,46 +499,66 @@ struct __DRIscreenRec { */ 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; +}; - /* 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; + +/** + * 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 void __driUtilMessage(const char *f, ...); extern void -__driUtilUpdateDrawableInfo(__DRIdrawable *pdp); +__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 ); +/* Test the version of the internal GLX API. Returns a value like strcmp. */ extern int -__driParseEvents(__DRIcontext *psp, __DRIdrawable *pdp); +driCompareGLXAPIVersion( GLint required_version ); extern float -driCalculateSwapUsage( __DRIdrawable *dPriv, +driCalculateSwapUsage( __DRIdrawablePrivate *dPriv, int64_t last_swap_ust, int64_t current_ust ); -extern GLint -driIntersectArea( drm_clip_rect_t rect1, drm_clip_rect_t rect2 ); +/** + * 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; #endif /* _DRI_UTIL_H_ */ diff --git a/src/mesa/drivers/dri/common/drirenderbuffer.c b/src/mesa/drivers/dri/common/drirenderbuffer.c index d36af3e5be..d34da53479 100644 --- a/src/mesa/drivers/dri/common/drirenderbuffer.c +++ b/src/mesa/drivers/dri/common/drirenderbuffer.c @@ -209,6 +209,8 @@ 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); } diff --git a/src/mesa/drivers/dri/common/spantmp2.h b/src/mesa/drivers/dri/common/spantmp2.h index 53f5f846a0..50f3cf5581 100644 --- a/src/mesa/drivers/dri/common/spantmp2.h +++ b/src/mesa/drivers/dri/common/spantmp2.h @@ -114,7 +114,7 @@ do { \ GLuint p = *(volatile GLuint *) GET_PTR(_x, _y); \ __asm__ __volatile__( "bswap %0; rorl $8, %0" \ - : "=r" (p) : "0" (p) ); \ + : "=r" (p) : "r" (p) ); \ ((GLuint *)rgba)[0] = p; \ } while (0) # elif defined( MESA_BIG_ENDIAN ) diff --git a/src/mesa/drivers/dri/common/utils.c b/src/mesa/drivers/dri/common/utils.c index 7fbe0d855d..6a189e7285 100644 --- a/src/mesa/drivers/dri/common/utils.c +++ b/src/mesa/drivers/dri/common/utils.c @@ -419,6 +419,21 @@ 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 ) @@ -452,6 +467,8 @@ GLboolean driClipRectToFramebuffer( const GLframebuffer *buffer, return GL_TRUE; } + + /** * Creates a set of \c __GLcontextModes that a driver will expose. * @@ -519,99 +536,86 @@ 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. */ -__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) +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 ) { - static const u_int8_t bits_table[4][4] = { + static const u_int8_t bits_table[3][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 */ }; - 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 */ + /* 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 }, { 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[6][4] = { - { 0x000000E0, 0x0000001C, 0x00000003, 0x00000000 }, /* 3_3_2 */ - { 0x00000007, 0x00000038, 0x000000C0, 0x00000000 }, /* 2_3_3_REV */ + static const u_int32_t masks_table_rgba[8][4] = { + { 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, + { 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, + { 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 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[6][4] = { - { 0x00000007, 0x00000038, 0x000000C0, 0x00000000 }, /* 3_3_2 */ - { 0x000000E0, 0x0000001C, 0x00000003, 0x00000000 }, /* 2_3_3_REV */ + static const u_int32_t masks_table_bgr[8][4] = { + { 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, + { 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, + { 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 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[6][4] = { - { 0x00000007, 0x00000038, 0x000000C0, 0x00000000 }, /* 3_3_2 */ - { 0x000000E0, 0x0000001C, 0x00000003, 0x00000000 }, /* 2_3_3_REV */ + static const u_int32_t masks_table_bgra[8][4] = { + { 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, + { 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, + { 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, { 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[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 */ + static const u_int8_t bytes_per_pixel[8] = { + 0, 0, 0, 2, 2, 4, 0, 4 }; const u_int8_t * bits; const u_int32_t * masks; - int index; - __DRIconfig **configs, **c; - __GLcontextModes *modes; + const int index = fb_type & 0x07; + __GLcontextModes * modes = *ptr_to_modes; unsigned i; unsigned j; unsigned k; - 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; + + + 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; } @@ -623,55 +627,40 @@ driCreateConfigs(GLenum fb_format, GLenum fb_type, 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] 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; + 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; } - 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 < num_accum_bits ; j++ ) { - *c = _mesa_malloc (sizeof **c); - modes = &(*c)->modes; - c++; + for ( j = 0 ; j < 2 ; j++ ) { - memset(modes, 0, sizeof *modes); modes->redBits = bits[0]; modes->greenBits = bits[1]; modes->blueBits = bits[2]; @@ -692,13 +681,7 @@ driCreateConfigs(GLenum fb_format, GLenum fb_type, modes->stencilBits = stencil_bits[k]; modes->depthBits = depth_bits[k]; - 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->visualType = visType; modes->renderType = GLX_RGBA_BIT; modes->drawableType = GLX_WINDOW_BIT; modes->rgbMode = GL_TRUE; @@ -718,155 +701,11 @@ driCreateConfigs(GLenum fb_format, GLenum fb_type, modes->haveDepthBuffer = (modes->depthBits > 0); modes->haveStencilBuffer = (modes->stencilBits > 0); - 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; + modes = modes->next; } } } - *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; -} diff --git a/src/mesa/drivers/dri/common/utils.h b/src/mesa/drivers/dri/common/utils.h index 9ac3b51447..b28b895627 100644 --- a/src/mesa/drivers/dri/common/utils.h +++ b/src/mesa/drivers/dri/common/utils.h @@ -28,11 +28,8 @@ #ifndef DRI_DEBUG_H #define DRI_DEBUG_H -#include -#include #include "context.h" - -typedef struct __DRIutilversionRec2 __DRIutilversion2; +#include "dri_util.h" struct dri_debug_control { const char * string; @@ -86,17 +83,6 @@ 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 ); @@ -119,27 +105,16 @@ 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 ); -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); +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 ); #endif /* DRI_DEBUG_H */ diff --git a/src/mesa/drivers/dri/common/vblank.c b/src/mesa/drivers/dri/common/vblank.c index 0008ab1c34..094950d362 100644 --- a/src/mesa/drivers/dri/common/vblank.c +++ b/src/mesa/drivers/dri/common/vblank.c @@ -34,16 +34,6 @@ #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); -} - /****************************************************************************/ /** @@ -51,7 +41,7 @@ static int64_t vblank_to_msc(__DRIdrawablePrivate * dPriv, unsigned int vblank) * * 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 for a given drawable. + * may, it will never decrease. * * \warning This function is called from \c glXGetVideoSyncSGI, which expects * a \c count of type \c unsigned (32-bit), and \c glXGetSyncValuesOML, which @@ -59,14 +49,11 @@ static int64_t vblank_to_msc(__DRIdrawablePrivate * dPriv, unsigned int vblank) * 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 driDrawableGetMSC32( __DRIscreenPrivate * priv, - __DRIdrawablePrivate * dPriv, - int64_t * count) +int driGetMSC32( __DRIscreenPrivate * priv, int64_t * count ) { drmVBlank vbl; int ret; @@ -75,21 +62,14 @@ int driDrawableGetMSC32( __DRIscreenPrivate * priv, 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 ); - - if (dPriv) { - *count = vblank_to_msc(dPriv, vbl.reply.sequence); - } else { - /* Old driver (no knowledge of drawable MSC callback) */ - *count = vbl.reply.sequence; - } + *count = (int64_t)vbl.reply.sequence; return ret; } + /****************************************************************************/ /** * Wait for a specified refresh count. This implements most of the @@ -142,9 +122,7 @@ int driWaitForMSC32( __DRIdrawablePrivate *priv, */ vbl.request.type = dont_wait ? DRM_VBLANK_RELATIVE : DRM_VBLANK_ABSOLUTE; - vbl.request.sequence = next ? msc_to_vblank(priv, next) : 0; - if ( priv->vblFlags & VBLANK_FLAG_SECONDARY ) - vbl.request.type |= DRM_VBLANK_SECONDARY; + vbl.request.sequence = next; if ( drmWaitVBlank( priv->driScreenPriv->fd, &vbl ) != 0 ) { /* FIXME: This doesn't seem like the right thing to return here. @@ -152,10 +130,8 @@ int driWaitForMSC32( __DRIdrawablePrivate *priv, return GLX_BAD_CONTEXT; } - *msc = vblank_to_msc(priv, vbl.reply.sequence); - dont_wait = 0; - if (target_msc != 0 && *msc == target) + if (target_msc != 0 && vbl.reply.sequence == target) break; /* Assuming the wait-done test fails, the next refresh to wait for @@ -165,9 +141,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 = (*msc % (unsigned int)divisor); - next = (*msc - r + (unsigned int)remainder); - if (next <= *msc) next += (unsigned int)divisor; + r = (vbl.reply.sequence % (unsigned int)divisor); + next = (vbl.reply.sequence - r + (unsigned int)remainder); + if (next <= vbl.reply.sequence) next += (unsigned int)divisor; } while ( r != (unsigned int)remainder ); } @@ -177,10 +153,7 @@ int driWaitForMSC32( __DRIdrawablePrivate *priv, */ vbl.request.type = DRM_VBLANK_ABSOLUTE; - vbl.request.sequence = target_msc ? msc_to_vblank(priv, target_msc) : 0; - - if ( priv->vblFlags & VBLANK_FLAG_SECONDARY ) - vbl.request.type |= DRM_VBLANK_SECONDARY; + vbl.request.sequence = target_msc; if ( drmWaitVBlank( priv->driScreenPriv->fd, &vbl ) != 0 ) { /* FIXME: This doesn't seem like the right thing to return here. @@ -189,8 +162,8 @@ int driWaitForMSC32( __DRIdrawablePrivate *priv, } } - *msc = vblank_to_msc(priv, vbl.reply.sequence); - + *msc = (target_msc & 0xffffffff00000000LL); + *msc |= vbl.reply.sequence; if ( *msc < target_msc ) { *msc += 0x0000000100000000LL; } @@ -259,8 +232,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 adjusting the vblank_mode" - " configuration parameter.\n", __FUNCTION__, ret); + " working correctly.\nTry running with LIBGL_THROTTLE_REFRESH" + " and LIBL_SYNC_REFRESH unset.\n", __FUNCTION__, ret); first_time = GL_FALSE; } @@ -272,44 +245,22 @@ 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 ) +void driDrawableInitVBlank( __DRIdrawablePrivate *priv, GLuint flags, + GLuint *vbl_seq ) { - if ( priv->swap_interval == (unsigned)-1 && - !( priv->vblFlags & VBLANK_FLAG_NO_IRQ ) ) { + if ( priv->pdraw->swap_interval == (unsigned)-1 ) { /* Get current vertical blank sequence */ - 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 ); + 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; } } @@ -320,17 +271,21 @@ void driDrawableInitVBlank( __DRIdrawablePrivate *priv ) */ unsigned -driGetVBlankInterval( const __DRIdrawablePrivate *priv ) +driGetVBlankInterval( const __DRIdrawablePrivate *priv, GLuint flags ) { - if ( (priv->vblFlags & VBLANK_FLAG_INTERVAL) != 0 ) { + if ( (flags & VBLANK_FLAG_INTERVAL) != 0 ) { /* this must have been initialized when the drawable was first bound * to a direct rendering context. */ - assert ( priv->swap_interval != (unsigned)-1 ); + assert ( priv->pdraw->swap_interval != (unsigned)-1 ); - return priv->swap_interval; + return priv->pdraw->swap_interval; + } + else if ( (flags & (VBLANK_FLAG_THROTTLE | VBLANK_FLAG_SYNC)) != 0 ) { + return 1; + } + else { + return 0; } - else - return driGetDefaultVBlankInterval( priv ); } @@ -340,17 +295,18 @@ driGetVBlankInterval( const __DRIdrawablePrivate *priv ) */ void -driGetCurrentVBlank( __DRIdrawablePrivate *priv ) +driGetCurrentVBlank( const __DRIdrawablePrivate *priv, GLuint flags, + GLuint *vbl_seq ) { drmVBlank vbl; vbl.request.type = DRM_VBLANK_RELATIVE; - if ( priv->vblFlags & VBLANK_FLAG_SECONDARY ) { + if ( flags & VBLANK_FLAG_SECONDARY ) { vbl.request.type |= DRM_VBLANK_SECONDARY; } vbl.request.sequence = 0; - (void) do_wait( &vbl, &priv->vblSeq, priv->driScreenPriv->fd ); + (void) do_wait( &vbl, vbl_seq, priv->driScreenPriv->fd ); } @@ -358,15 +314,19 @@ driGetCurrentVBlank( __DRIdrawablePrivate *priv ) /** * 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 priv->vblFlags. 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 flags. 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( __DRIdrawablePrivate *priv, GLboolean * missed_deadline ) +driWaitForVBlank( const __DRIdrawablePrivate *priv, GLuint * vbl_seq, + GLuint flags, GLboolean * missed_deadline ) { drmVBlank vbl; unsigned original_seq; @@ -375,10 +335,10 @@ driWaitForVBlank( __DRIdrawablePrivate *priv, GLboolean * missed_deadline ) unsigned diff; *missed_deadline = GL_FALSE; - if ( (priv->vblFlags & (VBLANK_FLAG_INTERVAL | - VBLANK_FLAG_THROTTLE | - VBLANK_FLAG_SYNC)) == 0 || - (priv->vblFlags & VBLANK_FLAG_NO_IRQ) != 0 ) { + if ( (flags & (VBLANK_FLAG_INTERVAL | + VBLANK_FLAG_THROTTLE | + VBLANK_FLAG_SYNC)) == 0 || + (flags & VBLANK_FLAG_NO_IRQ) != 0 ) { return 0; } @@ -389,45 +349,44 @@ driWaitForVBlank( __DRIdrawablePrivate *priv, GLboolean * missed_deadline ) * * VBLANK_FLAG_INTERVAL and VBLANK_FLAG_THROTTLE mean to wait for at * least one vertical blank since the last wait. Since do_wait modifies - * priv->vblSeq, we have to save the original value of priv->vblSeq for the + * vbl_seq, we have to save the original value of vbl_seq for the * VBLANK_FLAG_INTERVAL / VBLANK_FLAG_THROTTLE calculation later. */ - original_seq = priv->vblSeq; - interval = driGetVBlankInterval(priv); + original_seq = *vbl_seq; + interval = driGetVBlankInterval(priv, flags); deadline = original_seq + interval; vbl.request.type = DRM_VBLANK_RELATIVE; - if ( priv->vblFlags & VBLANK_FLAG_SECONDARY ) { + if ( flags & VBLANK_FLAG_SECONDARY ) { vbl.request.type |= DRM_VBLANK_SECONDARY; } - vbl.request.sequence = ((priv->vblFlags & VBLANK_FLAG_SYNC) != 0) ? 1 : 0; + vbl.request.sequence = ((flags & VBLANK_FLAG_SYNC) != 0) ? 1 : 0; - if ( do_wait( & vbl, &priv->vblSeq, priv->driScreenPriv->fd ) != 0 ) { + if ( do_wait( & vbl, vbl_seq, priv->driScreenPriv->fd ) != 0 ) { return -1; } - diff = priv->vblSeq - deadline; + diff = *vbl_seq - deadline; /* No need to wait again if we've already reached the target */ if (diff <= (1 << 23)) { - *missed_deadline = (priv->vblFlags & VBLANK_FLAG_SYNC) ? (diff > 0) : - GL_TRUE; + *missed_deadline = (flags & VBLANK_FLAG_SYNC) ? (diff > 0) : GL_TRUE; return 0; } /* Wait until the target vertical blank. */ vbl.request.type = DRM_VBLANK_ABSOLUTE; - if ( priv->vblFlags & VBLANK_FLAG_SECONDARY ) { + if ( flags & VBLANK_FLAG_SECONDARY ) { vbl.request.type |= DRM_VBLANK_SECONDARY; } vbl.request.sequence = deadline; - if ( do_wait( & vbl, &priv->vblSeq, priv->driScreenPriv->fd ) != 0 ) { + if ( do_wait( & vbl, vbl_seq, priv->driScreenPriv->fd ) != 0 ) { return -1; } - diff = priv->vblSeq - deadline; + diff = *vbl_seq - deadline; *missed_deadline = diff > 0 && diff <= (1 << 23); return 0; diff --git a/src/mesa/drivers/dri/common/vblank.h b/src/mesa/drivers/dri/common/vblank.h index b3a0dadab1..52c1933ca5 100644 --- a/src/mesa/drivers/dri/common/vblank.h +++ b/src/mesa/drivers/dri/common/vblank.h @@ -45,17 +45,17 @@ */ 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 ); -extern unsigned driGetVBlankInterval( const __DRIdrawablePrivate *priv ); -extern void driGetCurrentVBlank( __DRIdrawablePrivate *priv ); -extern int driWaitForVBlank( __DRIdrawablePrivate *priv, - GLboolean * missed_deadline ); +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 ); #undef usleep #include /* for usleep() */ diff --git a/src/mesa/drivers/dri/common/xmlconfig.c b/src/mesa/drivers/dri/common/xmlconfig.c index 8602d47cf9..b635894fe5 100644 --- a/src/mesa/drivers/dri/common/xmlconfig.c +++ b/src/mesa/drivers/dri/common/xmlconfig.c @@ -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 = NULL; + const XML_Char *tail; /* 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, \ - (int) XML_GetCurrentLineNumber(data->parser), \ - (int) XML_GetCurrentColumnNumber(data->parser)); \ + XML_GetCurrentLineNumber(data->parser), \ + XML_GetCurrentColumnNumber(data->parser)); \ } while (0) #define XML_WARNING(msg,args...) do { \ __driUtilMessage ("Warning in %s line %d, column %d: "msg, data->name, \ - (int) XML_GetCurrentLineNumber(data->parser), \ - (int) XML_GetCurrentColumnNumber(data->parser), \ + XML_GetCurrentLineNumber(data->parser), \ + 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, \ - (int) XML_GetCurrentLineNumber(data->parser), \ - (int) XML_GetCurrentColumnNumber(data->parser)); \ + XML_GetCurrentLineNumber(data->parser), \ + XML_GetCurrentColumnNumber(data->parser)); \ } while (0) #define XML_ERROR(msg,args...) do { \ __driUtilMessage ("Error in %s line %d, column %d: "msg, data->name, \ - (int) XML_GetCurrentLineNumber(data->parser), \ - (int) XML_GetCurrentColumnNumber(data->parser), \ + XML_GetCurrentLineNumber(data->parser), \ + 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, \ - (int) XML_GetCurrentLineNumber(data->parser), \ - (int) XML_GetCurrentColumnNumber(data->parser)); \ + XML_GetCurrentLineNumber(data->parser), \ + 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, \ - (int) XML_GetCurrentLineNumber(data->parser), \ - (int) XML_GetCurrentColumnNumber(data->parser), \ + XML_GetCurrentLineNumber(data->parser), \ + XML_GetCurrentColumnNumber(data->parser), \ args); \ abort();\ } while (0) -- cgit v1.2.3 From 543bba6ee3a1b3a947d1dfaca75e820ef7b98843 Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Tue, 24 Jun 2008 10:17:32 +0900 Subject: mesa: Don't include sys/types.h on WinCE. We probably shouldn't be including sys/types.h at all, but let's leave that for another time. --- include/GL/internal/glcore.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/GL/internal/glcore.h') diff --git a/include/GL/internal/glcore.h b/include/GL/internal/glcore.h index fc0aaf3d5e..d62f31bb29 100644 --- a/include/GL/internal/glcore.h +++ b/include/GL/internal/glcore.h @@ -36,7 +36,9 @@ ** */ +#if !defined(_WIN32_WCE) #include +#endif #define GL_CORE_SGI 1 #define GL_CORE_MESA 2 -- cgit v1.2.3 From 66175aac7609ad314f25fbdff0d3958af310dc24 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Wed, 18 Mar 2009 12:07:09 -0700 Subject: Fix DRI2 accelerated EXT_texture_from_pixmap with GL_RGB format. This requires upgrading the interface so that the argument to glXBindTexImageEXT isn't just dropped on the floor. Note that this only fixes the accelerated path on Intel, as Mesa's texture format support is missing x8r8g8b8 support (right now, GL_RGB textures get uploaded as a8r8gb8, but in this case we're not doing the upload so we can't really work around it that way). Fixes bugs with compositors trying to use shaders that use alpha channels, on windows without a valid alpha channel. Bug #19910 and likely others as well. Reviewed-by: Ian Romanick --- include/GL/internal/dri_interface.h | 16 ++++++++++++++-- include/GL/internal/glcore.h | 4 ++++ src/glx/x11/glx_pbuffer.c | 19 +++++++++++++++++++ src/glx/x11/glxclient.h | 1 + src/glx/x11/glxcmds.c | 18 +++++++++++++----- src/mesa/drivers/dri/i915/i830_texstate.c | 10 +++++++--- src/mesa/drivers/dri/i915/i915_texstate.c | 11 ++++++++--- src/mesa/drivers/dri/i965/brw_wm_surface_state.c | 24 +++++++++++++++++------- src/mesa/drivers/dri/intel/intel_screen.c | 1 + src/mesa/drivers/dri/intel/intel_tex.h | 2 ++ src/mesa/drivers/dri/intel/intel_tex_image.c | 18 ++++++++++++++++-- 11 files changed, 102 insertions(+), 22 deletions(-) (limited to 'include/GL/internal/glcore.h') diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h index a726b93234..a83602bfd8 100644 --- a/include/GL/internal/dri_interface.h +++ b/include/GL/internal/dri_interface.h @@ -231,7 +231,7 @@ struct __DRItexOffsetExtensionRec { #define __DRI_TEX_BUFFER "DRI_TexBuffer" -#define __DRI_TEX_BUFFER_VERSION 1 +#define __DRI_TEX_BUFFER_VERSION 2 struct __DRItexBufferExtensionRec { __DRIextension base; @@ -239,11 +239,23 @@ struct __DRItexBufferExtensionRec { * Method to override base texture image with the contents of a * __DRIdrawable. * - * For GLX_EXT_texture_from_pixmap with AIGLX. + * For GLX_EXT_texture_from_pixmap with AIGLX. Deprecated in favor of + * setTexBuffer2 in version 2 of this interface */ void (*setTexBuffer)(__DRIcontext *pDRICtx, GLint target, __DRIdrawable *pDraw); + + /** + * Method to override base texture image with the contents of a + * __DRIdrawable, including the required texture format attribute. + * + * For GLX_EXT_texture_from_pixmap with AIGLX. + */ + void (*setTexBuffer2)(__DRIcontext *pDRICtx, + GLint target, + GLint format, + __DRIdrawable *pDraw); }; /** diff --git a/include/GL/internal/glcore.h b/include/GL/internal/glcore.h index 547b111370..18f657662a 100644 --- a/include/GL/internal/glcore.h +++ b/include/GL/internal/glcore.h @@ -178,4 +178,8 @@ typedef struct __GLcontextModesRec { #define GLX_TEXTURE_2D_BIT_EXT 0x00000002 #define GLX_TEXTURE_RECTANGLE_BIT_EXT 0x00000004 +#define GLX_TEXTURE_FORMAT_NONE_EXT 0x20D8 +#define GLX_TEXTURE_FORMAT_RGB_EXT 0x20D9 +#define GLX_TEXTURE_FORMAT_RGBA_EXT 0x20DA + #endif /* __gl_core_h_ */ diff --git a/src/glx/x11/glx_pbuffer.c b/src/glx/x11/glx_pbuffer.c index a602cd2881..6bcf965056 100644 --- a/src/glx/x11/glx_pbuffer.c +++ b/src/glx/x11/glx_pbuffer.c @@ -189,6 +189,21 @@ determineTextureTarget(const int *attribs, int numAttribs) return target; } + + +static GLenum +determineTextureFormat(const int *attribs, int numAttribs) +{ + GLenum target = 0; + int i; + + for (i = 0; i < numAttribs; i++) { + if (attribs[2 * i] == GLX_TEXTURE_FORMAT_EXT) + return attribs[2 * i + 1]; + } + + return 0; +} #endif /** @@ -294,6 +309,9 @@ GetDrawableAttribute(Display * dpy, GLXDrawable drawable, if (pdraw != NULL && !pdraw->textureTarget) pdraw->textureTarget = determineTextureTarget((const int *) data, num_attributes); + if (pdraw != NULL && !pdraw->textureFormat) + pdraw->textureFormat = + determineTextureFormat((const int *) data, num_attributes); } #endif @@ -374,6 +392,7 @@ CreateDrawable(Display * dpy, const __GLcontextModes * fbconfig, } pdraw->textureTarget = determineTextureTarget(attrib_list, i); + pdraw->textureFormat = determineTextureFormat(attrib_list, i); } while (0); #endif diff --git a/src/glx/x11/glxclient.h b/src/glx/x11/glxclient.h index caf58bbd44..c42e80a0e8 100644 --- a/src/glx/x11/glxclient.h +++ b/src/glx/x11/glxclient.h @@ -161,6 +161,7 @@ struct __GLXDRIdrawableRec { __GLXscreenConfigs *psc; GLenum textureTarget; __DRIdrawable *driDrawable; + GLenum textureFormat; /* EXT_texture_from_pixmap support */ }; /* diff --git a/src/glx/x11/glxcmds.c b/src/glx/x11/glxcmds.c index fc0e593cb3..e5c0db4c96 100644 --- a/src/glx/x11/glxcmds.c +++ b/src/glx/x11/glxcmds.c @@ -2631,11 +2631,19 @@ static void __glXBindTexImageEXT(Display *dpy, if (gc->driContext) { __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, NULL); - if (pdraw != NULL) - (*pdraw->psc->texBuffer->setTexBuffer)(gc->__driContext, - pdraw->textureTarget, - pdraw->driDrawable); - + if (pdraw != NULL) { + if (pdraw->psc->texBuffer->base.version >= 2 && + pdraw->psc->texBuffer->setTexBuffer2 != NULL) { + (*pdraw->psc->texBuffer->setTexBuffer2)(gc->__driContext, + pdraw->textureTarget, + pdraw->textureFormat, + pdraw->driDrawable); + } else { + (*pdraw->psc->texBuffer->setTexBuffer)(gc->__driContext, + pdraw->textureTarget, + pdraw->driDrawable); + } + } return; } #endif diff --git a/src/mesa/drivers/dri/i915/i830_texstate.c b/src/mesa/drivers/dri/i915/i830_texstate.c index c718bb0055..df43b779a7 100644 --- a/src/mesa/drivers/dri/i915/i830_texstate.c +++ b/src/mesa/drivers/dri/i915/i830_texstate.c @@ -38,7 +38,7 @@ static GLuint -translate_texture_format(GLuint mesa_format) +translate_texture_format(GLuint mesa_format, GLuint internal_format) { switch (mesa_format) { case MESA_FORMAT_L8: @@ -56,7 +56,10 @@ translate_texture_format(GLuint mesa_format) case MESA_FORMAT_ARGB4444: return MAPSURF_16BIT | MT_16BIT_ARGB4444; case MESA_FORMAT_ARGB8888: - return MAPSURF_32BIT | MT_32BIT_ARGB8888; + if (internal_format == GL_RGB) + return MAPSURF_32BIT | MT_32BIT_XRGB8888; + else + return MAPSURF_32BIT | MT_32BIT_ARGB8888; case MESA_FORMAT_YCBCR_REV: return (MAPSURF_422 | MT_422_YCRCB_NORMAL); case MESA_FORMAT_YCBCR: @@ -162,7 +165,8 @@ i830_update_tex_unit(struct intel_context *intel, GLuint unit, GLuint ss3) 0, intelObj-> firstLevel); - format = translate_texture_format(firstImage->TexFormat->MesaFormat); + format = translate_texture_format(firstImage->TexFormat->MesaFormat, + firstImage->InternalFormat); pitch = intelObj->mt->pitch * intelObj->mt->cpp; } diff --git a/src/mesa/drivers/dri/i915/i915_texstate.c b/src/mesa/drivers/dri/i915/i915_texstate.c index adbb52a3a3..6d25f8dd8e 100644 --- a/src/mesa/drivers/dri/i915/i915_texstate.c +++ b/src/mesa/drivers/dri/i915/i915_texstate.c @@ -37,7 +37,8 @@ static GLuint -translate_texture_format(GLuint mesa_format, GLenum DepthMode) +translate_texture_format(GLuint mesa_format, GLuint internal_format, + GLenum DepthMode) { switch (mesa_format) { case MESA_FORMAT_L8: @@ -55,7 +56,10 @@ translate_texture_format(GLuint mesa_format, GLenum DepthMode) case MESA_FORMAT_ARGB4444: return MAPSURF_16BIT | MT_16BIT_ARGB4444; case MESA_FORMAT_ARGB8888: - return MAPSURF_32BIT | MT_32BIT_ARGB8888; + if (internal_format == GL_RGB) + return MAPSURF_32BIT | MT_32BIT_XRGB8888; + else + return MAPSURF_32BIT | MT_32BIT_ARGB8888; case MESA_FORMAT_YCBCR_REV: return (MAPSURF_422 | MT_422_YCRCB_NORMAL); case MESA_FORMAT_YCBCR: @@ -173,7 +177,8 @@ i915_update_tex_unit(struct intel_context *intel, GLuint unit, GLuint ss3) firstLevel); format = translate_texture_format(firstImage->TexFormat->MesaFormat, - tObj->DepthMode); + firstImage->InternalFormat, + tObj->DepthMode); pitch = intelObj->mt->pitch * intelObj->mt->cpp; } diff --git a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c index 9b320480b6..e6113eff87 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c +++ b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c @@ -69,7 +69,8 @@ static GLuint translate_tex_target( GLenum target ) } -static GLuint translate_tex_format( GLuint mesa_format, GLenum depth_mode ) +static GLuint translate_tex_format( GLuint mesa_format, GLenum internal_format, + GLenum depth_mode ) { switch( mesa_format ) { case MESA_FORMAT_L8: @@ -89,10 +90,16 @@ static GLuint translate_tex_format( GLuint mesa_format, GLenum depth_mode ) return BRW_SURFACEFORMAT_R8G8B8_UNORM; case MESA_FORMAT_ARGB8888: - return BRW_SURFACEFORMAT_B8G8R8A8_UNORM; + if (internal_format == GL_RGB) + return BRW_SURFACEFORMAT_B8G8R8X8_UNORM; + else + return BRW_SURFACEFORMAT_B8G8R8A8_UNORM; case MESA_FORMAT_RGBA8888_REV: - return BRW_SURFACEFORMAT_R8G8B8A8_UNORM; + if (internal_format == GL_RGB) + return BRW_SURFACEFORMAT_R8G8B8X8_UNORM; + else + return BRW_SURFACEFORMAT_R8G8B8A8_UNORM; case MESA_FORMAT_RGB565: return BRW_SURFACEFORMAT_B5G6R5_UNORM; @@ -161,7 +168,7 @@ static GLuint translate_tex_format( GLuint mesa_format, GLenum depth_mode ) struct brw_wm_surface_key { GLenum target, depthmode; dri_bo *bo; - GLint format; + GLint format, internal_format; GLint first_level, last_level; GLint width, height, depth; GLint pitch, cpp; @@ -199,9 +206,11 @@ brw_create_texture_surface( struct brw_context *brw, surf.ss0.mipmap_layout_mode = BRW_SURFACE_MIPMAPLAYOUT_BELOW; surf.ss0.surface_type = translate_tex_target(key->target); - - if (key->bo) - surf.ss0.surface_format = translate_tex_format(key->format, key->depthmode); + if (key->bo) { + surf.ss0.surface_format = translate_tex_format(key->format, + key->internal_format, + key->depthmode); + } else { switch (key->depth) { case 32: @@ -278,6 +287,7 @@ brw_update_texture_surface( GLcontext *ctx, GLuint unit ) key.offset = intelObj->textureOffset; } else { key.format = firstImage->TexFormat->MesaFormat; + key.internal_format = firstImage->InternalFormat; key.pitch = intelObj->mt->pitch; key.depth = firstImage->Depth; key.bo = intelObj->mt->region->buffer; diff --git a/src/mesa/drivers/dri/intel/intel_screen.c b/src/mesa/drivers/dri/intel/intel_screen.c index e8c074712c..d20ea15187 100644 --- a/src/mesa/drivers/dri/intel/intel_screen.c +++ b/src/mesa/drivers/dri/intel/intel_screen.c @@ -211,6 +211,7 @@ static const __DRItexOffsetExtension intelTexOffsetExtension = { static const __DRItexBufferExtension intelTexBufferExtension = { { __DRI_TEX_BUFFER, __DRI_TEX_BUFFER_VERSION }, intelSetTexBuffer, + intelSetTexBuffer2, }; static const __DRIextension *intelScreenExtensions[] = { diff --git a/src/mesa/drivers/dri/intel/intel_tex.h b/src/mesa/drivers/dri/intel/intel_tex.h index 742ccc043a..f5372d82fb 100644 --- a/src/mesa/drivers/dri/intel/intel_tex.h +++ b/src/mesa/drivers/dri/intel/intel_tex.h @@ -149,6 +149,8 @@ void intelSetTexOffset(__DRIcontext *pDRICtx, GLint texname, unsigned long long offset, GLint depth, GLuint pitch); void intelSetTexBuffer(__DRIcontext *pDRICtx, GLint target, __DRIdrawable *pDraw); +void intelSetTexBuffer2(__DRIcontext *pDRICtx, + GLint target, GLint format, __DRIdrawable *pDraw); GLuint intel_finalize_mipmap_tree(struct intel_context *intel, GLuint unit); diff --git a/src/mesa/drivers/dri/intel/intel_tex_image.c b/src/mesa/drivers/dri/intel/intel_tex_image.c index 943636c37b..e902187637 100644 --- a/src/mesa/drivers/dri/intel/intel_tex_image.c +++ b/src/mesa/drivers/dri/intel/intel_tex_image.c @@ -714,7 +714,9 @@ intelSetTexOffset(__DRIcontext *pDRICtx, GLint texname, } void -intelSetTexBuffer(__DRIcontext *pDRICtx, GLint target, __DRIdrawable *dPriv) +intelSetTexBuffer2(__DRIcontext *pDRICtx, GLint target, + GLint glx_texture_format, + __DRIdrawable *dPriv) { struct intel_framebuffer *intel_fb = dPriv->driverPrivate; struct intel_context *intel = pDRICtx->driverPrivate; @@ -745,7 +747,10 @@ intelSetTexBuffer(__DRIcontext *pDRICtx, GLint target, __DRIdrawable *dPriv) type = GL_BGRA; format = GL_UNSIGNED_BYTE; - internalFormat = (rb->region->cpp == 3 ? 3 : 4); + if (glx_texture_format == GLX_TEXTURE_FORMAT_RGB_EXT) + internalFormat = GL_RGB; + else + internalFormat = GL_RGBA; mt = intel_miptree_create_for_region(intel, target, internalFormat, @@ -785,3 +790,12 @@ intelSetTexBuffer(__DRIcontext *pDRICtx, GLint target, __DRIdrawable *dPriv) _mesa_unlock_texture(&intel->ctx, texObj); } + +void +intelSetTexBuffer(__DRIcontext *pDRICtx, GLint target, __DRIdrawable *dPriv) +{ + /* The old interface didn't have the format argument, so copy our + * implementation's behavior at the time. + */ + intelSetTexBuffer2(pDRICtx, target, GLX_TEXTURE_FORMAT_RGBA_EXT, dPriv); +} -- cgit v1.2.3