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