radeon_screen.c revision ae4a1cc0666860bf5cc37a5cb549afc9aa5448b0
1/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_screen.c,v 1.7 2003/03/26 20:43:51 tsi Exp $ */
2/**************************************************************************
3
4Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
5                     VA Linux Systems Inc., Fremont, California.
6
7All Rights Reserved.
8
9Permission is hereby granted, free of charge, to any person obtaining
10a copy of this software and associated documentation files (the
11"Software"), to deal in the Software without restriction, including
12without limitation the rights to use, copy, modify, merge, publish,
13distribute, sublicense, and/or sell copies of the Software, and to
14permit persons to whom the Software is furnished to do so, subject to
15the following conditions:
16
17The above copyright notice and this permission notice (including the
18next paragraph) shall be included in all copies or substantial
19portions of the Software.
20
21THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
24IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
25LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28
29**************************************************************************/
30
31/**
32 * \file radeon_screen.c
33 * Screen initialization functions for the Radeon driver.
34 *
35 * \author Kevin E. Martin <martin@valinux.com>
36 * \author  Gareth Hughes <gareth@valinux.com>
37 */
38
39#include "glheader.h"
40#include "imports.h"
41
42#include "radeon_context.h"
43#include "radeon_screen.h"
44#include "radeon_macros.h"
45
46#include "utils.h"
47#include "context.h"
48#include "vblank.h"
49
50#ifndef _SOLO
51#include "glxextensions.h"
52#endif
53
54/* Radeon configuration
55 */
56#include "xmlpool.h"
57
58const char __driConfigOptions[] =
59DRI_CONF_BEGIN
60    DRI_CONF_SECTION_PERFORMANCE
61        DRI_CONF_TCL_MODE(DRI_CONF_TCL_CODEGEN)
62        DRI_CONF_FTHROTTLE_MODE(DRI_CONF_FTHROTTLE_IRQS)
63        DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_DEF_INTERVAL_0)
64    DRI_CONF_SECTION_END
65    DRI_CONF_SECTION_QUALITY
66        DRI_CONF_TEXTURE_DEPTH(DRI_CONF_TEXTURE_DEPTH_FB)
67        DRI_CONF_DEF_MAX_ANISOTROPY(1.0,"1.0,2.0,4.0,8.0,16.0")
68        DRI_CONF_NO_NEG_LOD_BIAS(false)
69        DRI_CONF_COLOR_REDUCTION(DRI_CONF_COLOR_REDUCTION_DITHER)
70        DRI_CONF_ROUND_MODE(DRI_CONF_ROUND_TRUNC)
71        DRI_CONF_DITHER_MODE(DRI_CONF_DITHER_XERRORDIFF)
72    DRI_CONF_SECTION_END
73    DRI_CONF_SECTION_DEBUG
74        DRI_CONF_NO_RAST(false)
75    DRI_CONF_SECTION_END
76DRI_CONF_END;
77static const GLuint __driNConfigOptions = 10;
78
79#if 1
80/* Including xf86PciInfo.h introduces a bunch of errors...
81 */
82#define PCI_CHIP_RADEON_QD	0x5144
83#define PCI_CHIP_RADEON_QE	0x5145
84#define PCI_CHIP_RADEON_QF	0x5146
85#define PCI_CHIP_RADEON_QG	0x5147
86
87#define PCI_CHIP_RADEON_QY	0x5159
88#define PCI_CHIP_RADEON_QZ	0x515A
89
90#define PCI_CHIP_RADEON_LW	0x4C57 /* mobility 7 - has tcl */
91
92#define PCI_CHIP_RADEON_LY	0x4C59
93#define PCI_CHIP_RADEON_LZ	0x4C5A
94
95#define PCI_CHIP_RV200_QW	0x5157 /* Radeon 7500 - not an R200 at all */
96/* IGP Chipsets */
97#define PCI_CHIP_RS100_4136     0x4136
98#define PCI_CHIP_RS200_4137     0x4137
99#define PCI_CHIP_RS250_4237     0x4237
100#define PCI_CHIP_RS100_4336     0x4336
101#define PCI_CHIP_RS200_4337     0x4337
102#define PCI_CHIP_RS250_4437     0x4437
103#endif
104
105#ifdef USE_NEW_INTERFACE
106static PFNGLXCREATECONTEXTMODES create_context_modes = NULL;
107#endif /* USE_NEW_INTERFACE */
108
109static int getSwapInfo( __DRIdrawablePrivate *dPriv, __DRIswapInfo * sInfo );
110
111#ifdef USE_NEW_INTERFACE
112static __GLcontextModes * fill_in_modes( __GLcontextModes * modes,
113					 unsigned pixel_bits,
114					 unsigned depth_bits,
115					 unsigned stencil_bits,
116					 const GLenum * db_modes,
117					 unsigned num_db_modes,
118					 int visType )
119{
120    static const uint8_t bits[2][4] = {
121	{          5,          6,          5,          0 },
122	{          8,          8,          8,          8 }
123    };
124
125    static const uint32_t masks[2][4] = {
126	{ 0x0000F800, 0x000007E0, 0x0000001F, 0x00000000 },
127	{ 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000 }
128    };
129
130    unsigned   i;
131    unsigned   j;
132    const unsigned index = ((pixel_bits + 15) / 16) - 1;
133
134    for ( i = 0 ; i < num_db_modes ; i++ ) {
135	for ( j = 0 ; j < 2 ; j++ ) {
136
137	    modes->redBits   = bits[index][0];
138	    modes->greenBits = bits[index][1];
139	    modes->blueBits  = bits[index][2];
140	    modes->alphaBits = bits[index][3];
141	    modes->redMask   = masks[index][0];
142	    modes->greenMask = masks[index][1];
143	    modes->blueMask  = masks[index][2];
144	    modes->alphaMask = masks[index][3];
145	    modes->rgbBits   = modes->redBits + modes->greenBits
146		+ modes->blueBits + modes->alphaBits;
147
148	    modes->accumRedBits   = 16 * j;
149	    modes->accumGreenBits = 16 * j;
150	    modes->accumBlueBits  = 16 * j;
151	    modes->accumAlphaBits = (masks[index][3] != 0) ? 16 * j : 0;
152	    modes->visualRating = (j == 0) ? GLX_NONE : GLX_SLOW_CONFIG;
153
154	    modes->stencilBits = stencil_bits;
155	    modes->depthBits = depth_bits;
156
157	    modes->visualType = visType;
158	    modes->renderType = GLX_RGBA_BIT;
159	    modes->drawableType = GLX_WINDOW_BIT;
160	    modes->rgbMode = GL_TRUE;
161
162	    if ( db_modes[i] == GLX_NONE ) {
163		modes->doubleBufferMode = GL_FALSE;
164	    }
165	    else {
166		modes->doubleBufferMode = GL_TRUE;
167		modes->swapMethod = db_modes[i];
168	    }
169
170	    modes = modes->next;
171	}
172    }
173
174    return modes;
175}
176#endif /* USE_NEW_INTERFACE */
177
178#ifdef USE_NEW_INTERFACE
179static __GLcontextModes *
180radeonFillInModes( unsigned pixel_bits, unsigned depth_bits,
181		 unsigned stencil_bits, GLboolean have_back_buffer )
182{
183    __GLcontextModes * modes;
184    __GLcontextModes * m;
185    unsigned num_modes;
186    unsigned depth_buffer_factor;
187    unsigned back_buffer_factor;
188    unsigned i;
189
190    /* Right now GLX_SWAP_COPY_OML isn't supported, but it would be easy
191     * enough to add support.  Basically, if a context is created with an
192     * fbconfig where the swap method is GLX_SWAP_COPY_OML, pageflipping
193     * will never be used.
194     */
195    static const GLenum back_buffer_modes[] = {
196	GLX_NONE, GLX_SWAP_UNDEFINED_OML /*, GLX_SWAP_COPY_OML */
197    };
198
199    int depth_buffer_modes[2][2];
200
201
202    depth_buffer_modes[0][0] = depth_bits;
203    depth_buffer_modes[1][0] = depth_bits;
204
205    /* Just like with the accumulation buffer, always provide some modes
206     * with a stencil buffer.  It will be a sw fallback, but some apps won't
207     * care about that.
208     */
209    depth_buffer_modes[0][1] = 0;
210    depth_buffer_modes[1][1] = (stencil_bits == 0) ? 8 : stencil_bits;
211
212    depth_buffer_factor = ((depth_bits != 0) || (stencil_bits != 0)) ? 2 : 1;
213    back_buffer_factor  = (have_back_buffer) ? 2 : 1;
214
215    num_modes = depth_buffer_factor * back_buffer_factor * 4;
216
217    modes = (*create_context_modes)( num_modes, sizeof( __GLcontextModes ) );
218    m = modes;
219    for ( i = 0 ; i < depth_buffer_factor ; i++ ) {
220	m = fill_in_modes( m, pixel_bits,
221			   depth_buffer_modes[i][0], depth_buffer_modes[i][1],
222			   back_buffer_modes, back_buffer_factor,
223			   GLX_TRUE_COLOR );
224    }
225
226    for ( i = 0 ; i < depth_buffer_factor ; i++ ) {
227	m = fill_in_modes( m, pixel_bits,
228			   depth_buffer_modes[i][0], depth_buffer_modes[i][1],
229			   back_buffer_modes, back_buffer_factor,
230			   GLX_DIRECT_COLOR );
231    }
232
233    /* Mark the visual as slow if there are "fake" stencil bits.
234     */
235    for ( m = modes ; m != NULL ; m = m->next ) {
236	if ( (m->stencilBits != 0) && (m->stencilBits != stencil_bits) ) {
237	    m->visualRating = GLX_SLOW_CONFIG;
238	}
239    }
240
241    return modes;
242}
243#endif /* USE_NEW_INTERFACE */
244
245/* Create the device specific screen private data struct.
246 */
247radeonScreenPtr radeonCreateScreen( __DRIscreenPrivate *sPriv )
248{
249   radeonScreenPtr screen;
250   RADEONDRIPtr dri_priv = (RADEONDRIPtr)sPriv->pDevPriv;
251   unsigned char *RADEONMMIO;
252
253   if ( ! driCheckDriDdxDrmVersions( sPriv, "Radeon", 4, 0, 4, 0, 1, 3 ) )
254      return NULL;
255
256   /* Allocate the private area */
257   screen = (radeonScreenPtr) CALLOC( sizeof(*screen) );
258   if ( !screen ) {
259      __driUtilMessage("%s: Could not allocate memory for screen structure",
260		       __FUNCTION__);
261      return NULL;
262   }
263
264   /* parse information in __driConfigOptions */
265   driParseOptionInfo (&screen->optionCache,
266		       __driConfigOptions, __driNConfigOptions);
267
268   /* This is first since which regions we map depends on whether or
269    * not we are using a PCI card.
270    */
271   screen->IsPCI = dri_priv->IsPCI;
272
273   {
274      int ret;
275      drm_radeon_getparam_t gp;
276
277      gp.param = RADEON_PARAM_GART_BUFFER_OFFSET;
278      gp.value = &screen->gart_buffer_offset;
279
280      ret = drmCommandWriteRead( sPriv->fd, DRM_RADEON_GETPARAM,
281				 &gp, sizeof(gp));
282      if (ret) {
283	 FREE( screen );
284	 fprintf(stderr, "drm_radeon_getparam_t (RADEON_PARAM_GART_BUFFER_OFFSET): %d\n", ret);
285	 return NULL;
286      }
287
288      if (sPriv->drmMinor >= 6) {
289	 gp.param = RADEON_PARAM_IRQ_NR;
290	 gp.value = &screen->irq;
291
292	 ret = drmCommandWriteRead( sPriv->fd, DRM_RADEON_GETPARAM,
293				    &gp, sizeof(gp));
294	 if (ret) {
295	    FREE( screen );
296	    fprintf(stderr, "drm_radeon_getparam_t (RADEON_PARAM_IRQ_NR): %d\n", ret);
297	    return NULL;
298	 }
299      }
300   }
301
302   screen->mmio.handle = dri_priv->registerHandle;
303   screen->mmio.size   = dri_priv->registerSize;
304   if ( drmMap( sPriv->fd,
305		screen->mmio.handle,
306		screen->mmio.size,
307		&screen->mmio.map ) ) {
308      FREE( screen );
309      __driUtilMessage("%s: drmMap failed\n", __FUNCTION__ );
310      return NULL;
311   }
312
313   RADEONMMIO = screen->mmio.map;
314
315   screen->status.handle = dri_priv->statusHandle;
316   screen->status.size   = dri_priv->statusSize;
317   if ( drmMap( sPriv->fd,
318		screen->status.handle,
319		screen->status.size,
320		&screen->status.map ) ) {
321      drmUnmap( screen->mmio.map, screen->mmio.size );
322      FREE( screen );
323      __driUtilMessage("%s: drmMap (2) failed\n", __FUNCTION__ );
324      return NULL;
325   }
326   screen->scratch = (__volatile__ CARD32 *)
327      ((GLubyte *)screen->status.map + RADEON_SCRATCH_REG_OFFSET);
328
329   screen->buffers = drmMapBufs( sPriv->fd );
330   if ( !screen->buffers ) {
331      drmUnmap( screen->status.map, screen->status.size );
332      drmUnmap( screen->mmio.map, screen->mmio.size );
333      FREE( screen );
334      __driUtilMessage("%s: drmMapBufs failed\n", __FUNCTION__ );
335      return NULL;
336   }
337
338   if ( dri_priv->gartTexHandle && dri_priv->gartTexMapSize ) {
339      screen->gartTextures.handle = dri_priv->gartTexHandle;
340      screen->gartTextures.size   = dri_priv->gartTexMapSize;
341      if ( drmMap( sPriv->fd,
342		   screen->gartTextures.handle,
343		   screen->gartTextures.size,
344		   (drmAddressPtr)&screen->gartTextures.map ) ) {
345	 drmUnmapBufs( screen->buffers );
346	 drmUnmap( screen->status.map, screen->status.size );
347	 drmUnmap( screen->mmio.map, screen->mmio.size );
348	 FREE( screen );
349	 __driUtilMessage("%s: drmMap failed for GART texture area\n", __FUNCTION__);
350	 return NULL;
351      }
352
353      screen->gart_texture_offset = dri_priv->gartTexOffset + ( screen->IsPCI
354		? INREG( RADEON_AIC_LO_ADDR )
355		: ( ( INREG( RADEON_MC_AGP_LOCATION ) & 0x0ffffU ) << 16 ) );
356   }
357
358   screen->chipset = 0;
359   switch ( dri_priv->deviceID ) {
360   default:
361      fprintf(stderr, "unknown chip id, assuming full radeon support\n");
362   case PCI_CHIP_RADEON_QD:
363   case PCI_CHIP_RADEON_QE:
364   case PCI_CHIP_RADEON_QF:
365   case PCI_CHIP_RADEON_QG:
366   case PCI_CHIP_RV200_QW:
367   case PCI_CHIP_RADEON_LW:
368      screen->chipset |= RADEON_CHIPSET_TCL;
369   case PCI_CHIP_RADEON_QY:
370   case PCI_CHIP_RADEON_QZ:
371   case PCI_CHIP_RADEON_LY:
372   case PCI_CHIP_RADEON_LZ:
373   case PCI_CHIP_RS100_4136: /* IGPs don't have TCL */
374   case PCI_CHIP_RS200_4137:
375   case PCI_CHIP_RS250_4237:
376   case PCI_CHIP_RS100_4336:
377   case PCI_CHIP_RS200_4337:
378   case PCI_CHIP_RS250_4437:
379      break;
380   }
381
382   screen->cpp = dri_priv->bpp / 8;
383   screen->AGPMode = dri_priv->AGPMode;
384
385   screen->fbLocation	= ( INREG( RADEON_MC_FB_LOCATION ) & 0xffff ) << 16;
386
387   if ( sPriv->drmMinor >= 10 ) {
388      drm_radeon_setparam_t sp;
389
390      sp.param = RADEON_SETPARAM_FB_LOCATION;
391      sp.value = screen->fbLocation;
392
393      drmCommandWrite( sPriv->fd, DRM_RADEON_SETPARAM,
394		       &sp, sizeof( sp ) );
395   }
396
397   screen->frontOffset	= dri_priv->frontOffset;
398   screen->frontPitch	= dri_priv->frontPitch;
399   screen->backOffset	= dri_priv->backOffset;
400   screen->backPitch	= dri_priv->backPitch;
401   screen->depthOffset	= dri_priv->depthOffset;
402   screen->depthPitch	= dri_priv->depthPitch;
403
404   screen->texOffset[RADEON_LOCAL_TEX_HEAP] = dri_priv->textureOffset
405				       + screen->fbLocation;
406   screen->texSize[RADEON_LOCAL_TEX_HEAP] = dri_priv->textureSize;
407   screen->logTexGranularity[RADEON_LOCAL_TEX_HEAP] =
408      dri_priv->log2TexGran;
409
410   if ( !screen->gartTextures.map
411	|| getenv( "RADEON_GARTTEXTURING_FORCE_DISABLE" ) ) {
412      screen->numTexHeaps = RADEON_NR_TEX_HEAPS - 1;
413      screen->texOffset[RADEON_GART_TEX_HEAP] = 0;
414      screen->texSize[RADEON_GART_TEX_HEAP] = 0;
415      screen->logTexGranularity[RADEON_GART_TEX_HEAP] = 0;
416   } else {
417      screen->numTexHeaps = RADEON_NR_TEX_HEAPS;
418      screen->texOffset[RADEON_GART_TEX_HEAP] = screen->gart_texture_offset;
419      screen->texSize[RADEON_GART_TEX_HEAP] = dri_priv->gartTexMapSize;
420      screen->logTexGranularity[RADEON_GART_TEX_HEAP] =
421	 dri_priv->log2GARTTexGran;
422   }
423#ifndef _SOLO
424   if ( driCompareGLXAPIVersion( 20030813 ) >= 0 ) {
425      PFNGLXSCRENABLEEXTENSIONPROC glx_enable_extension =
426          (PFNGLXSCRENABLEEXTENSIONPROC) glXGetProcAddress( (const GLubyte *) "__glXScrEnableExtension" );
427      void * const psc = sPriv->psc->screenConfigs;
428
429      if ( glx_enable_extension != NULL ) {
430	 if ( screen->irq != 0 ) {
431	    (*glx_enable_extension)( psc, "GLX_SGI_swap_control" );
432	    (*glx_enable_extension)( psc, "GLX_SGI_video_sync" );
433	    (*glx_enable_extension)( psc, "GLX_MESA_swap_control" );
434	 }
435
436	 (*glx_enable_extension)( psc, "GLX_MESA_swap_frame_usage" );
437
438         if ( driCompareGLXAPIVersion( 20030915 ) >= 0 ) {
439	    (*glx_enable_extension)( psc, "GLX_SGIX_fbconfig" );
440	    (*glx_enable_extension)( psc, "GLX_OML_swap_method" );
441	 }
442
443      }
444   }
445#endif
446   screen->driScreen = sPriv;
447   screen->sarea_priv_offset = dri_priv->sarea_priv_offset;
448   return screen;
449}
450
451/* Destroy the device specific screen private data struct.
452 */
453void radeonDestroyScreen( __DRIscreenPrivate *sPriv )
454{
455   radeonScreenPtr screen = (radeonScreenPtr)sPriv->private;
456
457   if (!screen)
458      return;
459
460   if ( screen->gartTextures.map ) {
461      drmUnmap( screen->gartTextures.map, screen->gartTextures.size );
462   }
463   drmUnmapBufs( screen->buffers );
464   drmUnmap( screen->status.map, screen->status.size );
465   drmUnmap( screen->mmio.map, screen->mmio.size );
466
467   /* free all option information */
468   driDestroyOptionInfo (&screen->optionCache);
469
470   FREE( screen );
471   sPriv->private = NULL;
472}
473
474
475/* Initialize the driver specific screen private data.
476 */
477static GLboolean
478radeonInitDriver( __DRIscreenPrivate *sPriv )
479{
480   sPriv->private = (void *) radeonCreateScreen( sPriv );
481   if ( !sPriv->private ) {
482      radeonDestroyScreen( sPriv );
483      return GL_FALSE;
484   }
485
486   return GL_TRUE;
487}
488
489
490
491/**
492 * Create and initialize the Mesa and driver specific pixmap buffer
493 * data.
494 *
495 * \todo This function (and its interface) will need to be updated to support
496 * pbuffers.
497 */
498static GLboolean
499radeonCreateBuffer( __DRIscreenPrivate *driScrnPriv,
500                    __DRIdrawablePrivate *driDrawPriv,
501                    const __GLcontextModes *mesaVis,
502                    GLboolean isPixmap )
503{
504   if (isPixmap) {
505      return GL_FALSE; /* not implemented */
506   }
507   else {
508      const GLboolean swDepth = GL_FALSE;
509      const GLboolean swAlpha = GL_FALSE;
510      const GLboolean swAccum = mesaVis->accumRedBits > 0;
511      const GLboolean swStencil = mesaVis->stencilBits > 0 &&
512         mesaVis->depthBits != 24;
513      driDrawPriv->driverPrivate = (void *)
514         _mesa_create_framebuffer( mesaVis,
515                                   swDepth,
516                                   swStencil,
517                                   swAccum,
518                                   swAlpha );
519      return (driDrawPriv->driverPrivate != NULL);
520   }
521}
522
523
524static void
525radeonDestroyBuffer(__DRIdrawablePrivate *driDrawPriv)
526{
527   _mesa_destroy_framebuffer((GLframebuffer *) (driDrawPriv->driverPrivate));
528}
529
530
531
532
533static struct __DriverAPIRec radeonAPI = {
534   .InitDriver      = radeonInitDriver,
535   .DestroyScreen   = radeonDestroyScreen,
536   .CreateContext   = radeonCreateContext,
537   .DestroyContext  = radeonDestroyContext,
538   .CreateBuffer    = radeonCreateBuffer,
539   .DestroyBuffer   = radeonDestroyBuffer,
540   .SwapBuffers     = radeonSwapBuffers,
541   .MakeCurrent     = radeonMakeCurrent,
542   .UnbindContext   = radeonUnbindContext,
543   .OpenFullScreen  = NULL,
544   .CloseFullScreen = NULL,
545   .GetSwapInfo     = getSwapInfo,
546   .GetMSC          = driGetMSC32,
547   .WaitForMSC      = driWaitForMSC32,
548   .WaitForSBC      = NULL,
549   .SwapBuffersMSC  = NULL
550};
551
552
553
554/*
555 * This is the bootstrap function for the driver.
556 * The __driCreateScreen name is the symbol that libGL.so fetches.
557 * Return:  pointer to a __DRIscreenPrivate.
558 */
559#ifndef _SOLO
560void *__driCreateScreen(Display *dpy, int scrn, __DRIscreen *psc,
561                        int numConfigs, __GLXvisualConfig *config)
562{
563   __DRIscreenPrivate *psp;
564   psp = __driUtilCreateScreen(dpy, scrn, psc, numConfigs, config, &radeonAPI);
565   return (void *) psp;
566}
567#else
568void *__driCreateScreen(struct DRIDriverRec *driver,
569                        struct DRIDriverContextRec *driverContext)
570{
571   __DRIscreenPrivate *psp;
572   psp = __driUtilCreateScreen(driver, driverContext, &radeonAPI);
573   return (void *) psp;
574}
575#endif
576
577/**
578 * This is the bootstrap function for the driver.  libGL supplies all of the
579 * requisite information about the system, and the driver initializes itself.
580 * This routine also fills in the linked list pointed to by \c driver_modes
581 * with the \c __GLcontextModes that the driver can support for windows or
582 * pbuffers.
583 *
584 * \return A pointer to a \c __DRIscreenPrivate on success, or \c NULL on
585 *         failure.
586 */
587#ifdef USE_NEW_INTERFACE
588void * __driCreateNewScreen( Display *dpy, int scrn, __DRIscreen *psc,
589			     const __GLcontextModes * modes,
590			     const __DRIversion * ddx_version,
591			     const __DRIversion * dri_version,
592			     const __DRIversion * drm_version,
593			     const __DRIframebuffer * frame_buffer,
594			     drmAddress pSAREA, int fd,
595			     int internal_api_version,
596			     __GLcontextModes ** driver_modes )
597
598{
599   __DRIscreenPrivate *psp;
600
601   psp = __driUtilCreateNewScreen(dpy, scrn, psc, NULL,
602				  ddx_version, dri_version, drm_version,
603				  frame_buffer, pSAREA, fd,
604				  internal_api_version, &radeonAPI);
605
606
607   create_context_modes =
608       (PFNGLXCREATECONTEXTMODES) glXGetProcAddress( (const GLubyte *) "__glXCreateContextModes" );
609   if ( create_context_modes != NULL ) {
610      RADEONDRIPtr dri_priv = (RADEONDRIPtr) psp->pDevPriv;
611      *driver_modes = radeonFillInModes( dri_priv->bpp,
612				       (dri_priv->bpp == 16) ? 16 : 24,
613				       (dri_priv->bpp == 16) ? 0  : 8,
614				       (dri_priv->backOffset != dri_priv->depthOffset) );
615   }
616
617   return (void *) psp;
618}
619#endif /* USE_NEW_INTERFACE */
620
621/**
622 * Get information about previous buffer swaps.
623 */
624static int
625getSwapInfo( __DRIdrawablePrivate *dPriv, __DRIswapInfo * sInfo )
626{
627   radeonContextPtr  rmesa;
628
629   if ( (dPriv == NULL) || (dPriv->driContextPriv == NULL)
630	|| (dPriv->driContextPriv->driverPrivate == NULL)
631	|| (sInfo == NULL) ) {
632      return -1;
633   }
634
635   rmesa = (radeonContextPtr) dPriv->driContextPriv->driverPrivate;
636   sInfo->swap_count = rmesa->swap_count;
637   sInfo->swap_ust = rmesa->swap_ust;
638   sInfo->swap_missed_count = rmesa->swap_missed_count;
639
640   sInfo->swap_missed_usage = (sInfo->swap_missed_count != 0)
641       ? driCalculateSwapUsage( dPriv, 0, rmesa->swap_missed_ust )
642       : 0.0;
643
644   return 0;
645}
646