diff options
author | idr <idr> | 2004-03-03 21:57:59 +0000 |
---|---|---|
committer | idr <idr> | 2004-03-03 21:57:59 +0000 |
commit | 21a4a851e63845e2929824be22c0773e89d0b9d5 (patch) | |
tree | ff041113efa5b5d5586c4aa60dd23342c7e5e9dd | |
parent | bc3c2ce1456aae37ad1cb1f19096ab58776df6e2 (diff) |
Merged driinterface-0-0-3driinterface-0-0-3-20040303-merge
32 files changed, 2016 insertions, 1051 deletions
diff --git a/xc/include/GL/glxtokens.h b/xc/include/GL/glxtokens.h index af21475b1..0005b43a9 100644 --- a/xc/include/GL/glxtokens.h +++ b/xc/include/GL/glxtokens.h @@ -204,6 +204,12 @@ extern "C" { #define GLX_SLOW_VISUAL_EXT 0x8001 #define GLX_NON_CONFORMANT_VISUAL_EXT 0x800D +/* Property values for swap method (GLX_OML_swap_method) */ +#define GLX_SWAP_METHOD_OML 0x8060 +#define GLX_SWAP_EXCHANGE_OML 0x8061 +#define GLX_SWAP_COPY_OML 0x8062 +#define GLX_SWAP_UNDEFINED_OML 0x8063 + /* ** Names for attributes to glXGetClientString. */ diff --git a/xc/lib/GL/GL/Imakefile b/xc/lib/GL/GL/Imakefile index e12092ccb..a4444107c 100644 --- a/xc/lib/GL/GL/Imakefile +++ b/xc/lib/GL/GL/Imakefile @@ -75,20 +75,20 @@ XCOMM nothing #define MesaDrvGammaBuildDir $(GLXLIBSRC)/mesa/drivers/dri/gamma/ #include "../mesa/drivers/dri/gamma/Imakefile.inc" - DRVOBJS = $(GAMMAOBJS) $(MESAOBJS) $(DRMOBJS) - DRVUOBJS = $(GAMMAUOBJS) $(MESAUOBJS) $(DRMUOBJS) - DRVDOBJS = $(GAMMADOBJS) $(MESADOBJS) $(DRMDOBJS) - DRVPOBJS = $(GAMMAPOBJS) $(MESAPOBJS) $(DRMPOBJS) + DRVOBJS = $(GAMMAOBJS) $(MESAOBJS) + DRVUOBJS = $(GAMMAUOBJS) $(MESAUOBJS) + DRVDOBJS = $(GAMMADOBJS) $(MESADOBJS) + DRVPOBJS = $(GAMMAPOBJS) $(MESAPOBJS) #elif GlxBuiltInTdfx #define MesaDrvTdfxBuildDir $(GLXLIBSRC)/mesa/drivers/dri/tdfx/ #include "../mesa/drivers/dri/tdfx/Imakefile.inc" - DRVOBJS = $(TDFXOBJS) $(MESAOBJS) $(DRMOBJS) - DRVUOBJS = $(TDFXUOBJS) $(MESAUOBJS) $(DRMUOBJS) - DRVDOBJS = $(TDFXDOBJS) $(MESADOBJS) $(DRMDOBJS) - DRVPOBJS = $(TDFXPOBJS) $(MESAPOBJS) $(DRMPOBJS) + DRVOBJS = $(TDFXOBJS) $(MESAOBJS) + DRVUOBJS = $(TDFXUOBJS) $(MESAUOBJS) + DRVDOBJS = $(TDFXDOBJS) $(MESADOBJS) + DRVPOBJS = $(TDFXPOBJS) $(MESAPOBJS) OTHERREQUIREDLIBS = -lglide3 -ldl @@ -97,69 +97,69 @@ OTHERREQUIREDLIBS = -lglide3 -ldl #define MesaDrvI810BuildDir $(GLXLIBSRC)/mesa/drivers/dri/i810/ #include "../mesa/drivers/dri/i810/Imakefile.inc" - DRVOBJS = $(I810OBJS) $(COMMONOBJS) $(MESAOBJS) $(DRMOBJS) - DRVUOBJS = $(I810UOBJS) $(COMMONUOBJS) $(MESAUOBJS) $(DRMUOBJS) - DRVDOBJS = $(I810DOBJS) $(COMMONDOBJS) $(MESADOBJS) $(DRMDOBJS) - DRVPOBJS = $(I810POBJS) $(COMMONPOBJS) $(MESAPOBJS) $(DRMPOBJS) + DRVOBJS = $(I810OBJS) $(COMMONOBJS) $(MESAOBJS) + DRVUOBJS = $(I810UOBJS) $(COMMONUOBJS) $(MESAUOBJS) + DRVDOBJS = $(I810DOBJS) $(COMMONDOBJS) $(MESADOBJS) + DRVPOBJS = $(I810POBJS) $(COMMONPOBJS) $(MESAPOBJS) #elif GlxBuiltInI830 #define MesaDrvI830BuildDir $(GLXLIBSRC)/mesa/drivers/dri/i830/ #include "../mesa/drivers/dri/i830/Imakefile.inc" - DRVOBJS = $(I830OBJS) $(COMMONOBJS) $(MESAOBJS) $(DRMOBJS) - DRVUOBJS = $(I830UOBJS) $(COMMONUOBJS) $(MESAUOBJS) $(DRMUOBJS) - DRVDOBJS = $(I830DOBJS) $(COMMONDOBJS) $(MESADOBJS) $(DRMDOBJS) - DRVPOBJS = $(I830POBJS) $(COMMONPOBJS) $(MESAPOBJS) $(DRMPOBJS) + DRVOBJS = $(I830OBJS) $(COMMONOBJS) $(MESAOBJS) + DRVUOBJS = $(I830UOBJS) $(COMMONUOBJS) $(MESAUOBJS) + DRVDOBJS = $(I830DOBJS) $(COMMONDOBJS) $(MESADOBJS) + DRVPOBJS = $(I830POBJS) $(COMMONPOBJS) $(MESAPOBJS) #elif GlxBuiltInMga #define MesaDrvMgaBuildDir $(GLXLIBSRC)/mesa/drivers/dri/mga/ #include "../mesa/drivers/dri/mga/Imakefile.inc" - DRVOBJS = $(MGAOBJS) $(COMMONOBJS) $(MESAOBJS) $(DRMOBJS) - DRVUOBJS = $(MGAUOBJS) $(COMMONUOBJS) $(MESAUOBJS) $(DRMUOBJS) - DRVDOBJS = $(MGADOBJS) $(COMMONDOBJS) $(MESADOBJS) $(DRMDOBJS) - DRVPOBJS = $(MGAPOBJS) $(COMMONPOBJS) $(MESAPOBJS) $(DRMPOBJS) + DRVOBJS = $(MGAOBJS) $(COMMONOBJS) $(MESAOBJS) + DRVUOBJS = $(MGAUOBJS) $(COMMONUOBJS) $(MESAUOBJS) + DRVDOBJS = $(MGADOBJS) $(COMMONDOBJS) $(MESADOBJS) + DRVPOBJS = $(MGAPOBJS) $(COMMONPOBJS) $(MESAPOBJS) #elif GlxBuiltInR128 #define MesaDrvR128BuildDir $(GLXLIBSRC)/mesa/drivers/dri/r128/ #include "../mesa/drivers/dri/r128/Imakefile.inc" - DRVOBJS = $(R128OBJS) $(COMMONOBJS) $(MESAOBJS) $(DRMOBJS) - DRVUOBJS = $(R128UOBJS) $(COMMONUOBJS) $(MESAUOBJS) $(DRMUOBJS) - DRVDOBJS = $(R128DOBJS) $(COMMONDOBJS) $(MESADOBJS) $(DRMDOBJS) - DRVPOBJS = $(R128POBJS) $(COMMONPOBJS) $(MESAPOBJS) $(DRMPOBJS) + DRVOBJS = $(R128OBJS) $(COMMONOBJS) $(MESAOBJS) + DRVUOBJS = $(R128UOBJS) $(COMMONUOBJS) $(MESAUOBJS) + DRVDOBJS = $(R128DOBJS) $(COMMONDOBJS) $(MESADOBJS) + DRVPOBJS = $(R128POBJS) $(COMMONPOBJS) $(MESAPOBJS) #elif GlxBuiltInRadeon #define MesaDrvRadeonBuildDir $(GLXLIBSRC)/mesa/drivers/dri/radeon/ #include "../mesa/drivers/dri/radeon/Imakefile.inc" - DRVOBJS = $(RADEONOBJS) $(COMMONOBJS) $(MESAOBJS) $(DRMOBJS) - DRVUOBJS = $(RADEONUOBJS) $(COMMONUOBJS) $(MESAUOBJS) $(DRMUOBJS) - DRVDOBJS = $(RADEONDOBJS) $(COMMONDOBJS) $(MESADOBJS) $(DRMDOBJS) - DRVPOBJS = $(RADEONPOBJS) $(COMMONPOBJS) $(MESAPOBJS) $(DRMPOBJS) + DRVOBJS = $(RADEONOBJS) $(COMMONOBJS) $(MESAOBJS) + DRVUOBJS = $(RADEONUOBJS) $(COMMONUOBJS) $(MESAUOBJS) + DRVDOBJS = $(RADEONDOBJS) $(COMMONDOBJS) $(MESADOBJS) + DRVPOBJS = $(RADEONPOBJS) $(COMMONPOBJS) $(MESAPOBJS) #elif GlxBuiltInFfb #define MesaDrvFfbBuildDir $(GLXLIBSRC)/mesa/drivers/dri/ffb/ #include "../mesa/drivers/dri/ffb/Imakefile.inc" - DRVOBJS = $(FFBOBJS) $(MESAOBJS) $(DRMOBJS) - DRVUOBJS = $(FFBUOBJS) $(MESAUOBJS) $(DRMUOBJS) - DRVDOBJS = $(FFBDOBJS) $(MESADOBJS) $(DRMDOBJS) - DRVPOBJS = $(FFBPOBJS) $(MESAPOBJS) $(DRMPOBJS) + DRVOBJS = $(FFBOBJS) $(MESAOBJS) + DRVUOBJS = $(FFBUOBJS) $(MESAUOBJS) + DRVDOBJS = $(FFBDOBJS) $(MESADOBJS) + DRVPOBJS = $(FFBPOBJS) $(MESAPOBJS) #elif GlxBuiltInSIS #define MesaDrvSisBuildDir $(GLXLIBSRC)/mesa/drivers/dri/sis/ #include "../mesa/drivers/dri/sis/Imakefile.inc" - DRVOBJS = $(SISOBJS) $(MESAOBJS) $(DRMOBJS) - DRVUOBJS = $(SISUOBJS) $(MESAUOBJS) $(DRMUOBJS) - DRVDOBJS = $(SISDOBJS) $(MESADOBJS) $(DRMDOBJS) - DRVPOBJS = $(SISPOBJS) $(MESAPOBJS) $(DRMPOBJS) + DRVOBJS = $(SISOBJS) $(MESAOBJS) + DRVUOBJS = $(SISUOBJS) $(MESAUOBJS) + DRVDOBJS = $(SISDOBJS) $(MESADOBJS) + DRVPOBJS = $(SISPOBJS) $(MESAPOBJS) #elif GlxBuiltInXMesa @@ -197,14 +197,14 @@ OTHERREQUIREDLIBS = \ REQUIREDLIBS = $(BASEREQUIREDLIBS) $(OTHERREQUIREDLIBS) -lXxf86vm - OBJS = $(GLXOBJS) $(DRIOBJS) $(DRVOBJS) + OBJS = $(GLXOBJS) $(DRIOBJS) $(DRVOBJS) $(DRMOBJS) #if HasSharedLibraries && !SharedLibGlxWithoutPIC - UOBJS = $(GLXUOBJS) $(DRIUOBJS) $(DRVUOBJS) + UOBJS = $(GLXUOBJS) $(DRIUOBJS) $(DRVUOBJS) $(DRMUOBJS) #else UOBJS = $(OBJS) #endif - DOBJS = $(GLXDOBJS) $(DRIDOBJS) $(DRVDOBJS) - POBJS = $(GLXPOBJS) $(DRIPOBJS) $(DRVPOBJS) + DOBJS = $(GLXDOBJS) $(DRIDOBJS) $(DRVDOBJS) $(DRMDOBJS) + POBJS = $(GLXPOBJS) $(DRIPOBJS) $(DRVPOBJS) $(DRMPOBJS) #if LocalThreads #if NeedUIThrStubs diff --git a/xc/lib/GL/dri/XF86dri.c b/xc/lib/GL/dri/XF86dri.c index 24eeaf7ff..82ffb3035 100644 --- a/xc/lib/GL/dri/XF86dri.c +++ b/xc/lib/GL/dri/XF86dri.c @@ -324,10 +324,10 @@ Bool XF86DRIGetClientDriverName(dpy, screen, ddxDriverMajorVersion, return True; } -Bool XF86DRICreateContext(dpy, screen, visual, context, hHWContext) +Bool XF86DRICreateContextWithConfig(dpy, screen, configID, context, hHWContext) Display* dpy; int screen; - Visual* visual; + int configID; XID* context; drmContextPtr hHWContext; { @@ -342,7 +342,7 @@ Bool XF86DRICreateContext(dpy, screen, visual, context, hHWContext) GetReq(XF86DRICreateContext, req); req->reqType = info->codes->major_opcode; req->driReqType = X_XF86DRICreateContext; - req->visual = visual->visualid; + req->visual = configID; req->screen = screen; *context = XAllocID(dpy); req->context = *context; @@ -359,6 +359,17 @@ Bool XF86DRICreateContext(dpy, screen, visual, context, hHWContext) return True; } +Bool XF86DRICreateContext(dpy, screen, visual, context, hHWContext) + Display* dpy; + int screen; + Visual* visual; + XID* context; + drmContextPtr hHWContext; +{ + return XF86DRICreateContextWithConfig( dpy, screen, visual->visualid, + context, hHWContext ); +} + Bool XF86DRIDestroyContext(dpy, screen, context) Display* dpy; int screen; @@ -601,27 +612,12 @@ Bool XF86DRIOpenFullScreen(dpy, screen, drawable) int screen; Drawable drawable; { - XExtDisplayInfo *info = find_display (dpy); - xXF86DRIOpenFullScreenReply rep; - xXF86DRIOpenFullScreenReq *req; - - XF86DRICheckExtension (dpy, info, False); - - LockDisplay(dpy); - GetReq(XF86DRIOpenFullScreen, req); - req->reqType = info->codes->major_opcode; - req->driReqType = X_XF86DRIOpenFullScreen; - req->screen = screen; - req->drawable = drawable; - if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { - UnlockDisplay(dpy); - SyncHandle(); - return False; - } - - UnlockDisplay(dpy); - SyncHandle(); - return rep.isFullScreen ? True : False; + /* This function and the underlying X protocol are deprecated. + */ + (void) dpy; + (void) screen; + (void) drawable; + return False; } Bool XF86DRICloseFullScreen(dpy, screen, drawable) @@ -629,29 +625,10 @@ Bool XF86DRICloseFullScreen(dpy, screen, drawable) int screen; Drawable drawable; { - XExtDisplayInfo *info = find_display (dpy); - xXF86DRICloseFullScreenReply rep; - xXF86DRICloseFullScreenReq *req; - - XF86DRICheckExtension (dpy, info, False); - - LockDisplay(dpy); - GetReq(XF86DRICloseFullScreen, req); - req->reqType = info->codes->major_opcode; - req->driReqType = X_XF86DRICloseFullScreen; - req->screen = screen; - req->drawable = drawable; - - /* The reply doesn't contain any data -- - we just use it as a synchronization - point. */ - if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { - UnlockDisplay(dpy); - SyncHandle(); - return False; - } - - UnlockDisplay(dpy); - SyncHandle(); + /* This function and the underlying X protocol are deprecated. + */ + (void) dpy; + (void) screen; + (void) drawable; return True; } diff --git a/xc/lib/GL/dri/dri_glx.c b/xc/lib/GL/dri/dri_glx.c index a708ac256..f0b5f19ee 100644 --- a/xc/lib/GL/dri/dri_glx.c +++ b/xc/lib/GL/dri/dri_glx.c @@ -224,14 +224,19 @@ static __DRIdriver *OpenDriver(const char *driverName) Xfree(driver); return NULL; /* out of memory! */ } + driver->createScreenFunc = (CreateScreenFunc) dlsym(handle, "__driCreateScreen"); - if (!driver->createScreenFunc) { + driver->createNewScreenFunc = (CreateNewScreenFunc) + dlsym(handle, "__driCreateNewScreen"); + + if ( (driver->createScreenFunc == NULL) + && (driver->createNewScreenFunc == NULL) ) { /* If the driver doesn't have this symbol then something's * really, really wrong. */ - ErrorMessageF("__driCreateScreen() not defined in %s_dri.so!\n", - driverName); + ErrorMessageF("Neither __driCreateScreen or __driCreateNewScreen " + "are defined in %s_dri.so!\n", driverName); Xfree(driver); dlclose(handle); continue; @@ -415,15 +420,24 @@ void *driCreateDisplay(Display *dpy, __DRIdisplay *pdisp) /* allocate array of pointers to createScreen funcs */ pdisp->createScreen = (CreateScreenFunc *) Xmalloc(numScreens * sizeof(void *)); if (!pdisp->createScreen) { - XFree(pdpyp); + Xfree(pdpyp); + return NULL; + } + + /* allocate array of pointers to createScreen funcs */ + pdisp->createNewScreen = (CreateNewScreenFunc *) Xmalloc(numScreens * sizeof(void *)); + if (!pdisp->createNewScreen) { + Xfree(pdisp->createScreen); + Xfree(pdpyp); return NULL; } /* allocate array of library handles */ pdpyp->libraryHandles = (void **) Xmalloc(numScreens * sizeof(void*)); if (!pdpyp->libraryHandles) { + Xfree(pdisp->createNewScreen); Xfree(pdisp->createScreen); - XFree(pdpyp); + Xfree(pdpyp); return NULL; } @@ -431,6 +445,7 @@ void *driCreateDisplay(Display *dpy, __DRIdisplay *pdisp) /* we'll statically bind to the built-in __driCreateScreen function */ for (scrn = 0; scrn < numScreens; scrn++) { pdisp->createScreen[scrn] = __driCreateScreen; + pdisp->createNewScreen[scrn] = NULL; pdpyp->libraryHandles[scrn] = NULL; } @@ -443,10 +458,12 @@ void *driCreateDisplay(Display *dpy, __DRIdisplay *pdisp) __DRIdriver *driver = driGetDriver(dpy, scrn); if (driver) { pdisp->createScreen[scrn] = driver->createScreenFunc; + pdisp->createNewScreen[scrn] = driver->createNewScreenFunc; pdpyp->libraryHandles[scrn] = driver->handle; } else { pdisp->createScreen[scrn] = DummyCreateScreen; + pdisp->createNewScreen[scrn] = NULL; pdpyp->libraryHandles[scrn] = NULL; } } diff --git a/xc/lib/GL/dri/dri_util.c b/xc/lib/GL/dri/dri_util.c index ebfa6e561..428472873 100644 --- a/xc/lib/GL/dri/dri_util.c +++ b/xc/lib/GL/dri/dri_util.c @@ -13,6 +13,15 @@ * * These functions are compiled into each DRI driver so libGL.so knows nothing * about them. + * + * \note + * When \c DRI_NEW_INTERFACE_ONLY is defined, code is built / not built so + * that only the "new" libGL-to-driver interfaces are supported. This breaks + * backwards compatability. However, this may be necessary when DRI drivers + * are built to be used in non-XFree86 environments. + * + * \todo There are still some places in the code that need to be wrapped with + * \c DRI_NEW_INTERFACE_ONLY. */ @@ -22,6 +31,7 @@ #include <assert.h> #include <stdarg.h> #include <unistd.h> +#include <sys/mman.h> #include <X11/Xlibint.h> #include <Xext.h> #include <extutil.h> @@ -31,13 +41,27 @@ #include "dri_util.h" #include "glcontextmodes.h" +/*#define DRI_NEW_INTERFACE_ONLY*/ -/* This is used in a couple of places that call driCreateNewDrawable. +/** + * This is used in a couple of places that call \c driCreateNewDrawable. */ static const int empty_attribute_list[1] = { None }; +/** + * Function used to determine if a drawable (window) still exists. Ideally + * this function comes from libGL. With older versions of libGL from XFree86 + * we can fall-back to an internal version. + * + * \sa __driWindowExists __glXWindowExists + */ static PFNGLXWINDOWEXISTSPROC window_exists; +typedef Bool (*PFNGLXCREATECONTEXTWITHCONFIGPROC)( Display*, int, int, void *, + drmContextPtr ); + +static PFNGLXCREATECONTEXTWITHCONFIGPROC create_context_with_config; + /** * Cached copy of the internal API version used by libGL and the client-side * DRI driver. @@ -82,7 +106,7 @@ static Bool driFeatureOn(const char *name) * * Is called from the drivers. * - * \param f printf() like format string. + * \param f \c printf like format string. */ void __driUtilMessage(const char *f, ...) @@ -104,6 +128,7 @@ __driUtilMessage(const char *f, ...) /*****************************************************************/ /*@{*/ +#ifndef DRI_NEW_INTERFACE_ONLY /** * Find a \c __GLcontextModes structure matching the given visual ID. * @@ -115,26 +140,38 @@ __driUtilMessage(const char *f, ...) * if found, or \c NULL if no match is found. */ static const __GLcontextModes * -findConfigMode(Display *dpy, int scrn, VisualID vid) +findConfigMode(Display *dpy, int scrn, VisualID vid, + const __DRIscreen * pDRIScreen) { - const __GLcontextModes *modes = NULL; - const __DRIscreen * const pDRIScreen = __glXFindDRIScreen(dpy, scrn); - if ( (pDRIScreen != NULL) && (pDRIScreen->private != NULL) ) { const __DRIscreenPrivate * const psp = (const __DRIscreenPrivate *) pDRIScreen->private; - /* Search list of configs for matching vid */ - for ( modes = psp->modes ; modes != NULL ; modes = modes->next ) { - if (modes->visualID == vid) { - break; - } - } + return _gl_context_modes_find_visual( psp->modes, vid ); } - return modes; + return NULL; } + +/** + * This function is a hack to work-around old versions of libGL.so that + * do not export \c XF86DRICreateContextWithConfig. I would modify the + * code to just use this function, but the stand-alone driver (i.e., DRI + * drivers that are built to work without XFree86) shouldn't have to know + * about X structures like a \c Visual. + */ +static Bool +fake_XF86DRICreateContextWithConfig( Display* dpy, int screen, int configID, + XID* context, drmContextPtr hHWContext ) +{ + Visual vis; + + vis.visualid = configID; + return XF86DRICreateContext( dpy, screen, & vis, context, hHWContext ); +} +#endif /* DRI_NEW_INTERFACE_ONLY */ + /*@}*/ @@ -187,6 +224,26 @@ static int __driWindowExistsErrorHandler(Display *dpy, XErrorEvent *xerr) return 0; } +/** + * Determine if a window associated with a \c GLXDrawable exists on the + * X-server. + * + * \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. + * + * \deprecated + * \c __glXWindowExists (from libGL) is prefered over this function. Starting + * with the next major release of XFree86, this function will be removed. + * Even now this function is no longer directly called. Instead it is called + * via a function pointer if and only if \c __glXWindowExists does not exist. + * + * \sa __glXWindowExists glXGetProcAddress window_exists + */ static Bool __driWindowExists(Display *dpy, GLXDrawable draw) { XWindowAttributes xwa; @@ -201,6 +258,12 @@ static Bool __driWindowExists(Display *dpy, GLXDrawable draw) } #endif /* DRI_NEW_INTERFACE_ONLY */ +/** + * Find drawables in the local hash that have been destroyed on the + * server. + * + * \param drawHash Hash-table containing all know drawables. + */ static void __driGarbageCollectDrawables(void *drawHash) { GLXDrawable draw; @@ -239,7 +302,7 @@ static void __driGarbageCollectDrawables(void *drawHash) * \param read Current reading drawable. * \param gc context. * - * \return GL_TRUE on success, or GL_FALSE on failure. + * \return \c GL_TRUE on success, or \c GL_FALSE on failure. * * \internal * This function calls __DriverAPIRec::UnbindContext, and then decrements @@ -247,7 +310,7 @@ static void __driGarbageCollectDrawables(void *drawHash) * return. * * While casting the opaque private pointers associated with the parameters - * into their respective real types it also assures they are not null. + * into their respective real types it also assures they are not \c NULL. */ static Bool driUnbindContext2(Display *dpy, int scrn, GLXDrawable draw, GLXDrawable read, @@ -331,9 +394,14 @@ static Bool driUnbindContext2(Display *dpy, int scrn, /** - * This function takes both a read buffer and a draw buffer. - * This is needed for glXMakeCurrentReadSGI() or GLX 1.3's - * glxMakeContextCurrent() function. + * 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 Bool driBindContext2(Display *dpy, int scrn, GLXDrawable draw, GLXDrawable read, @@ -359,12 +427,32 @@ static Bool driBindContext2(Display *dpy, int scrn, } pDRIScreen = __glXFindDRIScreen(dpy, scrn); - modes = findConfigMode( dpy, scrn, gc->vid ); - if ( (pDRIScreen == NULL) || (pDRIScreen->private == NULL) - || (modes == NULL) ) { +#ifdef DRI_NEW_INTERFACE_ONLY + if ( (pDRIScreen == NULL) || (pDRIScreen->private == NULL) ) { /* ERROR!!! */ return GL_FALSE; } +#else + if ( driCompareGLXAPIVersion( 20031201 ) >= 0 ) { +#endif /* DRI_NEW_INTERFACE_ONLY */ + modes = gc->mode; +#ifndef DRI_NEW_INTERFACE_ONLY + } + else { + modes = findConfigMode( dpy, scrn, gc->vid, pDRIScreen ); + if ( modes == NULL ) { + /* ERROR!!! */ + return GL_FALSE; + } + } + + + /* findConfigMode will return NULL if the DRI screen or screen private + * are NULL. + */ + assert( (pDRIScreen != NULL) && (pDRIScreen->private != NULL) ); +#endif /* DRI_NEW_INTERFACE_ONLY */ + /* Find the _DRIdrawable which corresponds to the writing GLXDrawable */ psp = (__DRIscreenPrivate *)pDRIScreen->private; @@ -377,28 +465,15 @@ static Bool driBindContext2(Display *dpy, int scrn, return GL_FALSE; } - /* FIXME: Some checking might be needed here when support for pbuffers - * FIXME: and / or pixmaps is added. Is it safe to assume that the - * FIXME: drawable is a window? - */ - /* Create a new drawable */ - pdraw->private = driCreateNewDrawable(dpy, modes, draw, pdraw, - GLX_WINDOW_BIT, - empty_attribute_list); + driCreateNewDrawable(dpy, modes, draw, pdraw, GLX_WINDOW_BIT, + empty_attribute_list); if (!pdraw->private) { /* ERROR!!! */ Xfree(pdraw); return GL_FALSE; } - /* Add pdraw to drawable list */ - if (!__driAddDrawable(psp->drawHash, pdraw)) { - /* ERROR!!! */ - (*pdraw->destroyDrawable)(dpy, pdraw->private); - Xfree(pdraw); - return GL_FALSE; - } } pdp = (__DRIdrawablePrivate *) pdraw->private; @@ -417,27 +492,14 @@ static Bool driBindContext2(Display *dpy, int scrn, return GL_FALSE; } - /* FIXME: See the FIXME at the previous call to - * FIXME: driCreateNewDrawable. - */ - /* Create a new drawable */ - pread->private = driCreateNewDrawable(dpy, modes, read, pread, - GLX_WINDOW_BIT, - empty_attribute_list); + driCreateNewDrawable(dpy, modes, read, pread, GLX_WINDOW_BIT, + empty_attribute_list); if (!pread->private) { /* ERROR!!! */ Xfree(pread); return GL_FALSE; } - - /* Add pread to drawable list */ - if (!__driAddDrawable(psp->drawHash, pread)) { - /* ERROR!!! */ - (*pread->destroyDrawable)(dpy, pread->private); - Xfree(pread); - return GL_FALSE; - } } prp = (__DRIdrawablePrivate *) pread->private; } @@ -503,7 +565,7 @@ static Bool driUnbindContext(Display *dpy, int scrn, * \param pdp pointer to the private drawable information to update. * * This function basically updates the __DRIdrawablePrivate struct's - * cliprect information by calling XF86DRIGetDrawableInfo(). This is + * cliprect information by calling \c __DRIDrawablePrivate::getInfo. This is * usually called by the DRI_VALIDATE_DRAWABLE_INFO macro which * compares the __DRIdrwablePrivate pStamp and lastStamp values. If * the values are different that means we have to update the clipping @@ -537,15 +599,14 @@ __driUtilUpdateDrawableInfo(__DRIdrawablePrivate *pdp) DRM_SPINUNLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID); if (!__driFindDrawable(psp->drawHash, pdp->draw) || - !XF86DRIGetDrawableInfo(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->getInfo)(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 )) { /* Error -- eg the window may have been destroyed. Keep going * with no cliprects. */ @@ -661,24 +722,10 @@ static int64_t driSwapBuffersMSC( Display * dpy, void *drawablePriv, remainder ); } + /** - * This is called via __DRIscreenRec's createDrawable pointer. - * libGL doesn't use it at this time. See comments in glxclient.h. + * This is called via __DRIscreenRec's createNewDrawable pointer. */ -static void *driCreateDrawable_dummy(Display *dpy, int scrn, - GLXDrawable draw, - VisualID vid, __DRIdrawable *pdraw) -{ - const __GLcontextModes * const modes = findConfigMode(dpy, scrn, vid); - - return (modes != NULL) - ? driCreateNewDrawable( dpy, modes, draw, pdraw, GLX_WINDOW_BIT, - empty_attribute_list ) - : NULL; -} - - - static void *driCreateNewDrawable(Display *dpy, const __GLcontextModes *modes, GLXDrawable draw, @@ -686,7 +733,7 @@ static void *driCreateNewDrawable(Display *dpy, int renderType, const int *attrs) { - __DRIscreen *pDRIScreen; + __DRIscreen * const pDRIScreen = __glXFindDRIScreen(dpy, modes->screen); __DRIscreenPrivate *psp; __DRIdrawablePrivate *pdp; @@ -696,6 +743,10 @@ static void *driCreateNewDrawable(Display *dpy, */ (void) attrs; + if ( (pDRIScreen == NULL) || (pDRIScreen->private == NULL) ) { + return NULL; + } + pdp = (__DRIdrawablePrivate *)Xmalloc(sizeof(__DRIdrawablePrivate)); if (!pdp) { return NULL; @@ -723,17 +774,16 @@ static void *driCreateNewDrawable(Display *dpy, pdp->display = dpy; pdp->screen = modes->screen; - pDRIScreen = __glXFindDRIScreen(dpy, modes->screen); - if ( (pDRIScreen == NULL) || (pDRIScreen->private == NULL) ) { - (void)XF86DRIDestroyDrawable(dpy, modes->screen, pdp->draw); - Xfree(pdp); - return NULL; - } - psp = (__DRIscreenPrivate *)pDRIScreen->private; pdp->driScreenPriv = psp; pdp->driContextPriv = &psp->dummyContextPriv; + pdp->getInfo = (GetDrawableInfo *) + glXGetProcAddress( (const GLubyte *) "__glXGetDrawableInfo" ); + if ( pdp->getInfo == NULL ) { + pdp->getInfo = XF86DRIGetDrawableInfo; + } + if (!(*psp->DriverAPI.CreateBuffer)(psp, pdp, modes, renderType == GLX_PIXMAP_BIT)) { (void)XF86DRIDestroyDrawable(dpy, modes->screen, pdp->draw); @@ -741,6 +791,7 @@ static void *driCreateNewDrawable(Display *dpy, return NULL; } + pdraw->private = pdp; pdraw->destroyDrawable = driDestroyDrawable; pdraw->swapBuffers = driSwapBuffers; /* called by glXSwapBuffers() */ @@ -760,7 +811,16 @@ static void *driCreateNewDrawable(Display *dpy, pdp->swapBuffers = psp->DriverAPI.SwapBuffers; - return (void *) pdp; + /* Add pdraw to drawable list */ + if (!__driAddDrawable(psp->drawHash, pdraw)) { + /* ERROR!!! */ + (*pdraw->destroyDrawable)(dpy, pdp); + Xfree(pdp); + pdp = NULL; + pdraw->private = NULL; + } + + return (void *) pdp; } static __DRIdrawable *driGetDrawable(Display *dpy, GLXDrawable draw, @@ -828,33 +888,39 @@ static void driDestroyContext(Display *dpy, int scrn, void *contextPrivate) } } + /** * Create the per-drawable private driver information. * - * \param dpy the display handle. - * \param vis the visual information. - * \param sharedPrivate the shared context dependent methods or NULL if non-existent. - * \param pctx will receive the context dependent methods. + * \param dpy The display handle. + * \param modes Mode used to create the new context. + * \param render_type Type of rendering target. \c GLX_RGBA is the only + * type likely to ever be supported for direct-rendering. + * \param sharedPrivate The shared context dependent methods or \c NULL if + * non-existent. + * \param pctx DRI context to receive the context dependent methods. * - * \returns a opaque pointer to the per-context private information on success, or NULL - * on failure. + * \returns An opaque pointer to the per-context private information on + * success, or \c NULL on failure. * * \internal * This function allocates and fills a __DRIcontextPrivateRec structure. It - * gets the visual, converts it into a __GLcontextModesRec and passes it - * to __DriverAPIRec::CreateContext to create the context. + * performs some device independent initialization and passes all the + * relevent information to __DriverAPIRec::CreateContext to create the + * context. + * */ -static void *driCreateContext(Display *dpy, XVisualInfo *vis, - void *sharedPrivate, __DRIcontext *pctx) +static void * +driCreateNewContext(Display *dpy, const __GLcontextModes *modes, + int render_type, void *sharedPrivate, __DRIcontext *pctx) { __DRIscreen *pDRIScreen; __DRIcontextPrivate *pcp; __DRIcontextPrivate *pshare = (__DRIcontextPrivate *) sharedPrivate; __DRIscreenPrivate *psp; - const __GLcontextModes *modes; void * const shareCtx = (pshare != NULL) ? pshare->driverPrivate : NULL; - pDRIScreen = __glXFindDRIScreen(dpy, vis->screen); + pDRIScreen = __glXFindDRIScreen(dpy, modes->screen); if ( (pDRIScreen == NULL) || (pDRIScreen->private == NULL) ) { /* ERROR!!! */ return NULL; @@ -862,16 +928,13 @@ static void *driCreateContext(Display *dpy, XVisualInfo *vis, psp = (__DRIscreenPrivate *)pDRIScreen->private; - /* Create the hash table */ - if (!psp->drawHash) psp->drawHash = drmHashCreate(); - pcp = (__DRIcontextPrivate *)Xmalloc(sizeof(__DRIcontextPrivate)); if (!pcp) { return NULL; } - if (!XF86DRICreateContext(dpy, vis->screen, vis->visual, - &pcp->contextID, &pcp->hHWContext)) { + if (! (*create_context_with_config)(dpy, modes->screen, modes->fbconfigID, + &pcp->contextID, &pcp->hHWContext)) { Xfree(pcp); return NULL; } @@ -893,18 +956,6 @@ static void *driCreateContext(Display *dpy, XVisualInfo *vis, /* No other fields should be used! */ } - /* Setup a __GLcontextModes struct corresponding to vis->visualid - * and create the rendering context. - */ - - modes = findConfigMode(dpy, vis->screen, vis->visualid); - if ( (modes == NULL) - || !(*psp->DriverAPI.CreateContext)(modes, pcp, shareCtx) ) { - (void)XF86DRIDestroyContext(dpy, vis->screen, pcp->contextID); - Xfree(pcp); - return NULL; - } - pctx->destroyContext = driDestroyContext; pctx->bindContext = driBindContext; pctx->unbindContext = driUnbindContext; @@ -913,11 +964,67 @@ static void *driCreateContext(Display *dpy, XVisualInfo *vis, pctx->unbindContext2 = driUnbindContext2; } + if ( !(*psp->DriverAPI.CreateContext)(modes, pcp, shareCtx) ) { + (void)XF86DRIDestroyContext(dpy, modes->screen, pcp->contextID); + Xfree(pcp); + return NULL; + } + __driGarbageCollectDrawables(pcp->driScreenPriv->drawHash); return pcp; } + +#ifndef DRI_NEW_INTERFACE_ONLY +/** + * Create the per-drawable private driver information. + * + * \param dpy the display handle. + * \param vis the visual information. + * \param sharedPrivate the shared context dependent methods or \c NULL if + * non-existent. + * \param pctx will receive the context dependent methods. + * + * \returns a opaque pointer to the per-context private information on success, or \c NULL + * on failure. + * + * \deprecated + * This function has been replaced by \c driCreateNewContext. In drivers + * built to work with XFree86, this function will continue to exist to support + * older versions of libGL. Starting with the next major relelase of XFree86, + * this function will be removed. + * + * \internal + * This function allocates and fills a __DRIcontextPrivateRec structure. It + * gets the visual, converts it into a __GLcontextModesRec and passes it + * to __DriverAPIRec::CreateContext to create the context. + */ +static void *driCreateContext(Display *dpy, XVisualInfo *vis, + void *sharedPrivate, __DRIcontext *pctx) +{ + __DRIscreen *pDRIScreen; + const __GLcontextModes *modes; + + pDRIScreen = __glXFindDRIScreen(dpy, vis->screen); + if ( (pDRIScreen == NULL) || (pDRIScreen->private == NULL) ) { + /* ERROR!!! */ + return NULL; + } + + + /* Setup a __GLcontextModes struct corresponding to vis->visualid + * and create the rendering context. + */ + + modes = findConfigMode(dpy, vis->screen, vis->visualid, pDRIScreen); + return (modes == NULL) + ? NULL + : driCreateNewContext( dpy, modes, GLX_RGBA_TYPE, + sharedPrivate, pctx ); +} +#endif /* DRI_NEW_INTERFACE_ONLY */ + /*@}*/ @@ -954,30 +1061,52 @@ static void driDestroyScreen(Display *dpy, int scrn, void *screenPrivate) (void)drmUnmap((drmAddress)psp->pFB, psp->fbSize); Xfree(psp->pDevPriv); (void)drmClose(psp->fd); - _gl_context_modes_destroy( psp->modes ); + if ( psp->modes != NULL ) { + _gl_context_modes_destroy( psp->modes ); + } Xfree(psp); } } +/** + * 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 + * minimum, a list of modes based on the current display mode. + * These roughly match the set of available X11 visuals, but it + * need not be limited to X11! The calling libGL should create + * a list that will inform the driver of the current display + * mode (i.e., color buffer depth, depth buffer depth, etc.). + * \param ddx_version Version of the 2D DDX. This may not be meaningful for + * all drivers. + * \param dri_version Version of the "server-side" DRI. + * \param drm_version Version of the kernel DRM. + * \param frame_buffer Data describing the location and layout of the + * framebuffer. + * \param pSAREA Pointer the the SAREA. + * \param fd Device handle for the DRM. + * \param internal_api_version Version of the internal interface between the + * driver and libGL. + * \param driverAPI Driver API functions used by other routines in dri_util.c. + */ __DRIscreenPrivate * -__driUtilCreateScreen(Display *dpy, int scrn, __DRIscreen *psc, - int numConfigs, __GLXvisualConfig *configs, - const struct __DriverAPIRec *driverAPI) +__driUtilCreateNewScreen(Display *dpy, int scrn, __DRIscreen *psc, + __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 struct __DriverAPIRec *driverAPI) { - int directCapable; __DRIscreenPrivate *psp; - drmHandle hFB, hSAREA; - char *BusID, *driverName; - drmMagic magic; - __GLcontextModes *modes; - int i; - PFNGLXGETINTERNALVERSIONPROC get_ver; - - get_ver = (PFNGLXGETINTERNALVERSIONPROC) - glXGetProcAddress( (const GLubyte *) "__glXGetInternalVersion" ); - api_ver = (get_ver != NULL) ? (*get_ver)() : 1; window_exists = (PFNGLXWINDOWEXISTSPROC) glXGetProcAddress( (const GLubyte *) "__glXWindowExists" ); @@ -985,230 +1114,336 @@ __driUtilCreateScreen(Display *dpy, int scrn, __DRIscreen *psc, if ( window_exists == NULL ) { #ifdef DRI_NEW_INTERFACE_ONLY fprintf( stderr, "libGL error: libGL.so version (%08u) is too old. " - "20021128 or later is required.\n", api_ver ); + "20021128 or later is required.\n", internal_api_version ); return NULL; #else window_exists = (PFNGLXWINDOWEXISTSPROC) __driWindowExists; #endif /* DRI_NEW_INTERFACE_ONLY */ } - if (!XF86DRIQueryDirectRenderingCapable(dpy, scrn, &directCapable)) { + create_context_with_config = (PFNGLXCREATECONTEXTWITHCONFIGPROC) + glXGetProcAddress( (const GLubyte *) "__glXCreateContextWithConfig" ); + if ( create_context_with_config == NULL ) { +#ifdef DRI_NEW_INTERFACE_ONLY + fprintf( stderr, "libGL error: libGL.so version (%08u) is too old. " + "20031201 or later is required.\n", internal_api_version ); return NULL; +#else + create_context_with_config = (PFNGLXCREATECONTEXTWITHCONFIGPROC) + fake_XF86DRICreateContextWithConfig; +#endif /* DRI_NEW_INTERFACE_ONLY */ } + + api_ver = internal_api_version; - if (!directCapable) { + psp = (__DRIscreenPrivate *)Xmalloc(sizeof(__DRIscreenPrivate)); + if (!psp) { return NULL; } - psp = (__DRIscreenPrivate *)Xmalloc(sizeof(__DRIscreenPrivate)); - if (!psp) { + /* Create the hash table */ + psp->drawHash = drmHashCreate(); + if ( psp->drawHash == NULL ) { + Xfree( psp ); return NULL; } + 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 + ** has died while holding the drawable lock. The client sets the + ** drawable lock to this value. + */ + psp->drawLockID = 1; - /* Create the linked list of context modes, and populate it with the - * GLX visual information passed in by libGL. - */ + 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; - psp->modes = _gl_context_modes_create( numConfigs, - sizeof(__GLcontextModes) ); - if ( psp->modes == NULL ) { - Xfree(psp); - return NULL; - } + /* install driver's callback functions */ + memcpy( &psp->DriverAPI, driverAPI, sizeof(struct __DriverAPIRec) ); - modes = psp->modes; - for ( i = 0 ; i < numConfigs ; i++ ) { - assert( modes != NULL ); - _gl_copy_visual_to_context_mode( modes, & configs[i] ); - modes->screen = scrn; + psp->pSAREA = pSAREA; - modes = modes->next; - } + psp->pFB = frame_buffer->base; + psp->fbSize = frame_buffer->size; + psp->fbStride = frame_buffer->stride; + psp->fbWidth = frame_buffer->width; + psp->fbHeight = frame_buffer->height; + psp->devPrivSize = frame_buffer->dev_priv_size; + psp->pDevPriv = frame_buffer->dev_priv; - if (!XF86DRIOpenConnection(dpy, scrn, &hSAREA, &BusID)) { - _gl_context_modes_destroy( psp->modes ); - Xfree(psp); - return NULL; - } + psp->fd = fd; /* - ** NOT_DONE: This is used by the X server to detect when the client - ** has died while holding the drawable lock. The client sets the - ** drawable lock to this value. + ** Do not init dummy context here; actual initialization will be + ** done when the first DRI context is created. Init screen priv ptr + ** to NULL to let CreateContext routine that it needs to be inited. */ - psp->drawLockID = 1; + psp->dummyContextPriv.driScreenPriv = NULL; - psp->fd = drmOpen(NULL,BusID); - if (psp->fd < 0) { - fprintf(stderr, "libGL error: failed to open DRM: %s\n", strerror(-psp->fd)); - fprintf(stderr, "libGL error: reverting to (slow) indirect rendering\n"); - Xfree(BusID); - _gl_context_modes_destroy( psp->modes ); - Xfree(psp); - (void)XF86DRICloseConnection(dpy, scrn); - return NULL; + psc->destroyScreen = driDestroyScreen; +#ifndef DRI_NEW_INTERFACE_ONLY + psc->createContext = driCreateContext; +#else + psc->createConteext = NULL; +#endif + psc->createNewDrawable = driCreateNewDrawable; + psc->getDrawable = driGetDrawable; + if ( driCompareGLXAPIVersion( 20030317 ) >= 0 ) { + psc->getMSC = driGetMSC; + + if ( driCompareGLXAPIVersion( 20030824 ) >= 0 ) { + psc->createNewContext = driCreateNewContext; + } } - Xfree(BusID); /* No longer needed */ - if (drmGetMagic(psp->fd, &magic)) { - fprintf(stderr, "libGL error: drmGetMagic failed\n"); - (void)drmClose(psp->fd); - _gl_context_modes_destroy( psp->modes ); - Xfree(psp); - (void)XF86DRICloseConnection(dpy, scrn); + if ( (psp->DriverAPI.InitDriver != NULL) + && !(*psp->DriverAPI.InitDriver)(psp) ) { + Xfree( psp ); return NULL; } - { - drmVersionPtr version = drmGetVersion(psp->fd); - if (version) { - psp->drmMajor = version->version_major; - psp->drmMinor = version->version_minor; - psp->drmPatch = version->version_patchlevel; - drmFreeVersion(version); - } - else { - psp->drmMajor = -1; - psp->drmMinor = -1; - psp->drmPatch = -1; - } - } - if (!XF86DRIAuthConnection(dpy, scrn, magic)) { - fprintf(stderr, "libGL error: XF86DRIAuthConnection failed\n"); - (void)drmClose(psp->fd); - _gl_context_modes_destroy( psp->modes ); - Xfree(psp); - (void)XF86DRICloseConnection(dpy, scrn); - return NULL; - } + return psp; +} - /* - * Get device name (like "tdfx") and the ddx version numbers. - * We'll check the version in each DRI driver's "createScreen" - * function. - */ - if (!XF86DRIGetClientDriverName(dpy, scrn, - &psp->ddxMajor, - &psp->ddxMinor, - &psp->ddxPatch, - &driverName)) { - fprintf(stderr, "libGL error: XF86DRIGetClientDriverName failed\n"); - (void)drmClose(psp->fd); - _gl_context_modes_destroy( psp->modes ); - Xfree(psp); - (void)XF86DRICloseConnection(dpy, scrn); - return NULL; - } - /* - * Get the DRI X extension version. - */ - if (!XF86DRIQueryVersion(dpy, - &psp->driMajor, - &psp->driMinor, - &psp->driPatch)) { - fprintf(stderr, "libGL error: XF86DRIQueryVersion failed\n"); - (void)drmClose(psp->fd); - _gl_context_modes_destroy( psp->modes ); - Xfree(psp); - (void)XF86DRICloseConnection(dpy, scrn); +#ifndef DRI_NEW_INTERFACE_ONLY +/** + * 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 numConfigs Number of visual configs pointed to by \c configs. + * \param configs Array of GLXvisualConfigs exported by the 2D driver. + * \param driverAPI Driver API functions used by other routines in dri_util.c. + * + * \deprecated + * This function has been replaced by \c __driUtilCreateNewScreen. In drivers + * built to work with XFree86, this function will continue to exist to support + * older versions of libGL. Starting with the next major relelase of XFree86, + * this function will be removed. + */ +__DRIscreenPrivate * +__driUtilCreateScreen(Display *dpy, int scrn, __DRIscreen *psc, + int numConfigs, __GLXvisualConfig *configs, + const struct __DriverAPIRec *driverAPI) +{ + int directCapable; + __DRIscreenPrivate *psp = NULL; + drmHandle hSAREA; + drmAddress pSAREA; + char *BusID; + __GLcontextModes *modes; + __GLcontextModes *temp; + int i; + __DRIversion ddx_version; + __DRIversion dri_version; + __DRIversion drm_version; + __DRIframebuffer framebuffer; + int fd = -1; + int status; + const char * err_msg; + const char * err_extra; + + + if (!XF86DRIQueryDirectRenderingCapable(dpy, scrn, &directCapable) + || !directCapable) { return NULL; } - /* install driver's callback functions */ - memcpy(&psp->DriverAPI, driverAPI, sizeof(struct __DriverAPIRec)); - /* - * 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. + /* Create the linked list of context modes, and populate it with the + * GLX visual information passed in by libGL. */ - if (!XF86DRIGetDeviceInfo(dpy, scrn, - &hFB, - &psp->fbOrigin, - &psp->fbSize, - &psp->fbStride, - &psp->devPrivSize, - &psp->pDevPriv)) { - fprintf(stderr, "libGL error: XF86DRIGetDeviceInfo failed\n"); - (void)drmClose(psp->fd); - _gl_context_modes_destroy( psp->modes ); - Xfree(psp); - (void)XF86DRICloseConnection(dpy, scrn); - return NULL; - } - psp->fbWidth = DisplayWidth(dpy, scrn); - psp->fbHeight = DisplayHeight(dpy, scrn); - psp->fbBPP = 32; /* NOT_DONE: Get this from X server */ - /* - * Map the framebuffer region. - */ - if (drmMap(psp->fd, hFB, psp->fbSize, (drmAddressPtr)&psp->pFB)) { - fprintf(stderr, "libGL error: drmMap of framebuffer failed\n"); - Xfree(psp->pDevPriv); - (void)drmClose(psp->fd); - _gl_context_modes_destroy( psp->modes ); - Xfree(psp); - (void)XF86DRICloseConnection(dpy, scrn); + modes = _gl_context_modes_create( numConfigs, sizeof(__GLcontextModes) ); + if ( modes == NULL ) { return NULL; } - /* - * Map the SAREA region. Further mmap regions may be setup in - * each DRI driver's "createScreen" function. - */ - if (drmMap(psp->fd, hSAREA, SAREA_MAX, (drmAddressPtr)&psp->pSAREA)) { - fprintf(stderr, "libGL error: drmMap of sarea failed\n"); - (void)drmUnmap((drmAddress)psp->pFB, psp->fbSize); - Xfree(psp->pDevPriv); - (void)drmClose(psp->fd); - _gl_context_modes_destroy( psp->modes ); - Xfree(psp); - (void)XF86DRICloseConnection(dpy, scrn); - return NULL; + temp = modes; + for ( i = 0 ; i < numConfigs ; i++ ) { + assert( temp != NULL ); + _gl_copy_visual_to_context_mode( temp, & configs[i] ); + temp->screen = scrn; + + temp = temp->next; } - /* Initialize the screen specific GLX driver */ - if (psp->DriverAPI.InitDriver) { - if (!(*psp->DriverAPI.InitDriver)(psp)) { - fprintf(stderr, "libGL error: InitDriver failed\n"); - (void)drmUnmap((drmAddress)psp->pSAREA, SAREA_MAX); - (void)drmUnmap((drmAddress)psp->pFB, psp->fbSize); - Xfree(psp->pDevPriv); - (void)drmClose(psp->fd); - _gl_context_modes_destroy( psp->modes ); - Xfree(psp); - (void)XF86DRICloseConnection(dpy, scrn); - return NULL; + err_msg = "XF86DRIOpenConnection"; + err_extra = NULL; + + if (XF86DRIOpenConnection(dpy, scrn, &hSAREA, &BusID)) { + fd = drmOpen(NULL,BusID); + Xfree(BusID); /* No longer needed */ + + err_msg = "open DRM"; + err_extra = strerror( -fd ); + + if (fd >= 0) { + drmMagic 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 (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 "createScreen" + * function. + */ + err_msg = "XF86DRIGetClientDriverName"; + if (XF86DRIGetClientDriverName(dpy, scrn, + &ddx_version.major, + &ddx_version.minor, + &ddx_version.patch, + &driverName)) { + + /* No longer needed. */ + Xfree( driverName ); + + /* + * Get the DRI X extension version. + */ + err_msg = "XF86DRIQueryVersion"; + if (XF86DRIQueryVersion(dpy, + &dri_version.major, + &dri_version.minor, + &dri_version.patch)) { + drmHandle hFB; + int junk; + + /* + * 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 "createScreen" function. + */ + status = drmMap(fd, hSAREA, SAREA_MAX, + &pSAREA); + + err_msg = "drmMap of sarea"; + err_extra = strerror( -status ); + + if ( status == 0 ) { + PFNGLXGETINTERNALVERSIONPROC get_ver; + + get_ver = (PFNGLXGETINTERNALVERSIONPROC) + glXGetProcAddress( (const GLubyte *) "__glXGetInternalVersion" ); + + err_msg = "InitDriver"; + err_extra = NULL; + psp = __driUtilCreateNewScreen( dpy, scrn, psc, modes, + & ddx_version, + & dri_version, + & drm_version, + & framebuffer, + pSAREA, + fd, + (get_ver != NULL) ? (*get_ver)() : 1, + driverAPI ); + } + } + } + } + } + } + } } } - /* - ** Do not init dummy context here; actual initialization will be - ** done when the first DRI context is created. Init screen priv ptr - ** to NULL to let CreateContext routine that it needs to be inited. - */ - psp->dummyContextPriv.driScreenPriv = NULL; + if ( psp == NULL ) { + if ( pSAREA != MAP_FAILED ) { + (void)drmUnmap(pSAREA, SAREA_MAX); + } + + if ( framebuffer.base != MAP_FAILED ) { + (void)drmUnmap((drmAddress)framebuffer.base, framebuffer.size); + } + + if ( framebuffer.dev_priv != NULL ) { + Xfree(framebuffer.dev_priv); + } + + if ( fd >= 0 ) { + (void)drmClose(fd); + } + + if ( modes != NULL ) { + _gl_context_modes_destroy( modes ); + } - /* Initialize the drawHash when the first context is created */ - psp->drawHash = NULL; + (void)XF86DRICloseConnection(dpy, scrn); - psc->destroyScreen = driDestroyScreen; - psc->createContext = driCreateContext; - psc->createDrawable = driCreateDrawable_dummy; - psc->getDrawable = driGetDrawable; - if ( driCompareGLXAPIVersion( 20030317 ) >= 0 ) - psc->getMSC = driGetMSC; + 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"); + } return psp; } +#endif /* DRI_NEW_INTERFACE_ONLY */ /** @@ -1275,7 +1510,7 @@ driQueryFrameTracking( Display * dpy, void * priv, * * \f$p = t_d / (i * t_r)\f$ * - * Where \f$t_d\$f is the time since the last GLX buffer swap, \f$i\f$ is the + * Where \f$t_d\f$ is the time since the last GLX buffer swap, \f$i\f$ is the * swap interval (as set by \c glXSwapIntervalSGI), and \f$t_r\f$ time * required for a single vertical refresh period (as returned by \c * glXGetMscRateOML). @@ -1290,7 +1525,10 @@ driQueryFrameTracking( Display * dpy, void * priv, * required, 1.0 is returned, and if more than one is required then * a number greater than 1.0 will be returned. * - * \sa glXSwapIntervalSGI(), glXGetMscRateOML(). + * \sa glXSwapIntervalSGI glXGetMscRateOML + * + * \todo Instead of caching the \c glXGetMscRateOML function pointer, would it + * be possible to cache the sync rate? */ float driCalculateSwapUsage( __DRIdrawablePrivate *dPriv, int64_t last_swap_ust, @@ -1303,9 +1541,6 @@ driCalculateSwapUsage( __DRIdrawablePrivate *dPriv, int64_t last_swap_ust, float usage = 1.0; - /* FIXME: Instead of caching the function, would it be possible to - * FIXME: cache the sync rate? - */ if ( get_msc_rate == NULL ) { get_msc_rate = (PFNGLXGETMSCRATEOMLPROC) glXGetProcAddress( (const GLubyte *) "glXGetMscRateOML" ); diff --git a/xc/lib/GL/dri/dri_util.h b/xc/lib/GL/dri/dri_util.h index 88f6db9d1..38fd89344 100644 --- a/xc/lib/GL/dri/dri_util.h +++ b/xc/lib/GL/dri/dri_util.h @@ -167,28 +167,42 @@ struct __DriverAPIRec { /** * Full screen mode opening callback. * - * \deprecated Full screen functionality is no longer used by DRI. - * Drivers should simply install a function returning - * \c GL_TRUE for backwards compatability. + * \deprecated + * Full screen functionality is no longer used by DRI. Drivers should + * simply install a function returning \c GL_TRUE for backwards + * compatability. + * + * \todo + * Nothing calls this function anymore. Since this data structure is only + * accessed with in the driver (i.e., libGL never sees it), we need to + * remove the other cases that set this field and remove the field. */ GLboolean (*OpenFullScreen)(__DRIcontextPrivate *driContextPriv); /** * Full screen mode closing callback. - * - * \deprecated Full screen functionality is no longer used by DRI. - * Drivers should simply install a function returning - * \c GL_TRUE for backwards compatability. + * + * \deprecated + * Full screen functionality is no longer used by DRI. Drivers should + * simply install a function returning \c GL_TRUE for backwards + * compatability. + * + * \todo + * Nothing calls this function anymore. Since this data structure is only + * accessed with in the driver (i.e., libGL never sees it), we need to + * remove the other cases that set this field and remove the field. */ GLboolean (*CloseFullScreen)(__DRIcontextPrivate *driContextPriv); - /* Retrieves statistics about buffer swap operations. Required if + /** + * Retrieves statistics about buffer swap operations. Required if * GLX_OML_sync_control or GLX_MESA_swap_frame_usage is supported. */ int (*GetSwapInfo)( __DRIdrawablePrivate *dPriv, __DRIswapInfo * sInfo ); - /* Required if GLX_SGI_video_sync or GLX_OML_sync_control is + /** + * Required if GLX_SGI_video_sync or GLX_OML_sync_control is * supported. */ int (*GetMSC)( __DRIscreenPrivate * priv, int64_t * count ); @@ -215,13 +229,13 @@ struct __DRIswapInfoRec { */ uint64_t swap_count; - /* + /** * Unadjusted system time of the last buffer swap. This is the time * when the swap completed, not the time when swapBuffers was called. */ int64_t swap_ust; - /* + /** * Number of swap operations that occurred after the swap deadline. That * is if a swap happens more than swap_interval frames after the previous * swap, it has missed its deadline. If swap_interval is 0, then the @@ -229,7 +243,7 @@ struct __DRIswapInfoRec { */ uint64_t swap_missed_count; - /* + /** * Amount of time used by the last swap that missed its deadline. This * is calculated as (__glXGetUST() - swap_ust) / (swap_interval * * time_for_single_vrefresh)). If the actual value of swap_interval is @@ -240,6 +254,14 @@ struct __DRIswapInfoRec { }; +typedef Bool (GetDrawableInfo)( Display *dpy, int scrn, Drawable draw, + unsigned int * index, unsigned int * stamp, + int * x, int * y, int * width, int * height, + int * numClipRects, XF86DRIClipRectPtr * pClipRects, + int * backX, int * backY, + int * numBackClipRects, XF86DRIClipRectPtr * pBackClipRects ); + + /** * Per-drawable private DRI driver information. */ @@ -343,6 +365,12 @@ struct __DRIdrawablePrivateRec { * Called via glXSwapBuffers(). */ void (*swapBuffers)( __DRIdrawablePrivate *dPriv ); + + /** + * Get information about the location, size, and clip rects of the + * drawable within the display. + */ + GetDrawableInfo * getInfo; }; /** @@ -402,6 +430,7 @@ struct __DRIscreenPrivateRec { /** * \name DDX version * DDX / 2D driver version information. + * \todo Replace these fields with a \c __DRIversionRec. */ /*@{*/ int ddxMajor; @@ -412,6 +441,7 @@ struct __DRIscreenPrivateRec { /** * \name DRI version * DRI X extension version information. + * \todo Replace these fields with a \c __DRIversionRec. */ /*@{*/ int driMajor; @@ -422,6 +452,7 @@ struct __DRIscreenPrivateRec { /** * \name DRM version * DRM (kernel module) version information. + * \todo Replace these fields with a \c __DRIversionRec. */ /*@{*/ int drmMajor; @@ -507,6 +538,11 @@ struct __DRIscreenPrivateRec { /** * 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; @@ -527,16 +563,32 @@ extern void __driUtilUpdateDrawableInfo(__DRIdrawablePrivate *pdp); +extern __DRIscreenPrivate * __driUtilCreateNewScreen( Display *dpy, + int scrn, __DRIscreen *psc, __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 struct __DriverAPIRec *driverAPI ); + extern __DRIscreenPrivate * __driUtilCreateScreen(Display *dpy, int scrn, __DRIscreen *psc, int numConfigs, __GLXvisualConfig *config, const struct __DriverAPIRec *driverAPI); -/** This must be implemented in each driver */ +/** This must be implemented in each driver + * \deprecated + */ extern void * __driCreateScreen(Display *dpy, int scrn, __DRIscreen *psc, int numConfigs, __GLXvisualConfig *config); +/** This must be implemented in each driver */ +extern void * __driCreateNewScreen( Display *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, + __GLcontextModes ** driver_modes ); /** This is optionally implemented in each driver */ extern void diff --git a/xc/lib/GL/dri/xf86dri.h b/xc/lib/GL/dri/xf86dri.h index a3aee8805..013f5b32d 100644 --- a/xc/lib/GL/dri/xf86dri.h +++ b/xc/lib/GL/dri/xf86dri.h @@ -53,8 +53,8 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define X_XF86DRIGetDrawableInfo 9 #define X_XF86DRIGetDeviceInfo 10 #define X_XF86DRIAuthConnection 11 -#define X_XF86DRIOpenFullScreen 12 -#define X_XF86DRICloseFullScreen 13 +#define X_XF86DRIOpenFullScreen 12 /* Deprecated */ +#define X_XF86DRICloseFullScreen 13 /* Deprecated */ #define XF86DRINumberEvents 0 @@ -145,6 +145,16 @@ Bool XF86DRICreateContext( #endif ); +Bool XF86DRICreateContextWithConfig( +#if NeedFunctionPrototypes + Display* /* dpy */, + int /* screen */, + int /* visual ID / fbconfig ID */, + XID* /* ptr to returned context id */, + drmContextPtr /* hHWContext */ +#endif +); + Bool XF86DRIDestroyContext( #if NeedFunctionPrototypes Display* /* dpy */, @@ -203,22 +213,6 @@ Bool XF86DRIGetDeviceInfo( #endif ); -Bool XF86DRIOpenFullScreen( -#if NeedFunctionPrototypes - Display* /* dpy */, - int /* screen */, - Drawable /* drawable */ -#endif -); - -Bool XF86DRICloseFullScreen( -#if NeedFunctionPrototypes - Display* /* dpy */, - int /* screen */, - Drawable /* drawable */ -#endif -); - _XFUNCPROTOEND #endif /* _XF86DRI_SERVER_ */ diff --git a/xc/lib/GL/glx/Imakefile b/xc/lib/GL/glx/Imakefile index 9cadeeb11..43ca2699d 100644 --- a/xc/lib/GL/glx/Imakefile +++ b/xc/lib/GL/glx/Imakefile @@ -104,7 +104,7 @@ LinkSourceFile(glapi_sparc.S, $(MESASRCDIR)/src/mesa/sparc) #endif #if BuildXF86DRI - DRI_INCS = -I$(GLXLIBSRC)/dri + DRI_INCS = -I$(GLXLIBSRC)/dri -I$(SERVERSRC)/GL/dri #if defined(i386Architecture) && MesaUseX86Asm ASM_SRCS = glapi_x86.S ASM_OBJS = glapi_x86.o @@ -133,6 +133,7 @@ LinkSourceFile(glapi_sparc.S, $(MESASRCDIR)/src/mesa/sparc) -I$(MESASRCDIR)/src/mesa/glapi \ -I$(MESASRCDIR)/src/mesa/drivers/x11 \ -I$(MESASRCDIR)/src/mesa/$(ASM_DIR) \ + -I$(XF86OSSRC) \ $(DRI_INCS) #include <Library.tmpl> diff --git a/xc/lib/GL/glx/glcontextmodes.c b/xc/lib/GL/glx/glcontextmodes.c index 2cfbe213a..aec7322a5 100644 --- a/xc/lib/GL/glx/glcontextmodes.c +++ b/xc/lib/GL/glx/glcontextmodes.c @@ -103,6 +103,10 @@ _gl_convert_to_x_visual_type( int visualType ) * * \param mode Destination GL context mode. * \param config Source GLX visual config. + * + * \note + * The \c fbconfigID and \c visualID fields of the \c __GLcontextModes + * structure will be set to the \c vid of the \c __GLXvisualConfig structure. */ void _gl_copy_visual_to_context_mode( __GLcontextModes * mode, @@ -116,7 +120,7 @@ _gl_copy_visual_to_context_mode( __GLcontextModes * mode, mode->visualID = config->vid; mode->visualType = _gl_convert_from_x_visual_type( config->class ); mode->xRenderable = GL_TRUE; - mode->fbconfigID = GLX_DONT_CARE; + mode->fbconfigID = config->vid; mode->drawableType = GLX_WINDOW_BIT; mode->rgbMode = (config->rgba != 0); @@ -161,6 +165,8 @@ _gl_copy_visual_to_context_mode( __GLcontextModes * mode, mode->transparentBlue = config->transparentBlue; mode->transparentAlpha = config->transparentAlpha; mode->transparentIndex = config->transparentIndex; + + mode->swapMethod = GLX_SWAP_UNDEFINED_OML; } @@ -386,3 +392,92 @@ _gl_context_modes_destroy( __GLcontextModes * modes ) modes = next; } } + + +/** + * Find a context mode matching a Visual ID. + * + * \param modes List list of context-mode structures to be searched. + * \param vid Visual ID to be found. + * \returns A pointer to a context-mode in \c modes if \c vid was found in + * the list, or \c NULL if it was not. + */ + +__GLcontextModes * +_gl_context_modes_find_visual( __GLcontextModes * modes, int vid ) +{ + while ( modes != NULL ) { + if ( modes->visualID == vid ) { + break; + } + + modes = modes->next; + } + + return modes; +} + + +/** + * Determine if two context-modes are the same. This is intended to be used + * by libGL implementations to compare to sets of driver generated FBconfigs. + * + * \param a Context-mode to be compared. + * \param b Context-mode to be compared. + * \returns \c GL_TRUE if the two context-modes are the same. \c GL_FALSE is + * returned otherwise. + */ +GLboolean +_gl_context_modes_are_same( const __GLcontextModes * a, + const __GLcontextModes * b ) +{ + return( (a->rgbMode == b->rgbMode) && + (a->floatMode == b->floatMode) && + (a->colorIndexMode == b->colorIndexMode) && + (a->doubleBufferMode == b->doubleBufferMode) && + (a->stereoMode == b->stereoMode) && + (a->redBits == b->redBits) && + (a->greenBits == b->greenBits) && + (a->blueBits == b->blueBits) && + (a->alphaBits == b->alphaBits) && +#if 0 /* For some reason these don't get set on the client-side in libGL. */ + (a->redMask == b->redMask) && + (a->greenMask == b->greenMask) && + (a->blueMask == b->blueMask) && + (a->alphaMask == b->alphaMask) && +#endif + (a->rgbBits == b->rgbBits) && + (a->indexBits == b->indexBits) && + (a->accumRedBits == b->accumRedBits) && + (a->accumGreenBits == b->accumGreenBits) && + (a->accumBlueBits == b->accumBlueBits) && + (a->accumAlphaBits == b->accumAlphaBits) && + (a->depthBits == b->depthBits) && + (a->stencilBits == b->stencilBits) && + (a->numAuxBuffers == b->numAuxBuffers) && + (a->level == b->level) && + (a->pixmapMode == b->pixmapMode) && + (a->visualRating == b->visualRating) && + + (a->transparentPixel == b->transparentPixel) && + + ((a->transparentPixel != GLX_TRANSPARENT_RGB) || + ((a->transparentRed == b->transparentRed) && + (a->transparentGreen == b->transparentGreen) && + (a->transparentBlue == b->transparentBlue) && + (a->transparentAlpha == b->transparentAlpha))) && + + ((a->transparentPixel != GLX_TRANSPARENT_INDEX) || + (a->transparentIndex == b->transparentIndex)) && + + (a->sampleBuffers == b->sampleBuffers) && + (a->samples == b->samples) && + (a->drawableType == b->drawableType) && + (a->renderType == b->renderType) && + (a->maxPbufferWidth == b->maxPbufferWidth) && + (a->maxPbufferHeight == b->maxPbufferHeight) && + (a->maxPbufferPixels == b->maxPbufferPixels) && + (a->optimalPbufferWidth == b->optimalPbufferWidth) && + (a->optimalPbufferHeight == b->optimalPbufferHeight) && + (a->swapMethod == b->swapMethod) ); +} diff --git a/xc/lib/GL/glx/glcontextmodes.h b/xc/lib/GL/glx/glcontextmodes.h index 7fae88b41..5f8fa4f31 100644 --- a/xc/lib/GL/glx/glcontextmodes.h +++ b/xc/lib/GL/glx/glcontextmodes.h @@ -41,5 +41,9 @@ 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 GLboolean _gl_context_modes_are_same( const __GLcontextModes * a, + const __GLcontextModes * b ); #endif /* GLCONTEXTMODES_H */ diff --git a/xc/lib/GL/glx/glxclient.h b/xc/lib/GL/glx/glxclient.h index e6ed1ec11..317ea0111 100644 --- a/xc/lib/GL/glx/glxclient.h +++ b/xc/lib/GL/glx/glxclient.h @@ -48,6 +48,7 @@ #include <X11/Xlibint.h> #define GLX_GLXEXT_PROTOTYPES #include <GL/glx.h> +#include <GL/glxext.h> #include <string.h> #include <stdlib.h> #include "GL/glxint.h" @@ -89,11 +90,64 @@ typedef struct __DRIscreenRec __DRIscreen; typedef struct __DRIcontextRec __DRIcontext; typedef struct __DRIdrawableRec __DRIdrawable; typedef struct __DRIdriverRec __DRIdriver; +typedef struct __DRIframebufferRec __DRIframebuffer; +typedef struct __DRIversionRec __DRIversion; /*@}*/ extern __DRIscreen *__glXFindDRIScreen(Display *dpy, int scrn); /** + * Stored version of some component (i.e., server-side DRI module, kernel-side + * DRM, etc.). + * + * \todo There are several data structures that explicitly store a major + * version, minor version, and patch level. These structures should + * be modified to have a \c __DRIversionRec instead. + */ +struct __DRIversionRec { + int major; /**< Major version number. */ + int minor; /**< Minor version number. */ + int patch; /**< Patch-level. */ +}; + +/** + * Framebuffer information record. Used by libGL to communicate information + * about the framebuffer to the driver's \c __DRIdisplayRec::createNewScreen + * function. + * + * In XFree86, most of this information is derrived from data returned by + * calling \c XF86DRIGetDeviceInfo. + * + * \sa XF86DRIGetDeviceInfo __DRIdisplayRec::createNewScreen + * __driUtilCreateNewScreen CallCreateNewScreen + * + * \bug This structure could be better named. + */ +struct __DRIframebufferRec { + unsigned char *base; /**< Framebuffer base address in the CPU's + * address space. This value is calculated by + * calling \c drmMap on the framebuffer handle + * returned by \c XF86DRIGetDeviceInfo (or a + * similar function). + */ + int size; /**< Framebuffer size, in bytes. */ + int stride; /**< Number of bytes from one line to the next. */ + int width; /**< Pixel width of the framebuffer. */ + int height; /**< Pixel height of the framebuffer. */ + int dev_priv_size; /**< Size of the driver's dev-priv structure. */ + void *dev_priv; /**< Pointer to the driver's dev-priv structure. */ +}; + +typedef void *(*CreateScreenFunc)(Display *dpy, int scrn, __DRIscreen *psc, + int numConfigs, __GLXvisualConfig *config); + +typedef void *(*CreateNewScreenFunc)(Display *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, __GLcontextModes ** driver_modes); + +/** * Display dependent methods. This structure is initialized during the * \c driCreateDisplay call. */ @@ -107,16 +161,26 @@ struct __DRIdisplayRec { * Methods to create the private DRI screen data and initialize the * screen dependent methods. * This is an array [indexed by screen number] of function pointers. + * + * \deprecated This array of function pointers has been replaced by + * \c __DRIdisplayRec::createNewScreen. + * \sa __DRIdisplayRec::createNewScreen */ - void *(**createScreen)(Display *dpy, int scrn, __DRIscreen *psc, - int numConfigs, __GLXvisualConfig *config); + CreateScreenFunc * createScreen; /** * Opaque pointer to private per display direct rendering data. - * \c NULL if direct rendering is not supported on this display. Never - * dereferenced in libGL. + * \c NULL if direct rendering is not supported on this display. */ - void *private; + struct __DRIdisplayPrivateRec *private; + + /** + * Array of pointers to methods to create and initialize the private DRI + * screen data. + * + * \sa __DRIdisplayRec::createScreen + */ + CreateNewScreenFunc * createNewScreen; }; /** @@ -132,6 +196,13 @@ struct __DRIscreenRec { /** * Method to create the private DRI context data and initialize the * context dependent methods. + * + * \sa __DRIscreenRec::createNewContext driCreateContext + * driCreateNewContext + * \deprecated This function has been replaced by + * __DRIscreenRec::createNewContext. New drivers will + * continue to export this method, but it will eventually + * (in the next XFree86 major relearse) go away. */ void *(*createContext)(Display *dpy, XVisualInfo *vis, void *sharedPrivate, __DRIcontext *pctx); @@ -140,8 +211,9 @@ struct __DRIscreenRec { * Method to create the private DRI drawable data and initialize the * drawable dependent methods. */ - void *(*createDrawable)(Display *dpy, int scrn, GLXDrawable draw, - VisualID vid, __DRIdrawable *pdraw); + void *(*createNewDrawable)(Display *dpy, const __GLcontextModes *modes, + GLXDrawable draw, __DRIdrawable *pdraw, + int renderType, const int *attrs); /** * Method to return a pointer to the DRI drawable data. @@ -188,6 +260,16 @@ struct __DRIscreenRec { GLuint (*memoryOffset)(Display *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)(Display *dpy, const __GLcontextModes *modes, + int render_type, + void *sharedPrivate, __DRIcontext *pctx); }; /** @@ -327,9 +409,6 @@ struct __DRIdrawableRec { }; -typedef void *(*CreateScreenFunc)(Display *dpy, int scrn, __DRIscreen *psc, - int numConfigs, __GLXvisualConfig *config); - /* ** We keep a linked list of these structures, one per DRI device driver. */ @@ -337,6 +416,7 @@ struct __DRIdriverRec { const char *name; void *handle; CreateScreenFunc createScreenFunc; + CreateNewScreenFunc createNewScreenFunc; struct __DRIdriverRec *next; }; @@ -576,6 +656,10 @@ struct __GLXcontextRec { /** * Visual id. + * + * \deprecated + * This filed has been largely been replaced by the \c mode field, but + * the work is not quite done. */ VisualID vid; @@ -699,9 +783,14 @@ struct __GLXcontextRec { #endif /** - * \c GLXFBConfigID used to create this context. May be \c None. + * \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; @@ -721,6 +810,16 @@ struct __GLXcontextRec { * drivers should NEVER use this data or even care that it exists. */ void * client_state_private; + +#ifdef GLX_DIRECT_RENDERING + /** + * Pointer to the mode used to create this context. This field replaces + * the \c vid and \c fbconfigID fields. + * + * \since Internal API version 20031201. + */ + const __GLcontextModes * mode; +#endif /* GLX_DIRECT_RENDERING */ }; #define __glXSetError(gc,code) \ @@ -1030,4 +1129,15 @@ extern int __glXGetUST( int64_t * ust ); */ typedef int (* PFNGLXGETUSTPROC) ( int64_t * ust ); + +/** + * Type of pointer to \c __glXCreateContextModes, as returned by + * \c glXGetProcAddress. + * + * \sa _gl_context_modes_create, glXGetProcAddress + */ + +typedef __GLcontextModes * (* PFNGLXCREATECONTEXTMODES) ( unsigned count, + size_t minimum_bytes_per_struct ); + #endif /* !__GLX_client_h__ */ diff --git a/xc/lib/GL/glx/glxcmds.c b/xc/lib/GL/glx/glxcmds.c index ae8a23bdf..59c5b5986 100644 --- a/xc/lib/GL/glx/glxcmds.c +++ b/xc/lib/GL/glx/glxcmds.c @@ -54,6 +54,10 @@ #include "glcontextmodes.h" #include <sys/time.h> +#ifdef IN_DOXYGEN +#define GLX_PREFIX(x) x +#endif /* IN_DOXYGEN */ + const char __glXGLClientExtensions[] = "GL_ARB_depth_texture " "GL_ARB_imaging " @@ -175,11 +179,13 @@ static const char __glXGLXClientVersion[] = "1.2"; const char __glXGLClientVersion[] = "1.2"; #ifdef GLX_DIRECT_RENDERING +extern Bool XF86DRICreateContextWithConfig( void ); + static Bool __glXWindowExists(Display *dpy, GLXDrawable draw); -static void * DriverCreateContextWrapper( __GLXscreenConfigs *psc, +static void * DriverCreateContextWrapper( const __GLXscreenConfigs *psc, Display *dpy, XVisualInfo *vis, void *shared, __DRIcontext *ctx, - __GLcontextModes *fbconfig ); + const __GLcontextModes *fbconfig, int render_type ); static Bool dummyBindContext2( Display *dpy, int scrn, GLXDrawable draw, GLXDrawable read, GLXContext gc ); @@ -233,26 +239,44 @@ static Bool dummyUnbindContext2( Display *dpy, int scrn, * __DRIcontextRec::bindContext2, __DRIcontextRec::unbindContext2 */ -static void * DriverCreateContextWrapper( __GLXscreenConfigs *psc, +static void * DriverCreateContextWrapper( const __GLXscreenConfigs *psc, Display *dpy, XVisualInfo *vis, void *shared, __DRIcontext *ctx, - __GLcontextModes *fbconfig ) + const __GLcontextModes *modes, + int render_type ) { - void * ctx_priv; + void * ctx_priv = NULL; - (void) fbconfig; - ctx_priv = (*psc->driScreen.createContext)(dpy, vis, shared, ctx); - if ( ctx_priv != NULL ) { - if ( ctx->unbindContext2 == NULL ) { - ctx->unbindContext2 = dummyUnbindContext2; - } + if ( psc->driScreen.createNewContext != NULL ) { + assert( modes != NULL ); + ctx_priv = (*psc->driScreen.createNewContext)(dpy, modes, render_type, + shared, ctx); + + /* If the driver supports the createNewContext interface, then + * it MUST also support the bindContext2 / unbindContext2 + * interface. + */ + + assert( (ctx_priv == NULL) || (ctx->unbindContext2 != NULL) ); + assert( (ctx_priv == NULL) || (ctx->bindContext2 != NULL) ); + } + else { + if ( vis != NULL ) { + ctx_priv = (*psc->driScreen.createContext)(dpy, vis, shared, ctx); - if ( ctx->bindContext2 == NULL ) { - ctx->bindContext2 = dummyBindContext2; + if ( ctx_priv != NULL ) { + if ( ctx->unbindContext2 == NULL ) { + ctx->unbindContext2 = dummyUnbindContext2; + } + + if ( ctx->bindContext2 == NULL ) { + ctx->bindContext2 = dummyBindContext2; + } + } } } - + return ctx_priv; } #endif @@ -505,11 +529,12 @@ GLXContext AllocateGLXContext( Display *dpy ) * \param renderType For FBConfigs, what is the rendering type? */ -static -GLXContext CreateContext(Display *dpy, XVisualInfo *vis, - __GLcontextModes * fbconfig, GLXContext shareList, - Bool allowDirect, GLXContextID contextID, - Bool use_glx_1_3, int renderType) +static GLXContext +CreateContext(Display *dpy, XVisualInfo *vis, + const __GLcontextModes * const fbconfig, + GLXContext shareList, + Bool allowDirect, GLXContextID contextID, + Bool use_glx_1_3, int renderType) { GLXContext gc; @@ -528,24 +553,37 @@ GLXContext CreateContext(Display *dpy, XVisualInfo *vis, if (allowDirect) { int screen = (fbconfig == NULL) ? vis->screen : fbconfig->screen; __GLXscreenConfigs * const psc = GetGLXScreenConfigs(dpy, screen); + const __GLcontextModes * mode; + + /* The value of fbconfig cannot change because it is tested + * later in the function. + */ + if ( fbconfig == NULL ) { + /* FIXME: Is it possible for the __GLcontextModes structure + * FIXME: to not be found? + */ + mode = _gl_context_modes_find_visual( psc->configs, + vis->visualid ); + assert( mode != NULL ); + assert( mode->screen == screen ); + } + else { + mode = fbconfig; + } if (psc && psc->driScreen.private) { void * const shared = (shareList != NULL) ? shareList->driContext.private : NULL; gc->driContext.private = DriverCreateContextWrapper( psc, dpy, vis, shared, - &gc->driContext, fbconfig ); + &gc->driContext, mode, + renderType ); if (gc->driContext.private) { gc->isDirect = GL_TRUE; - gc->screen = screen; - if ( fbconfig == NULL ) { - gc->vid = vis->visualid; - gc->fbconfigID = None; - } - else { - gc->vid = fbconfig->visualID; - gc->fbconfigID = fbconfig->fbconfigID; - } + gc->screen = mode->screen; + gc->vid = mode->visualID; + gc->fbconfigID = mode->fbconfigID; + gc->mode = mode; } } } @@ -580,14 +618,15 @@ GLXContext CreateContext(Display *dpy, XVisualInfo *vis, req->isDirect = gc->isDirect; } else { - xGLXVendorPrivateReq *vpreq; + xGLXVendorPrivateWithReplyReq *vpreq; xGLXCreateContextWithConfigSGIXReq *req; /* Send the glXCreateNewContext request */ - GetReqExtra(GLXVendorPrivate, - sz_xGLXCreateContextWithConfigSGIXReq-sz_xGLXVendorPrivateReq,vpreq); + GetReqExtra(GLXVendorPrivateWithReply, + sz_xGLXCreateContextWithConfigSGIXReq-sz_xGLXVendorPrivateWithReplyReq,vpreq); req = (xGLXCreateContextWithConfigSGIXReq *)vpreq; req->reqType = gc->majorOpcode; + req->glxCode = X_GLXVendorPrivateWithReply; req->vendorCode = X_GLXvop_CreateContextWithConfigSGIX; req->context = gc->xid = XAllocID(dpy); req->fbconfig = fbconfig->fbconfigID; @@ -1023,15 +1062,12 @@ int GLX_PREFIX(glXGetConfig)(Display *dpy, XVisualInfo *vis, int attribute, status = GetGLXPrivScreenConfig( dpy, vis->screen, & priv, & psc ); if ( status == Success ) { - const __GLcontextModes * modes; + const __GLcontextModes * const modes = _gl_context_modes_find_visual( + psc->configs, vis->visualid ); /* Lookup attribute after first finding a match on the visual */ - for ( modes = psc->configs ; modes != NULL ; modes = modes->next ) { - if (modes->visualID == vis->visualid) { - return _gl_get_context_mode_data( modes, - attribute, - value_return ); - } + if ( modes != NULL ) { + return _gl_get_context_mode_data( modes, attribute, value_return ); } status = GLX_BAD_VISUAL; @@ -1051,6 +1087,38 @@ int GLX_PREFIX(glXGetConfig)(Display *dpy, XVisualInfo *vis, int attribute, /************************************************************************/ +static void +init_fbconfig_for_chooser( __GLcontextModes * config, + GLboolean fbconfig_style_tags ) +{ + memset( config, 0, sizeof( __GLcontextModes ) ); + config->visualID = (XID) GLX_DONT_CARE; + config->visualType = GLX_DONT_CARE; + + /* glXChooseFBConfig specifies different defaults for these two than + * glXChooseVisual. + */ + if ( fbconfig_style_tags ) { + config->rgbMode = GL_TRUE; + config->doubleBufferMode = GLX_DONT_CARE; + } + + config->visualRating = GLX_DONT_CARE; + config->transparentPixel = GLX_NONE; + config->transparentRed = GLX_DONT_CARE; + config->transparentGreen = GLX_DONT_CARE; + config->transparentBlue = GLX_DONT_CARE; + config->transparentAlpha = GLX_DONT_CARE; + config->transparentIndex = GLX_DONT_CARE; + + config->drawableType = GLX_WINDOW_BIT; + config->renderType = (config->rgbMode) ? GLX_RGBA_BIT : GLX_COLOR_INDEX_BIT; + config->xRenderable = GLX_DONT_CARE; + config->fbconfigID = (GLXFBConfigID)(GLX_DONT_CARE); + + config->swapMethod = GLX_DONT_CARE; +} + #define MATCH_DONT_CARE( param ) \ do { \ if ( (a-> param != GLX_DONT_CARE) \ @@ -1158,6 +1226,27 @@ fbconfigs_compatible( const __GLcontextModes * const a, } +/* There's some trickly language in the GLX spec about how this is supposed + * to work. Basically, if a given component size is either not specified + * or the requested size is zero, it is supposed to act like PERFER_SMALLER. + * Well, that's really hard to do with the code as-is. This behavior is + * closer to correct, but still not technically right. + */ +#define PREFER_LARGER_OR_ZERO(comp) \ + do { \ + if ( ((*a)-> comp) != ((*b)-> comp) ) { \ + if ( ((*a)-> comp) == 0 ) { \ + return -1; \ + } \ + else if ( ((*b)-> comp) == 0 ) { \ + return 1; \ + } \ + else { \ + return ((*b)-> comp) - ((*a)-> comp) ; \ + } \ + } \ + } while( 0 ) + #define PREFER_LARGER(comp) \ do { \ if ( ((*a)-> comp) != ((*b)-> comp) ) { \ @@ -1187,7 +1276,7 @@ fbconfig_compare( const __GLcontextModes * const * const a, const __GLcontextModes * const * const b ) { /* The order of these comparisons must NOT change. It is defined by - * SGIX_fbconfig, SGIX_pbuffer, and ARB_multisample. + * the GLX 1.3 spec and ARB_multisample. */ PREFER_SMALLER( visualSelectGroup ); @@ -1198,6 +1287,14 @@ fbconfig_compare( const __GLcontextModes * const * const a, */ PREFER_SMALLER( visualRating ); + /* This isn't quite right. It is supposed to compare the sum of the + * components the user specifically set minimums for. + */ + PREFER_LARGER_OR_ZERO( redBits ); + PREFER_LARGER_OR_ZERO( greenBits ); + PREFER_LARGER_OR_ZERO( blueBits ); + PREFER_LARGER_OR_ZERO( alphaBits ); + PREFER_SMALLER( rgbBits ); if ( ((*a)->doubleBufferMode != (*b)->doubleBufferMode) ) { @@ -1208,26 +1305,32 @@ fbconfig_compare( const __GLcontextModes * const * const a, PREFER_SMALLER( numAuxBuffers ); - PREFER_LARGER( redBits ); - PREFER_LARGER( greenBits ); - PREFER_LARGER( blueBits ); - PREFER_LARGER( alphaBits ); - PREFER_LARGER( stencilBits ); - PREFER_LARGER( accumRedBits ); - PREFER_LARGER( accumGreenBits ); - PREFER_LARGER( accumBlueBits ); - PREFER_LARGER( accumAlphaBits ); + PREFER_LARGER_OR_ZERO( depthBits ); + PREFER_SMALLER( stencilBits ); + /* This isn't quite right. It is supposed to compare the sum of the + * components the user specifically set minimums for. + */ + PREFER_LARGER_OR_ZERO( accumRedBits ); + PREFER_LARGER_OR_ZERO( accumGreenBits ); + PREFER_LARGER_OR_ZERO( accumBlueBits ); + PREFER_LARGER_OR_ZERO( accumAlphaBits ); + + PREFER_SMALLER( visualType ); + + /* None of the multisample specs say where this comparison should happen, + * so I put it near the end. + */ PREFER_SMALLER( sampleBuffers ); PREFER_SMALLER( samples ); + /* None of the pbuffer or fbconfig specs say that this comparison needs + * to happen at all, but it seems like it should. + */ PREFER_LARGER( maxPbufferWidth ); PREFER_LARGER( maxPbufferHeight ); PREFER_LARGER( maxPbufferPixels ); - PREFER_LARGER( drawableType ); - PREFER_LARGER( renderType ); - return 0; } @@ -1268,7 +1371,8 @@ choose_visual( __GLcontextModes ** configs, int num_configs, * list. */ - __glXInitializeVisualConfigFromTags( & test_config, 512, + init_fbconfig_for_chooser( & test_config, fbconfig_style_tags ); + __glXInitializeVisualConfigFromTags( & test_config, 512, (const INT32 *) attribList, GL_TRUE, fbconfig_style_tags ); @@ -1327,6 +1431,7 @@ XVisualInfo *GLX_PREFIX(glXChooseVisual)(Display *dpy, int screen, int *attribLi ** Build a template from the defaults and the attribute list ** Free visual list and return if an unexpected token is encountered */ + init_fbconfig_for_chooser( & test_config, GL_FALSE ); __glXInitializeVisualConfigFromTags( & test_config, 512, (const INT32 *) attribList, GL_TRUE, GL_FALSE ); @@ -1339,7 +1444,7 @@ XVisualInfo *GLX_PREFIX(glXChooseVisual)(Display *dpy, int screen, int *attribLi 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)) ) { + || (fbconfig_compare( (const __GLcontextModes * const * const)&modes, &best_config ) < 0)) ) { best_config = modes; } } @@ -2259,7 +2364,7 @@ GLX_ALIAS(XVisualInfo *, glXGetVisualFromFBConfigSGIX, GLXPixmap GLX_PREFIX(glXCreateGLXPixmapWithConfigSGIX)(Display *dpy, GLXFBConfigSGIX config, Pixmap pixmap) { - xGLXVendorPrivateReq *vpreq; + xGLXVendorPrivateWithReplyReq *vpreq; xGLXCreateGLXPixmapWithConfigSGIXReq *req; GLXPixmap xid = None; CARD8 opcode; @@ -2281,10 +2386,11 @@ GLXPixmap GLX_PREFIX(glXCreateGLXPixmapWithConfigSGIX)(Display *dpy, GLXFBConfig /* Send the glXCreateGLXPixmapWithConfigSGIX request */ LockDisplay(dpy); - GetReqExtra(GLXVendorPrivate, - sz_xGLXCreateGLXPixmapWithConfigSGIXReq-sz_xGLXVendorPrivateReq,vpreq); + GetReqExtra(GLXVendorPrivateWithReply, + sz_xGLXCreateGLXPixmapWithConfigSGIXReq-sz_xGLXVendorPrivateWithReplyReq,vpreq); req = (xGLXCreateGLXPixmapWithConfigSGIXReq *)vpreq; req->reqType = opcode; + req->glxCode = X_GLXVendorPrivateWithReply; req->vendorCode = X_GLXvop_CreateGLXPixmapWithConfigSGIX; req->screen = fbconfig->screen; req->fbconfig = fbconfig->fbconfigID; @@ -2323,16 +2429,12 @@ GLXFBConfigSGIX GLX_PREFIX(glXGetFBConfigFromVisualSGIX)(Display *dpy, XVisualIn { __GLXdisplayPrivate *priv; __GLXscreenConfigs *psc; - __GLcontextModes *modes; if ( (GetGLXPrivScreenConfig( dpy, vis->screen, & priv, & psc ) != Success) && __glXExtensionBitIsEnabled( psc, SGIX_fbconfig_bit ) && (psc->configs->fbconfigID != GLX_DONT_CARE) ) { - for ( modes = psc->configs ; modes != NULL ; modes = modes->next ) { - if ( modes->visualID == vis->visualid ) { - return (GLXFBConfigSGIX) modes; - } - } + return (GLXFBConfigSGIX) _gl_context_modes_find_visual( psc->configs, + vis->visualid ); } return NULL; @@ -2745,9 +2847,10 @@ Bool GLX_PREFIX(glXWaitForSbcOML)(Display * dpy, GLXDrawable drawable, } -/* -** GLX_MESA_allocate_memory -*/ +/** + * GLX_MESA_allocate_memory + */ +/*@{*/ void *GLX_PREFIX(glXAllocateMemoryMESA)(Display *dpy, int scrn, size_t size, @@ -2815,12 +2918,36 @@ GLuint GLX_PREFIX(glXGetMemoryOffsetMESA)( Display *dpy, int scrn, return ~0L; } +/*@}*/ -/* -** Mesa extension stubs. These will help reduce portability problems. -*/ +/** + * Mesa extension stubs. These will help reduce portability problems. + */ +/*@{*/ +/** + * Release all buffers associated with the specified GLX drawable. + * + * \todo + * This function was intended for stand-alone Mesa. The issue there is that + * the library doesn't get any notification when a window is closed. In + * DRI there is a similar but slightly different issue. When GLX 1.3 is + * supported, there are 3 different functions to destroy a drawable. It + * should be possible to create GLX protocol (or have it determine which + * protocol to use based on the type of the drawable) to have one function + * do the work of 3. For the direct-rendering case, this function could + * just call the driver's \c __DRIdrawableRec::destroyDrawable function. + * This would reduce the frequency with which \c __driGarbageCollectDrawables + * would need to be used. This really should be done as part of the new DRI + * interface work. + * + * \sa http://oss.sgi.com/projects/ogl-sample/registry/MESA/release_buffers.txt + * __driGarbageCollectDrawables + * glXDestroyGLXPixmap + * glXDestroyPbuffer glXDestroyPixmap glXDestroyWindow + * glXDestroyGLXPbufferSGIX glXDestroyGLXVideoSourceSGIX + */ Bool GLX_PREFIX(glXReleaseBuffersMESA)( Display *dpy, GLXDrawable d ) { (void) dpy; @@ -2858,6 +2985,7 @@ Bool GLX_PREFIX(glXSet3DfxModeMESA)( int mode ) (void) mode; return GL_FALSE; } +/*@}*/ @@ -3051,6 +3179,7 @@ static const struct name_address_pair GLX_functions[] = { GLX_FUNCTION( __glXFindDRIScreen ), GLX_FUNCTION( __glXGetInternalVersion ), GLX_FUNCTION( __glXWindowExists ), + GLX_FUNCTION2( __glXCreateContextWithConfig, XF86DRICreateContextWithConfig ), /*** DRI configuration ***/ GLX_FUNCTION( glXGetScreenDriver ), @@ -3059,6 +3188,9 @@ static const struct name_address_pair GLX_functions[] = { GLX_FUNCTION( __glXScrEnableExtension ), GLX_FUNCTION( __glXGetUST ), + + GLX_FUNCTION2( __glXCreateContextModes, _gl_context_modes_create ), + GLX_FUNCTION2( __glXDestroyContextModes, _gl_context_modes_destroy ), #endif { NULL, NULL } /* end of list */ @@ -3165,8 +3297,9 @@ int __glXGetInternalVersion(void) * 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. */ - return 20030818; + return 20031201; } diff --git a/xc/lib/GL/glx/glxext.c b/xc/lib/GL/glx/glxext.c index 9eaf48435..080ecf036 100644 --- a/xc/lib/GL/glx/glxext.c +++ b/xc/lib/GL/glx/glxext.c @@ -35,12 +35,13 @@ ** */ -/* < - * Direct rendering support added by Precision Insight, Inc. < - * < - * Authors: < - * Kevin E. Martin <kevin@precisioninsight.com> < - * < +/** + * \file glxext.c + * GLX protocol interface boot-strap code. + * + * Direct rendering support added by Precision Insight, Inc. + * + * \author Kevin E. Martin <kevin@precisioninsight.com> */ #include "packrender.h" @@ -56,6 +57,14 @@ #include "glxextensions.h" #include "glcontextmodes.h" +#ifdef GLX_DIRECT_RENDERING +#include <inttypes.h> +#include <sys/mman.h> +#include "xf86dri.h" +#include "sarea.h" +#include "dri_glx.h" +#endif + #include <assert.h> #ifdef DEBUG @@ -436,63 +445,12 @@ __glXInitializeVisualConfigFromTags( __GLcontextModes *config, int count, count -= __GLX_MIN_CONFIG_PROPS; } - else { - config->visualID = (XID) GLX_DONT_CARE; - config->visualType = GLX_DONT_CARE; - config->rgbMode = ( fbconfig_style_tags ) - ? GL_TRUE /* glXChooseFBConfig() */ - : GL_FALSE; /* glXChooseVisual() */ - - config->redBits = 0; - config->greenBits = 0; - config->blueBits = 0; - config->alphaBits = 0; - config->accumRedBits = 0; - config->accumGreenBits = 0; - config->accumBlueBits = 0; - config->accumAlphaBits = 0; - - config->doubleBufferMode = ( fbconfig_style_tags ) - ? GLX_DONT_CARE /* glXChooseFBConfig() */ - : GL_FALSE; /* glXChooseVisual() */ - config->stereoMode = GL_FALSE; - - config->rgbBits = 0; - config->depthBits = 0; - config->stencilBits = 0; - config->numAuxBuffers = 0; - config->level = 0; - } /* ** Additional properties may be in a list at the end ** of the reply. They are in pairs of property type ** and property value. */ - config->visualRating = GLX_DONT_CARE; - config->visualSelectGroup = 0; - config->transparentPixel = GLX_NONE; - config->transparentRed = GLX_DONT_CARE; - config->transparentGreen = GLX_DONT_CARE; - config->transparentBlue = GLX_DONT_CARE; - config->transparentAlpha = GLX_DONT_CARE; - config->transparentIndex = GLX_DONT_CARE; - - config->floatMode = GL_FALSE; - config->drawableType = GLX_WINDOW_BIT; - config->renderType = (config->rgbMode) ? GLX_RGBA_BIT : GLX_COLOR_INDEX_BIT; - config->xRenderable = GLX_DONT_CARE; - config->fbconfigID = (GLXFBConfigID)(GLX_DONT_CARE); - - config->maxPbufferWidth = 0; - config->maxPbufferHeight = 0; - config->maxPbufferPixels = 0; - config->optimalPbufferWidth = 0; - config->optimalPbufferHeight = 0; - - config->sampleBuffers = 0; - config->samples = 0; - config->swapMethod = GLX_SWAP_UNDEFINED_OML; #define FETCH_OR_SET(tag) \ config-> tag = ( fbconfig_style_tags ) ? *bp++ : 1 @@ -501,7 +459,6 @@ __glXInitializeVisualConfigFromTags( __GLcontextModes *config, int count, switch(*bp++) { case GLX_RGBA: FETCH_OR_SET( rgbMode ); - config->renderType = (config->rgbMode) ? GLX_RGBA_BIT : GLX_COLOR_INDEX_BIT; break; case GLX_BUFFER_SIZE: config->rgbBits = *bp++; @@ -622,6 +579,8 @@ __glXInitializeVisualConfigFromTags( __GLcontextModes *config, int count, } } + config->renderType = (config->rgbMode) ? GLX_RGBA_BIT : GLX_COLOR_INDEX_BIT; + config->haveAccumBuffer = ((config->accumRedBits + config->accumGreenBits + config->accumBlueBits + @@ -631,6 +590,259 @@ __glXInitializeVisualConfigFromTags( __GLcontextModes *config, int count, } +#ifdef GLX_DIRECT_RENDERING +static unsigned +filter_modes( __GLcontextModes ** server_modes, + const __GLcontextModes * driver_modes ) +{ + __GLcontextModes * m; + __GLcontextModes ** prev_next; + const __GLcontextModes * check; + unsigned modes_count = 0; + + if ( driver_modes == NULL ) { + fprintf(stderr, "libGL warning: 3D driver returned no fbconfigs.\n"); + return 0; + } + + /* For each mode in server_modes, check to see if a matching mode exists + * in driver_modes. If not, then the mode is not available. + */ + + prev_next = server_modes; + for ( m = *prev_next ; m != NULL ; m = *prev_next ) { + GLboolean do_delete = GL_TRUE; + + for ( check = driver_modes ; check != NULL ; check = check->next ) { + if ( _gl_context_modes_are_same( m, check ) ) { + do_delete = GL_FALSE; + break; + } + } + + /* 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; + + fprintf(stderr, "libGL warning: 3D driver claims to not support " + "visual 0x%02x\n", m->visualID); + } + + if ( do_delete ) { + *prev_next = m->next; + + m->next = NULL; + _gl_context_modes_destroy( m ); + } + else { + modes_count++; + prev_next = & m->next; + } + } + + return modes_count; +} + + + +/** + * 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, + CreateNewScreenFunc createNewScreen) +{ + __DRIscreenPrivate *psp = NULL; + drmHandle hSAREA; + drmAddress pSAREA; + 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; + + if (XF86DRIOpenConnection(dpy, scrn, &hSAREA, &BusID)) { + fd = drmOpen(NULL,BusID); + Xfree(BusID); /* No longer needed */ + + err_msg = "open DRM"; + err_extra = strerror( -fd ); + + if (fd >= 0) { + drmMagic 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 (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 "createScreen" + * function. + */ + err_msg = "XF86DRIGetClientDriverName"; + if (XF86DRIGetClientDriverName(dpy, scrn, + &ddx_version.major, + &ddx_version.minor, + &ddx_version.patch, + &driverName)) { + drmHandle 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 "createScreen" 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, + & driver_modes ); + + filter_modes( & configs->configs, + driver_modes ); + _gl_context_modes_destroy( driver_modes ); + } + } + } + } + } + } + } + } + + if ( psp == NULL ) { + if ( pSAREA != MAP_FAILED ) { + (void)drmUnmap(pSAREA, SAREA_MAX); + } + + if ( framebuffer.base != MAP_FAILED ) { + (void)drmUnmap((drmAddress)framebuffer.base, framebuffer.size); + } + + if ( framebuffer.dev_priv != NULL ) { + Xfree(framebuffer.dev_priv); + } + + if ( fd >= 0 ) { + (void)drmClose(fd); + } + + (void)XF86DRICloseConnection(dpy, scrn); + + 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"); + } + + return psp; +} +#endif /* GLX_DIRECT_RENDERING */ + + /* ** Allocate the memory for the per screen configs for each screen. ** If that works then fetch the per screen configs data. @@ -639,7 +851,7 @@ static Bool AllocAndFetchScreenConfigs(Display *dpy, __GLXdisplayPrivate *priv) { xGLXGetVisualConfigsReq *req; xGLXGetFBConfigsReq *fb_req; - xGLXVendorPrivateReq *vpreq; + xGLXVendorPrivateWithReplyReq *vpreq; xGLXGetFBConfigsSGIXReq *sgi_req; xGLXGetVisualConfigsReply reply; __GLXscreenConfigs *psc; @@ -699,8 +911,8 @@ static Bool AllocAndFetchScreenConfigs(Display *dpy, __GLXdisplayPrivate *priv) break; case 2: - GetReqExtra(GLXVendorPrivate, - sz_xGLXGetFBConfigsSGIXReq-sz_xGLXVendorPrivateReq,vpreq); + GetReqExtra(GLXVendorPrivateWithReply, + sz_xGLXGetFBConfigsSGIXReq-sz_xGLXVendorPrivateWithReplyReq,vpreq); sgi_req = (xGLXGetFBConfigsSGIXReq *) vpreq; sgi_req->reqType = priv->majorOpcode; sgi_req->glxCode = X_GLXVendorPrivateWithReply; @@ -773,9 +985,20 @@ static Bool AllocAndFetchScreenConfigs(Display *dpy, __GLXdisplayPrivate *priv) 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; } @@ -788,21 +1011,31 @@ static Bool AllocAndFetchScreenConfigs(Display *dpy, __GLXdisplayPrivate *priv) /* 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 && - priv->driDisplay.createScreen && - priv->driDisplay.createScreen[i]) { - /* screen initialization (bootstrap the driver) */ - if ( (psc->old_configs == NULL) - && !FillInVisuals(psc) ) { - FreeScreenConfigs(priv); - return GL_FALSE; + if (priv->driDisplay.private != 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] ); } + else if (priv->driDisplay.createScreen && + priv->driDisplay.createScreen[i]) { + /* screen initialization (bootstrap the driver) */ + if ( (psc->old_configs == NULL) + && !FillInVisuals(psc) ) { + FreeScreenConfigs(priv); + return GL_FALSE; + } - psc->driScreen.screenConfigs = (void *)psc; - psc->driScreen.private = - (*(priv->driDisplay.createScreen[i]))(dpy, i, &psc->driScreen, - psc->numOldConfigs, - psc->old_configs); + psc->driScreen.screenConfigs = (void *)psc; + psc->driScreen.private = + (*(priv->driDisplay.createScreen[i]))(dpy, i, &psc->driScreen, + psc->numOldConfigs, + psc->old_configs); + } } #endif } diff --git a/xc/lib/GL/mesa/drivers/dri/mga/Imakefile.inc b/xc/lib/GL/mesa/drivers/dri/mga/Imakefile.inc index 50ac1062c..ccff66bdf 100644 --- a/xc/lib/GL/mesa/drivers/dri/mga/Imakefile.inc +++ b/xc/lib/GL/mesa/drivers/dri/mga/Imakefile.inc @@ -16,7 +16,7 @@ ALLOC_DEFINES = -DMALLOC_0_RETURNS_NULL #endif #if BuildXF86DRI - DRI_DEFINES = GlxDefines -DX_BYTE_ORDER=ByteOrder + DRI_DEFINES = GlxDefines -DX_BYTE_ORDER=ByteOrder -DUSE_NEW_INTERFACE DRI_INCLUDES = -I$(GLXLIBSRC)/dri \ -I$(XINCLUDESRC) \ -I$(GLXLIBSRC)/glx \ diff --git a/xc/lib/GL/mesa/drivers/dri/r200/Imakefile.inc b/xc/lib/GL/mesa/drivers/dri/r200/Imakefile.inc index 3bb2d92a8..30b5cfe46 100644 --- a/xc/lib/GL/mesa/drivers/dri/r200/Imakefile.inc +++ b/xc/lib/GL/mesa/drivers/dri/r200/Imakefile.inc @@ -16,7 +16,7 @@ ALLOC_DEFINES = -DMALLOC_0_RETURNS_NULL #endif #if BuildXF86DRI - DRI_DEFINES = GlxDefines -DX_BYTE_ORDER=ByteOrder + DRI_DEFINES = GlxDefines -DX_BYTE_ORDER=ByteOrder -DUSE_NEW_INTERFACE DRI_INCLUDES = -I$(GLXLIBSRC)/dri \ -I$(XINCLUDESRC) \ -I$(GLXLIBSRC)/glx \ diff --git a/xc/programs/Xserver/GL/dri/dri.c b/xc/programs/Xserver/GL/dri/dri.c index 1575fea41..d41ff8439 100644 --- a/xc/programs/Xserver/GL/dri/dri.c +++ b/xc/programs/Xserver/GL/dri/dri.c @@ -780,7 +780,7 @@ DRICreateDummyContext(ScreenPtr pScreen, Bool needCtxPriv) { DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen); __GLXscreenInfo *pGLXScreen = &__glXActiveScreens[pScreen->myNum]; - __GLXvisualConfig *pGLXVis = pGLXScreen->pGlxVisual; + __GLcontextModes *modes = pGLXScreen->modes; void **pVisualConfigPriv = pGLXScreen->pVisualPriv; DRIContextPrivPtr pDRIContextPriv; void *contextStore; @@ -793,7 +793,7 @@ DRICreateDummyContext(ScreenPtr pScreen, Bool needCtxPriv) for (visNum = 0; visNum < pScreen->numVisuals; visNum++, visual++) { - if (pGLXVis->vid == visual->vid) + if (modes->visualID == visual->vid) break; } if (visNum == pScreen->numVisuals) return FALSE; @@ -844,11 +844,10 @@ DRICreateContext(ScreenPtr pScreen, VisualPtr visual, { DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen); __GLXscreenInfo *pGLXScreen = &__glXActiveScreens[pScreen->myNum]; - __GLXvisualConfig *pGLXVis = pGLXScreen->pGlxVisual; + __GLcontextModes *modes = pGLXScreen->modes; void **pVisualConfigPriv = pGLXScreen->pVisualPriv; DRIContextPrivPtr pDRIContextPriv; void *contextStore; - int visNum; if (pDRIPriv->createDummyCtx && !pDRIPriv->dummyCtxPriv) { if (!DRICreateDummyContext(pScreen, pDRIPriv->createDummyCtxPriv)) { @@ -859,12 +858,13 @@ DRICreateContext(ScreenPtr pScreen, VisualPtr visual, } /* Find the GLX visual associated with the one requested */ - for (visNum = 0; - visNum < pGLXScreen->numVisuals; - visNum++, pGLXVis++, pVisualConfigPriv++) - if (pGLXVis->vid == visual->vid) + for (modes = pGLXScreen->modes; modes != NULL; modes = modes->next) { + if (modes->visualID == visual->vid) break; - if (visNum == pGLXScreen->numVisuals) { + pVisualConfigPriv++; + } + + if (modes == NULL) { /* No matching GLX visual found */ return FALSE; } diff --git a/xc/programs/Xserver/GL/glx/Imakefile b/xc/programs/Xserver/GL/glx/Imakefile index af7d1a118..a2e232b3d 100644 --- a/xc/programs/Xserver/GL/glx/Imakefile +++ b/xc/programs/Xserver/GL/glx/Imakefile @@ -11,6 +11,9 @@ SUBDIRS = module #include <Server.tmpl> +LinkSourceFile(glcontextmodes.c,$(LIBSRC)/GL/glx) +LinkSourceFile(glcontextmodes.h,$(LIBSRC)/GL/glx) + SRCS = global.c glxbuf.c glxcmds.c glxcmdsswap.c glxext.c \ glxfb.c glximports.c glxmem.c glxpix.c glxscreens.c \ glxutil.c render2.c render2swap.c renderpix.c \ @@ -18,7 +21,7 @@ SUBDIRS = module single2swap.c singlepix.c singlepixswap.c \ singlesize.c xfont.c g_disptab.c g_disptab_EXT.c \ g_render.c g_renderswap.c g_single.c g_singleswap.c \ - $(MSRCS) + glcontextmodes.c $(MSRCS) OBJS = global.o glxbuf.o glxcmds.o glxcmdsswap.o glxext.o \ glxfb.o glximports.o glxmem.o glxpix.o glxscreens.o \ @@ -27,7 +30,7 @@ SUBDIRS = module single2swap.o singlepix.o singlepixswap.o \ singlesize.o xfont.o g_disptab.o g_disptab_EXT.o \ g_render.o g_renderswap.o g_single.o g_singleswap.o \ - $(MOBJS) + glcontextmodes.o $(MOBJS) INCLUDES = -I$(SERVERSRC)/GL/glx -I$(SERVERSRC)/GL/include -I$(SERVERSRC)/include -I$(INCLUDESRC) -I$(MESASRCDIR)/include \ -I$(XINCLUDESRC) -I$(SERVERSRC)/mi \ diff --git a/xc/programs/Xserver/GL/glx/g_disptab.c b/xc/programs/Xserver/GL/glx/g_disptab.c index e4224ee67..85bca389a 100644 --- a/xc/programs/Xserver/GL/glx/g_disptab.c +++ b/xc/programs/Xserver/GL/glx/g_disptab.c @@ -54,18 +54,18 @@ __GLXdispatchSingleProcPtr __glXSingleTable[__GLX_SINGLE_TABLE_SIZE] = { __glXQueryExtensionsString, __glXQueryServerString, __glXClientInfo, - __glXNoSuchSingleOpcode, /* glXGetFBConfigs */ - __glXNoSuchSingleOpcode, /* glXCreatePixmap */ - __glXNoSuchSingleOpcode, /* glXDestroyPixmap */ - __glXNoSuchSingleOpcode, /* glXCreateNewContext */ + __glXGetFBConfigs, + __glXCreatePixmap, + __glXDestroyGLXPixmap, /* glXDestroyPixmap */ + __glXCreateNewContext, __glXNoSuchSingleOpcode, /* glXQueryContext */ __glXMakeContextCurrent, - __glXNoSuchSingleOpcode, - __glXNoSuchSingleOpcode, - __glXNoSuchSingleOpcode, - __glXNoSuchSingleOpcode, - __glXNoSuchSingleOpcode, - __glXNoSuchSingleOpcode, + __glXNoSuchSingleOpcode, /* glXCreatePbuffer */ + __glXNoSuchSingleOpcode, /* glXDestroyPbuffer */ + __glXNoSuchSingleOpcode, /* glXGetDrawableAttributes */ + __glXNoSuchSingleOpcode, /* glXChangeDrawableAttributes */ + __glXNoSuchSingleOpcode, /* glXCreateWindow */ + __glXNoSuchSingleOpcode, /* glXDestroyWindow */ __glXNoSuchSingleOpcode, __glXNoSuchSingleOpcode, __glXNoSuchSingleOpcode, @@ -451,18 +451,18 @@ __GLXdispatchSingleProcPtr __glXSwapSingleTable[__GLX_SINGLE_TABLE_SIZE] = { __glXSwapQueryExtensionsString, __glXSwapQueryServerString, __glXSwapClientInfo, - __glXNoSuchSingleOpcode, /* glXGetFBConfigs */ - __glXNoSuchSingleOpcode, /* glXCreatePixmap */ - __glXNoSuchSingleOpcode, /* glXDestroyPixmap */ - __glXNoSuchSingleOpcode, /* glXCreateNewContext */ + __glXSwapGetFBConfigs, + __glXSwapCreatePixmap, + __glXSwapDestroyGLXPixmap, /* glXDestroyPixmap */ + __glXSwapCreateNewContext, __glXNoSuchSingleOpcode, /* glXQueryContext */ __glXSwapMakeContextCurrent, - __glXNoSuchSingleOpcode, - __glXNoSuchSingleOpcode, - __glXNoSuchSingleOpcode, - __glXNoSuchSingleOpcode, - __glXNoSuchSingleOpcode, - __glXNoSuchSingleOpcode, + __glXNoSuchSingleOpcode, /* glXCreatePbuffer */ + __glXNoSuchSingleOpcode, /* glXDestroyPbuffer */ + __glXNoSuchSingleOpcode, /* glXGetDrawableAttributes */ + __glXNoSuchSingleOpcode, /* glXChangeDrawableAttributes */ + __glXNoSuchSingleOpcode, /* glXCreateWindow */ + __glXNoSuchSingleOpcode, /* glXDestroyWindow */ __glXNoSuchSingleOpcode, __glXNoSuchSingleOpcode, __glXNoSuchSingleOpcode, diff --git a/xc/programs/Xserver/GL/glx/g_disptab.h b/xc/programs/Xserver/GL/glx/g_disptab.h index cd45c269a..6702980b9 100644 --- a/xc/programs/Xserver/GL/glx/g_disptab.h +++ b/xc/programs/Xserver/GL/glx/g_disptab.h @@ -52,6 +52,9 @@ extern int __glXQueryExtensionsString(__GLXclientState*, GLbyte*); extern int __glXQueryServerString(__GLXclientState*, GLbyte*); extern int __glXClientInfo(__GLXclientState*, GLbyte*); extern int __glXMakeContextCurrent(__GLXclientState*, GLbyte*); +extern int __glXGetFBConfigs(__GLXclientState*, GLbyte*); +extern int __glXCreateNewContext(__GLXclientState*, GLbyte*); +extern int __glXCreatePixmap(__GLXclientState*, GLbyte*); extern int __glXDisp_NewList(__GLXclientState*, GLbyte*); extern int __glXDisp_EndList(__GLXclientState*, GLbyte*); @@ -349,6 +352,9 @@ extern int __glXSwapQueryExtensionsString(__GLXclientState*, GLbyte*); extern int __glXSwapQueryServerString(__GLXclientState*, GLbyte*); extern int __glXSwapClientInfo(__GLXclientState*, GLbyte*); extern int __glXSwapMakeContextCurrent(__GLXclientState*, GLbyte*); +extern int __glXSwapGetFBConfigs(__GLXclientState*, GLbyte*); +extern int __glXSwapCreateNewContext(__GLXclientState*, GLbyte*); +extern int __glXSwapCreatePixmap(__GLXclientState*, GLbyte*); extern int __glXDispSwap_NewList(__GLXclientState*, GLbyte*); extern int __glXDispSwap_EndList(__GLXclientState*, GLbyte*); diff --git a/xc/programs/Xserver/GL/glx/glx-def.cpp b/xc/programs/Xserver/GL/glx/glx-def.cpp index 9f31ecd04..2c1965ec2 100644 --- a/xc/programs/Xserver/GL/glx/glx-def.cpp +++ b/xc/programs/Xserver/GL/glx/glx-def.cpp @@ -92,7 +92,6 @@ __glXCreateDrawablePrivate __glXDeassociateContext __glXDestroyDrawablePrivate __glXFindDrawablePrivate -__glXFormatGLModes __glXFree __glXGetDrawablePrivate __glXGetDrawableSize diff --git a/xc/programs/Xserver/GL/glx/glxcmds.c b/xc/programs/Xserver/GL/glx/glxcmds.c index edce34178..d3c9f2565 100644 --- a/xc/programs/Xserver/GL/glx/glxcmds.c +++ b/xc/programs/Xserver/GL/glx/glxcmds.c @@ -47,6 +47,7 @@ #include "glxutil.h" #include "glxext.h" #include "GL/glx_ansic.h" +#include "glcontextmodes.h" /************************************************************************/ @@ -68,29 +69,32 @@ static __GLimports imports = { NULL }; -static int DoMakeCurrent( __GLXclientState *cl, GLXDrawable drawId, - GLXDrawable readId, GLXContextID contextId, GLXContextTag tag ); +static int __glXGetFBConfigsSGIX(__GLXclientState *cl, GLbyte *pc); +static int __glXCreateContextWithConfigSGIX(__GLXclientState *cl, GLbyte *pc); +static int __glXCreateGLXPixmapWithConfigSGIX(__GLXclientState *cl, GLbyte *pc); +static int __glXMakeCurrentReadSGI(__GLXclientState *cl, GLbyte *pc); /************************************************************************/ -/* -** Create a GL context with the given properties. -*/ -int __glXCreateContext(__GLXclientState *cl, GLbyte *pc) +/** + * Create a GL context with the given properties. This routine is used + * to implement \c glXCreateContext, \c glXCreateNewContext, and + * \c glXCreateContextWithConfigSGIX. This works becuase of the hack way + * that GLXFBConfigs are implemented. Basically, the FBConfigID is the + * same as the VisualID. + */ + +int DoCreateContext(__GLXclientState *cl, GLXContextID gcId, + GLXContextID shareList, VisualID visual, + GLuint screen, GLboolean isDirect) { ClientPtr client = cl->client; - xGLXCreateContextReq *req = (xGLXCreateContextReq *) pc; VisualPtr pVisual; ScreenPtr pScreen; __GLXcontext *glxc, *shareglxc; - __GLXvisualConfig *pGlxVisual; + __GLcontextModes *modes; __GLXscreenInfo *pGlxScreen; __GLinterface *shareGC; - GLXContextID gcId = req->context; - GLXContextID shareList = req->shareList; - VisualID visual = req->visual; - GLuint screen = req->screen; - GLboolean isDirect = req->isDirect; GLint i; /* @@ -123,13 +127,9 @@ int __glXCreateContext(__GLXclientState *cl, GLbyte *pc) ** subset of Visuals that are supported by this implementation of the ** OpenGL. */ - pGlxVisual = pGlxScreen->pGlxVisual; - for (i = 0; i < pGlxScreen->numVisuals; i++, pGlxVisual++) { - if (pGlxVisual->vid == visual) { - break; - } - } - if (i == pGlxScreen->numVisuals) { + + modes = _gl_context_modes_find_visual( pGlxScreen->modes, visual ); + if (modes == NULL) { /* ** Visual not support on this screen by this OpenGL implementation. */ @@ -192,22 +192,15 @@ int __glXCreateContext(__GLXclientState *cl, GLbyte *pc) glxc->pScreen = pScreen; glxc->pGlxScreen = pGlxScreen; glxc->pVisual = pVisual; - glxc->pGlxVisual = pGlxVisual; + glxc->modes = modes; if (!isDirect) { - __GLcontextModes *modes; - /* - ** first build __GLcontextModes from __GLXvisualConfig - */ - modes = (__GLcontextModes *) __glXMalloc(sizeof(__GLcontextModes)); - glxc->modes = modes; - __glXFormatGLModes(modes, pGlxVisual); /* ** Allocate a GL context */ imports.other = (void *)glxc; - glxc->gc = (*pGlxScreen->createContext)(&imports, modes, shareGC); + glxc->gc = (*pGlxScreen->createContext)(&imports, glxc->modes, shareGC); if (!glxc->gc) { __glXFree(glxc); client->errorValue = gcId; @@ -245,6 +238,31 @@ int __glXCreateContext(__GLXclientState *cl, GLbyte *pc) return Success; } + +int __glXCreateContext(__GLXclientState *cl, GLbyte *pc) +{ + xGLXCreateContextReq *req = (xGLXCreateContextReq *) pc; + return DoCreateContext( cl, req->context, req->shareList, req->visual, + req->screen, req->isDirect ); +} + + +int __glXCreateNewContext(__GLXclientState *cl, GLbyte *pc) +{ + xGLXCreateNewContextReq *req = (xGLXCreateNewContextReq *) pc; + return DoCreateContext( cl, req->context, req->shareList, req->fbconfig, + req->screen, req->isDirect ); +} + + +int __glXCreateContextWithConfigSGIX(__GLXclientState *cl, GLbyte *pc) +{ + xGLXCreateContextWithConfigSGIXReq *req = + (xGLXCreateContextWithConfigSGIXReq *) pc; + return DoCreateContext( cl, req->context, req->shareList, req->fbconfig, + req->screen, req->isDirect ); +} + /* ** Destroy a GL context as an X resource. */ @@ -370,24 +388,24 @@ int __glXMakeCurrent(__GLXclientState *cl, GLbyte *pc) { xGLXMakeCurrentReq *req = (xGLXMakeCurrentReq *) pc; - return DoMakeCurrent( cl, req->drawable, req->drawable, - req->context, req->oldContextTag ); + return DoMakeCurrent( cl, req->drawable, req->drawable, + req->context, req->oldContextTag ); } int __glXMakeContextCurrent(__GLXclientState *cl, GLbyte *pc) { xGLXMakeContextCurrentReq *req = (xGLXMakeContextCurrentReq *) pc; - return DoMakeCurrent( cl, req->drawable, req->readdrawable, - req->context, req->oldContextTag ); + return DoMakeCurrent( cl, req->drawable, req->readdrawable, + req->context, req->oldContextTag ); } int __glXMakeCurrentReadSGI(__GLXclientState *cl, GLbyte *pc) { xGLXMakeCurrentReadSGIReq *req = (xGLXMakeCurrentReadSGIReq *) pc; - return DoMakeCurrent( cl, req->drawable, req->readable, - req->context, req->oldContextTag ); + return DoMakeCurrent( cl, req->drawable, req->readable, + req->context, req->oldContextTag ); } @@ -449,7 +467,7 @@ static int GetDrawableOrPixmap( __GLXcontext *glxc, GLXDrawable drawId, ** Check if pixmap and context are similar. */ if (drawPixmap->pScreen != glxc->pScreen || - drawPixmap->pGlxVisual != glxc->pGlxVisual) { + drawPixmap->modes->visualID != glxc->modes->visualID) { client->errorValue = drawId; return BadMatch; } @@ -471,9 +489,9 @@ static int GetDrawableOrPixmap( __GLXcontext *glxc, GLXDrawable drawId, } -static int DoMakeCurrent( __GLXclientState *cl, - GLXDrawable drawId, GLXDrawable readId, - GLXContextID contextId, GLXContextTag tag ) +int DoMakeCurrent( __GLXclientState *cl, + GLXDrawable drawId, GLXDrawable readId, + GLXContextID contextId, GLXContextTag tag ) { ClientPtr client = cl->client; DrawablePtr pDraw; @@ -879,18 +897,19 @@ int __glXCopyContext(__GLXclientState *cl, GLbyte *pc) return Success; } -int __glXGetVisualConfigs(__GLXclientState *cl, GLbyte *pc) + +int DoGetVisualConfigs(__GLXclientState *cl, unsigned screen, + GLboolean do_swap) { ClientPtr client = cl->client; - xGLXGetVisualConfigsReq *req = (xGLXGetVisualConfigsReq *) pc; xGLXGetVisualConfigsReply reply; __GLXscreenInfo *pGlxScreen; - __GLXvisualConfig *pGlxVisual; + __GLcontextModes *modes; CARD32 buf[__GLX_TOTAL_CONFIG]; - unsigned int screen; - int i, p; + int p; + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; - screen = req->screen; if (screen >= screenInfo.numScreens) { /* The client library must send a valid screen number. */ client->errorValue = screen; @@ -905,77 +924,206 @@ int __glXGetVisualConfigs(__GLXclientState *cl, GLbyte *pc) reply.type = X_Reply; reply.sequenceNumber = client->sequence; + if ( do_swap ) { + __GLX_SWAP_SHORT(&reply.sequenceNumber); + __GLX_SWAP_INT(&reply.length); + __GLX_SWAP_INT(&reply.numVisuals); + __GLX_SWAP_INT(&reply.numProps); + } + WriteToClient(client, sz_xGLXGetVisualConfigsReply, (char *)&reply); - for (i=0; i < pGlxScreen->numVisuals; i++) { - pGlxVisual = &pGlxScreen->pGlxVisual[i]; - if (pGlxVisual->vid == 0) { + for ( modes = pGlxScreen->modes ; modes != NULL ; modes = modes->next ) { + if (modes->visualID == 0) { /* not a usable visual */ continue; } p = 0; - buf[p++] = pGlxVisual->vid; - buf[p++] = pGlxVisual->class; - buf[p++] = pGlxVisual->rgba; - - buf[p++] = pGlxVisual->redSize; - buf[p++] = pGlxVisual->greenSize; - buf[p++] = pGlxVisual->blueSize; - buf[p++] = pGlxVisual->alphaSize; - buf[p++] = pGlxVisual->accumRedSize; - buf[p++] = pGlxVisual->accumGreenSize; - buf[p++] = pGlxVisual->accumBlueSize; - buf[p++] = pGlxVisual->accumAlphaSize; - - buf[p++] = pGlxVisual->doubleBuffer; - buf[p++] = pGlxVisual->stereo; - - buf[p++] = pGlxVisual->bufferSize; - buf[p++] = pGlxVisual->depthSize; - buf[p++] = pGlxVisual->stencilSize; - buf[p++] = pGlxVisual->auxBuffers; - buf[p++] = pGlxVisual->level; + buf[p++] = modes->visualID; + buf[p++] = _gl_convert_to_x_visual_type( modes->visualType ); + buf[p++] = modes->rgbMode; + + buf[p++] = modes->redBits; + buf[p++] = modes->greenBits; + buf[p++] = modes->blueBits; + buf[p++] = modes->alphaBits; + buf[p++] = modes->accumRedBits; + buf[p++] = modes->accumGreenBits; + buf[p++] = modes->accumBlueBits; + buf[p++] = modes->accumAlphaBits; + + buf[p++] = modes->doubleBufferMode; + buf[p++] = modes->stereoMode; + + buf[p++] = modes->rgbBits; + buf[p++] = modes->depthBits; + buf[p++] = modes->stencilBits; + buf[p++] = modes->numAuxBuffers; + buf[p++] = modes->level; /* ** Add token/value pairs for extensions. */ buf[p++] = GLX_VISUAL_CAVEAT_EXT; - buf[p++] = pGlxVisual->visualRating; - buf[p++] = GLX_TRANSPARENT_TYPE_EXT; - buf[p++] = pGlxVisual->transparentPixel; - buf[p++] = GLX_TRANSPARENT_RED_VALUE_EXT; - buf[p++] = pGlxVisual->transparentRed; - buf[p++] = GLX_TRANSPARENT_GREEN_VALUE_EXT; - buf[p++] = pGlxVisual->transparentGreen; - buf[p++] = GLX_TRANSPARENT_BLUE_VALUE_EXT; - buf[p++] = pGlxVisual->transparentBlue; - buf[p++] = GLX_TRANSPARENT_ALPHA_VALUE_EXT; - buf[p++] = pGlxVisual->transparentAlpha; - buf[p++] = GLX_TRANSPARENT_INDEX_VALUE_EXT; - buf[p++] = pGlxVisual->transparentIndex; - + buf[p++] = modes->visualRating; + buf[p++] = GLX_TRANSPARENT_TYPE; + buf[p++] = modes->transparentPixel; + buf[p++] = GLX_TRANSPARENT_RED_VALUE; + buf[p++] = modes->transparentRed; + buf[p++] = GLX_TRANSPARENT_GREEN_VALUE; + buf[p++] = modes->transparentGreen; + buf[p++] = GLX_TRANSPARENT_BLUE_VALUE; + buf[p++] = modes->transparentBlue; + buf[p++] = GLX_TRANSPARENT_ALPHA_VALUE; + buf[p++] = modes->transparentAlpha; + buf[p++] = GLX_TRANSPARENT_INDEX_VALUE; + buf[p++] = modes->transparentIndex; + + if ( do_swap ) { + __GLX_SWAP_INT_ARRAY(buf, __GLX_TOTAL_CONFIG); + } WriteToClient(client, __GLX_SIZE_CARD32 * __GLX_TOTAL_CONFIG, (char *)buf); } return Success; } +int __glXGetVisualConfigs(__GLXclientState *cl, GLbyte *pc) +{ + xGLXGetVisualConfigsReq *req = (xGLXGetVisualConfigsReq *) pc; + return DoGetVisualConfigs( cl, req->screen, GL_FALSE ); +} + + + +#define __GLX_TOTAL_FBCONFIG_ATTRIBS (28) + +/** + * Send the set of GLXFBConfigs to the client. There is not currently + * and interface into the driver on the server-side to get GLXFBConfigs, + * so we "invent" some based on the \c __GLXvisualConfig structures that + * the driver does supply. + * + * The reply format for both \c glXGetFBConfigs and \c glXGetFBConfigsSGIX + * is the same, so this routine pulls double duty. + */ + +int DoGetFBConfigs(__GLXclientState *cl, unsigned screen, GLboolean do_swap) +{ + ClientPtr client = cl->client; + xGLXGetFBConfigsReply reply; + __GLXscreenInfo *pGlxScreen; + CARD32 buf[__GLX_TOTAL_FBCONFIG_ATTRIBS * 2]; + int p; + __GLcontextModes *modes; + __GLX_DECLARE_SWAP_VARIABLES; + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + + + if (screen >= screenInfo.numScreens) { + /* The client library must send a valid screen number. */ + client->errorValue = screen; + return BadValue; + } + pGlxScreen = &__glXActiveScreens[screen]; + + reply.numFBConfigs = pGlxScreen->numUsableVisuals; + reply.numAttribs = __GLX_TOTAL_FBCONFIG_ATTRIBS; + reply.length = (reply.numAttribs * reply.numFBConfigs); + reply.type = X_Reply; + reply.sequenceNumber = client->sequence; + + if ( do_swap ) { + __GLX_SWAP_SHORT(&reply.sequenceNumber); + __GLX_SWAP_INT(&reply.length); + __GLX_SWAP_INT(&reply.numFBConfigs); + __GLX_SWAP_INT(&reply.numAttribs); + } + + WriteToClient(client, sz_xGLXGetFBConfigsReply, (char *)&reply); + + for ( modes = pGlxScreen->modes ; modes != NULL ; modes = modes->next ) { + if (modes->visualID == 0) { + /* not a usable visual */ + continue; + } + p = 0; + +#define WRITE_PAIR(tag,value) \ + do { buf[p++] = tag ; buf[p++] = value ; } while( 0 ) + + WRITE_PAIR( GLX_VISUAL_ID, modes->visualID ); + WRITE_PAIR( GLX_FBCONFIG_ID, modes->visualID ); + WRITE_PAIR( GLX_X_RENDERABLE, GL_TRUE ); + + WRITE_PAIR( GLX_RGBA, modes->rgbMode ); + WRITE_PAIR( GLX_DOUBLEBUFFER, modes->doubleBufferMode ); + WRITE_PAIR( GLX_STEREO, modes->stereoMode ); + + WRITE_PAIR( GLX_BUFFER_SIZE, modes->rgbBits ); + WRITE_PAIR( GLX_LEVEL, modes->level ); + WRITE_PAIR( GLX_AUX_BUFFERS, modes->numAuxBuffers ); + WRITE_PAIR( GLX_RED_SIZE, modes->redBits ); + WRITE_PAIR( GLX_GREEN_SIZE, modes->greenBits ); + WRITE_PAIR( GLX_BLUE_SIZE, modes->blueBits ); + WRITE_PAIR( GLX_ALPHA_SIZE, modes->alphaBits ); + WRITE_PAIR( GLX_ACCUM_RED_SIZE, modes->accumRedBits ); + WRITE_PAIR( GLX_ACCUM_GREEN_SIZE, modes->accumGreenBits ); + WRITE_PAIR( GLX_ACCUM_BLUE_SIZE, modes->accumBlueBits ); + WRITE_PAIR( GLX_ACCUM_ALPHA_SIZE, modes->accumAlphaBits ); + WRITE_PAIR( GLX_DEPTH_SIZE, modes->depthBits ); + WRITE_PAIR( GLX_STENCIL_SIZE, modes->stencilBits ); + + WRITE_PAIR( GLX_X_VISUAL_TYPE, modes->visualType ); + + /* + ** Add token/value pairs for extensions. + */ + WRITE_PAIR( GLX_CONFIG_CAVEAT, modes->visualRating ); + WRITE_PAIR( GLX_TRANSPARENT_TYPE, modes->transparentPixel ); + WRITE_PAIR( GLX_TRANSPARENT_RED_VALUE, modes->transparentRed ); + WRITE_PAIR( GLX_TRANSPARENT_GREEN_VALUE, modes->transparentGreen ); + WRITE_PAIR( GLX_TRANSPARENT_BLUE_VALUE, modes->transparentBlue ); + WRITE_PAIR( GLX_TRANSPARENT_ALPHA_VALUE, modes->transparentAlpha ); + WRITE_PAIR( GLX_TRANSPARENT_INDEX_VALUE, modes->transparentIndex ); + WRITE_PAIR( GLX_SWAP_METHOD_OML, modes->swapMethod ); + + if ( do_swap ) { + __GLX_SWAP_INT_ARRAY(buf, __GLX_TOTAL_FBCONFIG_ATTRIBS * 2); + } + WriteToClient(client, __GLX_SIZE_CARD32 * __GLX_TOTAL_FBCONFIG_ATTRIBS * 2, + (char *)buf); + } + return Success; +} + + +int __glXGetFBConfigs(__GLXclientState *cl, GLbyte *pc) +{ + xGLXGetFBConfigsReq *req = (xGLXGetFBConfigsReq *) pc; + return DoGetFBConfigs( cl, req->screen, GL_FALSE ); +} + + +int __glXGetFBConfigsSGIX(__GLXclientState *cl, GLbyte *pc) +{ + xGLXGetFBConfigsSGIXReq *req = (xGLXGetFBConfigsSGIXReq *) pc; + return DoGetFBConfigs( cl, req->screen, GL_FALSE ); +} + + /* ** Create a GLX Pixmap from an X Pixmap. */ -int __glXCreateGLXPixmap(__GLXclientState *cl, GLbyte *pc) +int DoCreateGLXPixmap(__GLXclientState *cl, VisualID visual, + GLuint screenNum, XID pixmapId, XID glxpixmapId) { ClientPtr client = cl->client; - xGLXCreateGLXPixmapReq *req = (xGLXCreateGLXPixmapReq *) pc; - VisualID visual = req->visual; - GLuint screenNum = req->screen; - XID pixmapId = req->pixmap; - XID glxpixmapId = req->glxpixmap; DrawablePtr pDraw; ScreenPtr pScreen; VisualPtr pVisual; __GLXpixmap *pGlxPixmap; __GLXscreenInfo *pGlxScreen; - __GLXvisualConfig *pGlxVisual; + __GLcontextModes *modes; int i; pDraw = (DrawablePtr) LookupDrawable(pixmapId, client); @@ -1016,13 +1164,8 @@ int __glXCreateGLXPixmap(__GLXclientState *cl, GLbyte *pc) ** Get configuration of the visual. */ pGlxScreen = &__glXActiveScreens[screenNum]; - pGlxVisual = pGlxScreen->pGlxVisual; - for (i = 0; i < pGlxScreen->numVisuals; i++, pGlxVisual++) { - if (pGlxVisual->vid == visual) { - break; - } - } - if (i == pGlxScreen->numVisuals) { + modes = _gl_context_modes_find_visual( pGlxScreen->modes, visual ); + if (modes == NULL) { /* ** Visual not support on this screen by this OpenGL implementation. */ @@ -1039,11 +1182,12 @@ int __glXCreateGLXPixmap(__GLXclientState *cl, GLbyte *pc) } pGlxPixmap->pDraw = pDraw; pGlxPixmap->pGlxScreen = pGlxScreen; - pGlxPixmap->pGlxVisual = pGlxVisual; pGlxPixmap->pScreen = pScreen; pGlxPixmap->idExists = True; pGlxPixmap->refcnt = 0; + pGlxPixmap->modes = modes; + /* ** Bump the ref count on the X pixmap so it won't disappear. */ @@ -1052,6 +1196,34 @@ int __glXCreateGLXPixmap(__GLXclientState *cl, GLbyte *pc) return Success; } +int __glXCreateGLXPixmap(__GLXclientState *cl, GLbyte *pc) +{ + xGLXCreateGLXPixmapReq *req = (xGLXCreateGLXPixmapReq *) pc; + return DoCreateGLXPixmap( cl, req->visual, req->screen, + req->pixmap, req->glxpixmap ); +} + +int __glXCreatePixmap(__GLXclientState *cl, GLbyte *pc) +{ + xGLXCreatePixmapReq *req = (xGLXCreatePixmapReq *) pc; + return DoCreateGLXPixmap( cl, req->fbconfig, req->screen, + req->pixmap, req->glxpixmap ); +} + +int __glXCreateGLXPixmapWithConfigSGIX(__GLXclientState *cl, GLbyte *pc) +{ + xGLXCreateGLXPixmapWithConfigSGIXReq *req = + (xGLXCreateGLXPixmapWithConfigSGIXReq *) pc; + return DoCreateGLXPixmap( cl, req->fbconfig, req->screen, + req->pixmap, req->glxpixmap ); +} + + +/** + * Destroy a GLX pixmap. This function is used for both + * \c glXDestroyGLXPixmap and \c glXDestroyPixmap. + */ + int __glXDestroyGLXPixmap(__GLXclientState *cl, GLbyte *pc) { ClientPtr client = cl->client; @@ -1589,6 +1761,12 @@ int __glXVendorPrivateWithReply(__GLXclientState *cl, GLbyte *pc) return __glXQueryContextInfoEXT(cl, pc); case X_GLXvop_MakeCurrentReadSGI: return __glXMakeCurrentReadSGI(cl, pc); + case X_GLXvop_GetFBConfigsSGIX: + return __glXGetFBConfigsSGIX(cl, pc); + case X_GLXvop_CreateContextWithConfigSGIX: + return __glXCreateContextWithConfigSGIX(cl, pc); + case X_GLXvop_CreateGLXPixmapWithConfigSGIX: + return __glXCreateGLXPixmapWithConfigSGIX(cl, pc); default: break; } diff --git a/xc/programs/Xserver/GL/glx/glxcmdsswap.c b/xc/programs/Xserver/GL/glx/glxcmdsswap.c index f9d57b0b0..6e63fc580 100644 --- a/xc/programs/Xserver/GL/glx/glxcmdsswap.c +++ b/xc/programs/Xserver/GL/glx/glxcmdsswap.c @@ -47,6 +47,11 @@ #include "glxext.h" #include "GL/glx_ansic.h" +static int __glXSwapGetFBConfigsSGIX(__GLXclientState *cl, GLbyte *pc); +static int __glXSwapCreateContextWithConfigSGIX(__GLXclientState *cl, GLbyte *pc); +static int __glXSwapCreateGLXPixmapWithConfigSGIX(__GLXclientState *cl, GLbyte *pc); +static int __glXSwapMakeCurrentReadSGI(__GLXclientState *cl, GLbyte *pc); + /************************************************************************/ /* @@ -67,7 +72,41 @@ int __glXSwapCreateContext(__GLXclientState *cl, GLbyte *pc) __GLX_SWAP_INT(&req->screen); __GLX_SWAP_INT(&req->shareList); - return __glXCreateContext(cl, pc); + return DoCreateContext( cl, req->context, req->shareList, req->visual, + req->screen, req->isDirect ); +} + +int __glXSwapCreateNewContext(__GLXclientState *cl, GLbyte *pc) +{ + xGLXCreateNewContextReq *req = (xGLXCreateNewContextReq *) pc; + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->context); + __GLX_SWAP_INT(&req->fbconfig); + __GLX_SWAP_INT(&req->screen); + __GLX_SWAP_INT(&req->renderType); + __GLX_SWAP_INT(&req->shareList); + + return DoCreateContext( cl, req->context, req->shareList, req->fbconfig, + req->screen, req->isDirect ); +} + +int __glXSwapCreateContextWithConfigSGIX(__GLXclientState *cl, GLbyte *pc) +{ + xGLXCreateContextWithConfigSGIXReq *req = + (xGLXCreateContextWithConfigSGIXReq *) pc; + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->context); + __GLX_SWAP_INT(&req->fbconfig); + __GLX_SWAP_INT(&req->screen); + __GLX_SWAP_INT(&req->renderType); + __GLX_SWAP_INT(&req->shareList); + + return DoCreateContext( cl, req->context, req->shareList, req->fbconfig, + req->screen, req->isDirect ); } int __glXSwapDestroyContext(__GLXclientState *cl, GLbyte *pc) @@ -91,7 +130,8 @@ int __glXSwapMakeCurrent(__GLXclientState *cl, GLbyte *pc) __GLX_SWAP_INT(&req->context); __GLX_SWAP_INT(&req->oldContextTag); - return __glXMakeCurrent(cl, pc); + return DoMakeCurrent( cl, req->drawable, req->drawable, + req->context, req->oldContextTag ); } int __glXSwapMakeContextCurrent(__GLXclientState *cl, GLbyte *pc) @@ -105,7 +145,8 @@ int __glXSwapMakeContextCurrent(__GLXclientState *cl, GLbyte *pc) __GLX_SWAP_INT(&req->context); __GLX_SWAP_INT(&req->oldContextTag); - return __glXMakeContextCurrent(cl, pc); + return DoMakeCurrent( cl, req->drawable, req->readdrawable, + req->context, req->oldContextTag ); } int __glXSwapMakeCurrentReadSGI(__GLXclientState *cl, GLbyte *pc) @@ -119,7 +160,8 @@ int __glXSwapMakeCurrentReadSGI(__GLXclientState *cl, GLbyte *pc) __GLX_SWAP_INT(&req->context); __GLX_SWAP_INT(&req->oldContextTag); - return __glXMakeCurrentReadSGI(cl, pc); + return DoMakeCurrent( cl, req->drawable, req->readable, + req->context, req->oldContextTag ); } int __glXSwapIsDirect(__GLXclientState *cl, GLbyte *pc) @@ -182,90 +224,29 @@ int __glXSwapCopyContext(__GLXclientState *cl, GLbyte *pc) int __glXSwapGetVisualConfigs(__GLXclientState *cl, GLbyte *pc) { - ClientPtr client = cl->client; xGLXGetVisualConfigsReq *req = (xGLXGetVisualConfigsReq *) pc; - xGLXGetVisualConfigsReply reply; - __GLXscreenInfo *pGlxScreen; - __GLXvisualConfig *pGlxVisual; - CARD32 buf[__GLX_TOTAL_CONFIG]; - unsigned int screen; - int i, p; __GLX_DECLARE_SWAP_VARIABLES; - __GLX_DECLARE_SWAP_ARRAY_VARIABLES; __GLX_SWAP_INT(&req->screen); - screen = req->screen; - if (screen > screenInfo.numScreens) { - /* The client library must send a valid screen number. */ - client->errorValue = screen; - return BadValue; - } - pGlxScreen = &__glXActiveScreens[screen]; - - reply.numVisuals = pGlxScreen->numUsableVisuals; - reply.numProps = __GLX_TOTAL_CONFIG; - reply.length = (pGlxScreen->numUsableVisuals * __GLX_SIZE_CARD32 * - __GLX_TOTAL_CONFIG) >> 2; - reply.type = X_Reply; - reply.sequenceNumber = client->sequence; - - __GLX_SWAP_SHORT(&reply.sequenceNumber); - __GLX_SWAP_INT(&reply.length); - __GLX_SWAP_INT(&reply.numVisuals); - __GLX_SWAP_INT(&reply.numProps); - WriteToClient(client, sz_xGLXGetVisualConfigsReply, (char *)&reply); - - for (i=0; i < pGlxScreen->numVisuals; i++) { - pGlxVisual = &pGlxScreen->pGlxVisual[i]; - if (pGlxVisual->vid == 0) { - /* not a usable visual */ - continue; - } - p = 0; - buf[p++] = pGlxVisual->vid; - buf[p++] = pGlxVisual->class; - buf[p++] = pGlxVisual->rgba; - - buf[p++] = pGlxVisual->redSize; - buf[p++] = pGlxVisual->greenSize; - buf[p++] = pGlxVisual->blueSize; - buf[p++] = pGlxVisual->alphaSize; - buf[p++] = pGlxVisual->accumRedSize; - buf[p++] = pGlxVisual->accumGreenSize; - buf[p++] = pGlxVisual->accumBlueSize; - buf[p++] = pGlxVisual->accumAlphaSize; - - buf[p++] = pGlxVisual->doubleBuffer; - buf[p++] = pGlxVisual->stereo; - - buf[p++] = pGlxVisual->bufferSize; - buf[p++] = pGlxVisual->depthSize; - buf[p++] = pGlxVisual->stencilSize; - buf[p++] = pGlxVisual->auxBuffers; - buf[p++] = pGlxVisual->level; - /* - ** Add token/value pairs for extensions. - */ - buf[p++] = GLX_VISUAL_CAVEAT_EXT; - buf[p++] = pGlxVisual->visualRating; - buf[p++] = GLX_TRANSPARENT_TYPE_EXT; - buf[p++] = pGlxVisual->transparentPixel; - buf[p++] = GLX_TRANSPARENT_RED_VALUE_EXT; - buf[p++] = pGlxVisual->transparentRed; - buf[p++] = GLX_TRANSPARENT_GREEN_VALUE_EXT; - buf[p++] = pGlxVisual->transparentGreen; - buf[p++] = GLX_TRANSPARENT_BLUE_VALUE_EXT; - buf[p++] = pGlxVisual->transparentBlue; - buf[p++] = GLX_TRANSPARENT_ALPHA_VALUE_EXT; - buf[p++] = pGlxVisual->transparentAlpha; - buf[p++] = GLX_TRANSPARENT_INDEX_VALUE_EXT; - buf[p++] = pGlxVisual->transparentIndex; - - __GLX_SWAP_INT_ARRAY(buf, __GLX_TOTAL_CONFIG); - WriteToClient(client, __GLX_SIZE_CARD32 * __GLX_TOTAL_CONFIG, - (char *)buf); - } - return Success; + return DoGetVisualConfigs( cl, req->screen, GL_TRUE ); +} + +int __glXSwapGetFBConfigs(__GLXclientState *cl, GLbyte *pc) +{ + xGLXGetFBConfigsReq *req = (xGLXGetFBConfigsReq *) pc; + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_INT(&req->screen); + return DoGetFBConfigs( cl, req->screen, GL_TRUE ); +} + +int __glXSwapGetFBConfigsSGIX(__GLXclientState *cl, GLbyte *pc) +{ + xGLXGetFBConfigsSGIXReq *req = (xGLXGetFBConfigsSGIXReq *) pc; + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_INT(&req->screen); + return DoGetFBConfigs( cl, req->screen, GL_TRUE ); } int __glXSwapCreateGLXPixmap(__GLXclientState *cl, GLbyte *pc) @@ -279,7 +260,39 @@ int __glXSwapCreateGLXPixmap(__GLXclientState *cl, GLbyte *pc) __GLX_SWAP_INT(&req->pixmap); __GLX_SWAP_INT(&req->glxpixmap); - return __glXCreateGLXPixmap(cl, pc); + return DoCreateGLXPixmap( cl, req->visual, req->screen, + req->pixmap, req->glxpixmap ); +} + +int __glXSwapCreatePixmap(__GLXclientState *cl, GLbyte *pc) +{ + xGLXCreatePixmapReq *req = (xGLXCreatePixmapReq *) pc; + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->screen); + __GLX_SWAP_INT(&req->fbconfig); + __GLX_SWAP_INT(&req->pixmap); + __GLX_SWAP_INT(&req->glxpixmap); + + return DoCreateGLXPixmap( cl, req->fbconfig, req->screen, + req->pixmap, req->glxpixmap ); +} + +int __glXSwapCreateGLXPixmapWithConfigSGIX(__GLXclientState *cl, GLbyte *pc) +{ + xGLXCreateGLXPixmapWithConfigSGIXReq *req = + (xGLXCreateGLXPixmapWithConfigSGIXReq *) pc; + __GLX_DECLARE_SWAP_VARIABLES; + + __GLX_SWAP_SHORT(&req->length); + __GLX_SWAP_INT(&req->screen); + __GLX_SWAP_INT(&req->fbconfig); + __GLX_SWAP_INT(&req->pixmap); + __GLX_SWAP_INT(&req->glxpixmap); + + return DoCreateGLXPixmap( cl, req->fbconfig, req->screen, + req->pixmap, req->glxpixmap ); } int __glXSwapDestroyGLXPixmap(__GLXclientState *cl, GLbyte *pc) @@ -357,7 +370,7 @@ int __glXSwapClientInfo(__GLXclientState *cl, GLbyte *pc) return __glXClientInfo(cl, pc); } -int __glXSwapQueryContextInfoEXT(__GLXclientState *cl, char *pc) +int __glXSwapQueryContextInfoEXT(__GLXclientState *cl, GLbyte *pc) { xGLXQueryContextInfoEXTReq *req = (xGLXQueryContextInfoEXTReq *) pc; __GLX_DECLARE_SWAP_VARIABLES; @@ -832,6 +845,12 @@ int __glXSwapVendorPrivateWithReply(__GLXclientState *cl, GLbyte *pc) return __glXSwapQueryContextInfoEXT(cl, pc); case X_GLXvop_MakeCurrentReadSGI: return __glXSwapMakeCurrentReadSGI(cl, pc); + case X_GLXvop_GetFBConfigsSGIX: + return __glXSwapGetFBConfigsSGIX(cl, pc); + case X_GLXvop_CreateContextWithConfigSGIX: + return __glXSwapCreateContextWithConfigSGIX(cl, pc); + case X_GLXvop_CreateGLXPixmapWithConfigSGIX: + return __glXSwapCreateGLXPixmapWithConfigSGIX(cl, pc); default: break; } diff --git a/xc/programs/Xserver/GL/glx/glxcontext.h b/xc/programs/Xserver/GL/glx/glxcontext.h index 5eb72177e..9a16851f0 100644 --- a/xc/programs/Xserver/GL/glx/glxcontext.h +++ b/xc/programs/Xserver/GL/glx/glxcontext.h @@ -80,7 +80,6 @@ struct __GLXcontextRec { ** This context is created with respect to this visual. */ VisualRec *pVisual; - __GLXvisualConfig *pGlxVisual; /* ** The XID of this context. diff --git a/xc/programs/Xserver/GL/glx/glxdrawable.h b/xc/programs/Xserver/GL/glx/glxdrawable.h index 972a6045f..1d7f44352 100644 --- a/xc/programs/Xserver/GL/glx/glxdrawable.h +++ b/xc/programs/Xserver/GL/glx/glxdrawable.h @@ -40,7 +40,7 @@ typedef struct { DrawablePtr pDraw; - __GLXvisualConfig *pGlxVisual; + __GLcontextModes *modes; __GLXscreenInfo *pGlxScreen; ScreenPtr pScreen; Bool idExists; @@ -69,11 +69,12 @@ struct __GLXdrawablePrivateRec { /* ** Configuration of the visual to which this drawable was created. */ - __GLXvisualConfig *pGlxVisual; + __GLcontextModes *modes; /* ** cached drawable size and origin */ + GLint xorigin, yorigin; GLint width, height; diff --git a/xc/programs/Xserver/GL/glx/glxext.h b/xc/programs/Xserver/GL/glx/glxext.h index 876449300..a5bf34d7f 100644 --- a/xc/programs/Xserver/GL/glx/glxext.h +++ b/xc/programs/Xserver/GL/glx/glxext.h @@ -71,10 +71,18 @@ extern GLboolean __glXErrorOccured(void); extern void __glXResetLargeCommandStatus(__GLXclientState*); extern int __glXQueryContextInfoEXT(__GLXclientState *cl, GLbyte *pc); -extern int __glXSwapQueryContextInfoEXT(__GLXclientState *cl, char *pc); +extern int __glXSwapQueryContextInfoEXT(__GLXclientState *cl, GLbyte *pc); -extern int __glXMakeCurrentReadSGI(__GLXclientState *cl, GLbyte *pc); -extern int __glXSwapMakeCurrentReadSGI(__GLXclientState *cl, GLbyte *pc); +extern int DoMakeCurrent( __GLXclientState *cl, GLXDrawable drawId, + GLXDrawable readId, GLXContextID contextId, GLXContextTag tag ); +extern int DoGetVisualConfigs(__GLXclientState *cl, unsigned screen, + GLboolean do_swap); +extern int DoGetFBConfigs(__GLXclientState *cl, unsigned screen, + GLboolean do_swap); +extern int DoCreateContext(__GLXclientState *cl, GLXContextID gcId, + GLXContextID shareList, VisualID visual, GLuint screen, GLboolean isDirect); +extern int DoCreateGLXPixmap(__GLXclientState *cl, VisualID visual, + GLuint screenNum, XID pixmapId, XID glxpixmapId); extern void GlxExtensionInit(void); diff --git a/xc/programs/Xserver/GL/glx/glxscreens.c b/xc/programs/Xserver/GL/glx/glxscreens.c index 8ec0e4768..04882098a 100644 --- a/xc/programs/Xserver/GL/glx/glxscreens.c +++ b/xc/programs/Xserver/GL/glx/glxscreens.c @@ -133,8 +133,10 @@ static char GLXServerExtensions[] = "GLX_EXT_visual_info " "GLX_EXT_visual_rating " "GLX_EXT_import_context " + "GLX_OML_swap_method " "GLX_SGI_make_current_read " "GLX_SGIS_multisample " + "GLX_SGIX_fbconfig " ; /* @@ -154,81 +156,6 @@ GLint __glXNumActiveScreens; RESTYPE __glXDrawableRes; -#if 0 -static int -CountBits(unsigned long mask) -{ - int count = 0; - - while(mask) { - count += (mask&1); - mask >>= 1; - } - - return count; -} -#endif - -#if 0 -/* -** A typical implementation would not probably not run through the screen's -** visuals to find ones that match the visual configs supplied by the DDX -** Sample OpenGL as we do here; we have done this to make this code easy to -** drop into an existing X server. -*/ -static int matchVisuals(__GLXvisualConfig *pGlxVisual, int numVisuals, - int screen) -{ - int i, j; - __GLXvisualConfig *pvis = pGlxVisual; - ScreenPtr pScreen = screenInfo.screens[screen]; - VisualPtr pVisual; - int numMatchingVisuals = 0; - int *used; - - used = (int *)__glXMalloc(pScreen->numVisuals*sizeof(int)); - __glXMemset(used, 0, pScreen->numVisuals*sizeof(int)); - - for (i=0; i < numVisuals; i++, pvis++) { - /* - ** Look through all the server's visuals to see which match. - */ - pvis->vid = 0; - pVisual = pScreen->visuals; - for (j=0; j < pScreen->numVisuals; j++, pVisual++) { - if (pvis->class == pVisual->class && - pvis->bufferSize == pVisual->nplanes && - !used[j]) { - int rBits, gBits, bBits, aBits; - - /* count bits per rgb */ - rBits = CountBits(pVisual->redMask); - gBits = CountBits(pVisual->greenMask); - bBits = CountBits(pVisual->blueMask); - aBits = 0; - if ((pvis->redSize == rBits) && - (pvis->greenSize == gBits) && - (pvis->blueSize == bBits) && - (pvis->alphaSize == aBits)) { - /* - ** We'll consider this a match. - */ - pvis->vid = pVisual->vid; - pvis->redMask = pVisual->redMask; - pvis->greenMask = pVisual->greenMask; - pvis->blueMask = pVisual->blueMask; - pvis->alphaMask = 0; - numMatchingVisuals++; - used[j] = 1; - break; - } - } - } - } - __glXFree(used); - return numMatchingVisuals; -} -#endif /* ** Destroy routine that gets called when a drawable is freed. A drawable @@ -358,14 +285,7 @@ void __glXScreenInit(GLint numscreens) if ((*__glXScreens[j]->screenProbe)(i)) { __glXActiveScreens[i] = *__glXScreens[j]; -#if 0 - /* we don't use this since matchVisuals doesn't allow alpha */ - __glXActiveScreens[i].numUsableVisuals = - matchVisuals(__glXActiveScreens[i].pGlxVisual, - __glXActiveScreens[i].numVisuals, i); -#else __glXActiveScreens[i].numUsableVisuals = __glXActiveScreens[i].numVisuals; -#endif __glXActiveScreens[i].GLextensions = __glXStrdup(GLServerExtensions); __glXActiveScreens[i].GLXvendor = __glXStrdup(GLXServerVendorName); __glXActiveScreens[i].GLXversion = __glXStrdup(GLXServerVersion); diff --git a/xc/programs/Xserver/GL/glx/glxscreens.h b/xc/programs/Xserver/GL/glx/glxscreens.h index 99f76dc38..9ca166b74 100644 --- a/xc/programs/Xserver/GL/glx/glxscreens.h +++ b/xc/programs/Xserver/GL/glx/glxscreens.h @@ -70,7 +70,11 @@ typedef struct { */ void (*createBuffer)(__GLXdrawablePrivate *glxPriv); - __GLXvisualConfig *pGlxVisual; + /** + * Linked list of valid context modes for this screen. + */ + __GLcontextModes *modes; + void **pVisualPriv; GLint numVisuals; GLint numUsableVisuals; diff --git a/xc/programs/Xserver/GL/glx/glxutil.c b/xc/programs/Xserver/GL/glx/glxutil.c index 7aafd0065..4512aa5e9 100644 --- a/xc/programs/Xserver/GL/glx/glxutil.c +++ b/xc/programs/Xserver/GL/glx/glxutil.c @@ -44,6 +44,9 @@ #include "glxutil.h" #include "glxbuf.h" #include "GL/glx_ansic.h" +#include "GL/internal/glcore.h" +#include "GL/glxint.h" +#include "glcontextmodes.h" /************************************************************************/ @@ -214,53 +217,6 @@ __glXResizeDrawable(__GLdrawablePrivate *glPriv) } -/************************************************************************/ - -void -__glXFormatGLModes(__GLcontextModes *modes, __GLXvisualConfig *config) -{ - __glXMemset(modes, 0, sizeof(__GLcontextModes)); - - modes->rgbMode = (config->rgba != 0); - modes->colorIndexMode = !(modes->rgbMode); - modes->doubleBufferMode = (config->doubleBuffer != 0); - modes->stereoMode = (config->stereo != 0); - - modes->haveAccumBuffer = ((config->accumRedSize + - config->accumGreenSize + - config->accumBlueSize + - config->accumAlphaSize) > 0); - modes->haveDepthBuffer = (config->depthSize > 0); - modes->haveStencilBuffer = (config->stencilSize > 0); - - modes->redBits = config->redSize; - modes->greenBits = config->greenSize; - modes->blueBits = config->blueSize; - modes->alphaBits = config->alphaSize; - modes->redMask = config->redMask; - modes->greenMask = config->greenMask; - modes->blueMask = config->blueMask; - modes->alphaMask = config->alphaMask; -#if 0 - modes->rgbBits = modes->redBits + modes->greenBits + - modes->blueBits + modes->alphaBits; -#endif - assert( !modes->rgbMode || ((config->bufferSize & 0x7) == 0) ); - modes->rgbBits = config->bufferSize; - modes->indexBits = config->bufferSize; - - modes->accumRedBits = config->accumRedSize; - modes->accumGreenBits = config->accumGreenSize; - modes->accumBlueBits = config->accumBlueSize; - modes->accumAlphaBits = config->accumAlphaSize; - modes->depthBits = config->depthSize; - modes->stencilBits = config->stencilSize; - - modes->numAuxBuffers = 0; /* XXX: should be picked up from the visual */ - - modes->level = config->level; -} - /*****************************************************************************/ /* accessing the drawable private */ @@ -382,21 +338,13 @@ __glXCreateDrawablePrivate(DrawablePtr pDraw, XID drawId, pGlxScreen = &__glXActiveScreens[pDraw->pScreen->myNum]; - /* allocate the buffers */ if (glxPriv->type == DRAWABLE_WINDOW) { - int i; VisualID vid = wVisual((WindowPtr)pDraw); - __GLXvisualConfig *pGlxVisual = pGlxScreen->pGlxVisual; - for (i = 0; i < pGlxScreen->numVisuals; i++, pGlxVisual++) { - if (pGlxVisual->vid == vid) { - glxPriv->pGlxVisual = pGlxVisual; - break; - } - } + glxPriv->modes = _gl_context_modes_find_visual( pGlxScreen->modes, vid ); __glXFBInitDrawable(glxPriv, modes); } else { - glxPriv->pGlxVisual = glxPriv->pGlxPixmap->pGlxVisual; + glxPriv->modes = glxPriv->pGlxPixmap->modes; __glXPixInitDrawable(glxPriv, modes); } diff --git a/xc/programs/Xserver/GL/glx/glxutil.h b/xc/programs/Xserver/GL/glx/glxutil.h index 67bfb06f9..970683cb1 100644 --- a/xc/programs/Xserver/GL/glx/glxutil.h +++ b/xc/programs/Xserver/GL/glx/glxutil.h @@ -55,7 +55,6 @@ extern void __glXGetDrawableSize(__GLdrawablePrivate *glPriv, GLuint *width, GLuint *height); extern GLboolean __glXResizeDrawable(__GLdrawablePrivate *glPriv); extern GLboolean __glXResizeDrawableBuffers(__GLXdrawablePrivate *glxPriv); -extern void __glXFormatGLModes(__GLcontextModes *modes, __GLXvisualConfig *config); /* drawable management */ extern void __glXRefDrawablePrivate(__GLXdrawablePrivate *glxPriv); diff --git a/xc/programs/Xserver/GL/glxmodule.c b/xc/programs/Xserver/GL/glxmodule.c index eb8e54f26..d03ce6464 100644 --- a/xc/programs/Xserver/GL/glxmodule.c +++ b/xc/programs/Xserver/GL/glxmodule.c @@ -776,7 +776,6 @@ static const char *glcoreSymbols[] = { "__glXFogfvReqSize", "__glXFogivReqSize", "__glXForceCurrent", - "__glXFormatGLModes", "__glXFree", "__glXFreeBuffers", "__glXFreeContext", diff --git a/xc/programs/Xserver/GL/mesa/X/xf86glx.c b/xc/programs/Xserver/GL/mesa/X/xf86glx.c index 19b8ba7c8..3947fb9d0 100644 --- a/xc/programs/Xserver/GL/mesa/X/xf86glx.c +++ b/xc/programs/Xserver/GL/mesa/X/xf86glx.c @@ -65,6 +65,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include <GL/internal/glcore.h> #endif +#include "glcontextmodes.h" /* * This structure is statically allocated in the __glXScreens[] @@ -79,7 +80,7 @@ __GLXscreenInfo __glDDXScreenInfo = { __MESA_screenProbe, /* Must be generic and handle all screens */ __MESA_createContext, /* Substitute screen's createContext routine */ __MESA_createBuffer, /* Substitute screen's createBuffer routine */ - NULL, /* Set up pGlxVisual in probe */ + NULL, /* Set up modes in probe */ NULL, /* Set up pVisualPriv in probe */ 0, /* Set up numVisuals in probe */ 0, /* Set up numUsableVisuals in probe */ @@ -118,18 +119,19 @@ static int count_bits(unsigned int n) static XMesaVisual find_mesa_visual(int screen, VisualID vid) { - XMesaVisual xm_vis = NULL; - __MESA_screen *pMScr = &MESAScreens[screen]; - int i; + __MESA_screen * const pMScr = &MESAScreens[screen]; + const __GLcontextModes *modes; + unsigned i = 0; - for (i = 0; i < pMScr->num_vis; i++) { - if (pMScr->glx_vis[i].vid == vid) { - xm_vis = pMScr->xm_vis[i]; + for ( modes = pMScr->modes ; modes != NULL ; modes = modes->next ) { + if ( modes->visualID == vid ) { break; } + + i++; } - return xm_vis; + return (modes != NULL) ? pMScr->xm_vis[i] : NULL; } @@ -257,7 +259,7 @@ static Bool init_visuals(int *nvisualp, VisualPtr *visualp, VisualPtr pVisual = *visualp; VisualPtr pVisualNew = NULL; VisualID *orig_vid = NULL; - __GLXvisualConfig *glXVisualPtr = NULL; + __GLcontextModes *modes; __GLXvisualConfig *pNewVisualConfigs = NULL; void **glXVisualPriv; void **pNewVisualPriv; @@ -331,9 +333,8 @@ static Bool init_visuals(int *nvisualp, VisualPtr *visualp, } /* Alloc space for the list of glXVisuals */ - glXVisualPtr = (__GLXvisualConfig *)__glXMalloc(numNewVisuals * - sizeof(__GLXvisualConfig)); - if (!glXVisualPtr) { + modes = _gl_context_modes_create(numNewVisuals, sizeof(__GLcontextModes)); + if (modes == NULL) { __glXFree(orig_vid); __glXFree(pNewVisualPriv); __glXFree(pNewVisualConfigs); @@ -343,7 +344,7 @@ static Bool init_visuals(int *nvisualp, VisualPtr *visualp, /* Alloc space for the list of glXVisualPrivates */ glXVisualPriv = (void **)__glXMalloc(numNewVisuals * sizeof(void *)); if (!glXVisualPriv) { - __glXFree(glXVisualPtr); + _gl_context_modes_destroy( modes ); __glXFree(orig_vid); __glXFree(pNewVisualPriv); __glXFree(pNewVisualConfigs); @@ -354,7 +355,7 @@ static Bool init_visuals(int *nvisualp, VisualPtr *visualp, pVisualNew = (VisualPtr)__glXMalloc(numNewVisuals * sizeof(VisualRec)); if (!pVisualNew) { __glXFree(glXVisualPriv); - __glXFree(glXVisualPtr); + _gl_context_modes_destroy( modes ); __glXFree(orig_vid); __glXFree(pNewVisualPriv); __glXFree(pNewVisualConfigs); @@ -363,6 +364,7 @@ static Bool init_visuals(int *nvisualp, VisualPtr *visualp, /* Initialize the new visuals */ found_default = FALSE; + MESAScreens[screenInfo.numScreens-1].modes = modes; for (i = j = 0; i < numVisuals; i++) { int is_rgb = (pVisual[i].class == TrueColor || pVisual[i].class == DirectColor); @@ -371,6 +373,8 @@ static Bool init_visuals(int *nvisualp, VisualPtr *visualp, if (pNewVisualConfigs[k].rgba != is_rgb) continue; + assert( modes != NULL ); + /* Initialize the new visual */ pVisualNew[j] = pVisual[i]; pVisualNew[j].vid = FakeClientID(0); @@ -385,8 +389,8 @@ static Bool init_visuals(int *nvisualp, VisualPtr *visualp, orig_vid[j] = pVisual[i].vid; /* Initialize the glXVisual */ - glXVisualPtr[j] = pNewVisualConfigs[k]; - glXVisualPtr[j].vid = pVisualNew[j].vid; + _gl_copy_visual_to_context_mode( modes, & pNewVisualConfigs[k] ); + modes->visualID = pVisualNew[j].vid; /* * If the class is -1, then assume the X visual information @@ -394,30 +398,27 @@ static Bool init_visuals(int *nvisualp, VisualPtr *visualp, * visual. NOTE: if class != -1, then all other fields MUST * be initialized. */ - if (glXVisualPtr[j].class == -1) { - glXVisualPtr[j].class = pVisual[i].class; - glXVisualPtr[j].redSize = count_bits(pVisual[i].redMask); - glXVisualPtr[j].greenSize = count_bits(pVisual[i].greenMask); - glXVisualPtr[j].blueSize = count_bits(pVisual[i].blueMask); - glXVisualPtr[j].alphaSize = glXVisualPtr[j].alphaSize; - glXVisualPtr[j].redMask = pVisual[i].redMask; - glXVisualPtr[j].greenMask = pVisual[i].greenMask; - glXVisualPtr[j].blueMask = pVisual[i].blueMask; - glXVisualPtr[j].alphaMask = glXVisualPtr[j].alphaMask; - if (is_rgb) { - glXVisualPtr[j].bufferSize = glXVisualPtr[j].redSize + - glXVisualPtr[j].greenSize + - glXVisualPtr[j].blueSize + - glXVisualPtr[j].alphaSize; - } else { - glXVisualPtr[j].bufferSize = rootDepth; - } + if (modes->visualType == GLX_NONE) { + modes->visualType = _gl_convert_from_x_visual_type( pVisual[i].class ); + modes->redBits = count_bits(pVisual[i].redMask); + modes->greenBits = count_bits(pVisual[i].greenMask); + modes->blueBits = count_bits(pVisual[i].blueMask); + modes->alphaBits = modes->alphaBits; + modes->redMask = pVisual[i].redMask; + modes->greenMask = pVisual[i].greenMask; + modes->blueMask = pVisual[i].blueMask; + modes->alphaMask = modes->alphaMask; + modes->rgbBits = (is_rgb) + ? (modes->redBits + modes->greenBits + + modes->blueBits + modes->alphaBits) + : rootDepth; } /* Save the device-dependent private for this visual */ glXVisualPriv[j] = pNewVisualPriv[k]; j++; + modes = modes->next; } } @@ -425,7 +426,6 @@ static Bool init_visuals(int *nvisualp, VisualPtr *visualp, /* Save the GLX visuals in the screen structure */ MESAScreens[screenInfo.numScreens-1].num_vis = numNewVisuals; - MESAScreens[screenInfo.numScreens-1].glx_vis = glXVisualPtr; MESAScreens[screenInfo.numScreens-1].private = glXVisualPriv; /* Set up depth's VisualIDs */ @@ -501,27 +501,28 @@ static void fixup_visuals(int screen) { ScreenPtr pScreen = screenInfo.screens[screen]; __MESA_screen *pMScr = &MESAScreens[screen]; - __GLXvisualConfig *pGLXVis = pMScr->glx_vis; - VisualPtr pVis; - int i, j; + int j; + __GLcontextModes *modes; - for (i = 0; i < pMScr->num_vis; i++, pGLXVis++) { - pVis = pScreen->visuals; + for ( modes = pMScr->modes ; modes != NULL ; modes = modes->next ) { + const int vis_class = _gl_convert_to_x_visual_type( modes->visualType ); + const int nplanes = (modes->rgbBits - modes->alphaBits); + const VisualPtr pVis = pScreen->visuals; /* Find a visual that matches the GLX visual's class and size */ - for (j = 0; j < pScreen->numVisuals; j++, pVis++) { - if (pVis->class == pGLXVis->class && - pVis->nplanes == (pGLXVis->bufferSize - pGLXVis->alphaSize)) { + for (j = 0; j < pScreen->numVisuals; j++) { + if (pVis[j].class == vis_class && + pVis[j].nplanes == nplanes) { /* Fixup the masks */ - pGLXVis->redMask = pVis->redMask; - pGLXVis->greenMask = pVis->greenMask; - pGLXVis->blueMask = pVis->blueMask; + modes->redMask = pVis[j].redMask; + modes->greenMask = pVis[j].greenMask; + modes->blueMask = pVis[j].blueMask; /* Recalc the sizes */ - pGLXVis->redSize = count_bits(pGLXVis->redMask); - pGLXVis->greenSize = count_bits(pGLXVis->greenMask); - pGLXVis->blueSize = count_bits(pGLXVis->blueMask); + modes->redBits = count_bits(modes->redMask); + modes->greenBits = count_bits(modes->greenMask); + modes->blueBits = count_bits(modes->blueMask); } } } @@ -530,9 +531,8 @@ static void fixup_visuals(int screen) static void init_screen_visuals(int screen) { ScreenPtr pScreen = screenInfo.screens[screen]; - __GLXvisualConfig *pGLXVis = MESAScreens[screen].glx_vis; + __GLcontextModes *modes; XMesaVisual *pXMesaVisual; - VisualPtr pVis; int *used; int i, j; @@ -542,49 +542,70 @@ static void init_screen_visuals(int screen) __glXMemset(pXMesaVisual, 0, MESAScreens[screen].num_vis * sizeof(XMesaVisual)); + /* FIXME: Change 'used' to be a array of bits (rather than of ints), + * FIXME: create a stack array of 8 or 16 bytes. If 'numVisuals' is less + * FIXME: than 64 or 128 the stack array can be used instead of calling + * FIXME: __glXMalloc / __glXFree. If nothing else, convert 'used' to + * FIXME: array of bytes instead of ints! + */ used = (int *)__glXMalloc(pScreen->numVisuals * sizeof(int)); __glXMemset(used, 0, pScreen->numVisuals * sizeof(int)); - for (i = 0; i < MESAScreens[screen].num_vis; i++, pGLXVis++) { - - pVis = pScreen->visuals; - for (j = 0; j < pScreen->numVisuals; j++, pVis++) { - - if (pVis->class == pGLXVis->class && - pVis->nplanes == (pGLXVis->bufferSize - pGLXVis->alphaSize) && + i = 0; + for ( modes = MESAScreens[screen].modes + ; modes != NULL + ; modes = modes->next ) { + const int vis_class = _gl_convert_to_x_visual_type( modes->visualType ); + const int nplanes = (modes->rgbBits - modes->alphaBits); + const VisualPtr pVis = pScreen->visuals; + + for (j = 0; j < pScreen->numVisuals; j++) { + if (pVis[j].class == vis_class && + pVis[j].nplanes == nplanes && + pVis[j].redMask == modes->redMask && + pVis[j].greenMask == modes->greenMask && + pVis[j].blueMask == modes->blueMask && !used[j]) { - if (pVis->redMask == pGLXVis->redMask && - pVis->greenMask == pGLXVis->greenMask && - pVis->blueMask == pGLXVis->blueMask) { - - /* Create the XMesa visual */ - pXMesaVisual[i] = - XMesaCreateVisual(pScreen, - pVis, - pGLXVis->rgba, - (pGLXVis->alphaSize > 0), - pGLXVis->doubleBuffer, - pGLXVis->stereo, - GL_TRUE, /* ximage_flag */ - pGLXVis->depthSize, - pGLXVis->stencilSize, - pGLXVis->accumRedSize, - pGLXVis->accumGreenSize, - pGLXVis->accumBlueSize, - pGLXVis->accumAlphaSize, - 0, /* numSamples */ - pGLXVis->level, - pGLXVis->visualRating ); - /* Set the VisualID */ - pGLXVis->vid = pVis->vid; - - /* Mark this visual used */ - used[j] = 1; - break; - } + /* Create the XMesa visual */ + pXMesaVisual[i] = + XMesaCreateVisual(pScreen, + pVis, + modes->rgbMode, + (modes->alphaBits > 0), + modes->doubleBufferMode, + modes->stereoMode, + GL_TRUE, /* ximage_flag */ + modes->depthBits, + modes->stencilBits, + modes->accumRedBits, + modes->accumGreenBits, + modes->accumBlueBits, + modes->accumAlphaBits, + modes->samples, + modes->level, + modes->visualRating); + /* Set the VisualID */ + modes->visualID = pVis[j].vid; + + /* Mark this visual used */ + used[j] = 1; + break; } } + + if ( j == pScreen->numVisuals ) { + ErrorF("No matching visual for __GLcontextMode with " + "visual class = %d (%d), nplanes = %u\n", + vis_class, + modes->visualType, + (modes->rgbBits - modes->alphaBits) ); + } + else if ( modes->visualID == -1 ) { + FatalError( "Matching visual found, but visualID still -1!\n" ); + } + + i++; } __glXFree(used); @@ -597,7 +618,7 @@ Bool __MESA_screenProbe(int screen) /* * Set up the current screen's visuals. */ - __glDDXScreenInfo.pGlxVisual = MESAScreens[screen].glx_vis; + __glDDXScreenInfo.modes = MESAScreens[screen].modes; __glDDXScreenInfo.pVisualPriv = MESAScreens[screen].private; __glDDXScreenInfo.numVisuals = __glDDXScreenInfo.numUsableVisuals = MESAScreens[screen].num_vis; @@ -636,15 +657,15 @@ extern void __MESA_resetExtension(void) MESAScreens[i].xm_vis[j] = NULL; } } - __glXFree(MESAScreens[i].glx_vis); - MESAScreens[i].glx_vis = NULL; + _gl_context_modes_destroy( MESAScreens[i].modes ); + MESAScreens[i].modes = NULL; __glXFree(MESAScreens[i].private); MESAScreens[i].private = NULL; __glXFree(MESAScreens[i].xm_vis); MESAScreens[i].xm_vis = NULL; MESAScreens[i].num_vis = 0; } - __glDDXScreenInfo.pGlxVisual = NULL; + __glDDXScreenInfo.modes = NULL; MESA_CC = NULL; } @@ -652,10 +673,14 @@ void __MESA_createBuffer(__GLXdrawablePrivate *glxPriv) { DrawablePtr pDraw = glxPriv->pDraw; XMesaVisual xm_vis = find_mesa_visual(pDraw->pScreen->myNum, - glxPriv->pGlxVisual->vid); + glxPriv->modes->visualID); __GLdrawablePrivate *glPriv = &glxPriv->glPriv; __MESA_buffer buf; + if (xm_vis == NULL) { + ErrorF("find_mesa_visual returned NULL for visualID = 0x%04x\n", + glxPriv->modes->visualID); + } buf = (__MESA_buffer)__glXMalloc(sizeof(struct __MESA_bufferRec)); /* Create Mesa's buffers */ @@ -736,12 +761,17 @@ __GLinterface *__MESA_createContext(__GLimports *imports, if (shareGC) m_share = (__GLcontext *)shareGC; - xm_vis = find_mesa_visual(glxc->pScreen->myNum, glxc->pGlxVisual->vid); + xm_vis = find_mesa_visual(glxc->pScreen->myNum, glxc->modes->visualID); if (xm_vis) { XMesaContext xmshare = m_share ? m_share->DriverCtx : 0; XMesaContext xmctx = XMesaCreateContext(xm_vis, xmshare); gl_ctx = xmctx ? &xmctx->mesa : 0; } + else { + ErrorF("find_mesa_visual returned NULL for visualID = 0x%04x\n", + glxc->modes->visualID); + } + if (!gl_ctx) return NULL; diff --git a/xc/programs/Xserver/GL/mesa/X/xf86glxint.h b/xc/programs/Xserver/GL/mesa/X/xf86glxint.h index 47c8e7608..3d7dcec6f 100644 --- a/xc/programs/Xserver/GL/mesa/X/xf86glxint.h +++ b/xc/programs/Xserver/GL/mesa/X/xf86glxint.h @@ -39,15 +39,10 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include <GL/gl.h> #include <GL/xmesa.h> -/* struct __GLcontextRec { */ -/* __GLinterface iface; */ -/* XMesaContext xm_ctx; */ -/* }; */ - typedef struct __MESA_screenRec __MESA_screen; struct __MESA_screenRec { int num_vis; - __GLXvisualConfig *glx_vis; + __GLcontextModes *modes; XMesaVisual *xm_vis; void **private; }; |