dri_util.c revision 7c46033130b1b4d6098647d85c2710367572e079
1680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/* $XFree86: xc/lib/GL/dri/dri_util.c,v 1.7 2003/04/28 17:01:25 dawes Exp $ */
2680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/**
3680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \file dri_util.c
4680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * DRI utility functions.
5680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
6680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * This module acts as glue between GLX and the actual hardware driver.  A DRI
7680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * driver doesn't really \e have to use any of this - it's optional.  But, some
8680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * useful stuff is done here that otherwise would have to be duplicated in most
9680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * drivers.
10680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
11680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * Basically, these utility functions take care of some of the dirty details of
12680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * screen initialization, context creation, context binding, DRM setup, etc.
13680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
14680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * These functions are compiled into each DRI driver so libGL.so knows nothing
15680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * about them.
16680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
17680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \note
18680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * When \c DRI_NEW_INTERFACE_ONLY is defined, code is built / not built so
19680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * that only the "new" libGL-to-driver interfaces are supported.  This breaks
20680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * backwards compatability.  However, this may be necessary when DRI drivers
21680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * are built to be used in non-XFree86 environments.
22680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
23680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \todo There are still some places in the code that need to be wrapped with
24680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *       \c DRI_NEW_INTERFACE_ONLY.
25680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */
26680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
27680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
28680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell#ifdef GLX_DIRECT_RENDERING
29680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
30680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell#include <inttypes.h>
31680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell#include <assert.h>
32680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell#include <stdarg.h>
33680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell#include <unistd.h>
34680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell#include <sys/mman.h>
35680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell#include <stdio.h>
367c46033130b1b4d6098647d85c2710367572e079Ian Romanick
37318aa8409983f3292b4919196df2ca42f4de6a16Ian Romanick#ifndef DRI_NEW_INTERFACE_ONLY
387c46033130b1b4d6098647d85c2710367572e079Ian Romanick# include <X11/Xlibint.h>
397c46033130b1b4d6098647d85c2710367572e079Ian Romanick# include <Xext.h>
407c46033130b1b4d6098647d85c2710367572e079Ian Romanick# include <extutil.h>
41318aa8409983f3292b4919196df2ca42f4de6a16Ian Romanick# include "xf86dri.h"
427c46033130b1b4d6098647d85c2710367572e079Ian Romanick# define _mesa_malloc(b) Xmalloc(b)
437c46033130b1b4d6098647d85c2710367572e079Ian Romanick# define _mesa_free(m) Xfree(m)
447c46033130b1b4d6098647d85c2710367572e079Ian Romanick#else
457c46033130b1b4d6098647d85c2710367572e079Ian Romanick# include "imports.h"
467c46033130b1b4d6098647d85c2710367572e079Ian Romanick# define None 0
47318aa8409983f3292b4919196df2ca42f4de6a16Ian Romanick#endif /* DRI_NEW_INTERFACE_ONLY */
487c46033130b1b4d6098647d85c2710367572e079Ian Romanick
497c46033130b1b4d6098647d85c2710367572e079Ian Romanick#include "dri_util.h"
50ffb36d57a5f6359b5b91b73af60482a0016dd431Jon Smirl#include "drm_sarea.h"
51680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell#include "glcontextmodes.h"
52680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
538cdccc82d7948daee256e092a5253d49e277ef75Ian Romanick#ifndef GLX_OML_sync_control
547c46033130b1b4d6098647d85c2710367572e079Ian Romanicktypedef GLboolean ( * PFNGLXGETMSCRATEOMLPROC) (__DRInativeDisplay *dpy, __DRIid drawable, int32_t *numerator, int32_t *denominator);
558cdccc82d7948daee256e092a5253d49e277ef75Ian Romanick#endif
568cdccc82d7948daee256e092a5253d49e277ef75Ian Romanick
57680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/**
58680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * This is used in a couple of places that call \c driCreateNewDrawable.
59680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */
60680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwellstatic const int empty_attribute_list[1] = { None };
61680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
62680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/**
63680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * Function used to determine if a drawable (window) still exists.  Ideally
64680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * this function comes from libGL.  With older versions of libGL from XFree86
65680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * we can fall-back to an internal version.
66680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
67680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \sa __driWindowExists __glXWindowExists
68680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */
69680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwellstatic PFNGLXWINDOWEXISTSPROC window_exists;
70680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
717c46033130b1b4d6098647d85c2710367572e079Ian Romanicktypedef GLboolean (*PFNGLXCREATECONTEXTWITHCONFIGPROC)( __DRInativeDisplay*, int, int, void *,
72c06b25594e5effe34a90c067e1a3da0f61cf2b13Ian Romanick    drm_context_t * );
73680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
74680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwellstatic PFNGLXCREATECONTEXTWITHCONFIGPROC create_context_with_config;
75680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
76680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/**
77680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * Cached copy of the internal API version used by libGL and the client-side
78680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * DRI driver.
79680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */
80680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwellstatic int api_ver = 0;
81680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
82680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/* forward declarations */
8360b0e12830310e7c05b4043857ed277b28b1c781Ian Romanickstatic int driQueryFrameTracking( __DRInativeDisplay * dpy, void * priv,
84680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    int64_t * sbc, int64_t * missedFrames, float * lastMissedUsage,
85680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    float * usage );
86680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
8760b0e12830310e7c05b4043857ed277b28b1c781Ian Romanickstatic void *driCreateNewDrawable(__DRInativeDisplay *dpy, const __GLcontextModes *modes,
880521ab46c1340d785ecfe64f4041c86912bc86afIan Romanick    __DRIid draw, __DRIdrawable *pdraw, int renderType, const int *attrs);
89680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
9060b0e12830310e7c05b4043857ed277b28b1c781Ian Romanickstatic void driDestroyDrawable(__DRInativeDisplay *dpy, void *drawablePrivate);
91680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
92680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
93680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
94680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
95680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell#ifdef not_defined
967c46033130b1b4d6098647d85c2710367572e079Ian Romanickstatic GLboolean driFeatureOn(const char *name)
97680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{
98680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    char *env = getenv(name);
99680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
100680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    if (!env) return GL_FALSE;
101680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    if (!strcasecmp(env, "enable")) return GL_TRUE;
102680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    if (!strcasecmp(env, "1"))      return GL_TRUE;
103680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    if (!strcasecmp(env, "on"))     return GL_TRUE;
104680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    if (!strcasecmp(env, "true"))   return GL_TRUE;
105680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    if (!strcasecmp(env, "t"))      return GL_TRUE;
106680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    if (!strcasecmp(env, "yes"))    return GL_TRUE;
107680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    if (!strcasecmp(env, "y"))      return GL_TRUE;
108680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
109680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    return GL_FALSE;
110680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell}
111680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell#endif /* not_defined */
112680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
113680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
114680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/**
115680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * Print message to \c stderr if the \c LIBGL_DEBUG environment variable
116680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * is set.
117680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
118680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * Is called from the drivers.
119680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
120680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param f \c printf like format string.
121680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */
122680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwellvoid
123680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell__driUtilMessage(const char *f, ...)
124680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{
125680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    va_list args;
126680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
127680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    if (getenv("LIBGL_DEBUG")) {
128680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell        fprintf(stderr, "libGL error: \n");
129680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell        va_start(args, f);
130680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell        vfprintf(stderr, f, args);
131680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell        va_end(args);
132680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell        fprintf(stderr, "\n");
133680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    }
134680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell}
135680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
136680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
137680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*****************************************************************/
138680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/** \name Visual utility functions                               */
139680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*****************************************************************/
140680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*@{*/
141680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
142680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell#ifndef DRI_NEW_INTERFACE_ONLY
143680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/**
144680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * Find a \c __GLcontextModes structure matching the given visual ID.
145680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
146680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param dpy   Display to search for a matching configuration.
147680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param scrn  Screen number on \c dpy to be searched.
148680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param vid   Desired \c VisualID to find.
149680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
150680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \returns A pointer to a \c __GLcontextModes structure that matches \c vid,
151680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *          if found, or \c NULL if no match is found.
152680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */
153680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwellstatic const __GLcontextModes *
15460b0e12830310e7c05b4043857ed277b28b1c781Ian RomanickfindConfigMode(__DRInativeDisplay *dpy, int scrn, VisualID vid,
155680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	       const __DRIscreen * pDRIScreen)
156680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{
157680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    if ( (pDRIScreen != NULL) && (pDRIScreen->private != NULL) ) {
158680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	const __DRIscreenPrivate * const psp =
159680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	    (const __DRIscreenPrivate *) pDRIScreen->private;
160680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
161680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	return _gl_context_modes_find_visual( psp->modes, vid );
162680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    }
163680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
164680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    return NULL;
165680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell}
166680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
167680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
168680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/**
169680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * This function is a hack to work-around old versions of libGL.so that
170680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * do not export \c XF86DRICreateContextWithConfig.  I would modify the
171680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * code to just use this function, but the stand-alone driver (i.e., DRI
172680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * drivers that are built to work without XFree86) shouldn't have to know
173680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * about X structures like a \c Visual.
174680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */
1757c46033130b1b4d6098647d85c2710367572e079Ian Romanickstatic GLboolean
17660b0e12830310e7c05b4043857ed277b28b1c781Ian Romanickfake_XF86DRICreateContextWithConfig( __DRInativeDisplay* dpy, int screen, int configID,
177c06b25594e5effe34a90c067e1a3da0f61cf2b13Ian Romanick				     XID* context, drm_context_t * hHWContext )
178680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{
179680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    Visual  vis;
180680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
181680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    vis.visualid = configID;
182680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    return XF86DRICreateContext( dpy, screen, & vis, context, hHWContext );
183680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell}
184680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell#endif /* DRI_NEW_INTERFACE_ONLY */
185680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
186680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*@}*/
187680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
188680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
189680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*****************************************************************/
190680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/** \name Drawable list management */
191680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*****************************************************************/
192680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*@{*/
193680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
1947c46033130b1b4d6098647d85c2710367572e079Ian Romanickstatic GLboolean __driAddDrawable(void *drawHash, __DRIdrawable *pdraw)
195680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{
196680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    __DRIdrawablePrivate *pdp = (__DRIdrawablePrivate *)pdraw->private;
197680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
198680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    if (drmHashInsert(drawHash, pdp->draw, pdraw))
199680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	return GL_FALSE;
200680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
201680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    return GL_TRUE;
202680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell}
203680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
2040521ab46c1340d785ecfe64f4041c86912bc86afIan Romanickstatic __DRIdrawable *__driFindDrawable(void *drawHash, __DRIid draw)
205680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{
206680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    int retcode;
207680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    __DRIdrawable *pdraw;
208680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
209680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    retcode = drmHashLookup(drawHash, draw, (void **)&pdraw);
210680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    if (retcode)
211680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	return NULL;
212680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
213680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    return pdraw;
214680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell}
215680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
216680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwellstatic void __driRemoveDrawable(void *drawHash, __DRIdrawable *pdraw)
217680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{
218680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    int retcode;
219680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    __DRIdrawablePrivate *pdp = (__DRIdrawablePrivate *)pdraw->private;
220680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
221680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    retcode = drmHashLookup(drawHash, pdp->draw, (void **)&pdraw);
222680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    if (!retcode) { /* Found */
223680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	drmHashDelete(drawHash, pdp->draw);
224680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    }
225680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell}
226680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
227680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell#ifndef DRI_NEW_INTERFACE_ONLY
2287c46033130b1b4d6098647d85c2710367572e079Ian Romanickstatic GLboolean __driWindowExistsFlag;
229680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
230680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwellstatic int __driWindowExistsErrorHandler(Display *dpy, XErrorEvent *xerr)
231680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{
232680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    if (xerr->error_code == BadWindow) {
233680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	__driWindowExistsFlag = GL_FALSE;
234680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    }
235680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    return 0;
236680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell}
237680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
238680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/**
239680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * Determine if a window associated with a \c GLXDrawable exists on the
240680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * X-server.
241680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
242680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param dpy  Display associated with the drawable to be queried.
243680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param draw \c GLXDrawable to test.
244680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
245680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \returns \c GL_TRUE if a window exists that is associated with \c draw,
246680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *          otherwise \c GL_FALSE is returned.
247680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
248680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \warning This function is not currently thread-safe.
249680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
250680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \deprecated
251680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \c __glXWindowExists (from libGL) is prefered over this function.  Starting
252680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * with the next major release of XFree86, this function will be removed.
253680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * Even now this function is no longer directly called.  Instead it is called
254680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * via a function pointer if and only if \c __glXWindowExists does not exist.
255680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
256680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \sa __glXWindowExists glXGetProcAddress window_exists
257680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */
2587c46033130b1b4d6098647d85c2710367572e079Ian Romanickstatic GLboolean __driWindowExists(Display *dpy, GLXDrawable draw)
259680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{
260680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    XWindowAttributes xwa;
261680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    int (*oldXErrorHandler)(Display *, XErrorEvent *);
262680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
263680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    XSync(dpy, GL_FALSE);
264680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    __driWindowExistsFlag = GL_TRUE;
265680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    oldXErrorHandler = XSetErrorHandler(__driWindowExistsErrorHandler);
266680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    XGetWindowAttributes(dpy, draw, &xwa); /* dummy request */
267680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    XSetErrorHandler(oldXErrorHandler);
268680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    return __driWindowExistsFlag;
269680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell}
270680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell#endif /* DRI_NEW_INTERFACE_ONLY */
271680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
272680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/**
273680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * Find drawables in the local hash that have been destroyed on the
274680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * server.
275680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
276680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param drawHash  Hash-table containing all know drawables.
277680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */
278680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwellstatic void __driGarbageCollectDrawables(void *drawHash)
279680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{
2800521ab46c1340d785ecfe64f4041c86912bc86afIan Romanick    __DRIid draw;
281680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    __DRIdrawable *pdraw;
28260b0e12830310e7c05b4043857ed277b28b1c781Ian Romanick    __DRInativeDisplay *dpy;
283680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
284680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    if (drmHashFirst(drawHash, &draw, (void **)&pdraw)) {
285680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	do {
286680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	    __DRIdrawablePrivate *pdp = (__DRIdrawablePrivate *)pdraw->private;
287680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	    dpy = pdp->driScreenPriv->display;
288680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	    if (! (*window_exists)(dpy, draw)) {
289680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell		/* Destroy the local drawable data in the hash table, if the
290680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell		   drawable no longer exists in the Xserver */
291680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell		__driRemoveDrawable(drawHash, pdraw);
292680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell		(*pdraw->destroyDrawable)(dpy, pdraw->private);
2937c46033130b1b4d6098647d85c2710367572e079Ian Romanick		_mesa_free(pdraw);
294680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	    }
295680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	} while (drmHashNext(drawHash, &draw, (void **)&pdraw));
296680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    }
297680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell}
298680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
299680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*@}*/
300680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
301680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
302680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*****************************************************************/
303680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/** \name Context (un)binding functions                          */
304680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*****************************************************************/
305680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*@{*/
306680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
307680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/**
308680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * Unbind context.
309680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
310680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param dpy the display handle.
311680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param scrn the screen number.
312680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param draw drawable.
313680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param read Current reading drawable.
314680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param gc context.
315680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
316680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \return \c GL_TRUE on success, or \c GL_FALSE on failure.
317680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
318680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \internal
319680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * This function calls __DriverAPIRec::UnbindContext, and then decrements
320680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * __DRIdrawablePrivateRec::refcount which must be non-zero for a successful
321680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * return.
322680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
323680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * While casting the opaque private pointers associated with the parameters
324680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * into their respective real types it also assures they are not \c NULL.
325680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */
326ffb36d57a5f6359b5b91b73af60482a0016dd431Jon Smirlstatic GLboolean driUnbindContext3(__DRInativeDisplay *dpy, int scrn,
3270521ab46c1340d785ecfe64f4041c86912bc86afIan Romanick			      __DRIid draw, __DRIid read,
32874d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell			      __DRIcontext *ctx)
329680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{
330680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    __DRIscreen *pDRIScreen;
331680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    __DRIdrawable *pdraw;
332680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    __DRIdrawable *pread;
333680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    __DRIcontextPrivate *pcp;
334680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    __DRIscreenPrivate *psp;
335680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    __DRIdrawablePrivate *pdp;
336680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    __DRIdrawablePrivate *prp;
337680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
338680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    /*
339680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    ** Assume error checking is done properly in glXMakeCurrent before
34074d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell    ** calling driUnbindContext3.
341680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    */
342680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
34374d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell    if (ctx == NULL || draw == None || read == None) {
344680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	/* ERROR!!! */
345680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	return GL_FALSE;
346680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    }
347680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
348680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    pDRIScreen = __glXFindDRIScreen(dpy, scrn);
349680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    if ( (pDRIScreen == NULL) || (pDRIScreen->private == NULL) ) {
350680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	/* ERROR!!! */
351680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	return GL_FALSE;
352680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    }
353680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
354680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    psp = (__DRIscreenPrivate *)pDRIScreen->private;
35574d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell    pcp = (__DRIcontextPrivate *)ctx->private;
356680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
357680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    pdraw = __driFindDrawable(psp->drawHash, draw);
358680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    if (!pdraw) {
359680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	/* ERROR!!! */
360680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	return GL_FALSE;
361680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    }
362680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    pdp = (__DRIdrawablePrivate *)pdraw->private;
363680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
364680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    pread = __driFindDrawable(psp->drawHash, read);
365680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    if (!pread) {
366680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	/* ERROR!!! */
367680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	return GL_FALSE;
368680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    }
369680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    prp = (__DRIdrawablePrivate *)pread->private;
370680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
371680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
372680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    /* Let driver unbind drawable from context */
373680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    (*psp->DriverAPI.UnbindContext)(pcp);
374680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
375680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
376680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    if (pdp->refcount == 0) {
377680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	/* ERROR!!! */
378680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	return GL_FALSE;
379680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    }
380680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
381680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    pdp->refcount--;
382680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
383680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    if (prp != pdp) {
384680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell        if (prp->refcount == 0) {
385680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	    /* ERROR!!! */
386680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	    return GL_FALSE;
387680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	}
388680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
389680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	prp->refcount--;
390680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    }
391680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
392680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
393680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    /* XXX this is disabled so that if we call SwapBuffers on an unbound
394680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell     * window we can determine the last context bound to the window and
395680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell     * use that context's lock. (BrianP, 2-Dec-2000)
396680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell     */
397680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell#if 0
398680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    /* Unbind the drawable */
399680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    pcp->driDrawablePriv = NULL;
400680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    pdp->driContextPriv = &psp->dummyContextPriv;
401680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell#endif
402680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
403680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    return GL_TRUE;
404680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell}
405680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
406680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
407680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/**
408680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * This function takes both a read buffer and a draw buffer.  This is needed
409680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * for \c glXMakeCurrentReadSGI or GLX 1.3's \c glXMakeContextCurrent
410680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * function.
411680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
412680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \bug This function calls \c driCreateNewDrawable in two places with the
413680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *      \c renderType hard-coded to \c GLX_WINDOW_BIT.  Some checking might
414680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *      be needed in those places when support for pbuffers and / or pixmaps
415680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *      is added.  Is it safe to assume that the drawable is a window?
416680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */
4177c46033130b1b4d6098647d85c2710367572e079Ian Romanickstatic GLboolean DoBindContext(__DRInativeDisplay *dpy,
4180521ab46c1340d785ecfe64f4041c86912bc86afIan Romanick			  __DRIid draw, __DRIid read,
41974d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell			  __DRIcontext *ctx, const __GLcontextModes * modes,
42074d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell			  __DRIscreenPrivate *psp)
421680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{
422680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    __DRIdrawable *pdraw;
423680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    __DRIdrawablePrivate *pdp;
424680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    __DRIdrawable *pread;
425680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    __DRIdrawablePrivate *prp;
42674d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell    __DRIcontextPrivate * const pcp = ctx->private;
427680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
428680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
4290521ab46c1340d785ecfe64f4041c86912bc86afIan Romanick    /* Find the _DRIdrawable which corresponds to the writing drawable. */
430680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    pdraw = __driFindDrawable(psp->drawHash, draw);
431680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    if (!pdraw) {
432680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	/* Allocate a new drawable */
4337c46033130b1b4d6098647d85c2710367572e079Ian Romanick	pdraw = (__DRIdrawable *)_mesa_malloc(sizeof(__DRIdrawable));
434680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	if (!pdraw) {
435680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	    /* ERROR!!! */
436680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	    return GL_FALSE;
437680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	}
438680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
439680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	/* Create a new drawable */
440680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	driCreateNewDrawable(dpy, modes, draw, pdraw, GLX_WINDOW_BIT,
441680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell			     empty_attribute_list);
442680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	if (!pdraw->private) {
443680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	    /* ERROR!!! */
4447c46033130b1b4d6098647d85c2710367572e079Ian Romanick	    _mesa_free(pdraw);
445680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	    return GL_FALSE;
446680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	}
447680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
448680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    }
449680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    pdp = (__DRIdrawablePrivate *) pdraw->private;
450680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
4510521ab46c1340d785ecfe64f4041c86912bc86afIan Romanick    /* Find the _DRIdrawable which corresponds to the reading drawable. */
452680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    if (read == draw) {
453680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell        /* read buffer == draw buffer */
454680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell        prp = pdp;
455680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    }
456680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    else {
457680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell        pread = __driFindDrawable(psp->drawHash, read);
458680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell        if (!pread) {
459680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell            /* Allocate a new drawable */
4607c46033130b1b4d6098647d85c2710367572e079Ian Romanick            pread = (__DRIdrawable *)_mesa_malloc(sizeof(__DRIdrawable));
461680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell            if (!pread) {
462680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell                /* ERROR!!! */
463680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell                return GL_FALSE;
464680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell            }
465680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
466680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell            /* Create a new drawable */
467680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	    driCreateNewDrawable(dpy, modes, read, pread, GLX_WINDOW_BIT,
468680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell				 empty_attribute_list);
469680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell            if (!pread->private) {
470680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell                /* ERROR!!! */
4717c46033130b1b4d6098647d85c2710367572e079Ian Romanick                _mesa_free(pread);
472680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell                return GL_FALSE;
473680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell            }
474680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell        }
475680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell        prp = (__DRIdrawablePrivate *) pread->private;
476680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    }
477680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
478680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    /* Bind the drawable to the context */
479680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    pcp->driDrawablePriv = pdp;
480680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    pdp->driContextPriv = pcp;
481680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    pdp->refcount++;
482680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    if ( pdp != prp ) {
483680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	prp->refcount++;
484680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    }
485680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
486680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    /*
487680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    ** Now that we have a context associated with this drawable, we can
488680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    ** initialize the drawable information if has not been done before.
489680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    */
490680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    if (!pdp->pStamp || *pdp->pStamp != pdp->lastStamp) {
491680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	DRM_SPINLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID);
492680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	__driUtilUpdateDrawableInfo(pdp);
493680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	DRM_SPINUNLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID);
494680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    }
495680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
496680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    /* Call device-specific MakeCurrent */
497680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    (*psp->DriverAPI.MakeCurrent)(pcp, pdp, prp);
498680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
499680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    return GL_TRUE;
500680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell}
501680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
502680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
50374d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell/**
50474d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell * This function takes both a read buffer and a draw buffer.  This is needed
50574d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell * for \c glXMakeCurrentReadSGI or GLX 1.3's \c glXMakeContextCurrent
50674d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell * function.
50774d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell */
508ffb36d57a5f6359b5b91b73af60482a0016dd431Jon Smirlstatic GLboolean driBindContext3(__DRInativeDisplay *dpy, int scrn,
5090521ab46c1340d785ecfe64f4041c86912bc86afIan Romanick                            __DRIid draw, __DRIid read,
51074d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell                            __DRIcontext * ctx)
51174d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell{
51274d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell    __DRIscreen *pDRIScreen;
51374d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell
51474d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell    /*
51574d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell    ** Assume error checking is done properly in glXMakeCurrent before
51674d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell    ** calling driBindContext.
51774d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell    */
51874d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell
51974d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell    if (ctx == NULL || draw == None || read == None) {
52074d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell	/* ERROR!!! */
52174d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell	return GL_FALSE;
52274d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell    }
52374d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell
52474d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell    pDRIScreen = __glXFindDRIScreen(dpy, scrn);
52574d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell    if ( (pDRIScreen == NULL) || (pDRIScreen->private == NULL) ) {
52674d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell	/* ERROR!!! */
52774d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell	return GL_FALSE;
52874d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell    }
52974d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell
53074d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell    return DoBindContext( dpy, draw, read, ctx, ctx->mode,
53174d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell			  (__DRIscreenPrivate *)pDRIScreen->private );
53274d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell}
53374d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell
53474d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell
53574d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell#ifndef DRI_NEW_INTERFACE_ONLY
53674d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell/**
53774d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell * This function takes both a read buffer and a draw buffer.  This is needed
53874d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell * for \c glXMakeCurrentReadSGI or GLX 1.3's \c glXMakeContextCurrent
53974d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell * function.
54074d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell */
5417c46033130b1b4d6098647d85c2710367572e079Ian Romanickstatic GLboolean driBindContext2(Display *dpy, int scrn,
54274d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell                            GLXDrawable draw, GLXDrawable read,
54374d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell                            GLXContext gc)
54474d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell{
54574d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell    __DRIscreen *pDRIScreen;
54674d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell    const __GLcontextModes *modes;
54774d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell
54874d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell    /*
54974d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell    ** Assume error checking is done properly in glXMakeCurrent before
55074d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell    ** calling driBindContext.
55174d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell    */
55274d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell
55374d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell    if (gc == NULL || draw == None || read == None) {
55474d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell	/* ERROR!!! */
55574d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell	return GL_FALSE;
55674d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell    }
55774d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell
55874d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell    pDRIScreen = __glXFindDRIScreen(dpy, scrn);
55974d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell    modes = (driCompareGLXAPIVersion( 20040317 ) >= 0)
56074d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell	? gc->driContext.mode
56174d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell	: findConfigMode( dpy, scrn, gc->vid, pDRIScreen );
56274d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell
56374d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell    if ( modes == NULL ) {
56474d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell	/* ERROR!!! */
56574d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell	return GL_FALSE;
56674d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell    }
56774d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell
56874d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell    /* findConfigMode will return NULL if the DRI screen or screen private
56974d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell     * are NULL.
57074d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell     */
57174d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell    assert( (pDRIScreen != NULL) && (pDRIScreen->private != NULL) );
57274d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell
57374d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell    return DoBindContext( dpy, draw, read, & gc->driContext, modes,
57474d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell			  (__DRIscreenPrivate *)pDRIScreen->private );
57574d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell}
57674d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell
5777c46033130b1b4d6098647d85c2710367572e079Ian Romanickstatic GLboolean driUnbindContext2(Display *dpy, int scrn,
57874d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell			      GLXDrawable draw, GLXDrawable read,
57974d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell			      GLXContext gc)
58074d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell{
58174d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell    return driUnbindContext3(dpy, scrn, draw, read, & gc->driContext);
58274d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell}
58374d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell
584680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*
585680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * Simply call bind with the same GLXDrawable for the read and draw buffers.
586680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */
5877c46033130b1b4d6098647d85c2710367572e079Ian Romanickstatic GLboolean driBindContext(Display *dpy, int scrn,
588680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell                           GLXDrawable draw, GLXContext gc)
589680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{
590680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    return driBindContext2(dpy, scrn, draw, draw, gc);
591680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell}
592680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
593680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
594680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*
595680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * Simply call bind with the same GLXDrawable for the read and draw buffers.
596680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */
5977c46033130b1b4d6098647d85c2710367572e079Ian Romanickstatic GLboolean driUnbindContext(Display *dpy, int scrn,
598680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell                             GLXDrawable draw, GLXContext gc,
599680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell                             int will_rebind)
600680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{
601680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell   (void) will_rebind;
602680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell   return driUnbindContext2( dpy, scrn, draw, draw, gc );
603680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell}
60474d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell#endif /* DRI_NEW_INTERFACE_ONLY */
605680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
606680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*@}*/
607680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
608680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
609680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*****************************************************************/
610680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/** \name Drawable handling functions                            */
611680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*****************************************************************/
612680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*@{*/
613680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
614680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/**
615680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * Update private drawable information.
616680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
617680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param pdp pointer to the private drawable information to update.
618680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
619680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * This function basically updates the __DRIdrawablePrivate struct's
620680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * cliprect information by calling \c __DRIDrawablePrivate::getInfo.  This is
621680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * usually called by the DRI_VALIDATE_DRAWABLE_INFO macro which
622680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * compares the __DRIdrwablePrivate pStamp and lastStamp values.  If
623680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * the values are different that means we have to update the clipping
624680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * info.
625680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */
626680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwellvoid
627680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell__driUtilUpdateDrawableInfo(__DRIdrawablePrivate *pdp)
628680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{
629680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    __DRIscreenPrivate *psp;
630680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    __DRIcontextPrivate *pcp = pdp->driContextPriv;
631680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
632680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    if (!pcp || (pdp != pcp->driDrawablePriv)) {
633680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	/* ERROR!!! */
634680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	return;
635680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    }
636680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
637680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    psp = pdp->driScreenPriv;
638680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    if (!psp) {
639680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	/* ERROR!!! */
640680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	return;
641680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    }
642680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
643680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    if (pdp->pClipRects) {
6447c46033130b1b4d6098647d85c2710367572e079Ian Romanick	_mesa_free(pdp->pClipRects);
645680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    }
646680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
647680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    if (pdp->pBackClipRects) {
6487c46033130b1b4d6098647d85c2710367572e079Ian Romanick	_mesa_free(pdp->pBackClipRects);
649680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    }
650680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
651680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    DRM_SPINUNLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID);
652680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
653680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    if (!__driFindDrawable(psp->drawHash, pdp->draw) ||
654680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	! (*pdp->getInfo)(pdp->display, pdp->screen, pdp->draw,
655680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell			  &pdp->index, &pdp->lastStamp,
656680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell			  &pdp->x, &pdp->y, &pdp->w, &pdp->h,
657680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell			  &pdp->numClipRects, &pdp->pClipRects,
658680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell			  &pdp->backX,
659680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell			  &pdp->backY,
660680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell			  &pdp->numBackClipRects,
661680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell			  &pdp->pBackClipRects )) {
662680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	/* Error -- eg the window may have been destroyed.  Keep going
663680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	 * with no cliprects.
664680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	 */
665680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell        pdp->pStamp = &pdp->lastStamp; /* prevent endless loop */
666680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	pdp->numClipRects = 0;
667680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	pdp->pClipRects = NULL;
668680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	pdp->numBackClipRects = 0;
669680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	pdp->pBackClipRects = NULL;
670680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    }
671680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    else
672680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell       pdp->pStamp = &(psp->pSAREA->drawableTable[pdp->index].stamp);
673680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
674680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    DRM_SPINLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID);
675680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
676680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell}
677680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
678680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*@}*/
679680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
680680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*****************************************************************/
681680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/** \name GLX callbacks                                          */
682680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*****************************************************************/
683680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*@{*/
684680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
685680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/**
686680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * Swap buffers.
687680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
688680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param dpy the display handle.
689680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param drawablePrivate opaque pointer to the per-drawable private info.
690680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
691680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \internal
692680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * This function calls __DRIdrawablePrivate::swapBuffers.
693680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
694680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * Is called directly from glXSwapBuffers().
695680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */
69660b0e12830310e7c05b4043857ed277b28b1c781Ian Romanickstatic void driSwapBuffers( __DRInativeDisplay *dpy, void *drawablePrivate )
697680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{
698680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    __DRIdrawablePrivate *dPriv = (__DRIdrawablePrivate *) drawablePrivate;
699680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    dPriv->swapBuffers(dPriv);
700680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    (void) dpy;
701680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell}
702680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
703680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/**
704680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * Called directly from a number of higher-level GLX functions.
705680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */
706680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwellstatic int driGetMSC( void *screenPrivate, int64_t *msc )
707680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{
708680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    __DRIscreenPrivate *sPriv = (__DRIscreenPrivate *) screenPrivate;
709680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
710680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    return sPriv->DriverAPI.GetMSC( sPriv, msc );
711680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell}
712680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
713680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/**
714680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * Called directly from a number of higher-level GLX functions.
715680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */
71660b0e12830310e7c05b4043857ed277b28b1c781Ian Romanickstatic int driGetSBC( __DRInativeDisplay *dpy, void *drawablePrivate, int64_t *sbc )
717680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{
718680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell   __DRIdrawablePrivate *dPriv = (__DRIdrawablePrivate *) drawablePrivate;
719680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell   __DRIswapInfo  sInfo;
720680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell   int  status;
721680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
722680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
723680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell   status = dPriv->driScreenPriv->DriverAPI.GetSwapInfo( dPriv, & sInfo );
724680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell   *sbc = sInfo.swap_count;
725680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
726680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell   return status;
727680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell}
728680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
72960b0e12830310e7c05b4043857ed277b28b1c781Ian Romanickstatic int driWaitForSBC( __DRInativeDisplay * dpy, void *drawablePriv,
730680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell			  int64_t target_sbc,
731680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell			  int64_t * msc, int64_t * sbc )
732680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{
733680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    __DRIdrawablePrivate *dPriv = (__DRIdrawablePrivate *) drawablePriv;
734680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
735680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    return dPriv->driScreenPriv->DriverAPI.WaitForSBC( dPriv, target_sbc,
736680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell                                                       msc, sbc );
737680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell}
738680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
73960b0e12830310e7c05b4043857ed277b28b1c781Ian Romanickstatic int driWaitForMSC( __DRInativeDisplay * dpy, void *drawablePriv,
740680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell			  int64_t target_msc,
741680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell			  int64_t divisor, int64_t remainder,
742680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell			  int64_t * msc, int64_t * sbc )
743680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{
744680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    __DRIdrawablePrivate *dPriv = (__DRIdrawablePrivate *) drawablePriv;
745680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    __DRIswapInfo  sInfo;
746680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    int  status;
747680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
748680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
749680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    status = dPriv->driScreenPriv->DriverAPI.WaitForMSC( dPriv, target_msc,
750680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell                                                         divisor, remainder,
751680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell                                                         msc );
752680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
753680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    /* GetSwapInfo() may not be provided by the driver if GLX_SGI_video_sync
754680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell     * is supported but GLX_OML_sync_control is not.  Therefore, don't return
755680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell     * an error value if GetSwapInfo() is not implemented.
756680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    */
757680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    if ( status == 0
758680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell         && dPriv->driScreenPriv->DriverAPI.GetSwapInfo ) {
759680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell        status = dPriv->driScreenPriv->DriverAPI.GetSwapInfo( dPriv, & sInfo );
760680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell        *sbc = sInfo.swap_count;
761680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    }
762680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
763680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    return status;
764680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell}
765680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
76660b0e12830310e7c05b4043857ed277b28b1c781Ian Romanickstatic int64_t driSwapBuffersMSC( __DRInativeDisplay * dpy, void *drawablePriv,
767680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell				  int64_t target_msc,
768680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell				  int64_t divisor, int64_t remainder )
769680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{
770680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    __DRIdrawablePrivate *dPriv = (__DRIdrawablePrivate *) drawablePriv;
771680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
772680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    return dPriv->driScreenPriv->DriverAPI.SwapBuffersMSC( dPriv, target_msc,
773680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell                                                           divisor,
774680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell                                                           remainder );
775680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell}
776680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
777680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
778680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/**
779680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * This is called via __DRIscreenRec's createNewDrawable pointer.
780680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */
78160b0e12830310e7c05b4043857ed277b28b1c781Ian Romanickstatic void *driCreateNewDrawable(__DRInativeDisplay *dpy,
782680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell				  const __GLcontextModes *modes,
7830521ab46c1340d785ecfe64f4041c86912bc86afIan Romanick				  __DRIid draw,
784680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell				  __DRIdrawable *pdraw,
785680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell				  int renderType,
786680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell				  const int *attrs)
787680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{
788680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    __DRIscreen * const pDRIScreen = __glXFindDRIScreen(dpy, modes->screen);
789680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    __DRIscreenPrivate *psp;
790680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    __DRIdrawablePrivate *pdp;
791680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
792680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
7931960182ece3f1eca06d2e439f64dd61be8a03ff5Ian Romanick    pdraw->private = NULL;
7941960182ece3f1eca06d2e439f64dd61be8a03ff5Ian Romanick
795680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    /* Since pbuffers are not yet supported, no drawable attributes are
796680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell     * supported either.
797680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell     */
798680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    (void) attrs;
799680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
800680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    if ( (pDRIScreen == NULL) || (pDRIScreen->private == NULL) ) {
801680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	return NULL;
802680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    }
803680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
8047c46033130b1b4d6098647d85c2710367572e079Ian Romanick    pdp = (__DRIdrawablePrivate *)_mesa_malloc(sizeof(__DRIdrawablePrivate));
805680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    if (!pdp) {
806680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	return NULL;
807680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    }
808680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
809680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    if (!XF86DRICreateDrawable(dpy, modes->screen, draw, &pdp->hHWDrawable)) {
8107c46033130b1b4d6098647d85c2710367572e079Ian Romanick	_mesa_free(pdp);
811680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	return NULL;
812680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    }
813680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
814680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    pdp->draw = draw;
815680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    pdp->pdraw = pdraw;
816680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    pdp->refcount = 0;
817680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    pdp->pStamp = NULL;
818680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    pdp->lastStamp = 0;
819680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    pdp->index = 0;
820680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    pdp->x = 0;
821680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    pdp->y = 0;
822680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    pdp->w = 0;
823680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    pdp->h = 0;
824680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    pdp->numClipRects = 0;
825680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    pdp->numBackClipRects = 0;
826680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    pdp->pClipRects = NULL;
827680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    pdp->pBackClipRects = NULL;
828680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    pdp->display = dpy;
829680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    pdp->screen = modes->screen;
830680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
831680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    psp = (__DRIscreenPrivate *)pDRIScreen->private;
832680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    pdp->driScreenPriv = psp;
833680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    pdp->driContextPriv = &psp->dummyContextPriv;
834680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
83560b0e12830310e7c05b4043857ed277b28b1c781Ian Romanick    pdp->getInfo = (PFNGLXGETDRAWABLEINFOPROC)
836680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	glXGetProcAddress( (const GLubyte *) "__glXGetDrawableInfo" );
837680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    if ( pdp->getInfo == NULL ) {
838ec032cb17b2ffb7b9401604258234998612b445fIan Romanick#ifdef DRI_NEW_INTERFACE_ONLY
839ec032cb17b2ffb7b9401604258234998612b445fIan Romanick        (void)XF86DRIDestroyDrawable(dpy, modes->screen, pdp->draw);
8407c46033130b1b4d6098647d85c2710367572e079Ian Romanick	_mesa_free(pdp);
841ec032cb17b2ffb7b9401604258234998612b445fIan Romanick	return NULL;
842ec032cb17b2ffb7b9401604258234998612b445fIan Romanick#else
843680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	pdp->getInfo = XF86DRIGetDrawableInfo;
844ec032cb17b2ffb7b9401604258234998612b445fIan Romanick#endif /* DRI_NEW_INTERFACE_ONLY */
845680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    }
846680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
847680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    if (!(*psp->DriverAPI.CreateBuffer)(psp, pdp, modes,
848680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell					renderType == GLX_PIXMAP_BIT)) {
849680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell       (void)XF86DRIDestroyDrawable(dpy, modes->screen, pdp->draw);
8507c46033130b1b4d6098647d85c2710367572e079Ian Romanick       _mesa_free(pdp);
851680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell       return NULL;
852680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    }
853680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
854680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    pdraw->private = pdp;
855680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    pdraw->destroyDrawable = driDestroyDrawable;
856680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    pdraw->swapBuffers = driSwapBuffers;  /* called by glXSwapBuffers() */
857680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
858680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    if ( driCompareGLXAPIVersion( 20030317 ) >= 0 ) {
859680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell        pdraw->getSBC = driGetSBC;
860680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell        pdraw->waitForSBC = driWaitForSBC;
861680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell        pdraw->waitForMSC = driWaitForMSC;
862680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell        pdraw->swapBuffersMSC = driSwapBuffersMSC;
863680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell        pdraw->frameTracking = NULL;
864680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell        pdraw->queryFrameTracking = driQueryFrameTracking;
865680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
866680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell        /* This special default value is replaced with the configured
867680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	 * default value when the drawable is first bound to a direct
868680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	 * rendering context. */
869680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell        pdraw->swap_interval = (unsigned)-1;
870680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    }
871680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
872680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    pdp->swapBuffers = psp->DriverAPI.SwapBuffers;
873680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
874680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    /* Add pdraw to drawable list */
875680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    if (!__driAddDrawable(psp->drawHash, pdraw)) {
876680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	/* ERROR!!! */
877680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	(*pdraw->destroyDrawable)(dpy, pdp);
8787c46033130b1b4d6098647d85c2710367572e079Ian Romanick	_mesa_free(pdp);
879680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	pdp = NULL;
880680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	pdraw->private = NULL;
881680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    }
882680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
883680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell   return (void *) pdp;
884680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell}
885680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
88660b0e12830310e7c05b4043857ed277b28b1c781Ian Romanickstatic __DRIdrawable *driGetDrawable(__DRInativeDisplay *dpy, __DRIid draw,
887680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell					 void *screenPrivate)
888680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{
889680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    __DRIscreenPrivate *psp = (__DRIscreenPrivate *) screenPrivate;
890680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
891680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    /*
892680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    ** Make sure this routine returns NULL if the drawable is not bound
893680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    ** to a direct rendering context!
894680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    */
895680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    return __driFindDrawable(psp->drawHash, draw);
896680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell}
897680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
89860b0e12830310e7c05b4043857ed277b28b1c781Ian Romanickstatic void driDestroyDrawable(__DRInativeDisplay *dpy, void *drawablePrivate)
899680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{
900680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    __DRIdrawablePrivate *pdp = (__DRIdrawablePrivate *) drawablePrivate;
901680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    __DRIscreenPrivate *psp = pdp->driScreenPriv;
902680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    int scrn = psp->myNum;
903680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
904680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    if (pdp) {
905680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell        (*psp->DriverAPI.DestroyBuffer)(pdp);
906680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	if ((*window_exists)(dpy, pdp->draw))
907680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	    (void)XF86DRIDestroyDrawable(dpy, scrn, pdp->draw);
908680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	if (pdp->pClipRects) {
9097c46033130b1b4d6098647d85c2710367572e079Ian Romanick	    _mesa_free(pdp->pClipRects);
910680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	    pdp->pClipRects = NULL;
911680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	}
912680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	if (pdp->pBackClipRects) {
9137c46033130b1b4d6098647d85c2710367572e079Ian Romanick	    _mesa_free(pdp->pBackClipRects);
914680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	    pdp->pBackClipRects = NULL;
915680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	}
9167c46033130b1b4d6098647d85c2710367572e079Ian Romanick	_mesa_free(pdp);
917680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    }
918680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell}
919680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
920680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*@}*/
921680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
922680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
923680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*****************************************************************/
924680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/** \name Context handling functions                             */
925680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*****************************************************************/
926680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*@{*/
927680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
928680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/**
929680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * Destroy the per-context private information.
930680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
931680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param dpy the display handle.
932680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param scrn the screen number.
933680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param contextPrivate opaque pointer to the per-drawable private info.
934680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
935680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \internal
936680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * This function calls __DriverAPIRec::DestroyContext on \p contextPrivate, calls
937680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * drmDestroyContext(), and finally frees \p contextPrivate.
938680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */
93960b0e12830310e7c05b4043857ed277b28b1c781Ian Romanickstatic void driDestroyContext(__DRInativeDisplay *dpy, int scrn, void *contextPrivate)
940680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{
941680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    __DRIcontextPrivate  *pcp   = (__DRIcontextPrivate *) contextPrivate;
942680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
943680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    if (pcp) {
944680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	(*pcp->driScreenPriv->DriverAPI.DestroyContext)(pcp);
945680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	__driGarbageCollectDrawables(pcp->driScreenPriv->drawHash);
946680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	(void)XF86DRIDestroyContext(dpy, scrn, pcp->contextID);
9477c46033130b1b4d6098647d85c2710367572e079Ian Romanick	_mesa_free(pcp);
948680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    }
949680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell}
950680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
951680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
952680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/**
953680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * Create the per-drawable private driver information.
954680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
955680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param dpy           The display handle.
956680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param modes         Mode used to create the new context.
957680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param render_type   Type of rendering target.  \c GLX_RGBA is the only
958680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *                      type likely to ever be supported for direct-rendering.
959680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param sharedPrivate The shared context dependent methods or \c NULL if
960680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *                      non-existent.
961680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param pctx          DRI context to receive the context dependent methods.
962680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
963680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \returns An opaque pointer to the per-context private information on
964680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *          success, or \c NULL on failure.
965680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
966680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \internal
967680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * This function allocates and fills a __DRIcontextPrivateRec structure.  It
968680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * performs some device independent initialization and passes all the
969680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * relevent information to __DriverAPIRec::CreateContext to create the
970680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * context.
971680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
972680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */
973680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwellstatic void *
97460b0e12830310e7c05b4043857ed277b28b1c781Ian RomanickdriCreateNewContext(__DRInativeDisplay *dpy, const __GLcontextModes *modes,
975680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell		    int render_type, void *sharedPrivate, __DRIcontext *pctx)
976680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{
977680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    __DRIscreen *pDRIScreen;
978680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    __DRIcontextPrivate *pcp;
979680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    __DRIcontextPrivate *pshare = (__DRIcontextPrivate *) sharedPrivate;
980680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    __DRIscreenPrivate *psp;
981680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    void * const shareCtx = (pshare != NULL) ? pshare->driverPrivate : NULL;
982680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
983680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    pDRIScreen = __glXFindDRIScreen(dpy, modes->screen);
984680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    if ( (pDRIScreen == NULL) || (pDRIScreen->private == NULL) ) {
985680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	/* ERROR!!! */
986680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	return NULL;
987680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    }
988680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
989680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    psp = (__DRIscreenPrivate *)pDRIScreen->private;
990680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
9917c46033130b1b4d6098647d85c2710367572e079Ian Romanick    pcp = (__DRIcontextPrivate *)_mesa_malloc(sizeof(__DRIcontextPrivate));
992680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    if (!pcp) {
993680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	return NULL;
994680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    }
995680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
996680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    if (! (*create_context_with_config)(dpy, modes->screen, modes->fbconfigID,
997680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell					&pcp->contextID, &pcp->hHWContext)) {
9987c46033130b1b4d6098647d85c2710367572e079Ian Romanick	_mesa_free(pcp);
999680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	return NULL;
1000680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    }
1001680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
1002680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    pcp->display = dpy;
1003680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    pcp->driScreenPriv = psp;
1004680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    pcp->driDrawablePriv = NULL;
1005680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
1006680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    /* When the first context is created for a screen, initialize a "dummy"
1007680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell     * context.
1008680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell     */
1009680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
1010680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    if (!psp->dummyContextPriv.driScreenPriv) {
1011680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell        psp->dummyContextPriv.contextID = 0;
1012680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell        psp->dummyContextPriv.hHWContext = psp->pSAREA->dummy_context;
1013680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell        psp->dummyContextPriv.driScreenPriv = psp;
1014680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell        psp->dummyContextPriv.driDrawablePriv = NULL;
1015680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell        psp->dummyContextPriv.driverPrivate = NULL;
1016680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	/* No other fields should be used! */
1017680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    }
1018680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
1019680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    pctx->destroyContext = driDestroyContext;
102074d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell#ifdef DRI_NEW_INTERFACE_ONLY
102174d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell    pctx->bindContext    = NULL;
102274d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell    pctx->unbindContext  = NULL;
102374d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell    pctx->bindContext2   = NULL;
102474d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell    pctx->unbindContext2 = NULL;
1025a249ad756f72835c5894e389150207b98532e114Ian Romanick    pctx->bindContext3   = driBindContext3;
102674d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell    pctx->unbindContext3 = driUnbindContext3;
102774d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell#else
1028680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    pctx->bindContext    = driBindContext;
1029680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    pctx->unbindContext  = driUnbindContext;
1030680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    if ( driCompareGLXAPIVersion( 20030606 ) >= 0 ) {
1031680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell        pctx->bindContext2   = driBindContext2;
1032680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell        pctx->unbindContext2 = driUnbindContext2;
1033680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    }
1034680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
103574d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell    if ( driCompareGLXAPIVersion( 20040415 ) >= 0 ) {
103674d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell        pctx->bindContext3   = driBindContext3;
103774d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell        pctx->unbindContext3 = driUnbindContext3;
103874d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell    }
103974d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell#endif
104074d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell
1041680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    if ( !(*psp->DriverAPI.CreateContext)(modes, pcp, shareCtx) ) {
1042680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell        (void)XF86DRIDestroyContext(dpy, modes->screen, pcp->contextID);
10437c46033130b1b4d6098647d85c2710367572e079Ian Romanick        _mesa_free(pcp);
1044680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell        return NULL;
1045680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    }
1046680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
1047680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    __driGarbageCollectDrawables(pcp->driScreenPriv->drawHash);
1048680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
1049680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    return pcp;
1050680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell}
1051680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
1052680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
1053680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell#ifndef DRI_NEW_INTERFACE_ONLY
1054680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/**
1055680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * Create the per-drawable private driver information.
1056680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
1057680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param dpy the display handle.
1058680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param vis the visual information.
1059680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param sharedPrivate the shared context dependent methods or \c NULL if
1060680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *                      non-existent.
1061680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param pctx will receive the context dependent methods.
1062680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
1063680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \returns a opaque pointer to the per-context private information on success, or \c NULL
1064680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * on failure.
1065680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
1066680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \deprecated
1067680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * This function has been replaced by \c driCreateNewContext.  In drivers
1068680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * built to work with XFree86, this function will continue to exist to support
1069680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * older versions of libGL.  Starting with the next major relelase of XFree86,
1070680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * this function will be removed.
1071680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
1072680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \internal
1073680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * This function allocates and fills a __DRIcontextPrivateRec structure.  It
1074680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * gets the visual, converts it into a __GLcontextModesRec and passes it
1075680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * to __DriverAPIRec::CreateContext to create the context.
1076680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */
1077680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwellstatic void *driCreateContext(Display *dpy, XVisualInfo *vis,
1078680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell                              void *sharedPrivate, __DRIcontext *pctx)
1079680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{
1080680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    __DRIscreen *pDRIScreen;
1081680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    const __GLcontextModes *modes;
1082680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
1083680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    pDRIScreen = __glXFindDRIScreen(dpy, vis->screen);
1084680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    if ( (pDRIScreen == NULL) || (pDRIScreen->private == NULL) ) {
1085680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	/* ERROR!!! */
1086680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	return NULL;
1087680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    }
1088680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
1089680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
1090680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    /* Setup a __GLcontextModes struct corresponding to vis->visualid
1091680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell     * and create the rendering context.
1092680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell     */
1093680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
1094680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    modes = findConfigMode(dpy, vis->screen, vis->visualid, pDRIScreen);
1095680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    return (modes == NULL)
1096680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	? NULL
1097680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	: driCreateNewContext( dpy, modes, GLX_RGBA_TYPE,
1098680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell			       sharedPrivate, pctx );
1099680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell}
1100680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell#endif /* DRI_NEW_INTERFACE_ONLY */
1101680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
1102680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*@}*/
1103680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
1104680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
1105680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*****************************************************************/
1106680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/** \name Screen handling functions                              */
1107680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*****************************************************************/
1108680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*@{*/
1109680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
1110680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/**
1111680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * Destroy the per-screen private information.
1112680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
1113680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param dpy the display handle.
1114680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param scrn the screen number.
1115680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param screenPrivate opaque pointer to the per-screen private information.
1116680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
1117680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \internal
1118680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * This function calls __DriverAPIRec::DestroyScreen on \p screenPrivate, calls
1119680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * drmClose(), and finally frees \p screenPrivate.
1120680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */
112160b0e12830310e7c05b4043857ed277b28b1c781Ian Romanickstatic void driDestroyScreen(__DRInativeDisplay *dpy, int scrn, void *screenPrivate)
1122680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{
1123680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    __DRIscreenPrivate *psp = (__DRIscreenPrivate *) screenPrivate;
1124680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
1125680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    if (psp) {
1126680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	/* No interaction with the X-server is possible at this point.  This
1127680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	 * routine is called after XCloseDisplay, so there is no protocol
1128680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	 * stream open to the X-server anymore.
1129680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	 */
1130680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
1131680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	if (psp->DriverAPI.DestroyScreen)
1132680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	    (*psp->DriverAPI.DestroyScreen)(psp);
1133680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
1134680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	(void)drmUnmap((drmAddress)psp->pSAREA, SAREA_MAX);
1135680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	(void)drmUnmap((drmAddress)psp->pFB, psp->fbSize);
11367c46033130b1b4d6098647d85c2710367572e079Ian Romanick	_mesa_free(psp->pDevPriv);
1137680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	(void)drmClose(psp->fd);
1138680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	if ( psp->modes != NULL ) {
1139680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	    _gl_context_modes_destroy( psp->modes );
1140680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	}
11417c46033130b1b4d6098647d85c2710367572e079Ian Romanick	_mesa_free(psp);
1142680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    }
1143680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell}
1144680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
1145680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
1146680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/**
1147680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * Utility function used to create a new driver-private screen structure.
1148680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
1149680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param dpy   Display pointer
1150680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param scrn  Index of the screen
1151680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param psc   DRI screen data (not driver private)
1152680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param modes Linked list of known display modes.  This list is, at a
1153680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *              minimum, a list of modes based on the current display mode.
1154680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *              These roughly match the set of available X11 visuals, but it
1155680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *              need not be limited to X11!  The calling libGL should create
1156680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *              a list that will inform the driver of the current display
1157680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *              mode (i.e., color buffer depth, depth buffer depth, etc.).
1158680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param ddx_version Version of the 2D DDX.  This may not be meaningful for
1159680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *                    all drivers.
1160680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param dri_version Version of the "server-side" DRI.
1161680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param drm_version Version of the kernel DRM.
1162680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param frame_buffer Data describing the location and layout of the
1163680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *                     framebuffer.
1164680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param pSAREA       Pointer the the SAREA.
1165680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param fd           Device handle for the DRM.
1166680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param internal_api_version  Version of the internal interface between the
1167680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *                              driver and libGL.
1168680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param driverAPI Driver API functions used by other routines in dri_util.c.
1169680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */
1170680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell__DRIscreenPrivate *
117160b0e12830310e7c05b4043857ed277b28b1c781Ian Romanick__driUtilCreateNewScreen(__DRInativeDisplay *dpy, int scrn, __DRIscreen *psc,
1172680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell			 __GLcontextModes * modes,
1173680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell			 const __DRIversion * ddx_version,
1174680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell			 const __DRIversion * dri_version,
1175680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell			 const __DRIversion * drm_version,
1176680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell			 const __DRIframebuffer * frame_buffer,
1177ffb36d57a5f6359b5b91b73af60482a0016dd431Jon Smirl			 drm_sarea_t *pSAREA,
1178680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell			 int fd,
1179680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell			 int internal_api_version,
1180680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell			 const struct __DriverAPIRec *driverAPI)
1181680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{
1182680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    __DRIscreenPrivate *psp;
1183680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
1184680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
118574d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell#ifdef DRI_NEW_INTERFACE_ONLY
11861960182ece3f1eca06d2e439f64dd61be8a03ff5Ian Romanick    if ( internal_api_version < 20040602 ) {
118774d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell	fprintf( stderr, "libGL error: libGL.so version (%08u) is too old.  "
11881960182ece3f1eca06d2e439f64dd61be8a03ff5Ian Romanick		 "20040602 or later is required.\n", internal_api_version );
118974d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell	return NULL;
119074d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell    }
119174d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell#else
119274d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell    if ( internal_api_version == 20031201 ) {
119374d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell	fprintf( stderr, "libGL error: libGL version 20031201 has critical "
119474d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell		 "binary compatilibity bugs.\nlibGL error: You must upgrade "
119574d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell		 "to use direct-rendering!\n" );
119674d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell	return NULL;
119774d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell    }
119874d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell#endif /* DRI_NEW_INTERFACE_ONLY */
119974d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell
120074d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell
1201680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    window_exists = (PFNGLXWINDOWEXISTSPROC)
1202680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	glXGetProcAddress( (const GLubyte *) "__glXWindowExists" );
1203680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
1204680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    if ( window_exists == NULL ) {
1205680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell#ifdef DRI_NEW_INTERFACE_ONLY
1206680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	fprintf( stderr, "libGL error: libGL.so version (%08u) is too old.  "
1207680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell		 "20021128 or later is required.\n", internal_api_version );
1208680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	return NULL;
1209680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell#else
1210680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	window_exists = (PFNGLXWINDOWEXISTSPROC) __driWindowExists;
1211680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell#endif /* DRI_NEW_INTERFACE_ONLY */
1212680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    }
1213680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
1214680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    create_context_with_config = (PFNGLXCREATECONTEXTWITHCONFIGPROC)
1215680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	glXGetProcAddress( (const GLubyte *) "__glXCreateContextWithConfig" );
1216680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    if ( create_context_with_config == NULL ) {
1217680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell#ifdef DRI_NEW_INTERFACE_ONLY
1218680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	fprintf( stderr, "libGL error: libGL.so version (%08u) is too old.  "
1219680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell		 "20031201 or later is required.\n", internal_api_version );
1220680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	return NULL;
1221680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell#else
1222680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	create_context_with_config = (PFNGLXCREATECONTEXTWITHCONFIGPROC)
1223680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	    fake_XF86DRICreateContextWithConfig;
1224680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell#endif /* DRI_NEW_INTERFACE_ONLY */
1225680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    }
1226680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
1227680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    api_ver = internal_api_version;
1228680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
12297c46033130b1b4d6098647d85c2710367572e079Ian Romanick    psp = (__DRIscreenPrivate *)_mesa_malloc(sizeof(__DRIscreenPrivate));
1230680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    if (!psp) {
1231680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	return NULL;
1232680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    }
1233680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
1234680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    /* Create the hash table */
1235680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    psp->drawHash = drmHashCreate();
1236680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    if ( psp->drawHash == NULL ) {
12377c46033130b1b4d6098647d85c2710367572e079Ian Romanick	_mesa_free( psp );
1238680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	return NULL;
1239680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    }
1240680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
1241680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    psp->display = dpy;
1242680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    psp->myNum = scrn;
1243680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    psp->psc = psc;
1244680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    psp->modes = modes;
1245680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
1246680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    /*
1247680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    ** NOT_DONE: This is used by the X server to detect when the client
1248680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    ** has died while holding the drawable lock.  The client sets the
1249680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    ** drawable lock to this value.
1250680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    */
1251680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    psp->drawLockID = 1;
1252680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
1253680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    psp->drmMajor = drm_version->major;
1254680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    psp->drmMinor = drm_version->minor;
1255680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    psp->drmPatch = drm_version->patch;
1256680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    psp->ddxMajor = ddx_version->major;
1257680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    psp->ddxMinor = ddx_version->minor;
1258680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    psp->ddxPatch = ddx_version->patch;
1259680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    psp->driMajor = dri_version->major;
1260680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    psp->driMinor = dri_version->minor;
1261680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    psp->driPatch = dri_version->patch;
1262680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
1263680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    /* install driver's callback functions */
1264680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    memcpy( &psp->DriverAPI, driverAPI, sizeof(struct __DriverAPIRec) );
1265680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
1266680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    psp->pSAREA = pSAREA;
1267680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
1268680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    psp->pFB = frame_buffer->base;
1269680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    psp->fbSize = frame_buffer->size;
1270680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    psp->fbStride = frame_buffer->stride;
1271680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    psp->fbWidth = frame_buffer->width;
1272680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    psp->fbHeight = frame_buffer->height;
1273680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    psp->devPrivSize = frame_buffer->dev_priv_size;
1274680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    psp->pDevPriv = frame_buffer->dev_priv;
1275680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
1276680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    psp->fd = fd;
1277680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
1278680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    /*
1279680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    ** Do not init dummy context here; actual initialization will be
1280680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    ** done when the first DRI context is created.  Init screen priv ptr
1281680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    ** to NULL to let CreateContext routine that it needs to be inited.
1282680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    */
1283680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    psp->dummyContextPriv.driScreenPriv = NULL;
1284680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
1285680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    psc->destroyScreen     = driDestroyScreen;
1286680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell#ifndef DRI_NEW_INTERFACE_ONLY
1287680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    psc->createContext     = driCreateContext;
1288680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell#else
1289a249ad756f72835c5894e389150207b98532e114Ian Romanick    psc->createContext     = NULL;
1290680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell#endif
1291680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    psc->createNewDrawable = driCreateNewDrawable;
1292680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    psc->getDrawable       = driGetDrawable;
129374d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell#ifdef DRI_NEW_INTERFACE_ONLY
129474d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell    psc->getMSC            = driGetMSC;
129574d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell    psc->createNewContext  = driCreateNewContext;
129674d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell#else
1297680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    if ( driCompareGLXAPIVersion( 20030317 ) >= 0 ) {
1298680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell        psc->getMSC        = driGetMSC;
1299680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
1300680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	if ( driCompareGLXAPIVersion( 20030824 ) >= 0 ) {
1301680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	    psc->createNewContext = driCreateNewContext;
1302680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	}
1303680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    }
130474d563cdfbfb07cc666d60dc909e90ddb9949cbbKeith Whitwell#endif
1305680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
1306680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    if ( (psp->DriverAPI.InitDriver != NULL)
1307680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	 && !(*psp->DriverAPI.InitDriver)(psp) ) {
13087c46033130b1b4d6098647d85c2710367572e079Ian Romanick	_mesa_free( psp );
1309680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	return NULL;
1310680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    }
1311680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
1312680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
1313680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    return psp;
1314680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell}
1315680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
1316680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
1317680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell#ifndef DRI_NEW_INTERFACE_ONLY
1318680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/**
1319680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * Utility function used to create a new driver-private screen structure.
1320680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
1321680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param dpy        Display pointer.
1322680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param scrn       Index of the screen.
1323680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param psc        DRI screen data (not driver private)
1324680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param numConfigs Number of visual configs pointed to by \c configs.
1325680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param configs    Array of GLXvisualConfigs exported by the 2D driver.
1326680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param driverAPI Driver API functions used by other routines in dri_util.c.
1327680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
1328680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \deprecated
1329680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * This function has been replaced by \c __driUtilCreateNewScreen.  In drivers
1330680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * built to work with XFree86, this function will continue to exist to support
1331680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * older versions of libGL.  Starting with the next major relelase of XFree86,
1332680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * this function will be removed.
1333680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */
1334680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell__DRIscreenPrivate *
1335680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell__driUtilCreateScreen(Display *dpy, int scrn, __DRIscreen *psc,
1336680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell                      int numConfigs, __GLXvisualConfig *configs,
1337680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell                      const struct __DriverAPIRec *driverAPI)
1338680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{
1339680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    int directCapable;
1340680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    __DRIscreenPrivate *psp = NULL;
1341c06b25594e5effe34a90c067e1a3da0f61cf2b13Ian Romanick    drm_handle_t hSAREA;
1342680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    drmAddress pSAREA;
1343680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    char *BusID;
1344680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    __GLcontextModes *modes;
1345680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    __GLcontextModes *temp;
1346680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    int   i;
1347680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    __DRIversion   ddx_version;
1348680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    __DRIversion   dri_version;
1349680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    __DRIversion   drm_version;
1350680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    __DRIframebuffer  framebuffer;
1351680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    int   fd = -1;
1352680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    int   status;
1353680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    const char * err_msg;
1354680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    const char * err_extra;
1355680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
1356680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
1357680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    if (!XF86DRIQueryDirectRenderingCapable(dpy, scrn, &directCapable)
1358680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	|| !directCapable) {
1359680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	return NULL;
1360680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    }
1361680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
1362680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
1363680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    /* Create the linked list of context modes, and populate it with the
1364680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell     * GLX visual information passed in by libGL.
1365680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell     */
1366680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
1367680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    modes = _gl_context_modes_create( numConfigs, sizeof(__GLcontextModes) );
1368680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    if ( modes == NULL ) {
1369680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	return NULL;
1370680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    }
1371680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
1372680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    temp = modes;
1373680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    for ( i = 0 ; i < numConfigs ; i++ ) {
1374680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	assert( temp != NULL );
1375680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	_gl_copy_visual_to_context_mode( temp, & configs[i] );
1376680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	temp->screen = scrn;
1377680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
1378680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	temp = temp->next;
1379680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    }
1380680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
1381680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    err_msg = "XF86DRIOpenConnection";
1382680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    err_extra = NULL;
1383680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
1384680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    if (XF86DRIOpenConnection(dpy, scrn, &hSAREA, &BusID)) {
1385680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	fd = drmOpen(NULL,BusID);
13867c46033130b1b4d6098647d85c2710367572e079Ian Romanick	_mesa_free(BusID); /* No longer needed */
1387680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
1388680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	err_msg = "open DRM";
1389680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	err_extra = strerror( -fd );
1390680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
1391680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	if (fd >= 0) {
1392c06b25594e5effe34a90c067e1a3da0f61cf2b13Ian Romanick	    drm_magic_t magic;
1393680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
1394680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	    err_msg = "drmGetMagic";
1395680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	    err_extra = NULL;
1396680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
1397680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	    if (!drmGetMagic(fd, &magic)) {
1398680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell		drmVersionPtr version = drmGetVersion(fd);
1399680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell		if (version) {
1400680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell		    drm_version.major = version->version_major;
1401680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell		    drm_version.minor = version->version_minor;
1402680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell		    drm_version.patch = version->version_patchlevel;
1403680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell		    drmFreeVersion(version);
1404680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell		}
1405680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell		else {
1406680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell		    drm_version.major = -1;
1407680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell		    drm_version.minor = -1;
1408680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell		    drm_version.patch = -1;
1409680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell		}
1410680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
1411680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell		err_msg = "XF86DRIAuthConnection";
1412680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell		if (XF86DRIAuthConnection(dpy, scrn, magic)) {
1413680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell		    char *driverName;
1414680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
1415680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell		    /*
1416680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell		     * Get device name (like "tdfx") and the ddx version numbers.
1417680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell		     * We'll check the version in each DRI driver's "createScreen"
1418680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell		     * function.
1419680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell		     */
1420680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell		    err_msg = "XF86DRIGetClientDriverName";
1421680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell		    if (XF86DRIGetClientDriverName(dpy, scrn,
1422680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell						   &ddx_version.major,
1423680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell						   &ddx_version.minor,
1424680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell						   &ddx_version.patch,
1425680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell						   &driverName)) {
1426680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
1427680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell			/* No longer needed. */
14287c46033130b1b4d6098647d85c2710367572e079Ian Romanick			_mesa_free( driverName );
1429680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
1430680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell			/*
1431680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell			 * Get the DRI X extension version.
1432680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell			 */
1433680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell			err_msg = "XF86DRIQueryVersion";
1434680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell			if (XF86DRIQueryVersion(dpy,
1435680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell						&dri_version.major,
1436680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell						&dri_version.minor,
1437680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell						&dri_version.patch)) {
1438c06b25594e5effe34a90c067e1a3da0f61cf2b13Ian Romanick			    drm_handle_t  hFB;
1439680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell			    int        junk;
1440680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
1441680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell			    /*
1442680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell			     * Get device-specific info.  pDevPriv will point to a struct
1443680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell			     * (such as DRIRADEONRec in xfree86/driver/ati/radeon_dri.h)
1444680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell			     * that has information about the screen size, depth, pitch,
1445680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell			     * ancilliary buffers, DRM mmap handles, etc.
1446680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell			     */
1447680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell			    err_msg = "XF86DRIGetDeviceInfo";
1448680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell			    if (XF86DRIGetDeviceInfo(dpy, scrn,
1449680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell						     &hFB,
1450680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell						     &junk,
1451680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell						     &framebuffer.size,
1452680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell						     &framebuffer.stride,
1453680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell						     &framebuffer.dev_priv_size,
1454680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell						     &framebuffer.dev_priv)) {
1455680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell				framebuffer.width = DisplayWidth(dpy, scrn);
1456680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell				framebuffer.height = DisplayHeight(dpy, scrn);
1457680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
1458680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell				/*
1459680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell				 * Map the framebuffer region.
1460680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell				 */
1461680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell				status = drmMap(fd, hFB, framebuffer.size,
1462680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell						(drmAddressPtr)&framebuffer.base);
1463680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
1464680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell				err_msg = "drmMap of framebuffer";
1465680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell				err_extra = strerror( -status );
1466680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
1467680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell				if ( status == 0 ) {
1468680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell				    /*
1469680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell				     * Map the SAREA region.  Further mmap regions may be setup in
1470680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell				     * each DRI driver's "createScreen" function.
1471680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell				     */
1472680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell				    status = drmMap(fd, hSAREA, SAREA_MAX,
1473680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell						    &pSAREA);
1474680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
1475680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell				    err_msg = "drmMap of sarea";
1476680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell				    err_extra = strerror( -status );
1477680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
1478680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell				    if ( status == 0 ) {
1479680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell					PFNGLXGETINTERNALVERSIONPROC get_ver;
1480680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
1481680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell					get_ver = (PFNGLXGETINTERNALVERSIONPROC)
1482680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell					    glXGetProcAddress( (const GLubyte *) "__glXGetInternalVersion" );
1483680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
1484680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell					err_msg = "InitDriver";
1485680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell					err_extra = NULL;
1486680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell					psp = __driUtilCreateNewScreen( dpy, scrn, psc, modes,
1487680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell									& ddx_version,
1488680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell									& dri_version,
1489680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell									& drm_version,
1490680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell									& framebuffer,
1491680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell									pSAREA,
1492680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell									fd,
1493680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell									(get_ver != NULL) ? (*get_ver)() : 1,
1494680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell									driverAPI );
1495680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell				    }
1496680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell				}
1497680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell			    }
1498680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell			}
1499680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell		    }
1500680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell		}
1501680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	    }
1502680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	}
1503680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    }
1504680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
1505680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    if ( psp == NULL ) {
1506680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	if ( pSAREA != MAP_FAILED ) {
1507680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	    (void)drmUnmap(pSAREA, SAREA_MAX);
1508680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	}
1509680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
1510680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	if ( framebuffer.base != MAP_FAILED ) {
1511680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	    (void)drmUnmap((drmAddress)framebuffer.base, framebuffer.size);
1512680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	}
1513680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
1514680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	if ( framebuffer.dev_priv != NULL ) {
15157c46033130b1b4d6098647d85c2710367572e079Ian Romanick	    _mesa_free(framebuffer.dev_priv);
1516680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	}
1517680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
1518680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	if ( fd >= 0 ) {
1519680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	    (void)drmClose(fd);
1520680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	}
1521680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
1522680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	if ( modes != NULL ) {
1523680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	    _gl_context_modes_destroy( modes );
1524680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	}
1525680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
1526680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	(void)XF86DRICloseConnection(dpy, scrn);
1527680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
1528680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	if ( err_extra != NULL ) {
1529680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	    fprintf(stderr, "libGL error: %s failed (%s)\n", err_msg,
1530680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell		    err_extra);
1531680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	}
1532680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	else {
1533680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	    fprintf(stderr, "libGL error: %s failed\n", err_msg );
1534680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	}
1535680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
1536680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell        fprintf(stderr, "libGL error: reverting to (slow) indirect rendering\n");
1537680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    }
1538680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
1539680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell    return psp;
1540680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell}
1541680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell#endif /* DRI_NEW_INTERFACE_ONLY */
1542680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
1543680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
1544680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/**
1545680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * Compare the current GLX API version with a driver supplied required version.
1546680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
1547680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * The minimum required version is compared with the API version exported by
1548680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * the \c __glXGetInternalVersion function (in libGL.so).
1549680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
1550680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param   required_version Minimum required internal GLX API version.
1551680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \return  A tri-value return, as from strcmp is returned.  A value less
1552680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *          than, equal to, or greater than zero will be returned if the
1553680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *          internal GLX API version is less than, equal to, or greater
1554680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *          than \c required_version.
1555680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
1556680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \sa __glXGetInternalVersion().
1557680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */
1558680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwellint driCompareGLXAPIVersion( GLuint required_version )
1559680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{
1560680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell   if ( api_ver > required_version ) {
1561680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell      return 1;
1562680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell   }
1563680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell   else if ( api_ver == required_version ) {
1564680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell      return 0;
1565680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell   }
1566680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
1567680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell   return -1;
1568680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell}
1569680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
1570680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
1571680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwellstatic int
157260b0e12830310e7c05b4043857ed277b28b1c781Ian RomanickdriQueryFrameTracking( __DRInativeDisplay * dpy, void * priv,
1573680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell		       int64_t * sbc, int64_t * missedFrames,
1574680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell		       float * lastMissedUsage, float * usage )
1575680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{
1576680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell   static PFNGLXGETUSTPROC   get_ust;
1577680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell   __DRIswapInfo   sInfo;
1578680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell   int             status;
1579680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell   int64_t         ust;
1580680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell   __DRIdrawablePrivate * dpriv = (__DRIdrawablePrivate *) priv;
1581680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
1582680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell   if ( get_ust == NULL ) {
1583680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell      get_ust = (PFNGLXGETUSTPROC) glXGetProcAddress( (const GLubyte *) "__glXGetUST" );
1584680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell   }
1585680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
1586680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell   status = dpriv->driScreenPriv->DriverAPI.GetSwapInfo( dpriv, & sInfo );
1587680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell   if ( status == 0 ) {
1588680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell      *sbc = sInfo.swap_count;
1589680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell      *missedFrames = sInfo.swap_missed_count;
1590680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell      *lastMissedUsage = sInfo.swap_missed_usage;
1591680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
1592680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell      (*get_ust)( & ust );
1593680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell      *usage = driCalculateSwapUsage( dpriv, sInfo.swap_ust, ust );
1594680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell   }
1595680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
1596680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell   return status;
1597680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell}
1598680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
1599680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
1600680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/**
1601680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * Calculate amount of swap interval used between GLX buffer swaps.
1602680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
1603680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * The usage value, on the range [0,max], is the fraction of total swap
1604680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * interval time used between GLX buffer swaps is calculated.
1605680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
1606680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *            \f$p = t_d / (i * t_r)\f$
1607680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
1608680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * Where \f$t_d\f$ is the time since the last GLX buffer swap, \f$i\f$ is the
1609680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * swap interval (as set by \c glXSwapIntervalSGI), and \f$t_r\f$ time
1610680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * required for a single vertical refresh period (as returned by \c
1611680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * glXGetMscRateOML).
1612680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
1613680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * See the documentation for the GLX_MESA_swap_frame_usage extension for more
1614680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * details.
1615680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
1616680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \param   dPriv  Pointer to the private drawable structure.
1617680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \return  If less than a single swap interval time period was required
1618680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *          between GLX buffer swaps, a number greater than 0 and less than
1619680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *          1.0 is returned.  If exactly one swap interval time period is
1620680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *          required, 1.0 is returned, and if more than one is required then
1621680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *          a number greater than 1.0 will be returned.
1622680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
1623680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \sa glXSwapIntervalSGI glXGetMscRateOML
1624680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *
1625680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell * \todo Instead of caching the \c glXGetMscRateOML function pointer, would it
1626680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell *       be possible to cache the sync rate?
1627680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell */
1628680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwellfloat
1629680ec7f85158eae58fd5ab56da8c66a645883cb0Keith WhitwelldriCalculateSwapUsage( __DRIdrawablePrivate *dPriv, int64_t last_swap_ust,
1630680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell		       int64_t current_ust )
1631680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell{
1632680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell   static PFNGLXGETMSCRATEOMLPROC get_msc_rate = NULL;
1633680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell   int32_t   n;
1634680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell   int32_t   d;
1635680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell   int       interval;
1636680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell   float     usage = 1.0;
1637680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
1638680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
1639680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell   if ( get_msc_rate == NULL ) {
1640680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell      get_msc_rate = (PFNGLXGETMSCRATEOMLPROC)
1641680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	  glXGetProcAddress( (const GLubyte *) "glXGetMscRateOML" );
1642680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell   }
1643680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
1644680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell   if ( (get_msc_rate != NULL)
1645680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	&& get_msc_rate( dPriv->display, dPriv->draw, &n, &d ) ) {
1646680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell      interval = (dPriv->pdraw->swap_interval != 0)
1647680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell	  ? dPriv->pdraw->swap_interval : 1;
1648680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
1649680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
1650680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell      /* We want to calculate
1651680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell       * (current_UST - last_swap_UST) / (interval * us_per_refresh).  We get
1652680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell       * current_UST by calling __glXGetUST.  last_swap_UST is stored in
1653680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell       * dPriv->swap_ust.  interval has already been calculated.
1654680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell       *
1655680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell       * The only tricky part is us_per_refresh.  us_per_refresh is
1656680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell       * 1000000 / MSC_rate.  We know the MSC_rate is n / d.  We can flip it
1657680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell       * around and say us_per_refresh = 1000000 * d / n.  Since this goes in
1658680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell       * the denominator of the final calculation, we calculate
1659680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell       * (interval * 1000000 * d) and move n into the numerator.
1660680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell       */
1661680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
1662680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell      usage = (current_ust - last_swap_ust);
1663680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell      usage *= n;
1664680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell      usage /= (interval * d);
1665680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell      usage /= 1000000.0;
1666680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell   }
1667680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
1668680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell   return usage;
1669680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell}
1670680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
1671680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell/*@}*/
1672680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell
1673680ec7f85158eae58fd5ab56da8c66a645883cb0Keith Whitwell#endif /* GLX_DIRECT_RENDERING */
1674