From: Ian Romanick Date: Thu, 27 May 2004 22:31:06 +0000 (+0000) Subject: Move dri_util.[ch] and glcontextmodes.[ch] from dri_client to common. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=b3981ab6e6762b4205ca5302d93be129f648a9cf;p=mesa.git Move dri_util.[ch] and glcontextmodes.[ch] from dri_client to common. --- diff --git a/src/mesa/drivers/dri/common/dri_util.c b/src/mesa/drivers/dri/common/dri_util.c new file mode 100644 index 00000000000..03d92c02f2e --- /dev/null +++ b/src/mesa/drivers/dri/common/dri_util.c @@ -0,0 +1,1654 @@ +/* $XFree86: xc/lib/GL/dri/dri_util.c,v 1.7 2003/04/28 17:01:25 dawes Exp $ */ +/** + * \file dri_util.c + * DRI utility functions. + * + * This module acts as glue between GLX and the actual hardware driver. A DRI + * driver doesn't really \e have to use any of this - it's optional. But, some + * useful stuff is done here that otherwise would have to be duplicated in most + * drivers. + * + * Basically, these utility functions take care of some of the dirty details of + * screen initialization, context creation, context binding, DRM setup, etc. + * + * These functions are compiled into each DRI driver so libGL.so knows nothing + * about them. + * + * \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. + */ + + +#ifdef GLX_DIRECT_RENDERING + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "dri_util.h" +#include "xf86dri.h" +#include "sarea.h" +#include "glcontextmodes.h" + +/*#define DRI_NEW_INTERFACE_ONLY*/ + +/** + * 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. + */ +static int api_ver = 0; + +/* forward declarations */ +static int driQueryFrameTracking( Display * dpy, void * priv, + int64_t * sbc, int64_t * missedFrames, float * lastMissedUsage, + float * usage ); + +static void *driCreateNewDrawable(Display *dpy, const __GLcontextModes *modes, + GLXDrawable draw, __DRIdrawable *pdraw, int renderType, const int *attrs); + +static void driDestroyDrawable(Display *dpy, void *drawablePrivate); + + + + +#ifdef not_defined +static Bool driFeatureOn(const char *name) +{ + char *env = getenv(name); + + if (!env) return GL_FALSE; + if (!strcasecmp(env, "enable")) return GL_TRUE; + if (!strcasecmp(env, "1")) return GL_TRUE; + if (!strcasecmp(env, "on")) return GL_TRUE; + if (!strcasecmp(env, "true")) return GL_TRUE; + if (!strcasecmp(env, "t")) return GL_TRUE; + if (!strcasecmp(env, "yes")) return GL_TRUE; + if (!strcasecmp(env, "y")) return GL_TRUE; + + return GL_FALSE; +} +#endif /* not_defined */ + + +/** + * Print message to \c stderr if the \c LIBGL_DEBUG environment variable + * is set. + * + * Is called from the drivers. + * + * \param f \c printf like format string. + */ +void +__driUtilMessage(const char *f, ...) +{ + va_list args; + + if (getenv("LIBGL_DEBUG")) { + fprintf(stderr, "libGL error: \n"); + va_start(args, f); + vfprintf(stderr, f, args); + va_end(args); + fprintf(stderr, "\n"); + } +} + + +/*****************************************************************/ +/** \name Visual utility functions */ +/*****************************************************************/ +/*@{*/ + +#ifndef DRI_NEW_INTERFACE_ONLY +/** + * Find a \c __GLcontextModes structure matching the given visual ID. + * + * \param dpy Display to search for a matching configuration. + * \param scrn Screen number on \c dpy to be searched. + * \param vid Desired \c VisualID to find. + * + * \returns A pointer to a \c __GLcontextModes structure that matches \c vid, + * if found, or \c NULL if no match is found. + */ +static const __GLcontextModes * +findConfigMode(Display *dpy, int scrn, VisualID vid, + const __DRIscreen * pDRIScreen) +{ + if ( (pDRIScreen != NULL) && (pDRIScreen->private != NULL) ) { + const __DRIscreenPrivate * const psp = + (const __DRIscreenPrivate *) pDRIScreen->private; + + return _gl_context_modes_find_visual( psp->modes, vid ); + } + + 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 */ + +/*@}*/ + + +/*****************************************************************/ +/** \name Drawable list management */ +/*****************************************************************/ +/*@{*/ + +static Bool __driAddDrawable(void *drawHash, __DRIdrawable *pdraw) +{ + __DRIdrawablePrivate *pdp = (__DRIdrawablePrivate *)pdraw->private; + + if (drmHashInsert(drawHash, pdp->draw, pdraw)) + return GL_FALSE; + + return GL_TRUE; +} + +static __DRIdrawable *__driFindDrawable(void *drawHash, GLXDrawable draw) +{ + int retcode; + __DRIdrawable *pdraw; + + retcode = drmHashLookup(drawHash, draw, (void **)&pdraw); + if (retcode) + return NULL; + + return pdraw; +} + +static void __driRemoveDrawable(void *drawHash, __DRIdrawable *pdraw) +{ + int retcode; + __DRIdrawablePrivate *pdp = (__DRIdrawablePrivate *)pdraw->private; + + retcode = drmHashLookup(drawHash, pdp->draw, (void **)&pdraw); + if (!retcode) { /* Found */ + drmHashDelete(drawHash, pdp->draw); + } +} + +#ifndef DRI_NEW_INTERFACE_ONLY +static Bool __driWindowExistsFlag; + +static int __driWindowExistsErrorHandler(Display *dpy, XErrorEvent *xerr) +{ + if (xerr->error_code == BadWindow) { + __driWindowExistsFlag = GL_FALSE; + } + 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; + int (*oldXErrorHandler)(Display *, XErrorEvent *); + + XSync(dpy, GL_FALSE); + __driWindowExistsFlag = GL_TRUE; + oldXErrorHandler = XSetErrorHandler(__driWindowExistsErrorHandler); + XGetWindowAttributes(dpy, draw, &xwa); /* dummy request */ + XSetErrorHandler(oldXErrorHandler); + return __driWindowExistsFlag; +} +#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; + __DRIdrawable *pdraw; + Display *dpy; + + if (drmHashFirst(drawHash, &draw, (void **)&pdraw)) { + do { + __DRIdrawablePrivate *pdp = (__DRIdrawablePrivate *)pdraw->private; + dpy = pdp->driScreenPriv->display; + if (! (*window_exists)(dpy, draw)) { + /* Destroy the local drawable data in the hash table, if the + drawable no longer exists in the Xserver */ + __driRemoveDrawable(drawHash, pdraw); + (*pdraw->destroyDrawable)(dpy, pdraw->private); + Xfree(pdraw); + } + } while (drmHashNext(drawHash, &draw, (void **)&pdraw)); + } +} + +/*@}*/ + + +/*****************************************************************/ +/** \name Context (un)binding functions */ +/*****************************************************************/ +/*@{*/ + +/** + * Unbind context. + * + * \param dpy the display handle. + * \param scrn the screen number. + * \param draw drawable. + * \param read Current reading drawable. + * \param gc context. + * + * \return \c GL_TRUE on success, or \c GL_FALSE on failure. + * + * \internal + * This function calls __DriverAPIRec::UnbindContext, and then decrements + * __DRIdrawablePrivateRec::refcount which must be non-zero for a successful + * return. + * + * While casting the opaque private pointers associated with the parameters + * into their respective real types it also assures they are not \c NULL. + */ +static Bool driUnbindContext3(Display *dpy, int scrn, + GLXDrawable draw, GLXDrawable read, + __DRIcontext *ctx) +{ + __DRIscreen *pDRIScreen; + __DRIdrawable *pdraw; + __DRIdrawable *pread; + __DRIcontextPrivate *pcp; + __DRIscreenPrivate *psp; + __DRIdrawablePrivate *pdp; + __DRIdrawablePrivate *prp; + + /* + ** Assume error checking is done properly in glXMakeCurrent before + ** calling driUnbindContext3. + */ + + if (ctx == NULL || draw == None || read == None) { + /* ERROR!!! */ + return GL_FALSE; + } + + pDRIScreen = __glXFindDRIScreen(dpy, scrn); + if ( (pDRIScreen == NULL) || (pDRIScreen->private == NULL) ) { + /* ERROR!!! */ + return GL_FALSE; + } + + psp = (__DRIscreenPrivate *)pDRIScreen->private; + pcp = (__DRIcontextPrivate *)ctx->private; + + pdraw = __driFindDrawable(psp->drawHash, draw); + if (!pdraw) { + /* ERROR!!! */ + return GL_FALSE; + } + pdp = (__DRIdrawablePrivate *)pdraw->private; + + pread = __driFindDrawable(psp->drawHash, read); + if (!pread) { + /* ERROR!!! */ + return GL_FALSE; + } + prp = (__DRIdrawablePrivate *)pread->private; + + + /* Let driver unbind drawable from context */ + (*psp->DriverAPI.UnbindContext)(pcp); + + + if (pdp->refcount == 0) { + /* ERROR!!! */ + return GL_FALSE; + } + + pdp->refcount--; + + if (prp != pdp) { + if (prp->refcount == 0) { + /* ERROR!!! */ + return GL_FALSE; + } + + prp->refcount--; + } + + + /* XXX this is disabled so that if we call SwapBuffers on an unbound + * window we can determine the last context bound to the window and + * use that context's lock. (BrianP, 2-Dec-2000) + */ +#if 0 + /* Unbind the drawable */ + pcp->driDrawablePriv = NULL; + pdp->driContextPriv = &psp->dummyContextPriv; +#endif + + return GL_TRUE; +} + + +/** + * This function takes both a read buffer and a draw buffer. This is needed + * for \c glXMakeCurrentReadSGI or GLX 1.3's \c glXMakeContextCurrent + * function. + * + * \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 DoBindContext(Display *dpy, + GLXDrawable draw, GLXDrawable read, + __DRIcontext *ctx, const __GLcontextModes * modes, + __DRIscreenPrivate *psp) +{ + __DRIdrawable *pdraw; + __DRIdrawablePrivate *pdp; + __DRIdrawable *pread; + __DRIdrawablePrivate *prp; + __DRIcontextPrivate * const pcp = ctx->private; + + + /* Find the _DRIdrawable which corresponds to the writing GLXDrawable */ + pdraw = __driFindDrawable(psp->drawHash, draw); + if (!pdraw) { + /* Allocate a new drawable */ + pdraw = (__DRIdrawable *)Xmalloc(sizeof(__DRIdrawable)); + if (!pdraw) { + /* ERROR!!! */ + return GL_FALSE; + } + + /* Create a new drawable */ + driCreateNewDrawable(dpy, modes, draw, pdraw, GLX_WINDOW_BIT, + empty_attribute_list); + if (!pdraw->private) { + /* ERROR!!! */ + Xfree(pdraw); + return GL_FALSE; + } + + } + pdp = (__DRIdrawablePrivate *) pdraw->private; + + /* Find the _DRIdrawable which corresponds to the reading GLXDrawable */ + if (read == draw) { + /* read buffer == draw buffer */ + prp = pdp; + } + else { + pread = __driFindDrawable(psp->drawHash, read); + if (!pread) { + /* Allocate a new drawable */ + pread = (__DRIdrawable *)Xmalloc(sizeof(__DRIdrawable)); + if (!pread) { + /* ERROR!!! */ + return GL_FALSE; + } + + /* Create a new drawable */ + driCreateNewDrawable(dpy, modes, read, pread, GLX_WINDOW_BIT, + empty_attribute_list); + if (!pread->private) { + /* ERROR!!! */ + Xfree(pread); + return GL_FALSE; + } + } + prp = (__DRIdrawablePrivate *) pread->private; + } + + /* Bind the drawable to the context */ + pcp->driDrawablePriv = pdp; + pdp->driContextPriv = pcp; + pdp->refcount++; + if ( pdp != prp ) { + prp->refcount++; + } + + /* + ** Now that we have a context associated with this drawable, we can + ** initialize the drawable information if has not been done before. + */ + if (!pdp->pStamp || *pdp->pStamp != pdp->lastStamp) { + DRM_SPINLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID); + __driUtilUpdateDrawableInfo(pdp); + DRM_SPINUNLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID); + } + + /* Call device-specific MakeCurrent */ + (*psp->DriverAPI.MakeCurrent)(pcp, pdp, prp); + + return GL_TRUE; +} + + +/** + * This function takes both a read buffer and a draw buffer. This is needed + * for \c glXMakeCurrentReadSGI or GLX 1.3's \c glXMakeContextCurrent + * function. + */ +static Bool driBindContext3(Display *dpy, int scrn, + GLXDrawable draw, GLXDrawable read, + __DRIcontext * ctx) +{ + __DRIscreen *pDRIScreen; + + /* + ** Assume error checking is done properly in glXMakeCurrent before + ** calling driBindContext. + */ + + if (ctx == NULL || draw == None || read == None) { + /* ERROR!!! */ + return GL_FALSE; + } + + pDRIScreen = __glXFindDRIScreen(dpy, scrn); + if ( (pDRIScreen == NULL) || (pDRIScreen->private == NULL) ) { + /* ERROR!!! */ + return GL_FALSE; + } + + return DoBindContext( dpy, draw, read, ctx, ctx->mode, + (__DRIscreenPrivate *)pDRIScreen->private ); +} + + +#ifndef DRI_NEW_INTERFACE_ONLY +/** + * This function takes both a read buffer and a draw buffer. This is needed + * for \c glXMakeCurrentReadSGI or GLX 1.3's \c glXMakeContextCurrent + * function. + */ +static Bool driBindContext2(Display *dpy, int scrn, + GLXDrawable draw, GLXDrawable read, + GLXContext gc) +{ + __DRIscreen *pDRIScreen; + const __GLcontextModes *modes; + + /* + ** Assume error checking is done properly in glXMakeCurrent before + ** calling driBindContext. + */ + + if (gc == NULL || draw == None || read == None) { + /* ERROR!!! */ + return GL_FALSE; + } + + pDRIScreen = __glXFindDRIScreen(dpy, scrn); + modes = (driCompareGLXAPIVersion( 20040317 ) >= 0) + ? gc->driContext.mode + : 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) ); + + return DoBindContext( dpy, draw, read, & gc->driContext, modes, + (__DRIscreenPrivate *)pDRIScreen->private ); +} + +static Bool driUnbindContext2(Display *dpy, int scrn, + GLXDrawable draw, GLXDrawable read, + GLXContext gc) +{ + return driUnbindContext3(dpy, scrn, draw, read, & gc->driContext); +} + +/* + * Simply call bind with the same GLXDrawable for the read and draw buffers. + */ +static Bool driBindContext(Display *dpy, int scrn, + GLXDrawable draw, GLXContext gc) +{ + return driBindContext2(dpy, scrn, draw, draw, gc); +} + + +/* + * Simply call bind with the same GLXDrawable for the read and draw buffers. + */ +static Bool driUnbindContext(Display *dpy, int scrn, + GLXDrawable draw, GLXContext gc, + int will_rebind) +{ + (void) will_rebind; + return driUnbindContext2( dpy, scrn, draw, draw, gc ); +} +#endif /* DRI_NEW_INTERFACE_ONLY */ + +/*@}*/ + + +/*****************************************************************/ +/** \name Drawable handling functions */ +/*****************************************************************/ +/*@{*/ + +/** + * Update private drawable information. + * + * \param pdp pointer to the private drawable information to update. + * + * This function basically updates the __DRIdrawablePrivate struct's + * 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 + * info. + */ +void +__driUtilUpdateDrawableInfo(__DRIdrawablePrivate *pdp) +{ + __DRIscreenPrivate *psp; + __DRIcontextPrivate *pcp = pdp->driContextPriv; + + if (!pcp || (pdp != pcp->driDrawablePriv)) { + /* ERROR!!! */ + return; + } + + psp = pdp->driScreenPriv; + if (!psp) { + /* ERROR!!! */ + return; + } + + if (pdp->pClipRects) { + Xfree(pdp->pClipRects); + } + + if (pdp->pBackClipRects) { + Xfree(pdp->pBackClipRects); + } + + DRM_SPINUNLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID); + + if (!__driFindDrawable(psp->drawHash, pdp->draw) || + ! (*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. + */ + pdp->pStamp = &pdp->lastStamp; /* prevent endless loop */ + pdp->numClipRects = 0; + pdp->pClipRects = NULL; + pdp->numBackClipRects = 0; + pdp->pBackClipRects = NULL; + } + else + pdp->pStamp = &(psp->pSAREA->drawableTable[pdp->index].stamp); + + DRM_SPINLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID); + +} + +/*@}*/ + +/*****************************************************************/ +/** \name GLX callbacks */ +/*****************************************************************/ +/*@{*/ + +/** + * Swap buffers. + * + * \param dpy the display handle. + * \param drawablePrivate opaque pointer to the per-drawable private info. + * + * \internal + * This function calls __DRIdrawablePrivate::swapBuffers. + * + * Is called directly from glXSwapBuffers(). + */ +static void driSwapBuffers( Display *dpy, void *drawablePrivate ) +{ + __DRIdrawablePrivate *dPriv = (__DRIdrawablePrivate *) drawablePrivate; + dPriv->swapBuffers(dPriv); + (void) dpy; +} + +/** + * Called directly from a number of higher-level GLX functions. + */ +static int driGetMSC( void *screenPrivate, int64_t *msc ) +{ + __DRIscreenPrivate *sPriv = (__DRIscreenPrivate *) screenPrivate; + + return sPriv->DriverAPI.GetMSC( sPriv, msc ); +} + +/** + * Called directly from a number of higher-level GLX functions. + */ +static int driGetSBC( Display *dpy, void *drawablePrivate, int64_t *sbc ) +{ + __DRIdrawablePrivate *dPriv = (__DRIdrawablePrivate *) drawablePrivate; + __DRIswapInfo sInfo; + int status; + + + status = dPriv->driScreenPriv->DriverAPI.GetSwapInfo( dPriv, & sInfo ); + *sbc = sInfo.swap_count; + + return status; +} + +static int driWaitForSBC( Display * dpy, void *drawablePriv, + int64_t target_sbc, + int64_t * msc, int64_t * sbc ) +{ + __DRIdrawablePrivate *dPriv = (__DRIdrawablePrivate *) drawablePriv; + + return dPriv->driScreenPriv->DriverAPI.WaitForSBC( dPriv, target_sbc, + msc, sbc ); +} + +static int driWaitForMSC( Display * dpy, void *drawablePriv, + int64_t target_msc, + int64_t divisor, int64_t remainder, + int64_t * msc, int64_t * sbc ) +{ + __DRIdrawablePrivate *dPriv = (__DRIdrawablePrivate *) drawablePriv; + __DRIswapInfo sInfo; + int status; + + + status = dPriv->driScreenPriv->DriverAPI.WaitForMSC( dPriv, target_msc, + divisor, remainder, + msc ); + + /* GetSwapInfo() may not be provided by the driver if GLX_SGI_video_sync + * is supported but GLX_OML_sync_control is not. Therefore, don't return + * an error value if GetSwapInfo() is not implemented. + */ + if ( status == 0 + && dPriv->driScreenPriv->DriverAPI.GetSwapInfo ) { + status = dPriv->driScreenPriv->DriverAPI.GetSwapInfo( dPriv, & sInfo ); + *sbc = sInfo.swap_count; + } + + return status; +} + +static int64_t driSwapBuffersMSC( Display * dpy, void *drawablePriv, + int64_t target_msc, + int64_t divisor, int64_t remainder ) +{ + __DRIdrawablePrivate *dPriv = (__DRIdrawablePrivate *) drawablePriv; + + return dPriv->driScreenPriv->DriverAPI.SwapBuffersMSC( dPriv, target_msc, + divisor, + remainder ); +} + + +/** + * This is called via __DRIscreenRec's createNewDrawable pointer. + */ +static void *driCreateNewDrawable(Display *dpy, + const __GLcontextModes *modes, + GLXDrawable draw, + __DRIdrawable *pdraw, + int renderType, + const int *attrs) +{ + __DRIscreen * const pDRIScreen = __glXFindDRIScreen(dpy, modes->screen); + __DRIscreenPrivate *psp; + __DRIdrawablePrivate *pdp; + + + /* Since pbuffers are not yet supported, no drawable attributes are + * supported either. + */ + (void) attrs; + + if ( (pDRIScreen == NULL) || (pDRIScreen->private == NULL) ) { + return NULL; + } + + pdp = (__DRIdrawablePrivate *)Xmalloc(sizeof(__DRIdrawablePrivate)); + if (!pdp) { + return NULL; + } + + if (!XF86DRICreateDrawable(dpy, modes->screen, draw, &pdp->hHWDrawable)) { + Xfree(pdp); + return NULL; + } + + pdp->draw = draw; + pdp->pdraw = pdraw; + pdp->refcount = 0; + pdp->pStamp = NULL; + pdp->lastStamp = 0; + pdp->index = 0; + pdp->x = 0; + pdp->y = 0; + pdp->w = 0; + pdp->h = 0; + pdp->numClipRects = 0; + pdp->numBackClipRects = 0; + pdp->pClipRects = NULL; + pdp->pBackClipRects = NULL; + pdp->display = dpy; + pdp->screen = modes->screen; + + 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); + Xfree(pdp); + return NULL; + } + + pdraw->private = pdp; + pdraw->destroyDrawable = driDestroyDrawable; + pdraw->swapBuffers = driSwapBuffers; /* called by glXSwapBuffers() */ + + if ( driCompareGLXAPIVersion( 20030317 ) >= 0 ) { + pdraw->getSBC = driGetSBC; + pdraw->waitForSBC = driWaitForSBC; + pdraw->waitForMSC = driWaitForMSC; + pdraw->swapBuffersMSC = driSwapBuffersMSC; + pdraw->frameTracking = NULL; + pdraw->queryFrameTracking = driQueryFrameTracking; + + /* This special default value is replaced with the configured + * default value when the drawable is first bound to a direct + * rendering context. */ + pdraw->swap_interval = (unsigned)-1; + } + + pdp->swapBuffers = psp->DriverAPI.SwapBuffers; + + /* 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, + void *screenPrivate) +{ + __DRIscreenPrivate *psp = (__DRIscreenPrivate *) screenPrivate; + + /* + ** Make sure this routine returns NULL if the drawable is not bound + ** to a direct rendering context! + */ + return __driFindDrawable(psp->drawHash, draw); +} + +static void driDestroyDrawable(Display *dpy, void *drawablePrivate) +{ + __DRIdrawablePrivate *pdp = (__DRIdrawablePrivate *) drawablePrivate; + __DRIscreenPrivate *psp = pdp->driScreenPriv; + int scrn = psp->myNum; + + if (pdp) { + (*psp->DriverAPI.DestroyBuffer)(pdp); + if ((*window_exists)(dpy, pdp->draw)) + (void)XF86DRIDestroyDrawable(dpy, scrn, pdp->draw); + if (pdp->pClipRects) { + Xfree(pdp->pClipRects); + pdp->pClipRects = NULL; + } + if (pdp->pBackClipRects) { + Xfree(pdp->pBackClipRects); + pdp->pBackClipRects = NULL; + } + Xfree(pdp); + } +} + +/*@}*/ + + +/*****************************************************************/ +/** \name Context handling functions */ +/*****************************************************************/ +/*@{*/ + +/** + * Destroy the per-context private information. + * + * \param dpy the display handle. + * \param scrn the screen number. + * \param contextPrivate opaque pointer to the per-drawable private info. + * + * \internal + * This function calls __DriverAPIRec::DestroyContext on \p contextPrivate, calls + * drmDestroyContext(), and finally frees \p contextPrivate. + */ +static void driDestroyContext(Display *dpy, int scrn, void *contextPrivate) +{ + __DRIcontextPrivate *pcp = (__DRIcontextPrivate *) contextPrivate; + + if (pcp) { + (*pcp->driScreenPriv->DriverAPI.DestroyContext)(pcp); + __driGarbageCollectDrawables(pcp->driScreenPriv->drawHash); + (void)XF86DRIDestroyContext(dpy, scrn, pcp->contextID); + Xfree(pcp); + } +} + + +/** + * Create the per-drawable private driver information. + * + * \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 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 + * performs some device independent initialization and passes all the + * relevent information to __DriverAPIRec::CreateContext to create the + * context. + * + */ +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; + void * const shareCtx = (pshare != NULL) ? pshare->driverPrivate : NULL; + + pDRIScreen = __glXFindDRIScreen(dpy, modes->screen); + if ( (pDRIScreen == NULL) || (pDRIScreen->private == NULL) ) { + /* ERROR!!! */ + return NULL; + } + + psp = (__DRIscreenPrivate *)pDRIScreen->private; + + pcp = (__DRIcontextPrivate *)Xmalloc(sizeof(__DRIcontextPrivate)); + if (!pcp) { + return NULL; + } + + if (! (*create_context_with_config)(dpy, modes->screen, modes->fbconfigID, + &pcp->contextID, &pcp->hHWContext)) { + Xfree(pcp); + return NULL; + } + + pcp->display = dpy; + pcp->driScreenPriv = psp; + pcp->driDrawablePriv = NULL; + + /* When the first context is created for a screen, initialize a "dummy" + * context. + */ + + if (!psp->dummyContextPriv.driScreenPriv) { + psp->dummyContextPriv.contextID = 0; + psp->dummyContextPriv.hHWContext = psp->pSAREA->dummy_context; + psp->dummyContextPriv.driScreenPriv = psp; + psp->dummyContextPriv.driDrawablePriv = NULL; + psp->dummyContextPriv.driverPrivate = NULL; + /* No other fields should be used! */ + } + + pctx->destroyContext = driDestroyContext; +#ifdef DRI_NEW_INTERFACE_ONLY + pctx->bindContext = NULL; + pctx->unbindContext = NULL; + pctx->bindContext2 = NULL; + pctx->unbindContext2 = NULL; + pctx->bindContex3 = driBindContext3; + pctx->unbindContext3 = driUnbindContext3; +#else + pctx->bindContext = driBindContext; + pctx->unbindContext = driUnbindContext; + if ( driCompareGLXAPIVersion( 20030606 ) >= 0 ) { + pctx->bindContext2 = driBindContext2; + pctx->unbindContext2 = driUnbindContext2; + } + + if ( driCompareGLXAPIVersion( 20040415 ) >= 0 ) { + pctx->bindContext3 = driBindContext3; + pctx->unbindContext3 = driUnbindContext3; + } +#endif + + 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 */ + +/*@}*/ + + +/*****************************************************************/ +/** \name Screen handling functions */ +/*****************************************************************/ +/*@{*/ + +/** + * Destroy the per-screen private information. + * + * \param dpy the display handle. + * \param scrn the screen number. + * \param screenPrivate opaque pointer to the per-screen private information. + * + * \internal + * This function calls __DriverAPIRec::DestroyScreen on \p screenPrivate, calls + * drmClose(), and finally frees \p screenPrivate. + */ +static void driDestroyScreen(Display *dpy, int scrn, void *screenPrivate) +{ + __DRIscreenPrivate *psp = (__DRIscreenPrivate *) screenPrivate; + + if (psp) { + /* No interaction with the X-server is possible at this point. This + * routine is called after XCloseDisplay, so there is no protocol + * stream open to the X-server anymore. + */ + + if (psp->DriverAPI.DestroyScreen) + (*psp->DriverAPI.DestroyScreen)(psp); + + (void)drmUnmap((drmAddress)psp->pSAREA, SAREA_MAX); + (void)drmUnmap((drmAddress)psp->pFB, psp->fbSize); + Xfree(psp->pDevPriv); + (void)drmClose(psp->fd); + 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 * +__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) +{ + __DRIscreenPrivate *psp; + + +#ifdef DRI_NEW_INTERFACE_ONLY + if ( internal_api_version < 20040415 ) { + fprintf( stderr, "libGL error: libGL.so version (%08u) is too old. " + "20040415 or later is required.\n", internal_api_version ); + return NULL; + } +#else + if ( internal_api_version == 20031201 ) { + fprintf( stderr, "libGL error: libGL version 20031201 has critical " + "binary compatilibity bugs.\nlibGL error: You must upgrade " + "to use direct-rendering!\n" ); + return NULL; + } +#endif /* DRI_NEW_INTERFACE_ONLY */ + + + window_exists = (PFNGLXWINDOWEXISTSPROC) + glXGetProcAddress( (const GLubyte *) "__glXWindowExists" ); + + 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", internal_api_version ); + return NULL; +#else + window_exists = (PFNGLXWINDOWEXISTSPROC) __driWindowExists; +#endif /* DRI_NEW_INTERFACE_ONLY */ + } + + 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; + + psp = (__DRIscreenPrivate *)Xmalloc(sizeof(__DRIscreenPrivate)); + if (!psp) { + return NULL; + } + + /* 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; + + psp->drmMajor = drm_version->major; + psp->drmMinor = drm_version->minor; + psp->drmPatch = drm_version->patch; + psp->ddxMajor = ddx_version->major; + psp->ddxMinor = ddx_version->minor; + psp->ddxPatch = ddx_version->patch; + psp->driMajor = dri_version->major; + psp->driMinor = dri_version->minor; + psp->driPatch = dri_version->patch; + + /* install driver's callback functions */ + memcpy( &psp->DriverAPI, driverAPI, sizeof(struct __DriverAPIRec) ); + + psp->pSAREA = pSAREA; + + psp->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; + + psp->fd = fd; + + /* + ** 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; + + psc->destroyScreen = driDestroyScreen; +#ifndef DRI_NEW_INTERFACE_ONLY + psc->createContext = driCreateContext; +#else + psc->createConteext = NULL; +#endif + psc->createNewDrawable = driCreateNewDrawable; + psc->getDrawable = driGetDrawable; +#ifdef DRI_NEW_INTERFACE_ONLY + psc->getMSC = driGetMSC; + psc->createNewContext = driCreateNewContext; +#else + if ( driCompareGLXAPIVersion( 20030317 ) >= 0 ) { + psc->getMSC = driGetMSC; + + if ( driCompareGLXAPIVersion( 20030824 ) >= 0 ) { + psc->createNewContext = driCreateNewContext; + } + } +#endif + + if ( (psp->DriverAPI.InitDriver != NULL) + && !(*psp->DriverAPI.InitDriver)(psp) ) { + Xfree( psp ); + return NULL; + } + + + return psp; +} + + +#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; + } + + + /* Create the linked list of context modes, and populate it with the + * GLX visual information passed in by libGL. + */ + + modes = _gl_context_modes_create( numConfigs, sizeof(__GLcontextModes) ); + if ( modes == NULL ) { + 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; + } + + 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 ); + } + } + } + } + } + } + } + } + } + + 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 ); + } + + (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 /* DRI_NEW_INTERFACE_ONLY */ + + +/** + * Compare the current GLX API version with a driver supplied required version. + * + * The minimum required version is compared with the API version exported by + * the \c __glXGetInternalVersion function (in libGL.so). + * + * \param required_version Minimum required internal GLX API version. + * \return A tri-value return, as from strcmp is returned. A value less + * than, equal to, or greater than zero will be returned if the + * internal GLX API version is less than, equal to, or greater + * than \c required_version. + * + * \sa __glXGetInternalVersion(). + */ +int driCompareGLXAPIVersion( GLuint required_version ) +{ + if ( api_ver > required_version ) { + return 1; + } + else if ( api_ver == required_version ) { + return 0; + } + + return -1; +} + + +static int +driQueryFrameTracking( Display * dpy, void * priv, + int64_t * sbc, int64_t * missedFrames, + float * lastMissedUsage, float * usage ) +{ + static PFNGLXGETUSTPROC get_ust; + __DRIswapInfo sInfo; + int status; + int64_t ust; + __DRIdrawablePrivate * dpriv = (__DRIdrawablePrivate *) priv; + + if ( get_ust == NULL ) { + get_ust = (PFNGLXGETUSTPROC) glXGetProcAddress( (const GLubyte *) "__glXGetUST" ); + } + + status = dpriv->driScreenPriv->DriverAPI.GetSwapInfo( dpriv, & sInfo ); + if ( status == 0 ) { + *sbc = sInfo.swap_count; + *missedFrames = sInfo.swap_missed_count; + *lastMissedUsage = sInfo.swap_missed_usage; + + (*get_ust)( & ust ); + *usage = driCalculateSwapUsage( dpriv, sInfo.swap_ust, ust ); + } + + return status; +} + + +/** + * Calculate amount of swap interval used between GLX buffer swaps. + * + * The usage value, on the range [0,max], is the fraction of total swap + * interval time used between GLX buffer swaps is calculated. + * + * \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 + * 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). + * + * See the documentation for the GLX_MESA_swap_frame_usage extension for more + * details. + * + * \param dPriv Pointer to the private drawable structure. + * \return If less than a single swap interval time period was required + * between GLX buffer swaps, a number greater than 0 and less than + * 1.0 is returned. If exactly one swap interval time period is + * 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 + * + * \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, + int64_t current_ust ) +{ + static PFNGLXGETMSCRATEOMLPROC get_msc_rate = NULL; + int32_t n; + int32_t d; + int interval; + float usage = 1.0; + + + if ( get_msc_rate == NULL ) { + get_msc_rate = (PFNGLXGETMSCRATEOMLPROC) + glXGetProcAddress( (const GLubyte *) "glXGetMscRateOML" ); + } + + if ( (get_msc_rate != NULL) + && get_msc_rate( dPriv->display, dPriv->draw, &n, &d ) ) { + interval = (dPriv->pdraw->swap_interval != 0) + ? dPriv->pdraw->swap_interval : 1; + + + /* We want to calculate + * (current_UST - last_swap_UST) / (interval * us_per_refresh). We get + * current_UST by calling __glXGetUST. last_swap_UST is stored in + * dPriv->swap_ust. interval has already been calculated. + * + * The only tricky part is us_per_refresh. us_per_refresh is + * 1000000 / MSC_rate. We know the MSC_rate is n / d. We can flip it + * around and say us_per_refresh = 1000000 * d / n. Since this goes in + * the denominator of the final calculation, we calculate + * (interval * 1000000 * d) and move n into the numerator. + */ + + usage = (current_ust - last_swap_ust); + usage *= n; + usage /= (interval * d); + usage /= 1000000.0; + } + + return usage; +} + +/*@}*/ + +#endif /* GLX_DIRECT_RENDERING */ diff --git a/src/mesa/drivers/dri/common/dri_util.h b/src/mesa/drivers/dri/common/dri_util.h new file mode 100644 index 00000000000..5c198810f72 --- /dev/null +++ b/src/mesa/drivers/dri/common/dri_util.h @@ -0,0 +1,588 @@ +/* $XFree86: xc/lib/GL/dri/dri_util.h,v 1.1 2002/02/22 21:32:52 dawes Exp $ */ +/** + * \file dri_util.h + * DRI utility functions definitions. + * + * This module acts as glue between GLX and the actual hardware driver. A DRI + * driver doesn't really \e have to use any of this - it's optional. But, some + * useful stuff is done here that otherwise would have to be duplicated in most + * drivers. + * + * Basically, these utility functions take care of some of the dirty details of + * screen initialization, context creation, context binding, DRM setup, etc. + * + * These functions are compiled into each DRI driver so libGL.so knows nothing + * about them. + * + * \sa dri_util.c. + * + * \author Kevin E. Martin + * \author Brian Paul + */ + +/* + * Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + + +#ifndef _DRI_UTIL_H_ +#define _DRI_UTIL_H_ + +#ifdef GLX_DIRECT_RENDERING + +#define CAPI /* XXX this should be globally defined somewhere */ + +#include +#include "glxclient.h" /* for GLXDrawable */ +/* temporary */ +/* typedef Bool ( * PFNGLXGETMSCRATEOMLPROC) (Display *dpy, GLXDrawable drawable, int32_t *numerator, int32_t *denominator); */ +#include "drm.h" /* for drm_clip_rect_t */ +#include "sarea.h" /* for XF86DRISAREAPtr */ +#include "GL/internal/glcore.h" /* for __GLcontextModes */ + + +typedef struct __DRIdisplayPrivateRec __DRIdisplayPrivate; +typedef struct __DRIscreenPrivateRec __DRIscreenPrivate; +typedef struct __DRIcontextPrivateRec __DRIcontextPrivate; +typedef struct __DRIdrawablePrivateRec __DRIdrawablePrivate; +typedef struct __DRIswapInfoRec __DRIswapInfo; + + +/** + * Used by DRI_VALIDATE_DRAWABLE_INFO + */ +#define DRI_VALIDATE_DRAWABLE_INFO_ONCE(pDrawPriv) \ + do { \ + if (*(pDrawPriv->pStamp) != pDrawPriv->lastStamp) { \ + __driUtilUpdateDrawableInfo(pDrawPriv); \ + } \ + } while (0) + + +/** + * Utility macro to validate the drawable information. + * + * See __DRIdrawablePrivate::pStamp and __DRIdrawablePrivate::lastStamp. + */ +#define DRI_VALIDATE_DRAWABLE_INFO(psp, pdp) \ +do { \ + while (*(pdp->pStamp) != pdp->lastStamp) { \ + DRM_UNLOCK(psp->fd, &psp->pSAREA->lock, \ + pdp->driContextPriv->hHWContext); \ + \ + DRM_SPINLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID); \ + DRI_VALIDATE_DRAWABLE_INFO_ONCE(pdp); \ + DRM_SPINUNLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID); \ + \ + DRM_LIGHT_LOCK(psp->fd, &psp->pSAREA->lock, \ + pdp->driContextPriv->hHWContext); \ + } \ +} while (0) + + +/** + * Driver callback functions. + * + * Each DRI driver must have one of these structures with all the pointers set + * to appropriate functions within the driver. + * + * When glXCreateContext() is called, for example, it'll call a helper function + * dri_util.c which in turn will jump through the \a CreateContext pointer in + * this structure. + */ +struct __DriverAPIRec { + /** + * Driver initialization callback + */ + GLboolean (*InitDriver)(__DRIscreenPrivate *driScrnPriv); + + /** + * Screen destruction callback + */ + void (*DestroyScreen)(__DRIscreenPrivate *driScrnPriv); + + /** + * Context creation callback + */ + GLboolean (*CreateContext)(const __GLcontextModes *glVis, + __DRIcontextPrivate *driContextPriv, + void *sharedContextPrivate); + + /** + * Context destruction callback + */ + void (*DestroyContext)(__DRIcontextPrivate *driContextPriv); + + /** + * Buffer (drawable) creation callback + */ + GLboolean (*CreateBuffer)(__DRIscreenPrivate *driScrnPriv, + __DRIdrawablePrivate *driDrawPriv, + const __GLcontextModes *glVis, + GLboolean pixmapBuffer); + + /** + * Buffer (drawable) destruction callback + */ + void (*DestroyBuffer)(__DRIdrawablePrivate *driDrawPriv); + + /** + * Buffer swapping callback + */ + void (*SwapBuffers)(__DRIdrawablePrivate *driDrawPriv); + + /** + * Context activation callback + */ + GLboolean (*MakeCurrent)(__DRIcontextPrivate *driContextPriv, + __DRIdrawablePrivate *driDrawPriv, + __DRIdrawablePrivate *driReadPriv); + + /** + * Context unbinding callback + */ + GLboolean (*UnbindContext)(__DRIcontextPrivate *driContextPriv); + + /** + * 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. + * + * \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. + * + * \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 + * 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 + * supported. + */ + int (*GetMSC)( __DRIscreenPrivate * priv, int64_t * count ); + + /** + * These are required if GLX_OML_sync_control is supported. + */ + /*@{*/ + int (*WaitForMSC)( __DRIdrawablePrivate *priv, int64_t target_msc, + int64_t divisor, int64_t remainder, + int64_t * msc ); + int (*WaitForSBC)( __DRIdrawablePrivate *priv, int64_t target_sbc, + int64_t * msc, int64_t * sbc ); + + int64_t (*SwapBuffersMSC)( __DRIdrawablePrivate *priv, int64_t target_msc, + int64_t divisor, int64_t remainder ); + /*@}*/ +}; + + +struct __DRIswapInfoRec { + /** + * Number of swapBuffers operations that have been *completed*. + */ + 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 + * swap deadline is 1 frame after the previous swap. + */ + 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 + * 0, then 1 is used instead. If swap_missed_count is non-zero, this + * should be greater-than 1.0. + */ + float swap_missed_usage; +}; + + +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, drm_clip_rect_t * pClipRects, + int * backX, int * backY, + int * numBackClipRects, drm_clip_rect_t * pBackClipRects ); + + +/** + * Per-drawable private DRI driver information. + */ +struct __DRIdrawablePrivateRec { + /** + * Kernel drawable handle + */ + drmDrawable hHWDrawable; + + /** + * Driver's private drawable information. + * + * This structure is opaque. + */ + void *driverPrivate; + + /** + * X's drawable ID associated with this private drawable. + */ + GLXDrawable draw; + __DRIdrawable *pdraw; + + /** + * Reference count for number of context's currently bound to this + * drawable. + * + * Once it reaches zero, the drawable can be destroyed. + * + * \note This behavior will change with GLX 1.3. + */ + int refcount; + + /** + * Index of this drawable information in the SAREA. + */ + unsigned int index; + + /** + * Pointer to the "drawable has changed ID" stamp in the SAREA. + */ + unsigned int *pStamp; + + /** + * Last value of the stamp. + * + * If this differs from the value stored at __DRIdrawablePrivate::pStamp, + * then the drawable information has been modified by the X server, and the + * drawable information (below) should be retrieved from the X server. + */ + unsigned int lastStamp; + + /** + * \name Drawable + * + * Drawable information used in software fallbacks. + */ + /*@{*/ + int x; + int y; + int w; + int h; + int numClipRects; + drm_clip_rect_t *pClipRects; + /*@}*/ + + /** + * \name Back and depthbuffer + * + * Information about the back and depthbuffer where different from above. + */ + /*@{*/ + int backX; + int backY; + int backClipRectType; + int numBackClipRects; + drm_clip_rect_t *pBackClipRects; + /*@}*/ + + /** + * Pointer to context to which this drawable is currently bound. + */ + __DRIcontextPrivate *driContextPriv; + + /** + * Pointer to screen on which this drawable was created. + */ + __DRIscreenPrivate *driScreenPriv; + + /** + * \name Display and screen information. + * + * Basically just need these for when the locking code needs to call + * __driUtilUpdateDrawableInfo() which calls XF86DRIGetDrawableInfo(). + */ + /*@{*/ + Display *display; + int screen; + /*@}*/ + + /** + * Called via glXSwapBuffers(). + */ + void (*swapBuffers)( __DRIdrawablePrivate *dPriv ); + + /** + * Get information about the location, size, and clip rects of the + * drawable within the display. + */ + GetDrawableInfo * getInfo; +}; + +/** + * Per-context private driver information. + */ +struct __DRIcontextPrivateRec { + /** + * Kernel context handle used to access the device lock. + */ + XID contextID; + + /** + * Kernel context handle used to access the device lock. + */ + drmContext hHWContext; + + /** + * Device driver's private context data. This structure is opaque. + */ + void *driverPrivate; + + /** + * This context's display pointer. + */ + Display *display; + + /** + * Pointer to drawable currently bound to this context. + */ + __DRIdrawablePrivate *driDrawablePriv; + + /** + * Pointer to screen on which this context was created. + */ + __DRIscreenPrivate *driScreenPriv; +}; + +/** + * Per-screen private driver information. + */ +struct __DRIscreenPrivateRec { + /** + * Display for this screen + */ + Display *display; + + /** + * Current screen's number + */ + int myNum; + + /** + * Callback functions into the hardware-specific DRI driver code. + */ + struct __DriverAPIRec DriverAPI; + + /** + * \name DDX version + * DDX / 2D driver version information. + * \todo Replace these fields with a \c __DRIversionRec. + */ + /*@{*/ + int ddxMajor; + int ddxMinor; + int ddxPatch; + /*@}*/ + + /** + * \name DRI version + * DRI X extension version information. + * \todo Replace these fields with a \c __DRIversionRec. + */ + /*@{*/ + int driMajor; + int driMinor; + int driPatch; + /*@}*/ + + /** + * \name DRM version + * DRM (kernel module) version information. + * \todo Replace these fields with a \c __DRIversionRec. + */ + /*@{*/ + int drmMajor; + int drmMinor; + int drmPatch; + /*@}*/ + + /** + * ID used when the client sets the drawable lock. + * + * The X server uses this value to detect if the client has died while + * holding the drawable lock. + */ + int drawLockID; + + /** + * File descriptor returned when the kernel device driver is opened. + * + * Used to: + * - authenticate client to kernel + * - map the frame buffer, SAREA, etc. + * - close the kernel device driver + */ + int fd; + + /** + * SAREA pointer + * + * Used to access: + * - the device lock + * - the device-independent per-drawable and per-context(?) information + */ + XF86DRISAREAPtr pSAREA; + + /** + * \name Direct frame buffer access information + * Used for software fallbacks. + */ + /*@{*/ + unsigned char *pFB; + int fbSize; + int fbOrigin; + int fbStride; + int fbWidth; + int fbHeight; + int fbBPP; + /*@}*/ + + /** + * \name Device-dependent private information (stored in the SAREA). + * + * This data is accessed by the client driver only. + */ + /*@{*/ + void *pDevPriv; + int devPrivSize; + /*@}*/ + + /** + * Dummy context to which drawables are bound when not bound to any + * other context. + * + * A dummy hHWContext is created for this context, and is used by the GL + * core when a hardware lock is required but the drawable is not currently + * bound (e.g., potentially during a SwapBuffers request). The dummy + * context is created when the first "real" context is created on this + * screen. + */ + __DRIcontextPrivate dummyContextPriv; + + /** + * Hash table to hold the drawable information for this screen. + */ + void *drawHash; + + /** + * Device-dependent private information (not stored in the SAREA). + * + * This pointer is never touched by the DRI layer. + */ + void *private; + + /** + * GLX visuals / FBConfigs for this screen. These are stored as a + * linked list. + * + * \note + * This field is \b only used in conjunction with the old interfaces. If + * the new interfaces are used, this field will be set to \c NULL and will + * not be dereferenced. + */ + __GLcontextModes *modes; + + /** + * Pointer back to the \c __DRIscreen that contains this structure. + */ + + __DRIscreen *psc; +}; + + + +extern void +__driUtilMessage(const char *f, ...); + + +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); + +/* Test the version of the internal GLX API. Returns a value like strcmp. */ +extern int +driCompareGLXAPIVersion( GLuint required_version ); + +extern float +driCalculateSwapUsage( __DRIdrawablePrivate *dPriv, + int64_t last_swap_ust, int64_t current_ust ); + +#endif /* GLX_DIRECT_RENDERING */ + +#endif /* _DRI_UTIL_H_ */ diff --git a/src/mesa/drivers/dri/common/glcontextmodes.c b/src/mesa/drivers/dri/common/glcontextmodes.c new file mode 100644 index 00000000000..784ad30259b --- /dev/null +++ b/src/mesa/drivers/dri/common/glcontextmodes.c @@ -0,0 +1,483 @@ +/* + * (C) Copyright IBM Corporation 2003 + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * on the rights to use, copy, modify, merge, publish, distribute, sub + * license, and/or sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * VA LINUX SYSTEM, IBM AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/** + * \file glcontextmodes.c + * Utility routines for working with \c __GLcontextModes structures. At + * some point most or all of these functions will be moved to the Mesa + * code base. + * + * \author Ian Romanick + */ + +#include +#include +#include "GL/glxint.h" + +#ifdef XFree86Server +# include "GL/glx_ansic.h" +extern void * __glXMalloc( size_t size ); +extern void __glXFree( void * ptr ); +# define Xmalloc __glXMalloc +# define Xfree __glXFree +#else +# include +# define __glXMemset memset +#endif /* XFree86Server */ + +#include "glcontextmodes.h" + +#define NUM_VISUAL_TYPES 6 + +/** + * Convert an X visual type to a GLX visual type. + * + * \param visualType X visual type (i.e., \c TrueColor, \c StaticGray, etc.) + * to be converted. + * \return If \c visualType is a valid X visual type, a GLX visual type will + * be returned. Otherwise \c GLX_NONE will be returned. + */ +GLint +_gl_convert_from_x_visual_type( int visualType ) +{ + static const int glx_visual_types[ NUM_VISUAL_TYPES ] = { + GLX_STATIC_GRAY, GLX_GRAY_SCALE, + GLX_STATIC_COLOR, GLX_PSEUDO_COLOR, + GLX_TRUE_COLOR, GLX_DIRECT_COLOR + }; + + return ( (unsigned) visualType < NUM_VISUAL_TYPES ) + ? glx_visual_types[ visualType ] : GLX_NONE; +} + + +/** + * Convert a GLX visual type to an X visual type. + * + * \param visualType GLX visual type (i.e., \c GLX_TRUE_COLOR, + * \c GLX_STATIC_GRAY, etc.) to be converted. + * \return If \c visualType is a valid GLX visual type, an X visual type will + * be returned. Otherwise -1 will be returned. + */ +GLint +_gl_convert_to_x_visual_type( int visualType ) +{ + static const int x_visual_types[ NUM_VISUAL_TYPES ] = { + TrueColor, DirectColor, + PseudoColor, StaticColor, + GrayScale, StaticGray + }; + + return ( (unsigned) (visualType - GLX_TRUE_COLOR) <= NUM_VISUAL_TYPES ) + ? x_visual_types[ visualType - GLX_TRUE_COLOR ] : -1; +} + + +/** + * Copy a GLX visual config structure to a GL context mode structure. All + * of the fields in \c config are copied to \c mode. Additional fields in + * \c mode that can be derrived from the fields of \c config (i.e., + * \c haveDepthBuffer) are also filled in. The remaining fields in \c mode + * that cannot be derrived are set to default values. + * + * \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, + const __GLXvisualConfig * config ) +{ + __GLcontextModes * const next = mode->next; + + (void) __glXMemset( mode, 0, sizeof( __GLcontextModes ) ); + mode->next = next; + + mode->visualID = config->vid; + mode->visualType = _gl_convert_from_x_visual_type( config->class ); + mode->xRenderable = GL_TRUE; + mode->fbconfigID = config->vid; + mode->drawableType = GLX_WINDOW_BIT | GLX_PIXMAP_BIT; + + mode->rgbMode = (config->rgba != 0); + mode->renderType = (mode->rgbMode) ? GLX_RGBA_BIT : GLX_COLOR_INDEX_BIT; + + mode->colorIndexMode = !(mode->rgbMode); + mode->doubleBufferMode = (config->doubleBuffer != 0); + mode->stereoMode = (config->stereo != 0); + + mode->haveAccumBuffer = ((config->accumRedSize + + config->accumGreenSize + + config->accumBlueSize + + config->accumAlphaSize) > 0); + mode->haveDepthBuffer = (config->depthSize > 0); + mode->haveStencilBuffer = (config->stencilSize > 0); + + mode->redBits = config->redSize; + mode->greenBits = config->greenSize; + mode->blueBits = config->blueSize; + mode->alphaBits = config->alphaSize; + mode->redMask = config->redMask; + mode->greenMask = config->greenMask; + mode->blueMask = config->blueMask; + mode->alphaMask = config->alphaMask; + mode->rgbBits = config->bufferSize; + mode->indexBits = config->bufferSize; + + mode->accumRedBits = config->accumRedSize; + mode->accumGreenBits = config->accumGreenSize; + mode->accumBlueBits = config->accumBlueSize; + mode->accumAlphaBits = config->accumAlphaSize; + mode->depthBits = config->depthSize; + mode->stencilBits = config->stencilSize; + + mode->numAuxBuffers = config->auxBuffers; + mode->level = config->level; + + mode->visualRating = config->visualRating; + mode->transparentPixel = config->transparentPixel; + mode->transparentRed = config->transparentRed; + mode->transparentGreen = config->transparentGreen; + mode->transparentBlue = config->transparentBlue; + mode->transparentAlpha = config->transparentAlpha; + mode->transparentIndex = config->transparentIndex; + + mode->swapMethod = GLX_SWAP_UNDEFINED_OML; +} + + +/** + * Get data from a GL context mode. + * + * \param mode GL context mode whose data is to be returned. + * \param attribute Attribute of \c mode that is to be returned. + * \param value_return Location to store the data member of \c mode. + * \return If \c attribute is a valid attribute of \c mode, \c Success is + * returned. Otherwise \c GLX_BAD_ATTRIBUTE is returned. + */ +int +_gl_get_context_mode_data(const __GLcontextModes *mode, int attribute, + int *value_return) +{ + switch (attribute) { + case GLX_USE_GL: + *value_return = GL_TRUE; + return Success; + case GLX_BUFFER_SIZE: + *value_return = mode->rgbBits; + return Success; + case GLX_RGBA: + *value_return = mode->rgbMode; + return Success; + case GLX_RED_SIZE: + *value_return = mode->redBits; + return Success; + case GLX_GREEN_SIZE: + *value_return = mode->greenBits; + return Success; + case GLX_BLUE_SIZE: + *value_return = mode->blueBits; + return Success; + case GLX_ALPHA_SIZE: + *value_return = mode->alphaBits; + return Success; + case GLX_DOUBLEBUFFER: + *value_return = mode->doubleBufferMode; + return Success; + case GLX_STEREO: + *value_return = mode->stereoMode; + return Success; + case GLX_AUX_BUFFERS: + *value_return = mode->numAuxBuffers; + return Success; + case GLX_DEPTH_SIZE: + *value_return = mode->depthBits; + return Success; + case GLX_STENCIL_SIZE: + *value_return = mode->stencilBits; + return Success; + case GLX_ACCUM_RED_SIZE: + *value_return = mode->accumRedBits; + return Success; + case GLX_ACCUM_GREEN_SIZE: + *value_return = mode->accumGreenBits; + return Success; + case GLX_ACCUM_BLUE_SIZE: + *value_return = mode->accumBlueBits; + return Success; + case GLX_ACCUM_ALPHA_SIZE: + *value_return = mode->accumAlphaBits; + return Success; + case GLX_LEVEL: + *value_return = mode->level; + return Success; + case GLX_TRANSPARENT_TYPE_EXT: + *value_return = mode->transparentPixel; + return Success; + case GLX_TRANSPARENT_RED_VALUE: + *value_return = mode->transparentRed; + return Success; + case GLX_TRANSPARENT_GREEN_VALUE: + *value_return = mode->transparentGreen; + return Success; + case GLX_TRANSPARENT_BLUE_VALUE: + *value_return = mode->transparentBlue; + return Success; + case GLX_TRANSPARENT_ALPHA_VALUE: + *value_return = mode->transparentAlpha; + return Success; + case GLX_TRANSPARENT_INDEX_VALUE: + *value_return = mode->transparentIndex; + return Success; + case GLX_X_VISUAL_TYPE: + *value_return = mode->visualType; + return Success; + case GLX_CONFIG_CAVEAT: + *value_return = mode->visualRating; + return Success; + case GLX_VISUAL_ID: + *value_return = mode->visualID; + return Success; + case GLX_DRAWABLE_TYPE: + *value_return = mode->drawableType; + return Success; + case GLX_RENDER_TYPE: + *value_return = mode->renderType; + return Success; + case GLX_X_RENDERABLE: + *value_return = mode->xRenderable; + return Success; + case GLX_FBCONFIG_ID: + *value_return = mode->fbconfigID; + return Success; + case GLX_MAX_PBUFFER_WIDTH: + *value_return = mode->maxPbufferWidth; + return Success; + case GLX_MAX_PBUFFER_HEIGHT: + *value_return = mode->maxPbufferHeight; + return Success; + case GLX_MAX_PBUFFER_PIXELS: + *value_return = mode->maxPbufferPixels; + return Success; + case GLX_OPTIMAL_PBUFFER_WIDTH_SGIX: + *value_return = mode->optimalPbufferWidth; + return Success; + case GLX_OPTIMAL_PBUFFER_HEIGHT_SGIX: + *value_return = mode->optimalPbufferHeight; + return Success; + case GLX_SWAP_METHOD_OML: + *value_return = mode->swapMethod; + return Success; + case GLX_SAMPLE_BUFFERS_SGIS: + *value_return = mode->sampleBuffers; + return Success; + case GLX_SAMPLES_SGIS: + *value_return = mode->samples; + return Success; + + /* Applications are NOT allowed to query GLX_VISUAL_SELECT_GROUP_SGIX. + * It is ONLY for communication between the GLX client and the GLX + * server. + */ + case GLX_VISUAL_SELECT_GROUP_SGIX: + default: + return GLX_BAD_ATTRIBUTE; + } +} + + +/** + * Allocate a linked list of \c __GLcontextModes structures. The fields of + * each structure will be initialized to "reasonable" default values. In + * most cases this is the default value defined by table 3.4 of the GLX + * 1.3 specification. This means that most values are either initialized to + * zero or \c GLX_DONT_CARE (which is -1). As support for additional + * extensions is added, the new values will be initialized to appropriate + * values from the extension specification. + * + * \param count Number of structures to allocate. + * \param minimum_size Minimum size of a structure to allocate. This allows + * for differences in the version of the + * \c __GLcontextModes stucture used in libGL and in a + * DRI-based driver. + * \returns A pointer to the first element in a linked list of \c count + * stuctures on success, or \c NULL on failure. + * + * \warning Use of \c minimum_size does \b not guarantee binary compatibility. + * The fundamental assumption is that if the \c minimum_size + * specified by the driver and the size of the \c __GLcontextModes + * structure in libGL is the same, then the meaning of each byte in + * the structure is the same in both places. \b Be \b careful! + * Basically this means that fields have to be added in libGL and + * then propagated to drivers. Drivers should \b never arbitrarilly + * extend the \c __GLcontextModes data-structure. + */ +__GLcontextModes * +_gl_context_modes_create( unsigned count, size_t minimum_size ) +{ + const size_t size = (minimum_size > sizeof( __GLcontextModes )) + ? minimum_size : sizeof( __GLcontextModes ); + __GLcontextModes * base = NULL; + __GLcontextModes ** next; + unsigned i; + + next = & base; + for ( i = 0 ; i < count ; i++ ) { + *next = (__GLcontextModes *) Xmalloc( size ); + if ( *next == NULL ) { + _gl_context_modes_destroy( base ); + base = NULL; + break; + } + + (void) __glXMemset( *next, 0, size ); + (*next)->visualID = GLX_DONT_CARE; + (*next)->visualType = GLX_DONT_CARE; + (*next)->visualRating = GLX_NONE; + (*next)->transparentPixel = GLX_NONE; + (*next)->transparentRed = GLX_DONT_CARE; + (*next)->transparentGreen = GLX_DONT_CARE; + (*next)->transparentBlue = GLX_DONT_CARE; + (*next)->transparentAlpha = GLX_DONT_CARE; + (*next)->transparentIndex = GLX_DONT_CARE; + (*next)->xRenderable = GLX_DONT_CARE; + (*next)->fbconfigID = GLX_DONT_CARE; + (*next)->swapMethod = GLX_SWAP_UNDEFINED_OML; + + next = & ((*next)->next); + } + + return base; +} + + +/** + * Destroy a linked list of \c __GLcontextModes structures created by + * \c _gl_context_modes_create. + * + * \param modes Linked list of structures to be destroyed. All structres + * in the list will be freed. + */ +void +_gl_context_modes_destroy( __GLcontextModes * modes ) +{ + while ( modes != NULL ) { + __GLcontextModes * const next = modes->next; + + Xfree( 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) != 0) && + (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/src/mesa/drivers/dri/common/glcontextmodes.h b/src/mesa/drivers/dri/common/glcontextmodes.h new file mode 100644 index 00000000000..5f8fa4f3116 --- /dev/null +++ b/src/mesa/drivers/dri/common/glcontextmodes.h @@ -0,0 +1,49 @@ +/* + * (C) Copyright IBM Corporation 2003 + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * on the rights to use, copy, modify, merge, publish, distribute, sub + * license, and/or sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * VA LINUX SYSTEM, IBM AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/** + * \file glcontextmodes.h + * \author Ian Romanick + */ + +#ifndef GLCONTEXTMODES_H +#define GLCONTEXTMODES_H + +#include "GL/internal/glcore.h" + +extern GLint _gl_convert_from_x_visual_type( int visualType ); +extern GLint _gl_convert_to_x_visual_type( int visualType ); +extern void _gl_copy_visual_to_context_mode( __GLcontextModes * mode, + const __GLXvisualConfig * config ); +extern int _gl_get_context_mode_data( const __GLcontextModes *mode, + int attribute, int *value_return ); +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/src/mesa/drivers/dri/dri_client/Makefile b/src/mesa/drivers/dri/dri_client/Makefile index 48ec3cce4e4..6fcfab7ec9c 100644 --- a/src/mesa/drivers/dri/dri_client/Makefile +++ b/src/mesa/drivers/dri/dri_client/Makefile @@ -8,8 +8,6 @@ include $(TOP)/configs/current DEFINES += -DGLX_DIRECT_RENDERING C_SOURCES = \ - dri_util.c \ - glcontextmodes.c \ xf86drm.c \ xf86drmHash.c \ xf86drmRandom.c \ diff --git a/src/mesa/drivers/dri/dri_client/dri_util.c b/src/mesa/drivers/dri/dri_client/dri_util.c deleted file mode 100644 index 03d92c02f2e..00000000000 --- a/src/mesa/drivers/dri/dri_client/dri_util.c +++ /dev/null @@ -1,1654 +0,0 @@ -/* $XFree86: xc/lib/GL/dri/dri_util.c,v 1.7 2003/04/28 17:01:25 dawes Exp $ */ -/** - * \file dri_util.c - * DRI utility functions. - * - * This module acts as glue between GLX and the actual hardware driver. A DRI - * driver doesn't really \e have to use any of this - it's optional. But, some - * useful stuff is done here that otherwise would have to be duplicated in most - * drivers. - * - * Basically, these utility functions take care of some of the dirty details of - * screen initialization, context creation, context binding, DRM setup, etc. - * - * These functions are compiled into each DRI driver so libGL.so knows nothing - * about them. - * - * \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. - */ - - -#ifdef GLX_DIRECT_RENDERING - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "dri_util.h" -#include "xf86dri.h" -#include "sarea.h" -#include "glcontextmodes.h" - -/*#define DRI_NEW_INTERFACE_ONLY*/ - -/** - * 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. - */ -static int api_ver = 0; - -/* forward declarations */ -static int driQueryFrameTracking( Display * dpy, void * priv, - int64_t * sbc, int64_t * missedFrames, float * lastMissedUsage, - float * usage ); - -static void *driCreateNewDrawable(Display *dpy, const __GLcontextModes *modes, - GLXDrawable draw, __DRIdrawable *pdraw, int renderType, const int *attrs); - -static void driDestroyDrawable(Display *dpy, void *drawablePrivate); - - - - -#ifdef not_defined -static Bool driFeatureOn(const char *name) -{ - char *env = getenv(name); - - if (!env) return GL_FALSE; - if (!strcasecmp(env, "enable")) return GL_TRUE; - if (!strcasecmp(env, "1")) return GL_TRUE; - if (!strcasecmp(env, "on")) return GL_TRUE; - if (!strcasecmp(env, "true")) return GL_TRUE; - if (!strcasecmp(env, "t")) return GL_TRUE; - if (!strcasecmp(env, "yes")) return GL_TRUE; - if (!strcasecmp(env, "y")) return GL_TRUE; - - return GL_FALSE; -} -#endif /* not_defined */ - - -/** - * Print message to \c stderr if the \c LIBGL_DEBUG environment variable - * is set. - * - * Is called from the drivers. - * - * \param f \c printf like format string. - */ -void -__driUtilMessage(const char *f, ...) -{ - va_list args; - - if (getenv("LIBGL_DEBUG")) { - fprintf(stderr, "libGL error: \n"); - va_start(args, f); - vfprintf(stderr, f, args); - va_end(args); - fprintf(stderr, "\n"); - } -} - - -/*****************************************************************/ -/** \name Visual utility functions */ -/*****************************************************************/ -/*@{*/ - -#ifndef DRI_NEW_INTERFACE_ONLY -/** - * Find a \c __GLcontextModes structure matching the given visual ID. - * - * \param dpy Display to search for a matching configuration. - * \param scrn Screen number on \c dpy to be searched. - * \param vid Desired \c VisualID to find. - * - * \returns A pointer to a \c __GLcontextModes structure that matches \c vid, - * if found, or \c NULL if no match is found. - */ -static const __GLcontextModes * -findConfigMode(Display *dpy, int scrn, VisualID vid, - const __DRIscreen * pDRIScreen) -{ - if ( (pDRIScreen != NULL) && (pDRIScreen->private != NULL) ) { - const __DRIscreenPrivate * const psp = - (const __DRIscreenPrivate *) pDRIScreen->private; - - return _gl_context_modes_find_visual( psp->modes, vid ); - } - - 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 */ - -/*@}*/ - - -/*****************************************************************/ -/** \name Drawable list management */ -/*****************************************************************/ -/*@{*/ - -static Bool __driAddDrawable(void *drawHash, __DRIdrawable *pdraw) -{ - __DRIdrawablePrivate *pdp = (__DRIdrawablePrivate *)pdraw->private; - - if (drmHashInsert(drawHash, pdp->draw, pdraw)) - return GL_FALSE; - - return GL_TRUE; -} - -static __DRIdrawable *__driFindDrawable(void *drawHash, GLXDrawable draw) -{ - int retcode; - __DRIdrawable *pdraw; - - retcode = drmHashLookup(drawHash, draw, (void **)&pdraw); - if (retcode) - return NULL; - - return pdraw; -} - -static void __driRemoveDrawable(void *drawHash, __DRIdrawable *pdraw) -{ - int retcode; - __DRIdrawablePrivate *pdp = (__DRIdrawablePrivate *)pdraw->private; - - retcode = drmHashLookup(drawHash, pdp->draw, (void **)&pdraw); - if (!retcode) { /* Found */ - drmHashDelete(drawHash, pdp->draw); - } -} - -#ifndef DRI_NEW_INTERFACE_ONLY -static Bool __driWindowExistsFlag; - -static int __driWindowExistsErrorHandler(Display *dpy, XErrorEvent *xerr) -{ - if (xerr->error_code == BadWindow) { - __driWindowExistsFlag = GL_FALSE; - } - 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; - int (*oldXErrorHandler)(Display *, XErrorEvent *); - - XSync(dpy, GL_FALSE); - __driWindowExistsFlag = GL_TRUE; - oldXErrorHandler = XSetErrorHandler(__driWindowExistsErrorHandler); - XGetWindowAttributes(dpy, draw, &xwa); /* dummy request */ - XSetErrorHandler(oldXErrorHandler); - return __driWindowExistsFlag; -} -#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; - __DRIdrawable *pdraw; - Display *dpy; - - if (drmHashFirst(drawHash, &draw, (void **)&pdraw)) { - do { - __DRIdrawablePrivate *pdp = (__DRIdrawablePrivate *)pdraw->private; - dpy = pdp->driScreenPriv->display; - if (! (*window_exists)(dpy, draw)) { - /* Destroy the local drawable data in the hash table, if the - drawable no longer exists in the Xserver */ - __driRemoveDrawable(drawHash, pdraw); - (*pdraw->destroyDrawable)(dpy, pdraw->private); - Xfree(pdraw); - } - } while (drmHashNext(drawHash, &draw, (void **)&pdraw)); - } -} - -/*@}*/ - - -/*****************************************************************/ -/** \name Context (un)binding functions */ -/*****************************************************************/ -/*@{*/ - -/** - * Unbind context. - * - * \param dpy the display handle. - * \param scrn the screen number. - * \param draw drawable. - * \param read Current reading drawable. - * \param gc context. - * - * \return \c GL_TRUE on success, or \c GL_FALSE on failure. - * - * \internal - * This function calls __DriverAPIRec::UnbindContext, and then decrements - * __DRIdrawablePrivateRec::refcount which must be non-zero for a successful - * return. - * - * While casting the opaque private pointers associated with the parameters - * into their respective real types it also assures they are not \c NULL. - */ -static Bool driUnbindContext3(Display *dpy, int scrn, - GLXDrawable draw, GLXDrawable read, - __DRIcontext *ctx) -{ - __DRIscreen *pDRIScreen; - __DRIdrawable *pdraw; - __DRIdrawable *pread; - __DRIcontextPrivate *pcp; - __DRIscreenPrivate *psp; - __DRIdrawablePrivate *pdp; - __DRIdrawablePrivate *prp; - - /* - ** Assume error checking is done properly in glXMakeCurrent before - ** calling driUnbindContext3. - */ - - if (ctx == NULL || draw == None || read == None) { - /* ERROR!!! */ - return GL_FALSE; - } - - pDRIScreen = __glXFindDRIScreen(dpy, scrn); - if ( (pDRIScreen == NULL) || (pDRIScreen->private == NULL) ) { - /* ERROR!!! */ - return GL_FALSE; - } - - psp = (__DRIscreenPrivate *)pDRIScreen->private; - pcp = (__DRIcontextPrivate *)ctx->private; - - pdraw = __driFindDrawable(psp->drawHash, draw); - if (!pdraw) { - /* ERROR!!! */ - return GL_FALSE; - } - pdp = (__DRIdrawablePrivate *)pdraw->private; - - pread = __driFindDrawable(psp->drawHash, read); - if (!pread) { - /* ERROR!!! */ - return GL_FALSE; - } - prp = (__DRIdrawablePrivate *)pread->private; - - - /* Let driver unbind drawable from context */ - (*psp->DriverAPI.UnbindContext)(pcp); - - - if (pdp->refcount == 0) { - /* ERROR!!! */ - return GL_FALSE; - } - - pdp->refcount--; - - if (prp != pdp) { - if (prp->refcount == 0) { - /* ERROR!!! */ - return GL_FALSE; - } - - prp->refcount--; - } - - - /* XXX this is disabled so that if we call SwapBuffers on an unbound - * window we can determine the last context bound to the window and - * use that context's lock. (BrianP, 2-Dec-2000) - */ -#if 0 - /* Unbind the drawable */ - pcp->driDrawablePriv = NULL; - pdp->driContextPriv = &psp->dummyContextPriv; -#endif - - return GL_TRUE; -} - - -/** - * This function takes both a read buffer and a draw buffer. This is needed - * for \c glXMakeCurrentReadSGI or GLX 1.3's \c glXMakeContextCurrent - * function. - * - * \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 DoBindContext(Display *dpy, - GLXDrawable draw, GLXDrawable read, - __DRIcontext *ctx, const __GLcontextModes * modes, - __DRIscreenPrivate *psp) -{ - __DRIdrawable *pdraw; - __DRIdrawablePrivate *pdp; - __DRIdrawable *pread; - __DRIdrawablePrivate *prp; - __DRIcontextPrivate * const pcp = ctx->private; - - - /* Find the _DRIdrawable which corresponds to the writing GLXDrawable */ - pdraw = __driFindDrawable(psp->drawHash, draw); - if (!pdraw) { - /* Allocate a new drawable */ - pdraw = (__DRIdrawable *)Xmalloc(sizeof(__DRIdrawable)); - if (!pdraw) { - /* ERROR!!! */ - return GL_FALSE; - } - - /* Create a new drawable */ - driCreateNewDrawable(dpy, modes, draw, pdraw, GLX_WINDOW_BIT, - empty_attribute_list); - if (!pdraw->private) { - /* ERROR!!! */ - Xfree(pdraw); - return GL_FALSE; - } - - } - pdp = (__DRIdrawablePrivate *) pdraw->private; - - /* Find the _DRIdrawable which corresponds to the reading GLXDrawable */ - if (read == draw) { - /* read buffer == draw buffer */ - prp = pdp; - } - else { - pread = __driFindDrawable(psp->drawHash, read); - if (!pread) { - /* Allocate a new drawable */ - pread = (__DRIdrawable *)Xmalloc(sizeof(__DRIdrawable)); - if (!pread) { - /* ERROR!!! */ - return GL_FALSE; - } - - /* Create a new drawable */ - driCreateNewDrawable(dpy, modes, read, pread, GLX_WINDOW_BIT, - empty_attribute_list); - if (!pread->private) { - /* ERROR!!! */ - Xfree(pread); - return GL_FALSE; - } - } - prp = (__DRIdrawablePrivate *) pread->private; - } - - /* Bind the drawable to the context */ - pcp->driDrawablePriv = pdp; - pdp->driContextPriv = pcp; - pdp->refcount++; - if ( pdp != prp ) { - prp->refcount++; - } - - /* - ** Now that we have a context associated with this drawable, we can - ** initialize the drawable information if has not been done before. - */ - if (!pdp->pStamp || *pdp->pStamp != pdp->lastStamp) { - DRM_SPINLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID); - __driUtilUpdateDrawableInfo(pdp); - DRM_SPINUNLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID); - } - - /* Call device-specific MakeCurrent */ - (*psp->DriverAPI.MakeCurrent)(pcp, pdp, prp); - - return GL_TRUE; -} - - -/** - * This function takes both a read buffer and a draw buffer. This is needed - * for \c glXMakeCurrentReadSGI or GLX 1.3's \c glXMakeContextCurrent - * function. - */ -static Bool driBindContext3(Display *dpy, int scrn, - GLXDrawable draw, GLXDrawable read, - __DRIcontext * ctx) -{ - __DRIscreen *pDRIScreen; - - /* - ** Assume error checking is done properly in glXMakeCurrent before - ** calling driBindContext. - */ - - if (ctx == NULL || draw == None || read == None) { - /* ERROR!!! */ - return GL_FALSE; - } - - pDRIScreen = __glXFindDRIScreen(dpy, scrn); - if ( (pDRIScreen == NULL) || (pDRIScreen->private == NULL) ) { - /* ERROR!!! */ - return GL_FALSE; - } - - return DoBindContext( dpy, draw, read, ctx, ctx->mode, - (__DRIscreenPrivate *)pDRIScreen->private ); -} - - -#ifndef DRI_NEW_INTERFACE_ONLY -/** - * This function takes both a read buffer and a draw buffer. This is needed - * for \c glXMakeCurrentReadSGI or GLX 1.3's \c glXMakeContextCurrent - * function. - */ -static Bool driBindContext2(Display *dpy, int scrn, - GLXDrawable draw, GLXDrawable read, - GLXContext gc) -{ - __DRIscreen *pDRIScreen; - const __GLcontextModes *modes; - - /* - ** Assume error checking is done properly in glXMakeCurrent before - ** calling driBindContext. - */ - - if (gc == NULL || draw == None || read == None) { - /* ERROR!!! */ - return GL_FALSE; - } - - pDRIScreen = __glXFindDRIScreen(dpy, scrn); - modes = (driCompareGLXAPIVersion( 20040317 ) >= 0) - ? gc->driContext.mode - : 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) ); - - return DoBindContext( dpy, draw, read, & gc->driContext, modes, - (__DRIscreenPrivate *)pDRIScreen->private ); -} - -static Bool driUnbindContext2(Display *dpy, int scrn, - GLXDrawable draw, GLXDrawable read, - GLXContext gc) -{ - return driUnbindContext3(dpy, scrn, draw, read, & gc->driContext); -} - -/* - * Simply call bind with the same GLXDrawable for the read and draw buffers. - */ -static Bool driBindContext(Display *dpy, int scrn, - GLXDrawable draw, GLXContext gc) -{ - return driBindContext2(dpy, scrn, draw, draw, gc); -} - - -/* - * Simply call bind with the same GLXDrawable for the read and draw buffers. - */ -static Bool driUnbindContext(Display *dpy, int scrn, - GLXDrawable draw, GLXContext gc, - int will_rebind) -{ - (void) will_rebind; - return driUnbindContext2( dpy, scrn, draw, draw, gc ); -} -#endif /* DRI_NEW_INTERFACE_ONLY */ - -/*@}*/ - - -/*****************************************************************/ -/** \name Drawable handling functions */ -/*****************************************************************/ -/*@{*/ - -/** - * Update private drawable information. - * - * \param pdp pointer to the private drawable information to update. - * - * This function basically updates the __DRIdrawablePrivate struct's - * 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 - * info. - */ -void -__driUtilUpdateDrawableInfo(__DRIdrawablePrivate *pdp) -{ - __DRIscreenPrivate *psp; - __DRIcontextPrivate *pcp = pdp->driContextPriv; - - if (!pcp || (pdp != pcp->driDrawablePriv)) { - /* ERROR!!! */ - return; - } - - psp = pdp->driScreenPriv; - if (!psp) { - /* ERROR!!! */ - return; - } - - if (pdp->pClipRects) { - Xfree(pdp->pClipRects); - } - - if (pdp->pBackClipRects) { - Xfree(pdp->pBackClipRects); - } - - DRM_SPINUNLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID); - - if (!__driFindDrawable(psp->drawHash, pdp->draw) || - ! (*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. - */ - pdp->pStamp = &pdp->lastStamp; /* prevent endless loop */ - pdp->numClipRects = 0; - pdp->pClipRects = NULL; - pdp->numBackClipRects = 0; - pdp->pBackClipRects = NULL; - } - else - pdp->pStamp = &(psp->pSAREA->drawableTable[pdp->index].stamp); - - DRM_SPINLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID); - -} - -/*@}*/ - -/*****************************************************************/ -/** \name GLX callbacks */ -/*****************************************************************/ -/*@{*/ - -/** - * Swap buffers. - * - * \param dpy the display handle. - * \param drawablePrivate opaque pointer to the per-drawable private info. - * - * \internal - * This function calls __DRIdrawablePrivate::swapBuffers. - * - * Is called directly from glXSwapBuffers(). - */ -static void driSwapBuffers( Display *dpy, void *drawablePrivate ) -{ - __DRIdrawablePrivate *dPriv = (__DRIdrawablePrivate *) drawablePrivate; - dPriv->swapBuffers(dPriv); - (void) dpy; -} - -/** - * Called directly from a number of higher-level GLX functions. - */ -static int driGetMSC( void *screenPrivate, int64_t *msc ) -{ - __DRIscreenPrivate *sPriv = (__DRIscreenPrivate *) screenPrivate; - - return sPriv->DriverAPI.GetMSC( sPriv, msc ); -} - -/** - * Called directly from a number of higher-level GLX functions. - */ -static int driGetSBC( Display *dpy, void *drawablePrivate, int64_t *sbc ) -{ - __DRIdrawablePrivate *dPriv = (__DRIdrawablePrivate *) drawablePrivate; - __DRIswapInfo sInfo; - int status; - - - status = dPriv->driScreenPriv->DriverAPI.GetSwapInfo( dPriv, & sInfo ); - *sbc = sInfo.swap_count; - - return status; -} - -static int driWaitForSBC( Display * dpy, void *drawablePriv, - int64_t target_sbc, - int64_t * msc, int64_t * sbc ) -{ - __DRIdrawablePrivate *dPriv = (__DRIdrawablePrivate *) drawablePriv; - - return dPriv->driScreenPriv->DriverAPI.WaitForSBC( dPriv, target_sbc, - msc, sbc ); -} - -static int driWaitForMSC( Display * dpy, void *drawablePriv, - int64_t target_msc, - int64_t divisor, int64_t remainder, - int64_t * msc, int64_t * sbc ) -{ - __DRIdrawablePrivate *dPriv = (__DRIdrawablePrivate *) drawablePriv; - __DRIswapInfo sInfo; - int status; - - - status = dPriv->driScreenPriv->DriverAPI.WaitForMSC( dPriv, target_msc, - divisor, remainder, - msc ); - - /* GetSwapInfo() may not be provided by the driver if GLX_SGI_video_sync - * is supported but GLX_OML_sync_control is not. Therefore, don't return - * an error value if GetSwapInfo() is not implemented. - */ - if ( status == 0 - && dPriv->driScreenPriv->DriverAPI.GetSwapInfo ) { - status = dPriv->driScreenPriv->DriverAPI.GetSwapInfo( dPriv, & sInfo ); - *sbc = sInfo.swap_count; - } - - return status; -} - -static int64_t driSwapBuffersMSC( Display * dpy, void *drawablePriv, - int64_t target_msc, - int64_t divisor, int64_t remainder ) -{ - __DRIdrawablePrivate *dPriv = (__DRIdrawablePrivate *) drawablePriv; - - return dPriv->driScreenPriv->DriverAPI.SwapBuffersMSC( dPriv, target_msc, - divisor, - remainder ); -} - - -/** - * This is called via __DRIscreenRec's createNewDrawable pointer. - */ -static void *driCreateNewDrawable(Display *dpy, - const __GLcontextModes *modes, - GLXDrawable draw, - __DRIdrawable *pdraw, - int renderType, - const int *attrs) -{ - __DRIscreen * const pDRIScreen = __glXFindDRIScreen(dpy, modes->screen); - __DRIscreenPrivate *psp; - __DRIdrawablePrivate *pdp; - - - /* Since pbuffers are not yet supported, no drawable attributes are - * supported either. - */ - (void) attrs; - - if ( (pDRIScreen == NULL) || (pDRIScreen->private == NULL) ) { - return NULL; - } - - pdp = (__DRIdrawablePrivate *)Xmalloc(sizeof(__DRIdrawablePrivate)); - if (!pdp) { - return NULL; - } - - if (!XF86DRICreateDrawable(dpy, modes->screen, draw, &pdp->hHWDrawable)) { - Xfree(pdp); - return NULL; - } - - pdp->draw = draw; - pdp->pdraw = pdraw; - pdp->refcount = 0; - pdp->pStamp = NULL; - pdp->lastStamp = 0; - pdp->index = 0; - pdp->x = 0; - pdp->y = 0; - pdp->w = 0; - pdp->h = 0; - pdp->numClipRects = 0; - pdp->numBackClipRects = 0; - pdp->pClipRects = NULL; - pdp->pBackClipRects = NULL; - pdp->display = dpy; - pdp->screen = modes->screen; - - 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); - Xfree(pdp); - return NULL; - } - - pdraw->private = pdp; - pdraw->destroyDrawable = driDestroyDrawable; - pdraw->swapBuffers = driSwapBuffers; /* called by glXSwapBuffers() */ - - if ( driCompareGLXAPIVersion( 20030317 ) >= 0 ) { - pdraw->getSBC = driGetSBC; - pdraw->waitForSBC = driWaitForSBC; - pdraw->waitForMSC = driWaitForMSC; - pdraw->swapBuffersMSC = driSwapBuffersMSC; - pdraw->frameTracking = NULL; - pdraw->queryFrameTracking = driQueryFrameTracking; - - /* This special default value is replaced with the configured - * default value when the drawable is first bound to a direct - * rendering context. */ - pdraw->swap_interval = (unsigned)-1; - } - - pdp->swapBuffers = psp->DriverAPI.SwapBuffers; - - /* 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, - void *screenPrivate) -{ - __DRIscreenPrivate *psp = (__DRIscreenPrivate *) screenPrivate; - - /* - ** Make sure this routine returns NULL if the drawable is not bound - ** to a direct rendering context! - */ - return __driFindDrawable(psp->drawHash, draw); -} - -static void driDestroyDrawable(Display *dpy, void *drawablePrivate) -{ - __DRIdrawablePrivate *pdp = (__DRIdrawablePrivate *) drawablePrivate; - __DRIscreenPrivate *psp = pdp->driScreenPriv; - int scrn = psp->myNum; - - if (pdp) { - (*psp->DriverAPI.DestroyBuffer)(pdp); - if ((*window_exists)(dpy, pdp->draw)) - (void)XF86DRIDestroyDrawable(dpy, scrn, pdp->draw); - if (pdp->pClipRects) { - Xfree(pdp->pClipRects); - pdp->pClipRects = NULL; - } - if (pdp->pBackClipRects) { - Xfree(pdp->pBackClipRects); - pdp->pBackClipRects = NULL; - } - Xfree(pdp); - } -} - -/*@}*/ - - -/*****************************************************************/ -/** \name Context handling functions */ -/*****************************************************************/ -/*@{*/ - -/** - * Destroy the per-context private information. - * - * \param dpy the display handle. - * \param scrn the screen number. - * \param contextPrivate opaque pointer to the per-drawable private info. - * - * \internal - * This function calls __DriverAPIRec::DestroyContext on \p contextPrivate, calls - * drmDestroyContext(), and finally frees \p contextPrivate. - */ -static void driDestroyContext(Display *dpy, int scrn, void *contextPrivate) -{ - __DRIcontextPrivate *pcp = (__DRIcontextPrivate *) contextPrivate; - - if (pcp) { - (*pcp->driScreenPriv->DriverAPI.DestroyContext)(pcp); - __driGarbageCollectDrawables(pcp->driScreenPriv->drawHash); - (void)XF86DRIDestroyContext(dpy, scrn, pcp->contextID); - Xfree(pcp); - } -} - - -/** - * Create the per-drawable private driver information. - * - * \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 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 - * performs some device independent initialization and passes all the - * relevent information to __DriverAPIRec::CreateContext to create the - * context. - * - */ -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; - void * const shareCtx = (pshare != NULL) ? pshare->driverPrivate : NULL; - - pDRIScreen = __glXFindDRIScreen(dpy, modes->screen); - if ( (pDRIScreen == NULL) || (pDRIScreen->private == NULL) ) { - /* ERROR!!! */ - return NULL; - } - - psp = (__DRIscreenPrivate *)pDRIScreen->private; - - pcp = (__DRIcontextPrivate *)Xmalloc(sizeof(__DRIcontextPrivate)); - if (!pcp) { - return NULL; - } - - if (! (*create_context_with_config)(dpy, modes->screen, modes->fbconfigID, - &pcp->contextID, &pcp->hHWContext)) { - Xfree(pcp); - return NULL; - } - - pcp->display = dpy; - pcp->driScreenPriv = psp; - pcp->driDrawablePriv = NULL; - - /* When the first context is created for a screen, initialize a "dummy" - * context. - */ - - if (!psp->dummyContextPriv.driScreenPriv) { - psp->dummyContextPriv.contextID = 0; - psp->dummyContextPriv.hHWContext = psp->pSAREA->dummy_context; - psp->dummyContextPriv.driScreenPriv = psp; - psp->dummyContextPriv.driDrawablePriv = NULL; - psp->dummyContextPriv.driverPrivate = NULL; - /* No other fields should be used! */ - } - - pctx->destroyContext = driDestroyContext; -#ifdef DRI_NEW_INTERFACE_ONLY - pctx->bindContext = NULL; - pctx->unbindContext = NULL; - pctx->bindContext2 = NULL; - pctx->unbindContext2 = NULL; - pctx->bindContex3 = driBindContext3; - pctx->unbindContext3 = driUnbindContext3; -#else - pctx->bindContext = driBindContext; - pctx->unbindContext = driUnbindContext; - if ( driCompareGLXAPIVersion( 20030606 ) >= 0 ) { - pctx->bindContext2 = driBindContext2; - pctx->unbindContext2 = driUnbindContext2; - } - - if ( driCompareGLXAPIVersion( 20040415 ) >= 0 ) { - pctx->bindContext3 = driBindContext3; - pctx->unbindContext3 = driUnbindContext3; - } -#endif - - 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 */ - -/*@}*/ - - -/*****************************************************************/ -/** \name Screen handling functions */ -/*****************************************************************/ -/*@{*/ - -/** - * Destroy the per-screen private information. - * - * \param dpy the display handle. - * \param scrn the screen number. - * \param screenPrivate opaque pointer to the per-screen private information. - * - * \internal - * This function calls __DriverAPIRec::DestroyScreen on \p screenPrivate, calls - * drmClose(), and finally frees \p screenPrivate. - */ -static void driDestroyScreen(Display *dpy, int scrn, void *screenPrivate) -{ - __DRIscreenPrivate *psp = (__DRIscreenPrivate *) screenPrivate; - - if (psp) { - /* No interaction with the X-server is possible at this point. This - * routine is called after XCloseDisplay, so there is no protocol - * stream open to the X-server anymore. - */ - - if (psp->DriverAPI.DestroyScreen) - (*psp->DriverAPI.DestroyScreen)(psp); - - (void)drmUnmap((drmAddress)psp->pSAREA, SAREA_MAX); - (void)drmUnmap((drmAddress)psp->pFB, psp->fbSize); - Xfree(psp->pDevPriv); - (void)drmClose(psp->fd); - 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 * -__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) -{ - __DRIscreenPrivate *psp; - - -#ifdef DRI_NEW_INTERFACE_ONLY - if ( internal_api_version < 20040415 ) { - fprintf( stderr, "libGL error: libGL.so version (%08u) is too old. " - "20040415 or later is required.\n", internal_api_version ); - return NULL; - } -#else - if ( internal_api_version == 20031201 ) { - fprintf( stderr, "libGL error: libGL version 20031201 has critical " - "binary compatilibity bugs.\nlibGL error: You must upgrade " - "to use direct-rendering!\n" ); - return NULL; - } -#endif /* DRI_NEW_INTERFACE_ONLY */ - - - window_exists = (PFNGLXWINDOWEXISTSPROC) - glXGetProcAddress( (const GLubyte *) "__glXWindowExists" ); - - 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", internal_api_version ); - return NULL; -#else - window_exists = (PFNGLXWINDOWEXISTSPROC) __driWindowExists; -#endif /* DRI_NEW_INTERFACE_ONLY */ - } - - 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; - - psp = (__DRIscreenPrivate *)Xmalloc(sizeof(__DRIscreenPrivate)); - if (!psp) { - return NULL; - } - - /* 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; - - psp->drmMajor = drm_version->major; - psp->drmMinor = drm_version->minor; - psp->drmPatch = drm_version->patch; - psp->ddxMajor = ddx_version->major; - psp->ddxMinor = ddx_version->minor; - psp->ddxPatch = ddx_version->patch; - psp->driMajor = dri_version->major; - psp->driMinor = dri_version->minor; - psp->driPatch = dri_version->patch; - - /* install driver's callback functions */ - memcpy( &psp->DriverAPI, driverAPI, sizeof(struct __DriverAPIRec) ); - - psp->pSAREA = pSAREA; - - psp->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; - - psp->fd = fd; - - /* - ** 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; - - psc->destroyScreen = driDestroyScreen; -#ifndef DRI_NEW_INTERFACE_ONLY - psc->createContext = driCreateContext; -#else - psc->createConteext = NULL; -#endif - psc->createNewDrawable = driCreateNewDrawable; - psc->getDrawable = driGetDrawable; -#ifdef DRI_NEW_INTERFACE_ONLY - psc->getMSC = driGetMSC; - psc->createNewContext = driCreateNewContext; -#else - if ( driCompareGLXAPIVersion( 20030317 ) >= 0 ) { - psc->getMSC = driGetMSC; - - if ( driCompareGLXAPIVersion( 20030824 ) >= 0 ) { - psc->createNewContext = driCreateNewContext; - } - } -#endif - - if ( (psp->DriverAPI.InitDriver != NULL) - && !(*psp->DriverAPI.InitDriver)(psp) ) { - Xfree( psp ); - return NULL; - } - - - return psp; -} - - -#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; - } - - - /* Create the linked list of context modes, and populate it with the - * GLX visual information passed in by libGL. - */ - - modes = _gl_context_modes_create( numConfigs, sizeof(__GLcontextModes) ); - if ( modes == NULL ) { - 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; - } - - 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 ); - } - } - } - } - } - } - } - } - } - - 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 ); - } - - (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 /* DRI_NEW_INTERFACE_ONLY */ - - -/** - * Compare the current GLX API version with a driver supplied required version. - * - * The minimum required version is compared with the API version exported by - * the \c __glXGetInternalVersion function (in libGL.so). - * - * \param required_version Minimum required internal GLX API version. - * \return A tri-value return, as from strcmp is returned. A value less - * than, equal to, or greater than zero will be returned if the - * internal GLX API version is less than, equal to, or greater - * than \c required_version. - * - * \sa __glXGetInternalVersion(). - */ -int driCompareGLXAPIVersion( GLuint required_version ) -{ - if ( api_ver > required_version ) { - return 1; - } - else if ( api_ver == required_version ) { - return 0; - } - - return -1; -} - - -static int -driQueryFrameTracking( Display * dpy, void * priv, - int64_t * sbc, int64_t * missedFrames, - float * lastMissedUsage, float * usage ) -{ - static PFNGLXGETUSTPROC get_ust; - __DRIswapInfo sInfo; - int status; - int64_t ust; - __DRIdrawablePrivate * dpriv = (__DRIdrawablePrivate *) priv; - - if ( get_ust == NULL ) { - get_ust = (PFNGLXGETUSTPROC) glXGetProcAddress( (const GLubyte *) "__glXGetUST" ); - } - - status = dpriv->driScreenPriv->DriverAPI.GetSwapInfo( dpriv, & sInfo ); - if ( status == 0 ) { - *sbc = sInfo.swap_count; - *missedFrames = sInfo.swap_missed_count; - *lastMissedUsage = sInfo.swap_missed_usage; - - (*get_ust)( & ust ); - *usage = driCalculateSwapUsage( dpriv, sInfo.swap_ust, ust ); - } - - return status; -} - - -/** - * Calculate amount of swap interval used between GLX buffer swaps. - * - * The usage value, on the range [0,max], is the fraction of total swap - * interval time used between GLX buffer swaps is calculated. - * - * \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 - * 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). - * - * See the documentation for the GLX_MESA_swap_frame_usage extension for more - * details. - * - * \param dPriv Pointer to the private drawable structure. - * \return If less than a single swap interval time period was required - * between GLX buffer swaps, a number greater than 0 and less than - * 1.0 is returned. If exactly one swap interval time period is - * 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 - * - * \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, - int64_t current_ust ) -{ - static PFNGLXGETMSCRATEOMLPROC get_msc_rate = NULL; - int32_t n; - int32_t d; - int interval; - float usage = 1.0; - - - if ( get_msc_rate == NULL ) { - get_msc_rate = (PFNGLXGETMSCRATEOMLPROC) - glXGetProcAddress( (const GLubyte *) "glXGetMscRateOML" ); - } - - if ( (get_msc_rate != NULL) - && get_msc_rate( dPriv->display, dPriv->draw, &n, &d ) ) { - interval = (dPriv->pdraw->swap_interval != 0) - ? dPriv->pdraw->swap_interval : 1; - - - /* We want to calculate - * (current_UST - last_swap_UST) / (interval * us_per_refresh). We get - * current_UST by calling __glXGetUST. last_swap_UST is stored in - * dPriv->swap_ust. interval has already been calculated. - * - * The only tricky part is us_per_refresh. us_per_refresh is - * 1000000 / MSC_rate. We know the MSC_rate is n / d. We can flip it - * around and say us_per_refresh = 1000000 * d / n. Since this goes in - * the denominator of the final calculation, we calculate - * (interval * 1000000 * d) and move n into the numerator. - */ - - usage = (current_ust - last_swap_ust); - usage *= n; - usage /= (interval * d); - usage /= 1000000.0; - } - - return usage; -} - -/*@}*/ - -#endif /* GLX_DIRECT_RENDERING */ diff --git a/src/mesa/drivers/dri/dri_client/dri_util.h b/src/mesa/drivers/dri/dri_client/dri_util.h deleted file mode 100644 index 5c198810f72..00000000000 --- a/src/mesa/drivers/dri/dri_client/dri_util.h +++ /dev/null @@ -1,588 +0,0 @@ -/* $XFree86: xc/lib/GL/dri/dri_util.h,v 1.1 2002/02/22 21:32:52 dawes Exp $ */ -/** - * \file dri_util.h - * DRI utility functions definitions. - * - * This module acts as glue between GLX and the actual hardware driver. A DRI - * driver doesn't really \e have to use any of this - it's optional. But, some - * useful stuff is done here that otherwise would have to be duplicated in most - * drivers. - * - * Basically, these utility functions take care of some of the dirty details of - * screen initialization, context creation, context binding, DRM setup, etc. - * - * These functions are compiled into each DRI driver so libGL.so knows nothing - * about them. - * - * \sa dri_util.c. - * - * \author Kevin E. Martin - * \author Brian Paul - */ - -/* - * Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - - -#ifndef _DRI_UTIL_H_ -#define _DRI_UTIL_H_ - -#ifdef GLX_DIRECT_RENDERING - -#define CAPI /* XXX this should be globally defined somewhere */ - -#include -#include "glxclient.h" /* for GLXDrawable */ -/* temporary */ -/* typedef Bool ( * PFNGLXGETMSCRATEOMLPROC) (Display *dpy, GLXDrawable drawable, int32_t *numerator, int32_t *denominator); */ -#include "drm.h" /* for drm_clip_rect_t */ -#include "sarea.h" /* for XF86DRISAREAPtr */ -#include "GL/internal/glcore.h" /* for __GLcontextModes */ - - -typedef struct __DRIdisplayPrivateRec __DRIdisplayPrivate; -typedef struct __DRIscreenPrivateRec __DRIscreenPrivate; -typedef struct __DRIcontextPrivateRec __DRIcontextPrivate; -typedef struct __DRIdrawablePrivateRec __DRIdrawablePrivate; -typedef struct __DRIswapInfoRec __DRIswapInfo; - - -/** - * Used by DRI_VALIDATE_DRAWABLE_INFO - */ -#define DRI_VALIDATE_DRAWABLE_INFO_ONCE(pDrawPriv) \ - do { \ - if (*(pDrawPriv->pStamp) != pDrawPriv->lastStamp) { \ - __driUtilUpdateDrawableInfo(pDrawPriv); \ - } \ - } while (0) - - -/** - * Utility macro to validate the drawable information. - * - * See __DRIdrawablePrivate::pStamp and __DRIdrawablePrivate::lastStamp. - */ -#define DRI_VALIDATE_DRAWABLE_INFO(psp, pdp) \ -do { \ - while (*(pdp->pStamp) != pdp->lastStamp) { \ - DRM_UNLOCK(psp->fd, &psp->pSAREA->lock, \ - pdp->driContextPriv->hHWContext); \ - \ - DRM_SPINLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID); \ - DRI_VALIDATE_DRAWABLE_INFO_ONCE(pdp); \ - DRM_SPINUNLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID); \ - \ - DRM_LIGHT_LOCK(psp->fd, &psp->pSAREA->lock, \ - pdp->driContextPriv->hHWContext); \ - } \ -} while (0) - - -/** - * Driver callback functions. - * - * Each DRI driver must have one of these structures with all the pointers set - * to appropriate functions within the driver. - * - * When glXCreateContext() is called, for example, it'll call a helper function - * dri_util.c which in turn will jump through the \a CreateContext pointer in - * this structure. - */ -struct __DriverAPIRec { - /** - * Driver initialization callback - */ - GLboolean (*InitDriver)(__DRIscreenPrivate *driScrnPriv); - - /** - * Screen destruction callback - */ - void (*DestroyScreen)(__DRIscreenPrivate *driScrnPriv); - - /** - * Context creation callback - */ - GLboolean (*CreateContext)(const __GLcontextModes *glVis, - __DRIcontextPrivate *driContextPriv, - void *sharedContextPrivate); - - /** - * Context destruction callback - */ - void (*DestroyContext)(__DRIcontextPrivate *driContextPriv); - - /** - * Buffer (drawable) creation callback - */ - GLboolean (*CreateBuffer)(__DRIscreenPrivate *driScrnPriv, - __DRIdrawablePrivate *driDrawPriv, - const __GLcontextModes *glVis, - GLboolean pixmapBuffer); - - /** - * Buffer (drawable) destruction callback - */ - void (*DestroyBuffer)(__DRIdrawablePrivate *driDrawPriv); - - /** - * Buffer swapping callback - */ - void (*SwapBuffers)(__DRIdrawablePrivate *driDrawPriv); - - /** - * Context activation callback - */ - GLboolean (*MakeCurrent)(__DRIcontextPrivate *driContextPriv, - __DRIdrawablePrivate *driDrawPriv, - __DRIdrawablePrivate *driReadPriv); - - /** - * Context unbinding callback - */ - GLboolean (*UnbindContext)(__DRIcontextPrivate *driContextPriv); - - /** - * 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. - * - * \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. - * - * \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 - * 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 - * supported. - */ - int (*GetMSC)( __DRIscreenPrivate * priv, int64_t * count ); - - /** - * These are required if GLX_OML_sync_control is supported. - */ - /*@{*/ - int (*WaitForMSC)( __DRIdrawablePrivate *priv, int64_t target_msc, - int64_t divisor, int64_t remainder, - int64_t * msc ); - int (*WaitForSBC)( __DRIdrawablePrivate *priv, int64_t target_sbc, - int64_t * msc, int64_t * sbc ); - - int64_t (*SwapBuffersMSC)( __DRIdrawablePrivate *priv, int64_t target_msc, - int64_t divisor, int64_t remainder ); - /*@}*/ -}; - - -struct __DRIswapInfoRec { - /** - * Number of swapBuffers operations that have been *completed*. - */ - 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 - * swap deadline is 1 frame after the previous swap. - */ - 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 - * 0, then 1 is used instead. If swap_missed_count is non-zero, this - * should be greater-than 1.0. - */ - float swap_missed_usage; -}; - - -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, drm_clip_rect_t * pClipRects, - int * backX, int * backY, - int * numBackClipRects, drm_clip_rect_t * pBackClipRects ); - - -/** - * Per-drawable private DRI driver information. - */ -struct __DRIdrawablePrivateRec { - /** - * Kernel drawable handle - */ - drmDrawable hHWDrawable; - - /** - * Driver's private drawable information. - * - * This structure is opaque. - */ - void *driverPrivate; - - /** - * X's drawable ID associated with this private drawable. - */ - GLXDrawable draw; - __DRIdrawable *pdraw; - - /** - * Reference count for number of context's currently bound to this - * drawable. - * - * Once it reaches zero, the drawable can be destroyed. - * - * \note This behavior will change with GLX 1.3. - */ - int refcount; - - /** - * Index of this drawable information in the SAREA. - */ - unsigned int index; - - /** - * Pointer to the "drawable has changed ID" stamp in the SAREA. - */ - unsigned int *pStamp; - - /** - * Last value of the stamp. - * - * If this differs from the value stored at __DRIdrawablePrivate::pStamp, - * then the drawable information has been modified by the X server, and the - * drawable information (below) should be retrieved from the X server. - */ - unsigned int lastStamp; - - /** - * \name Drawable - * - * Drawable information used in software fallbacks. - */ - /*@{*/ - int x; - int y; - int w; - int h; - int numClipRects; - drm_clip_rect_t *pClipRects; - /*@}*/ - - /** - * \name Back and depthbuffer - * - * Information about the back and depthbuffer where different from above. - */ - /*@{*/ - int backX; - int backY; - int backClipRectType; - int numBackClipRects; - drm_clip_rect_t *pBackClipRects; - /*@}*/ - - /** - * Pointer to context to which this drawable is currently bound. - */ - __DRIcontextPrivate *driContextPriv; - - /** - * Pointer to screen on which this drawable was created. - */ - __DRIscreenPrivate *driScreenPriv; - - /** - * \name Display and screen information. - * - * Basically just need these for when the locking code needs to call - * __driUtilUpdateDrawableInfo() which calls XF86DRIGetDrawableInfo(). - */ - /*@{*/ - Display *display; - int screen; - /*@}*/ - - /** - * Called via glXSwapBuffers(). - */ - void (*swapBuffers)( __DRIdrawablePrivate *dPriv ); - - /** - * Get information about the location, size, and clip rects of the - * drawable within the display. - */ - GetDrawableInfo * getInfo; -}; - -/** - * Per-context private driver information. - */ -struct __DRIcontextPrivateRec { - /** - * Kernel context handle used to access the device lock. - */ - XID contextID; - - /** - * Kernel context handle used to access the device lock. - */ - drmContext hHWContext; - - /** - * Device driver's private context data. This structure is opaque. - */ - void *driverPrivate; - - /** - * This context's display pointer. - */ - Display *display; - - /** - * Pointer to drawable currently bound to this context. - */ - __DRIdrawablePrivate *driDrawablePriv; - - /** - * Pointer to screen on which this context was created. - */ - __DRIscreenPrivate *driScreenPriv; -}; - -/** - * Per-screen private driver information. - */ -struct __DRIscreenPrivateRec { - /** - * Display for this screen - */ - Display *display; - - /** - * Current screen's number - */ - int myNum; - - /** - * Callback functions into the hardware-specific DRI driver code. - */ - struct __DriverAPIRec DriverAPI; - - /** - * \name DDX version - * DDX / 2D driver version information. - * \todo Replace these fields with a \c __DRIversionRec. - */ - /*@{*/ - int ddxMajor; - int ddxMinor; - int ddxPatch; - /*@}*/ - - /** - * \name DRI version - * DRI X extension version information. - * \todo Replace these fields with a \c __DRIversionRec. - */ - /*@{*/ - int driMajor; - int driMinor; - int driPatch; - /*@}*/ - - /** - * \name DRM version - * DRM (kernel module) version information. - * \todo Replace these fields with a \c __DRIversionRec. - */ - /*@{*/ - int drmMajor; - int drmMinor; - int drmPatch; - /*@}*/ - - /** - * ID used when the client sets the drawable lock. - * - * The X server uses this value to detect if the client has died while - * holding the drawable lock. - */ - int drawLockID; - - /** - * File descriptor returned when the kernel device driver is opened. - * - * Used to: - * - authenticate client to kernel - * - map the frame buffer, SAREA, etc. - * - close the kernel device driver - */ - int fd; - - /** - * SAREA pointer - * - * Used to access: - * - the device lock - * - the device-independent per-drawable and per-context(?) information - */ - XF86DRISAREAPtr pSAREA; - - /** - * \name Direct frame buffer access information - * Used for software fallbacks. - */ - /*@{*/ - unsigned char *pFB; - int fbSize; - int fbOrigin; - int fbStride; - int fbWidth; - int fbHeight; - int fbBPP; - /*@}*/ - - /** - * \name Device-dependent private information (stored in the SAREA). - * - * This data is accessed by the client driver only. - */ - /*@{*/ - void *pDevPriv; - int devPrivSize; - /*@}*/ - - /** - * Dummy context to which drawables are bound when not bound to any - * other context. - * - * A dummy hHWContext is created for this context, and is used by the GL - * core when a hardware lock is required but the drawable is not currently - * bound (e.g., potentially during a SwapBuffers request). The dummy - * context is created when the first "real" context is created on this - * screen. - */ - __DRIcontextPrivate dummyContextPriv; - - /** - * Hash table to hold the drawable information for this screen. - */ - void *drawHash; - - /** - * Device-dependent private information (not stored in the SAREA). - * - * This pointer is never touched by the DRI layer. - */ - void *private; - - /** - * GLX visuals / FBConfigs for this screen. These are stored as a - * linked list. - * - * \note - * This field is \b only used in conjunction with the old interfaces. If - * the new interfaces are used, this field will be set to \c NULL and will - * not be dereferenced. - */ - __GLcontextModes *modes; - - /** - * Pointer back to the \c __DRIscreen that contains this structure. - */ - - __DRIscreen *psc; -}; - - - -extern void -__driUtilMessage(const char *f, ...); - - -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); - -/* Test the version of the internal GLX API. Returns a value like strcmp. */ -extern int -driCompareGLXAPIVersion( GLuint required_version ); - -extern float -driCalculateSwapUsage( __DRIdrawablePrivate *dPriv, - int64_t last_swap_ust, int64_t current_ust ); - -#endif /* GLX_DIRECT_RENDERING */ - -#endif /* _DRI_UTIL_H_ */ diff --git a/src/mesa/drivers/dri/dri_client/glcontextmodes.c b/src/mesa/drivers/dri/dri_client/glcontextmodes.c deleted file mode 100644 index 784ad30259b..00000000000 --- a/src/mesa/drivers/dri/dri_client/glcontextmodes.c +++ /dev/null @@ -1,483 +0,0 @@ -/* - * (C) Copyright IBM Corporation 2003 - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * on the rights to use, copy, modify, merge, publish, distribute, sub - * license, and/or sell copies of the Software, and to permit persons to whom - * the Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEM, IBM AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -/** - * \file glcontextmodes.c - * Utility routines for working with \c __GLcontextModes structures. At - * some point most or all of these functions will be moved to the Mesa - * code base. - * - * \author Ian Romanick - */ - -#include -#include -#include "GL/glxint.h" - -#ifdef XFree86Server -# include "GL/glx_ansic.h" -extern void * __glXMalloc( size_t size ); -extern void __glXFree( void * ptr ); -# define Xmalloc __glXMalloc -# define Xfree __glXFree -#else -# include -# define __glXMemset memset -#endif /* XFree86Server */ - -#include "glcontextmodes.h" - -#define NUM_VISUAL_TYPES 6 - -/** - * Convert an X visual type to a GLX visual type. - * - * \param visualType X visual type (i.e., \c TrueColor, \c StaticGray, etc.) - * to be converted. - * \return If \c visualType is a valid X visual type, a GLX visual type will - * be returned. Otherwise \c GLX_NONE will be returned. - */ -GLint -_gl_convert_from_x_visual_type( int visualType ) -{ - static const int glx_visual_types[ NUM_VISUAL_TYPES ] = { - GLX_STATIC_GRAY, GLX_GRAY_SCALE, - GLX_STATIC_COLOR, GLX_PSEUDO_COLOR, - GLX_TRUE_COLOR, GLX_DIRECT_COLOR - }; - - return ( (unsigned) visualType < NUM_VISUAL_TYPES ) - ? glx_visual_types[ visualType ] : GLX_NONE; -} - - -/** - * Convert a GLX visual type to an X visual type. - * - * \param visualType GLX visual type (i.e., \c GLX_TRUE_COLOR, - * \c GLX_STATIC_GRAY, etc.) to be converted. - * \return If \c visualType is a valid GLX visual type, an X visual type will - * be returned. Otherwise -1 will be returned. - */ -GLint -_gl_convert_to_x_visual_type( int visualType ) -{ - static const int x_visual_types[ NUM_VISUAL_TYPES ] = { - TrueColor, DirectColor, - PseudoColor, StaticColor, - GrayScale, StaticGray - }; - - return ( (unsigned) (visualType - GLX_TRUE_COLOR) <= NUM_VISUAL_TYPES ) - ? x_visual_types[ visualType - GLX_TRUE_COLOR ] : -1; -} - - -/** - * Copy a GLX visual config structure to a GL context mode structure. All - * of the fields in \c config are copied to \c mode. Additional fields in - * \c mode that can be derrived from the fields of \c config (i.e., - * \c haveDepthBuffer) are also filled in. The remaining fields in \c mode - * that cannot be derrived are set to default values. - * - * \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, - const __GLXvisualConfig * config ) -{ - __GLcontextModes * const next = mode->next; - - (void) __glXMemset( mode, 0, sizeof( __GLcontextModes ) ); - mode->next = next; - - mode->visualID = config->vid; - mode->visualType = _gl_convert_from_x_visual_type( config->class ); - mode->xRenderable = GL_TRUE; - mode->fbconfigID = config->vid; - mode->drawableType = GLX_WINDOW_BIT | GLX_PIXMAP_BIT; - - mode->rgbMode = (config->rgba != 0); - mode->renderType = (mode->rgbMode) ? GLX_RGBA_BIT : GLX_COLOR_INDEX_BIT; - - mode->colorIndexMode = !(mode->rgbMode); - mode->doubleBufferMode = (config->doubleBuffer != 0); - mode->stereoMode = (config->stereo != 0); - - mode->haveAccumBuffer = ((config->accumRedSize + - config->accumGreenSize + - config->accumBlueSize + - config->accumAlphaSize) > 0); - mode->haveDepthBuffer = (config->depthSize > 0); - mode->haveStencilBuffer = (config->stencilSize > 0); - - mode->redBits = config->redSize; - mode->greenBits = config->greenSize; - mode->blueBits = config->blueSize; - mode->alphaBits = config->alphaSize; - mode->redMask = config->redMask; - mode->greenMask = config->greenMask; - mode->blueMask = config->blueMask; - mode->alphaMask = config->alphaMask; - mode->rgbBits = config->bufferSize; - mode->indexBits = config->bufferSize; - - mode->accumRedBits = config->accumRedSize; - mode->accumGreenBits = config->accumGreenSize; - mode->accumBlueBits = config->accumBlueSize; - mode->accumAlphaBits = config->accumAlphaSize; - mode->depthBits = config->depthSize; - mode->stencilBits = config->stencilSize; - - mode->numAuxBuffers = config->auxBuffers; - mode->level = config->level; - - mode->visualRating = config->visualRating; - mode->transparentPixel = config->transparentPixel; - mode->transparentRed = config->transparentRed; - mode->transparentGreen = config->transparentGreen; - mode->transparentBlue = config->transparentBlue; - mode->transparentAlpha = config->transparentAlpha; - mode->transparentIndex = config->transparentIndex; - - mode->swapMethod = GLX_SWAP_UNDEFINED_OML; -} - - -/** - * Get data from a GL context mode. - * - * \param mode GL context mode whose data is to be returned. - * \param attribute Attribute of \c mode that is to be returned. - * \param value_return Location to store the data member of \c mode. - * \return If \c attribute is a valid attribute of \c mode, \c Success is - * returned. Otherwise \c GLX_BAD_ATTRIBUTE is returned. - */ -int -_gl_get_context_mode_data(const __GLcontextModes *mode, int attribute, - int *value_return) -{ - switch (attribute) { - case GLX_USE_GL: - *value_return = GL_TRUE; - return Success; - case GLX_BUFFER_SIZE: - *value_return = mode->rgbBits; - return Success; - case GLX_RGBA: - *value_return = mode->rgbMode; - return Success; - case GLX_RED_SIZE: - *value_return = mode->redBits; - return Success; - case GLX_GREEN_SIZE: - *value_return = mode->greenBits; - return Success; - case GLX_BLUE_SIZE: - *value_return = mode->blueBits; - return Success; - case GLX_ALPHA_SIZE: - *value_return = mode->alphaBits; - return Success; - case GLX_DOUBLEBUFFER: - *value_return = mode->doubleBufferMode; - return Success; - case GLX_STEREO: - *value_return = mode->stereoMode; - return Success; - case GLX_AUX_BUFFERS: - *value_return = mode->numAuxBuffers; - return Success; - case GLX_DEPTH_SIZE: - *value_return = mode->depthBits; - return Success; - case GLX_STENCIL_SIZE: - *value_return = mode->stencilBits; - return Success; - case GLX_ACCUM_RED_SIZE: - *value_return = mode->accumRedBits; - return Success; - case GLX_ACCUM_GREEN_SIZE: - *value_return = mode->accumGreenBits; - return Success; - case GLX_ACCUM_BLUE_SIZE: - *value_return = mode->accumBlueBits; - return Success; - case GLX_ACCUM_ALPHA_SIZE: - *value_return = mode->accumAlphaBits; - return Success; - case GLX_LEVEL: - *value_return = mode->level; - return Success; - case GLX_TRANSPARENT_TYPE_EXT: - *value_return = mode->transparentPixel; - return Success; - case GLX_TRANSPARENT_RED_VALUE: - *value_return = mode->transparentRed; - return Success; - case GLX_TRANSPARENT_GREEN_VALUE: - *value_return = mode->transparentGreen; - return Success; - case GLX_TRANSPARENT_BLUE_VALUE: - *value_return = mode->transparentBlue; - return Success; - case GLX_TRANSPARENT_ALPHA_VALUE: - *value_return = mode->transparentAlpha; - return Success; - case GLX_TRANSPARENT_INDEX_VALUE: - *value_return = mode->transparentIndex; - return Success; - case GLX_X_VISUAL_TYPE: - *value_return = mode->visualType; - return Success; - case GLX_CONFIG_CAVEAT: - *value_return = mode->visualRating; - return Success; - case GLX_VISUAL_ID: - *value_return = mode->visualID; - return Success; - case GLX_DRAWABLE_TYPE: - *value_return = mode->drawableType; - return Success; - case GLX_RENDER_TYPE: - *value_return = mode->renderType; - return Success; - case GLX_X_RENDERABLE: - *value_return = mode->xRenderable; - return Success; - case GLX_FBCONFIG_ID: - *value_return = mode->fbconfigID; - return Success; - case GLX_MAX_PBUFFER_WIDTH: - *value_return = mode->maxPbufferWidth; - return Success; - case GLX_MAX_PBUFFER_HEIGHT: - *value_return = mode->maxPbufferHeight; - return Success; - case GLX_MAX_PBUFFER_PIXELS: - *value_return = mode->maxPbufferPixels; - return Success; - case GLX_OPTIMAL_PBUFFER_WIDTH_SGIX: - *value_return = mode->optimalPbufferWidth; - return Success; - case GLX_OPTIMAL_PBUFFER_HEIGHT_SGIX: - *value_return = mode->optimalPbufferHeight; - return Success; - case GLX_SWAP_METHOD_OML: - *value_return = mode->swapMethod; - return Success; - case GLX_SAMPLE_BUFFERS_SGIS: - *value_return = mode->sampleBuffers; - return Success; - case GLX_SAMPLES_SGIS: - *value_return = mode->samples; - return Success; - - /* Applications are NOT allowed to query GLX_VISUAL_SELECT_GROUP_SGIX. - * It is ONLY for communication between the GLX client and the GLX - * server. - */ - case GLX_VISUAL_SELECT_GROUP_SGIX: - default: - return GLX_BAD_ATTRIBUTE; - } -} - - -/** - * Allocate a linked list of \c __GLcontextModes structures. The fields of - * each structure will be initialized to "reasonable" default values. In - * most cases this is the default value defined by table 3.4 of the GLX - * 1.3 specification. This means that most values are either initialized to - * zero or \c GLX_DONT_CARE (which is -1). As support for additional - * extensions is added, the new values will be initialized to appropriate - * values from the extension specification. - * - * \param count Number of structures to allocate. - * \param minimum_size Minimum size of a structure to allocate. This allows - * for differences in the version of the - * \c __GLcontextModes stucture used in libGL and in a - * DRI-based driver. - * \returns A pointer to the first element in a linked list of \c count - * stuctures on success, or \c NULL on failure. - * - * \warning Use of \c minimum_size does \b not guarantee binary compatibility. - * The fundamental assumption is that if the \c minimum_size - * specified by the driver and the size of the \c __GLcontextModes - * structure in libGL is the same, then the meaning of each byte in - * the structure is the same in both places. \b Be \b careful! - * Basically this means that fields have to be added in libGL and - * then propagated to drivers. Drivers should \b never arbitrarilly - * extend the \c __GLcontextModes data-structure. - */ -__GLcontextModes * -_gl_context_modes_create( unsigned count, size_t minimum_size ) -{ - const size_t size = (minimum_size > sizeof( __GLcontextModes )) - ? minimum_size : sizeof( __GLcontextModes ); - __GLcontextModes * base = NULL; - __GLcontextModes ** next; - unsigned i; - - next = & base; - for ( i = 0 ; i < count ; i++ ) { - *next = (__GLcontextModes *) Xmalloc( size ); - if ( *next == NULL ) { - _gl_context_modes_destroy( base ); - base = NULL; - break; - } - - (void) __glXMemset( *next, 0, size ); - (*next)->visualID = GLX_DONT_CARE; - (*next)->visualType = GLX_DONT_CARE; - (*next)->visualRating = GLX_NONE; - (*next)->transparentPixel = GLX_NONE; - (*next)->transparentRed = GLX_DONT_CARE; - (*next)->transparentGreen = GLX_DONT_CARE; - (*next)->transparentBlue = GLX_DONT_CARE; - (*next)->transparentAlpha = GLX_DONT_CARE; - (*next)->transparentIndex = GLX_DONT_CARE; - (*next)->xRenderable = GLX_DONT_CARE; - (*next)->fbconfigID = GLX_DONT_CARE; - (*next)->swapMethod = GLX_SWAP_UNDEFINED_OML; - - next = & ((*next)->next); - } - - return base; -} - - -/** - * Destroy a linked list of \c __GLcontextModes structures created by - * \c _gl_context_modes_create. - * - * \param modes Linked list of structures to be destroyed. All structres - * in the list will be freed. - */ -void -_gl_context_modes_destroy( __GLcontextModes * modes ) -{ - while ( modes != NULL ) { - __GLcontextModes * const next = modes->next; - - Xfree( 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) != 0) && - (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/src/mesa/drivers/dri/dri_client/glcontextmodes.h b/src/mesa/drivers/dri/dri_client/glcontextmodes.h deleted file mode 100644 index 5f8fa4f3116..00000000000 --- a/src/mesa/drivers/dri/dri_client/glcontextmodes.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * (C) Copyright IBM Corporation 2003 - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * on the rights to use, copy, modify, merge, publish, distribute, sub - * license, and/or sell copies of the Software, and to permit persons to whom - * the Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEM, IBM AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -/** - * \file glcontextmodes.h - * \author Ian Romanick - */ - -#ifndef GLCONTEXTMODES_H -#define GLCONTEXTMODES_H - -#include "GL/internal/glcore.h" - -extern GLint _gl_convert_from_x_visual_type( int visualType ); -extern GLint _gl_convert_to_x_visual_type( int visualType ); -extern void _gl_copy_visual_to_context_mode( __GLcontextModes * mode, - const __GLXvisualConfig * config ); -extern int _gl_get_context_mode_data( const __GLcontextModes *mode, - int attribute, int *value_return ); -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/src/mesa/drivers/dri/ffb/Makefile b/src/mesa/drivers/dri/ffb/Makefile index 05972ca70f6..564832d5ee6 100644 --- a/src/mesa/drivers/dri/ffb/Makefile +++ b/src/mesa/drivers/dri/ffb/Makefile @@ -15,6 +15,8 @@ COMMON_SOURCES = \ ../common/texmem.c \ ../common/vblank.c \ ../common/xmlconfig.c \ + ../common/dri_util.c \ + ../common/glcontextmodes.c DRIVER_SOURCES = \ ffb_bitmap.c \ diff --git a/src/mesa/drivers/dri/gamma/Makefile b/src/mesa/drivers/dri/gamma/Makefile index e72246100c3..e95518eada7 100644 --- a/src/mesa/drivers/dri/gamma/Makefile +++ b/src/mesa/drivers/dri/gamma/Makefile @@ -13,7 +13,9 @@ COMMON_SOURCES = \ ../common/mm.c \ ../common/utils.c \ ../common/texmem.c \ - ../common/vblank.c + ../common/vblank.c \ + ../common/dri_util.c \ + ../common/glcontextmodes.c DRIVER_SOURCES = \ gamma_context.c \ diff --git a/src/mesa/drivers/dri/i810/Makefile b/src/mesa/drivers/dri/i810/Makefile index 4f36a33762f..ac792a527d0 100644 --- a/src/mesa/drivers/dri/i810/Makefile +++ b/src/mesa/drivers/dri/i810/Makefile @@ -13,7 +13,9 @@ COMMON_SOURCES = \ ../common/mm.c \ ../common/utils.c \ ../common/texmem.c \ - ../common/vblank.c + ../common/vblank.c \ + ../common/dri_util.c \ + ../common/glcontextmodes.c DRIVER_SOURCES = \ i810context.c \ diff --git a/src/mesa/drivers/dri/i830/Makefile b/src/mesa/drivers/dri/i830/Makefile index 8a75927081d..d2db225c7d0 100644 --- a/src/mesa/drivers/dri/i830/Makefile +++ b/src/mesa/drivers/dri/i830/Makefile @@ -11,7 +11,9 @@ COMMON_SOURCES = \ ../common/utils.c \ ../common/texmem.c \ ../common/vblank.c \ - ../common/xmlconfig.c + ../common/xmlconfig.c \ + ../common/dri_util.c \ + ../common/glcontextmodes.c DRIVER_SOURCES = \ i830_context.c \ diff --git a/src/mesa/drivers/dri/mach64/Makefile b/src/mesa/drivers/dri/mach64/Makefile index c855f4d882a..4fd3e26a3a3 100644 --- a/src/mesa/drivers/dri/mach64/Makefile +++ b/src/mesa/drivers/dri/mach64/Makefile @@ -14,7 +14,9 @@ COMMON_SOURCES = \ ../common/utils.c \ ../common/texmem.c \ ../common/vblank.c \ - ../common/xmlconfig.c + ../common/xmlconfig.c \ + ../common/dri_util.c \ + ../common/glcontextmodes.c DRIVER_SOURCES = \ mach64_context.c \ diff --git a/src/mesa/drivers/dri/mga/Makefile b/src/mesa/drivers/dri/mga/Makefile index 58c925da487..80089e75472 100644 --- a/src/mesa/drivers/dri/mga/Makefile +++ b/src/mesa/drivers/dri/mga/Makefile @@ -13,7 +13,9 @@ COMMON_SOURCES = \ ../common/utils.c \ ../common/texmem.c \ ../common/vblank.c \ - ../common/xmlconfig.c + ../common/xmlconfig.c \ + ../common/dri_util.c \ + ../common/glcontextmodes.c DRIVER_SOURCES = \ mgadd.c \ diff --git a/src/mesa/drivers/dri/r128/Makefile b/src/mesa/drivers/dri/r128/Makefile index bcda0a4d7d6..65e872e90ca 100644 --- a/src/mesa/drivers/dri/r128/Makefile +++ b/src/mesa/drivers/dri/r128/Makefile @@ -13,7 +13,9 @@ COMMON_SOURCES = \ ../common/utils.c \ ../common/texmem.c \ ../common/vblank.c \ - ../common/xmlconfig.c + ../common/xmlconfig.c \ + ../common/dri_util.c \ + ../common/glcontextmodes.c DRIVER_SOURCES = \ r128_context.c \ diff --git a/src/mesa/drivers/dri/r200/Makefile b/src/mesa/drivers/dri/r200/Makefile index 66835ca30de..a2aeeb5a945 100644 --- a/src/mesa/drivers/dri/r200/Makefile +++ b/src/mesa/drivers/dri/r200/Makefile @@ -13,7 +13,9 @@ COMMON_SOURCES = \ ../common/utils.c \ ../common/texmem.c \ ../common/vblank.c \ - ../common/xmlconfig.c + ../common/xmlconfig.c \ + ../common/dri_util.c \ + ../common/glcontextmodes.c DRIVER_SOURCES = r200_context.c \ r200_ioctl.c \ diff --git a/src/mesa/drivers/dri/radeon/Makefile b/src/mesa/drivers/dri/radeon/Makefile index 191ac8c46d4..b9f9186f593 100644 --- a/src/mesa/drivers/dri/radeon/Makefile +++ b/src/mesa/drivers/dri/radeon/Makefile @@ -14,7 +14,9 @@ COMMON_SOURCES = \ ../common/utils.c \ ../common/texmem.c \ ../common/vblank.c \ - ../common/xmlconfig.c + ../common/xmlconfig.c \ + ../common/dri_util.c \ + ../common/glcontextmodes.c DRIVER_SOURCES = \ radeon_context.c \ diff --git a/src/mesa/drivers/dri/sis/Makefile b/src/mesa/drivers/dri/sis/Makefile index 0c1c5081c74..bd4c0201d07 100644 --- a/src/mesa/drivers/dri/sis/Makefile +++ b/src/mesa/drivers/dri/sis/Makefile @@ -15,7 +15,9 @@ COMMON_SOURCES = \ ../common/utils.c \ ../common/texmem.c \ ../common/vblank.c \ - ../common/xmlconfig.c + ../common/xmlconfig.c \ + ../common/dri_util.c \ + ../common/glcontextmodes.c DRIVER_SOURCES = \ sis_alloc.c \ diff --git a/src/mesa/drivers/dri/tdfx/Makefile b/src/mesa/drivers/dri/tdfx/Makefile index 6517285e4ba..5c51012d7b5 100644 --- a/src/mesa/drivers/dri/tdfx/Makefile +++ b/src/mesa/drivers/dri/tdfx/Makefile @@ -14,7 +14,9 @@ COMMON_SOURCES = \ ../common/utils.c \ ../common/texmem.c \ ../common/vblank.c \ - ../common/xmlconfig.c + ../common/xmlconfig.c \ + ../common/dri_util.c \ + ../common/glcontextmodes.c DRIVER_SOURCES = \ tdfx_context.c \ diff --git a/src/mesa/drivers/dri/unichrome/Makefile b/src/mesa/drivers/dri/unichrome/Makefile index 5cef902860d..1d43e5d8b90 100644 --- a/src/mesa/drivers/dri/unichrome/Makefile +++ b/src/mesa/drivers/dri/unichrome/Makefile @@ -13,7 +13,9 @@ COMMON_SOURCES = \ ../common/utils.c \ ../common/texmem.c \ ../common/vblank.c \ - ../common/xmlconfig.c + ../common/xmlconfig.c \ + ../common/dri_util.c \ + ../common/glcontextmodes.c DRIVER_SOURCES = \ via_context.c \ diff --git a/src/mesa/drivers/dri/x11/Makefile b/src/mesa/drivers/dri/x11/Makefile index b98441a299a..9804411030f 100644 --- a/src/mesa/drivers/dri/x11/Makefile +++ b/src/mesa/drivers/dri/x11/Makefile @@ -7,7 +7,7 @@ LIBNAME = x11_dri.so DRIVER_SOURCES = x11_dri.c \ $(TOP)/src/mesa/drivers/common/driverfuncs.c \ - ../dri_client/dri_util.c \ + ../common/dri_util.c \ ../../x11/xm_api.c \ ../../x11/xm_dd.c \ ../../x11/xm_line.c \