Hello, this is hopefully the final version of the per-screen dynamic GLX extensions patch. Major changes from the last version:
- per-screen data in __GLXscreenConfigs - __DRIscreen has an opaque pointer back to the screenConfigs - Bumped the internal libGL API version to 20030813 - __glXExtensionBitIsEnabled must be per-screen too - requires two helper functions to find the __GLXscreenConfigs from either a GLXcontext or a display, screen pair - Updated some comments in glxextensions.c To test that the screen finding functions actually work as expected we should test at least one of the SwapInverval-related extensions and one of the FBConfig-related ones. Can someone point me to some simple test cases. I remember some posts about glxgears with SwapInterval support. Is that in Mesa CVS? It is a bit inconvenient for me to download a whole mesa CVS tree through a modem connection. Ian, IIRC you made those changes in glxgears. Could you send me only the updated glxgears source? Regards, Felix ------------ __\|/__ ___ ___ ------------------------- Felix ___\_e -_/___/ __\___/ __\_____ You can do anything, Kühling (_____\Ä/____/ /_____/ /________) just not everything [EMAIL PROTECTED] \___/ \___/ U at the same time.
? dri/DONE ? dri/Makefile ? dri/drm/DONE ? dri/drm/Makefile ? glx/DONE ? glx/Makefile ? glx/glxextensions.patch ? glx/glxextensions2.patch Index: dri/dri_glx.c =================================================================== RCS file: /cvsroot/dri/xc/xc/lib/GL/dri/dri_glx.c,v retrieving revision 1.29.4.1 diff -u -r1.29.4.1 dri_glx.c --- dri/dri_glx.c 26 May 2003 17:41:59 -0000 1.29.4.1 +++ dri/dri_glx.c 14 Aug 2003 16:31:27 -0000 @@ -230,8 +230,6 @@ dlclose(handle); continue; } - driver->registerExtensionsFunc = (RegisterExtensionsFunc) - dlsym(handle, "__driRegisterExtensions"); driver->handle = handle; /* put at head of linked list */ driver->next = Drivers; @@ -435,7 +433,6 @@ * driver's "__driCreateScreen" function pointer. That's the bootstrap * entrypoint for all DRI drivers. */ - __glXRegisterExtensions(); for (scrn = 0; scrn < numScreens; scrn++) { __DRIdriver *driver = driGetDriver(dpy, scrn); if (driver) { @@ -451,71 +448,5 @@ return (void *)pdpyp; } - - - -/* -** Here we'll query the DRI driver for each screen and let each -** driver register its GL extension functions. We only have to -** do this once. -** -** In older versions of libGL (prior to October 2002) we _always_ -** called this function during libGL start-up. Now, we only call -** it from glXGetProcAddress() as a last resort. -** -** Two key things changed along the way: -** 1. _glapi_get_proc_address() now generates new dispatch stub functions -** anytime it gets an unknown "gl*" function name. I.e. we always return -** a valid function address and later patch it up to use the correct -** dispatch offset. -** 2. The GL API dispatch table is a fixed size (with plenty of extra slots). -** This means we don't have to register all new functions before we create -** the first dispatch table. -*/ -void -__glXRegisterExtensions(void) -{ -#ifndef BUILT_IN_DRI_DRIVER - static GLboolean alreadyCalled = GL_FALSE; - int displayNum, maxDisplays; - - if (alreadyCalled) - return; - alreadyCalled = GL_TRUE; - - if (getenv("LIBGL_MULTIHEAD")) { - /* we'd like to always take this path but doing so causes a second - * or more of delay while the XOpenDisplay() function times out. - */ - maxDisplays = 10; /* infinity, really */ - } - else { - /* just open the :0 display */ - maxDisplays = 1; - } - - for (displayNum = 0; displayNum < maxDisplays; displayNum++) { - char displayName[200]; - Display *dpy; - snprintf(displayName, 199, ":%d.0", displayNum); - dpy = XOpenDisplay(displayName); - if (dpy) { - const int numScreens = ScreenCount(dpy); - int screenNum; - for (screenNum = 0; screenNum < numScreens; screenNum++) { - __DRIdriver *driver = driGetDriver(dpy, screenNum); - if (driver && driver->registerExtensionsFunc) { - (*driver->registerExtensionsFunc)(); - } - } - XCloseDisplay(dpy); - } - else { - break; - } - } -#endif -} - #endif /* GLX_DIRECT_RENDERING */ Index: dri/dri_util.c =================================================================== RCS file: /cvsroot/dri/xc/xc/lib/GL/dri/dri_util.c,v retrieving revision 1.13 diff -u -r1.13 dri_util.c --- dri/dri_util.c 21 May 2003 17:32:04 -0000 1.13 +++ dri/dri_util.c 14 Aug 2003 16:31:42 -0000 @@ -1031,6 +1031,7 @@ if (!psp) { return NULL; } + psp->psc = psc; psp->fullscreen = NULL; psp->display = dpy; psp->myNum = scrn; Index: dri/dri_util.h =================================================================== RCS file: /cvsroot/dri/xc/xc/lib/GL/dri/dri_util.h,v retrieving revision 1.8 diff -u -r1.8 dri_util.h --- dri/dri_util.h 21 May 2003 17:32:05 -0000 1.8 +++ dri/dri_util.h 14 Aug 2003 16:31:46 -0000 @@ -406,6 +406,11 @@ */ int numConfigs; __GLXvisualConfig *configs; + + /* + ** Point back to the containing __DRIscreen + */ + __DRIscreen *psc; }; Index: glx/glxclient.h =================================================================== RCS file: /cvsroot/dri/xc/xc/lib/GL/glx/glxclient.h,v retrieving revision 1.28.2.1 diff -u -r1.28.2.1 glxclient.h --- glx/glxclient.h 26 May 2003 17:41:59 -0000 1.28.2.1 +++ glx/glxclient.h 14 Aug 2003 16:31:54 -0000 @@ -167,6 +167,16 @@ ** Added with internal API version "20030317". */ int (*getMSC)( void *screenPrivate, int64_t *msc ); + + /* + ** Opaque pointer that points back to the containing __GLXscreenConfigs. + ** This data structure is shared with DRI drivers but __GLXscreenConfigs + ** is not. However, they are needed by some GLX functions called by DRI + ** drivers. + ** + ** Added with internal API version "20030813". + */ + void *screenConfigs; }; /* @@ -292,8 +302,6 @@ typedef void *(*CreateScreenFunc)(Display *dpy, int scrn, __DRIscreen *psc, int numConfigs, __GLXvisualConfig *config); -typedef void *(*RegisterExtensionsFunc)(void); - /* ** We keep a linked list of these structures, one per DRI device driver. */ @@ -301,7 +309,6 @@ const char *name; void *handle; CreateScreenFunc createScreenFunc; - RegisterExtensionsFunc registerExtensionsFunc; struct __DRIdriverRec *next; }; @@ -595,6 +602,11 @@ ** Per screen direct rendering interface functions and data. */ __DRIscreen driScreen; + /* + ** Per screen dynamic client GLX extensions + */ + unsigned char direct_support[8]; + GLboolean ext_list_first_time; #endif } __GLXscreenConfigs; @@ -641,6 +653,8 @@ #endif }; +__GLXscreenConfigs *__glXFindGLXScreenConfigs(Display *dpy, int scrn); + void __glXFreeContext(__GLXcontext*); extern GLubyte *__glXFlushRenderBuffer(__GLXcontext*, GLubyte*); @@ -650,15 +664,6 @@ /* Initialize the GLX extension for dpy */ extern __GLXdisplayPrivate *__glXInitialize(Display*); - -/* Query drivers for dynamically registered extensions */ -extern void __glXRegisterExtensions(void); - -/* Functions for extending the GLX API: */ -extern void *__glXRegisterGLXFunction(const char *funcName, void *funcAddr); -extern void __glXRegisterGLXExtensionString(const char *extName); -typedef void * (* PFNGLXREGISTERGLXFUNCTIONPROC) ( const char * funcName, - void * funcAdd ); /************************************************************************/ Index: glx/glxcmds.c =================================================================== RCS file: /cvsroot/dri/xc/xc/lib/GL/glx/glxcmds.c,v retrieving revision 1.41.2.1 diff -u -r1.41.2.1 glxcmds.c --- glx/glxcmds.c 26 May 2003 17:41:59 -0000 1.41.2.1 +++ glx/glxcmds.c 14 Aug 2003 16:32:24 -0000 @@ -104,6 +104,21 @@ static const char __glXGLXClientVersion[] = "1.2"; /****************************************************************************/ + +static __GLXscreenConfigs * +GetGLXScreenConfigs( GLXContext gc ) +{ + __GLXscreenConfigs *psc = NULL; + + if (gc != NULL) { + __GLXdisplayPrivate *priv = __glXInitialize(gc->currentDpy); + if (priv->screenConfigs) + psc = &priv->screenConfigs[gc->screen]; + } + + return psc; +} + /** * Get the write __DRIdrawable bound to the specificed GLXContext * @@ -1330,7 +1345,7 @@ screen, GLX_EXTENSIONS); } - psc->effectiveGLXexts = (char *) __glXGetUsableExtensions(psc->serverGLXexts); + psc->effectiveGLXexts = (char *) __glXGetUsableExtensions(psc, psc->serverGLXexts); } return psc->effectiveGLXexts; @@ -1872,7 +1887,10 @@ } #ifdef GLX_DIRECT_RENDERING - if ( gc->isDirect && __glXExtensionBitIsEnabled( SGI_swap_control_bit ) ) { + { + __GLXscreenConfigs *psc = GetGLXScreenConfigs( gc ); + if ( gc->isDirect && + __glXExtensionBitIsEnabled( psc, SGI_swap_control_bit ) ) { __DRIdrawable *pdraw = GetDRIDrawable( gc ); if ( pdraw != NULL ) { @@ -1880,6 +1898,7 @@ return 0; } } + } #endif dpy = gc->currentDpy; opcode = __glXSetupForCommand(dpy); @@ -1913,6 +1932,7 @@ { #ifdef GLX_DIRECT_RENDERING GLXContext gc = __glXGetCurrentContext(); + __GLXscreenConfigs *psc = GetGLXScreenConfigs( gc ); __DRIdrawable *pdraw = GetDRIDrawable( gc ); if ( pdraw == NULL ) { @@ -1923,7 +1943,7 @@ return GLX_BAD_VALUE; } - if ( __glXExtensionBitIsEnabled( MESA_swap_control_bit ) ) { + if ( __glXExtensionBitIsEnabled( psc, MESA_swap_control_bit ) ) { pdraw->swap_interval = interval; return 0; } @@ -1938,10 +1958,11 @@ { #ifdef GLX_DIRECT_RENDERING GLXContext gc = __glXGetCurrentContext(); + __GLXscreenConfigs *psc = GetGLXScreenConfigs( gc ); __DRIdrawable *pdraw = GetDRIDrawable( gc ); - if ( pdraw && __glXExtensionBitIsEnabled( MESA_swap_control_bit ) ) { + if ( pdraw && __glXExtensionBitIsEnabled( psc, MESA_swap_control_bit ) ) { return pdraw->swap_interval; } #endif @@ -1959,10 +1980,12 @@ int status = GLX_BAD_CONTEXT; #ifdef GLX_DIRECT_RENDERING GLXContext gc = __glXGetCurrentContext(); + __GLXscreenConfigs *psc = GetGLXScreenConfigs( gc ); __DRIdrawable *pdraw; __GLXdisplayPrivate *priv; - if ( (gc != NULL) && __glXExtensionBitIsEnabled( MESA_swap_frame_usage_bit ) ) { + if ( (gc != NULL) && + __glXExtensionBitIsEnabled( psc, MESA_swap_frame_usage_bit ) ) { priv = __glXInitialize(gc->currentDpy); if (priv->driDisplay.private) { __GLXscreenConfigs *psc = &priv->screenConfigs[gc->screen]; @@ -1992,10 +2015,12 @@ int status = GLX_BAD_CONTEXT; #ifdef GLX_DIRECT_RENDERING GLXContext gc = __glXGetCurrentContext(); + __GLXscreenConfigs *psc = GetGLXScreenConfigs( gc ); __DRIdrawable *pdraw; __GLXdisplayPrivate *priv; - if ( (gc != NULL) && __glXExtensionBitIsEnabled( MESA_swap_frame_usage_bit ) ) { + if ( (gc != NULL) && + __glXExtensionBitIsEnabled( psc, MESA_swap_frame_usage_bit ) ) { priv = __glXInitialize(gc->currentDpy); if (priv->driDisplay.private) { __GLXscreenConfigs *psc = &priv->screenConfigs[gc->screen]; @@ -2026,10 +2051,11 @@ int status = GLX_BAD_CONTEXT; #ifdef GLX_DIRECT_RENDERING GLXContext gc = __glXGetCurrentContext(); + __GLXscreenConfigs *psc = GetGLXScreenConfigs( gc ); __DRIdrawable *pdraw = GetDRIDrawable( gc ); if ( (pdraw != NULL ) && (pdraw->queryFrameTracking != NULL) - && __glXExtensionBitIsEnabled( MESA_swap_frame_usage_bit ) ) { + && __glXExtensionBitIsEnabled( psc, MESA_swap_frame_usage_bit ) ) { int64_t sbc, missedFrames; float lastMissedUsage; @@ -2053,10 +2079,11 @@ int status = GLX_BAD_CONTEXT; #ifdef GLX_DIRECT_RENDERING GLXContext gc = __glXGetCurrentContext(); + __GLXscreenConfigs *psc = GetGLXScreenConfigs( gc ); __DRIdrawable *pdraw = GetDRIDrawable( gc ); if ( (pdraw != NULL ) && (pdraw->queryFrameTracking != NULL) - && __glXExtensionBitIsEnabled( MESA_swap_frame_usage_bit ) ) { + && __glXExtensionBitIsEnabled( psc, MESA_swap_frame_usage_bit ) ) { float usage; status = pdraw->queryFrameTracking( dpy, pdraw->private, sbc, @@ -2085,10 +2112,10 @@ */ #ifdef GLX_DIRECT_RENDERING GLXContext gc = __glXGetCurrentContext(); - + __GLXscreenConfigs *psc = GetGLXScreenConfigs( gc ); if ( (gc != NULL) && gc->isDirect - && __glXExtensionBitIsEnabled( SGI_video_sync_bit ) ) { + && __glXExtensionBitIsEnabled( psc, SGI_video_sync_bit ) ) { __GLXdisplayPrivate *priv = __glXInitialize(gc->currentDpy); if (priv->driDisplay.private) { __GLXscreenConfigs *psc = &priv->screenConfigs[gc->screen]; @@ -2112,13 +2139,14 @@ { #ifdef GLX_DIRECT_RENDERING GLXContext gc = __glXGetCurrentContext(); + __GLXscreenConfigs *psc = GetGLXScreenConfigs( gc ); __DRIdrawable *pdraw = GetDRIDrawable( gc ); if ( divisor <= 0 || remainder < 0 ) return GLX_BAD_VALUE; if (pdraw && pdraw->waitForMSC - && __glXExtensionBitIsEnabled( SGI_video_sync_bit )) { + && __glXExtensionBitIsEnabled( psc, SGI_video_sync_bit )) { int ret; int64_t msc; int64_t sbc; @@ -2181,9 +2209,9 @@ GLXPixmap xid = None; CARD8 opcode; __GLXFBConfig * fbconfig = (__GLXFBConfig *) config; + __GLXscreenConfigs *psc = __glXFindGLXScreenConfigs( dpy, fbconfig->screen ); - - if ( __glXExtensionBitIsEnabled( SGIX_fbconfig_bit ) ) { + if ( __glXExtensionBitIsEnabled( psc, SGIX_fbconfig_bit ) ) { opcode = __glXSetupForCommand(dpy); if (!opcode) { return None; @@ -2216,8 +2244,9 @@ __GLXdisplayPrivate *priv; #endif __GLXFBConfig * fbconfig = (__GLXFBConfig *) config; + __GLXscreenConfigs *psc = __glXFindGLXScreenConfigs( dpy, fbconfig->screen ); - if ( __glXExtensionBitIsEnabled( SGIX_fbconfig_bit ) ) { + if ( __glXExtensionBitIsEnabled( psc, SGIX_fbconfig_bit ) ) { if (!dpy || !fbconfig) return NULL; @@ -2475,11 +2504,13 @@ { #ifdef GLX_DIRECT_RENDERING GLXContext gc = __glXGetCurrentContext(); + __GLXscreenConfigs *psc = GetGLXScreenConfigs( gc ); __DRIdrawable *pdraw; __GLXdisplayPrivate *priv; int ret; - if ( (gc != NULL) && __glXExtensionBitIsEnabled( OML_sync_control_bit ) ) { + if ( (gc != NULL) && + __glXExtensionBitIsEnabled( psc, OML_sync_control_bit ) ) { priv = __glXInitialize(gc->currentDpy); if (priv->driDisplay.private) { __GLXscreenConfigs *psc = &priv->screenConfigs[gc->screen]; @@ -2598,6 +2629,7 @@ { #ifdef GLX_DIRECT_RENDERING GLXContext gc = __glXGetCurrentContext(); + __GLXscreenConfigs *psc = GetGLXScreenConfigs( gc ); __DRIdrawable *pdraw = GetDRIDrawable( gc ); /* The OML_sync_control spec says these should "generate a GLX_BAD_VALUE @@ -2610,7 +2642,7 @@ if ( divisor > 0 && remainder >= divisor ) return -1; - if (pdraw && __glXExtensionBitIsEnabled( OML_sync_control_bit )) { + if (pdraw && __glXExtensionBitIsEnabled( psc, OML_sync_control_bit )) { return (*pdraw->swapBuffersMSC)(dpy, pdraw->private, target_msc, divisor, remainder); } @@ -2632,6 +2664,7 @@ { #ifdef GLX_DIRECT_RENDERING GLXContext gc = __glXGetCurrentContext(); + __GLXscreenConfigs *psc = GetGLXScreenConfigs( gc ); __DRIdrawable *pdraw = GetDRIDrawable( gc ); int ret; @@ -2644,7 +2677,7 @@ return False; if ( (pdraw != NULL) && (pdraw->waitForMSC != NULL) - && __glXExtensionBitIsEnabled( OML_sync_control_bit )) { + && __glXExtensionBitIsEnabled( psc, OML_sync_control_bit )) { ret = (*pdraw->waitForMSC)( dpy, pdraw->private, target_msc, divisor, remainder, msc, sbc ); @@ -2673,6 +2706,7 @@ { #ifdef GLX_DIRECT_RENDERING GLXContext gc = __glXGetCurrentContext(); + __GLXscreenConfigs *psc = GetGLXScreenConfigs( gc ); __DRIdrawable *pdraw = GetDRIDrawable( gc ); int ret; @@ -2683,7 +2717,7 @@ return False; if ( (pdraw != NULL) && (pdraw->waitForSBC != NULL) - && __glXExtensionBitIsEnabled( OML_sync_control_bit )) { + && __glXExtensionBitIsEnabled( psc, OML_sync_control_bit )) { ret = (*pdraw->waitForSBC)( dpy, pdraw->private, target_sbc, msc, sbc ); /* __glXGetUST returns zero on success and non-zero on failure. @@ -2936,13 +2970,10 @@ { "__glXInitialize", (GLvoid *) __glXInitialize, NULL }, { "__glXFindDRIScreen", (GLvoid *) __glXFindDRIScreen, NULL }, { "__glXGetInternalVersion", (GLvoid *) __glXGetInternalVersion, NULL }, - { "__glXRegisterGLXExtensionString", (GLvoid *) __glXRegisterGLXExtensionString, NULL }, - { "__glXRegisterGLXFunction", (GLvoid *) __glXRegisterGLXFunction, NULL }, { "__glXWindowExists", (GLvoid *) __glXWindowExists, NULL }, - { "__glXEnableExtension", (GLvoid *) __glXEnableExtension, NULL }, - { "__glXDisableExtension", (GLvoid *) __glXDisableExtension, NULL }, - { "__glXAddExtension", (GLvoid *) __glXAddExtension, NULL }, + { "__glXScrEnableExtension", (GLvoid *) __glXScrEnableExtension, NULL }, + { "__glXScrDisableExtension", (GLvoid *) __glXScrDisableExtension, NULL }, { "__glXGetUST", (GLvoid *) __glXGetUST, NULL }, @@ -2950,85 +2981,11 @@ }; -static struct name_address_pair *Dynamic_GLX_functions = NULL; - - -/* - * Drivers can call this function to append the name of a new GLX - * extension string to __glXGLXClientExtensions. Then, when the user - * calls glXGetClientString() they'll see it listed. - * This is a companion to __glXRegisterGLXFunction(). - */ -void -__glXRegisterGLXExtensionString(const char *extName) -{ - __glXEnableExtension( extName, GL_TRUE ); -} - - -/** - * DRI drivers should call this function if they want to extend - * the GLX API. After registering a new GLX function, the user - * can query and use it by calling \c glXGetProcAddress. - * - * \param funcName name of new GLX function - * \param funcAddr pointer to the function - * \return Address of previously registered function with this name or NULL. - * - * \sa __glXEnableExtension glXGetProcAddress - */ -void * -__glXRegisterGLXFunction(const char *funcName, void *funcAddr) -{ - struct name_address_pair *ext; - - assert(funcName); - assert(funcName[0] == 'g'); - assert(funcName[1] == 'l'); - assert(funcName[2] == 'X'); - - /* look if the function is already registered */ - for (ext = Dynamic_GLX_functions; ext; ext = ext->Next) { - if (strcmp(ext->Name, funcName) == 0) { - /* It's up the caller to use this return value if he wants - * to chain-call or wrap the previously registered function. - */ - void *prevAddr = ext->Address; - ext->Address = funcAddr; - return prevAddr; - } - } - - /* add new function */ - ext = Xmalloc(sizeof(struct name_address_pair)); - if (!ext) - return NULL; - ext->Name = __glXstrdup(funcName); - if (!ext->Name) { - Xfree(ext); - return NULL; - } - ext->Address = funcAddr; - ext->Next = Dynamic_GLX_functions; - Dynamic_GLX_functions = ext; - return NULL; -} - - static const GLvoid * get_glx_proc_address(const char *funcName, GLboolean dynamic_only) { - const struct name_address_pair *ext; GLuint i; - /* try dynamic functions */ - for (ext = Dynamic_GLX_functions; ext; ext = ext->Next) { - if (strcmp(ext->Name, funcName) == 0) { - return ext->Address; - } - } - - /* try static functions */ if ( ! dynamic_only ) { for (i = 0; GLX_functions[i].Name; i++) { if (strcmp(GLX_functions[i].Name, funcName) == 0) @@ -3056,7 +3013,6 @@ * dynamically added by a driver. Call __glXRegisterExtensions() * to try to make that happen. */ - __glXRegisterExtensions(); f = (gl_function) get_glx_proc_address((const char *) procName, GL_TRUE); return f; /* may be NULL */ } @@ -3163,8 +3119,9 @@ * GLX_MESA_swap_frame_usage, GLX_OML_swap_method, * GLX_{ARB,SGIS}_multisample, and * GLX_SGIX_visual_select_group. + * 20030813 - Made support for dynamic extensions multi-head aware. */ - return 20030317; + return 20030813; } Index: glx/glxext.c =================================================================== RCS file: /cvsroot/dri/xc/xc/lib/GL/glx/glxext.c,v retrieving revision 1.28 diff -u -r1.28 glxext.c --- glx/glxext.c 13 May 2003 13:48:21 -0000 1.28 +++ glx/glxext.c 14 Aug 2003 16:32:37 -0000 @@ -771,22 +771,20 @@ UnlockDisplay(dpy); #ifdef GLX_DIRECT_RENDERING + /* Initialize per screen dynamic client GLX extensions */ + psc->ext_list_first_time = GL_TRUE; /* Initialize the direct rendering per screen data and functions */ if (priv->driDisplay.private && priv->driDisplay.createScreen && priv->driDisplay.createScreen[i]) { - /* register glx extensions */ - __DRIdriver *driver = driGetDriver(dpy, i); - if (driver && driver->registerExtensionsFunc) - (*driver->registerExtensionsFunc)(); /* 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, @@ -1064,11 +1062,10 @@ /************************************************************************/ -#ifdef GLX_DIRECT_RENDERING -/* Return the DRI per screen structure */ -__DRIscreen *__glXFindDRIScreen(Display *dpy, int scrn) +/* Return the GLX per screen structure */ +__GLXscreenConfigs *__glXFindGLXScreenConfigs(Display *dpy, int scrn) { - __DRIscreen *pDRIScreen = NULL; + __GLXscreenConfigs *pGLXScreen = NULL; XExtDisplayInfo *info = __glXFindDisplay(dpy); XExtData **privList, *found; __GLXdisplayPrivate *dpyPriv; @@ -1082,8 +1079,21 @@ if (found) { dpyPriv = (__GLXdisplayPrivate *)found->private_data; - pDRIScreen = &dpyPriv->screenConfigs[scrn].driScreen; + pGLXScreen = &dpyPriv->screenConfigs[scrn]; } + + return pGLXScreen; +} + +#ifdef GLX_DIRECT_RENDERING +/* Return the DRI per screen structure */ +__DRIscreen *__glXFindDRIScreen(Display *dpy, int scrn) +{ + __DRIscreen *pDRIScreen = NULL; + __GLXscreenConfigs *pGLXScreen = __glXFindGLXScreenConfigs(dpy, scrn); + + if (pGLXScreen) + pDRIScreen = &pGLXScreen->driScreen; return pDRIScreen; } Index: glx/glxextensions.c =================================================================== RCS file: /cvsroot/dri/xc/xc/lib/GL/glx/glxextensions.c,v retrieving revision 1.3 diff -u -r1.3 glxextensions.c --- glx/glxextensions.c 3 May 2003 05:19:30 -0000 1.3 +++ glx/glxextensions.c 14 Aug 2003 16:32:43 -0000 @@ -116,18 +116,22 @@ { NULL } }; +/* global list of available extensions */ static struct glx_extension ext_list; static GLboolean ext_list_first_time = GL_TRUE; -static GLuint next_bit = 0; +/* global bit-fields of available extensions and their characteristics */ static unsigned char client_support[8]; -static unsigned char direct_support[8]; static unsigned char client_only[8]; static unsigned char direct_only[8]; +/* extensions enabled by default on all screens */ +static unsigned char direct_support[8]; +/* client extensions string */ static const char * __glXGLXClientExtensions = NULL; static void __glXExtensionsCtr( void ); +static void __glXExtensionsCtrScreen( __GLXscreenConfigs *psc ); static void __glXProcessServerString( const char * server_string, unsigned char * server_support ); @@ -209,53 +213,49 @@ /** - * Enable a named GLX extension. + * Enable a named GLX extension on a given screen. * + * \param psc Pointer to GLX per-screen record. * \param name Name of the extension to enable. - * \param force_client Enable client-side support also. If this is set - * to GL_TRUE, then the driver MUST supply function - * entry-points via \c __glXRegisterGLXFunction. - * \sa __glXRegisterGLXFunction, __glXDisableExtension + * \sa __glXDisableExtension */ void -__glXEnableExtension( const char * name, GLboolean force_client ) +__glXScrEnableExtension( __GLXscreenConfigs *psc, const char * name ) { - if ( __glXGLXClientExtensions == NULL ) { - __glXExtensionsCtr(); - set_glx_extension( name, strlen( name ), GL_TRUE, direct_support ); - if ( force_client ) { - set_glx_extension( name, strlen( name ), GL_TRUE, client_support ); - } - } + __glXExtensionsCtr(); + __glXExtensionsCtrScreen(psc); + set_glx_extension( name, strlen( name ), GL_TRUE, psc->direct_support ); } /** - * Disable a named GLX extension. + * Disable a named GLX extension on a given screen. * + * \param psc Pointer to GLX per-screen record. * \param name Name of the extension to disable. * \sa __glXEnableExtension */ void -__glXDisableExtension( const char * name ) +__glXScrDisableExtension( __GLXscreenConfigs *psc, const char * name ) { - if ( __glXGLXClientExtensions == NULL ) { - __glXExtensionsCtr(); - set_glx_extension( name, strlen( name ), GL_FALSE, direct_support ); - } + __glXExtensionsCtr(); + __glXExtensionsCtrScreen(psc); + set_glx_extension( name, strlen( name ), GL_FALSE, psc->direct_support ); } /** * Add an extension to the global list of known GLX extensions. * - * \param enabled Default state of the extension. - * \param name Text name of the extension. - * \param version_major Major GLX version that requires this extension. - * \param version_minor Minor GLX version that requires this extension. - * \param bit Bit number in the global table that is set if this - * extension is enabled. - * \param client_only_flag Is this extension client-side only? + * \param name Text name of the extension. + * \param version_major Major GLX version that requires this extension. + * \param version_minor Minor GLX version that requires this extension. + * \param bit Bit number in the global table that is set if + * this extension is enabled. + * \param client_enabled_flag Client-side support in libGL present? + * \param direct_enabled_flag Direct-rendering support in DRI driver present? + * \param client_only_flag Is this extension client-side only? + * \param direct_only_flag Is this extension direct-rendering only? */ static void add_extension( const char * name, GLuint version_major, GLuint version_minor, @@ -312,39 +312,9 @@ } - - /** - * Add a new extension string to the set of possible strings. This is - * intended to be used by drivers to advertise support for unlisted, - * proprietary extensions. - * - * \param enabled Is the extension enabled by default? - * \param name Name of the extension. - * \param client_only Is the extension client-side only? + * Make sure that global extension support tables are initialized. */ -void -__glXAddExtension( GLboolean enabled, const char * name, - GLboolean client_only ) -{ - if ( __glXGLXClientExtensions == NULL ) { - GLuint bit; - - __glXExtensionsCtr(); - - bit = next_bit; - if ( next_bit < 255 ) { - next_bit++; - } - - add_extension( name, 0, 0, bit, enabled, enabled, - client_only, GL_TRUE ); - } -} - - - - static void __glXExtensionsCtr( void ) { @@ -370,26 +340,41 @@ default_glx_extensions[i].direct_support, default_glx_extensions[i].client_only, default_glx_extensions[i].direct_only ); - if ( default_glx_extensions[i].bit >= next_bit ) { - next_bit = default_glx_extensions[i].bit + 1; - } } } } +/** + * Make sure that per-screen direct-support table is initialized. + * + * \param psc Pointer to GLX per-screen record. + */ +static void +__glXExtensionsCtrScreen( __GLXscreenConfigs *psc ) +{ + if (psc->ext_list_first_time) { + psc->ext_list_first_time = GL_FALSE; + (void) memcpy( psc->direct_support, direct_support, sizeof( direct_support ) ); + } +} +/** + * Check if a certain extension is enabled on a given screen. + * + * \param psc Pointer to GLX per-screen record. + * \param bit Bit index in the direct-support table. + */ GLboolean -__glXExtensionBitIsEnabled( unsigned bit ) +__glXExtensionBitIsEnabled( __GLXscreenConfigs *psc, unsigned bit ) { __glXExtensionsCtr(); - return EXT_ENABLED( bit, direct_support ); + __glXExtensionsCtrScreen( psc ); + return EXT_ENABLED( bit, psc->direct_support ); } - - /** * Convert a bit-field to a string of supported extensions. */ @@ -448,16 +433,19 @@ /** * Get the list of application usable extensions. * - * \returns A pointer to the string. + * \param psc Pointer to GLX per-screen record. + * \param server_string Extension string describing server-side support. + * \returns A pointer to the string of usable extensions. */ char * -__glXGetUsableExtensions( const char * server_string ) +__glXGetUsableExtensions( __GLXscreenConfigs *psc, const char * server_string ) { unsigned char server_support[8]; unsigned char usable[8]; unsigned i; __glXExtensionsCtr(); + __glXExtensionsCtrScreen( psc ); __glXProcessServerString( server_string, server_support ); /* An extension is supported if the client-side (i.e., libGL) supports @@ -467,8 +455,8 @@ */ for ( i = 0 ; i < 8 ; i++ ) { usable[i] = (client_support[i] & client_only[i]) - | (client_support[i] & (direct_support[i] & server_support[i])) - | (client_support[i] & (direct_support[i] & direct_only[i])); + | (client_support[i] & psc->direct_support[i] & server_support[i]) + | (client_support[i] & psc->direct_support[i] & direct_only[i]); } return __glXGetStringFromTable( usable ); Index: glx/glxextensions.h =================================================================== RCS file: /cvsroot/dri/xc/xc/lib/GL/glx/glxextensions.h,v retrieving revision 1.2 diff -u -r1.2 glxextensions.h --- glx/glxextensions.h 30 Apr 2003 01:50:35 -0000 1.2 +++ glx/glxextensions.h 14 Aug 2003 16:32:43 -0000 @@ -69,15 +69,19 @@ SUN_get_transparent_index_bit }; -extern GLboolean __glXExtensionBitIsEnabled( unsigned bit ); +extern GLboolean __glXExtensionBitIsEnabled( __GLXscreenConfigs *psc, unsigned bit ); extern const char * __glXGetClientExtensions( void ); -extern char * __glXGetUsableExtensions( const char * server_string ); -extern void __glXAddExtension( GLboolean enabled, const char * name, - GLboolean client_side ); -extern void __glXEnableExtension( const char * name, GLboolean force_client ); -extern void __glXDisableExtension( const char * name ); +extern char * __glXGetUsableExtensions( __GLXscreenConfigs *psc, const char * server_string ); +extern void __glXScrEnableExtension( __GLXscreenConfigs *psc, const char * name ); +extern void __glXScrDisableExtension( __GLXscreenConfigs *psc, const char * name ); -typedef void (* PFNGLXADDEXTENSIONPROC) ( GLboolean enabled, const char * name ); +/* The void pointers here are because __GLXscreenConfigs is opaque for + * DRI drivers. */ +typedef void (* PFNGLXSCRENABLEEXTENSIONPROC) ( void *psc, const char * name ); +typedef void (* PFNGLXSCRDISABLEEXTENSIONPROC) ( void *psc, const char * name ); + +/* Source-level backwards compatibility with old drivers. They won't + * find the respective functions, though. */ typedef void (* PFNGLXENABLEEXTENSIONPROC) ( const char * name, GLboolean force_client ); typedef void (* PFNGLXDISABLEEXTENSIONPROC) ( const char * name );