radeon_screen.c revision 8f980b0e748f7c5a49e75c00ef4fa0b077d78197
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
255   /* Allocate the private area */
256   screen = (radeonScreenPtr) CALLOC( sizeof(*screen) );
257   if ( !screen ) {
258      __driUtilMessage("%s: Could not allocate memory for screen structure",
259		       __FUNCTION__);
260      return NULL;
261   }
262
263   /* parse information in __driConfigOptions */
264   driParseOptionInfo (&screen->optionCache,
265		       __driConfigOptions, __driNConfigOptions);
266
267   /* This is first since which regions we map depends on whether or
268    * not we are using a PCI card.
269    */
270   screen->IsPCI = dri_priv->IsPCI;
271
272   {
273      int ret;
274      drm_radeon_getparam_t gp;
275
276      gp.param = RADEON_PARAM_GART_BUFFER_OFFSET;
277      gp.value = &screen->gart_buffer_offset;
278
279      ret = drmCommandWriteRead( sPriv->fd, DRM_RADEON_GETPARAM,
280				 &gp, sizeof(gp));
281      if (ret) {
282	 FREE( screen );
283	 fprintf(stderr, "drm_radeon_getparam_t (RADEON_PARAM_GART_BUFFER_OFFSET): %d\n", ret);
284	 return NULL;
285      }
286
287      if (sPriv->drmMinor >= 6) {
288	 gp.param = RADEON_PARAM_IRQ_NR;
289	 gp.value = &screen->irq;
290
291	 ret = drmCommandWriteRead( sPriv->fd, DRM_RADEON_GETPARAM,
292				    &gp, sizeof(gp));
293	 if (ret) {
294	    FREE( screen );
295	    fprintf(stderr, "drm_radeon_getparam_t (RADEON_PARAM_IRQ_NR): %d\n", ret);
296	    return NULL;
297	 }
298      }
299   }
300
301   screen->mmio.handle = dri_priv->registerHandle;
302   screen->mmio.size   = dri_priv->registerSize;
303   if ( drmMap( sPriv->fd,
304		screen->mmio.handle,
305		screen->mmio.size,
306		&screen->mmio.map ) ) {
307      FREE( screen );
308      __driUtilMessage("%s: drmMap failed\n", __FUNCTION__ );
309      return NULL;
310   }
311
312   RADEONMMIO = screen->mmio.map;
313
314   screen->status.handle = dri_priv->statusHandle;
315   screen->status.size   = dri_priv->statusSize;
316   if ( drmMap( sPriv->fd,
317		screen->status.handle,
318		screen->status.size,
319		&screen->status.map ) ) {
320      drmUnmap( screen->mmio.map, screen->mmio.size );
321      FREE( screen );
322      __driUtilMessage("%s: drmMap (2) failed\n", __FUNCTION__ );
323      return NULL;
324   }
325   screen->scratch = (__volatile__ uint32_t *)
326      ((GLubyte *)screen->status.map + RADEON_SCRATCH_REG_OFFSET);
327
328   screen->buffers = drmMapBufs( sPriv->fd );
329   if ( !screen->buffers ) {
330      drmUnmap( screen->status.map, screen->status.size );
331      drmUnmap( screen->mmio.map, screen->mmio.size );
332      FREE( screen );
333      __driUtilMessage("%s: drmMapBufs failed\n", __FUNCTION__ );
334      return NULL;
335   }
336
337   if ( dri_priv->gartTexHandle && dri_priv->gartTexMapSize ) {
338      screen->gartTextures.handle = dri_priv->gartTexHandle;
339      screen->gartTextures.size   = dri_priv->gartTexMapSize;
340      if ( drmMap( sPriv->fd,
341		   screen->gartTextures.handle,
342		   screen->gartTextures.size,
343		   (drmAddressPtr)&screen->gartTextures.map ) ) {
344	 drmUnmapBufs( screen->buffers );
345	 drmUnmap( screen->status.map, screen->status.size );
346	 drmUnmap( screen->mmio.map, screen->mmio.size );
347	 FREE( screen );
348	 __driUtilMessage("%s: drmMap failed for GART texture area\n", __FUNCTION__);
349	 return NULL;
350      }
351
352      screen->gart_texture_offset = dri_priv->gartTexOffset + ( screen->IsPCI
353		? INREG( RADEON_AIC_LO_ADDR )
354		: ( ( INREG( RADEON_MC_AGP_LOCATION ) & 0x0ffffU ) << 16 ) );
355   }
356
357   screen->chipset = 0;
358   switch ( dri_priv->deviceID ) {
359   default:
360      fprintf(stderr, "unknown chip id, assuming full radeon support\n");
361   case PCI_CHIP_RADEON_QD:
362   case PCI_CHIP_RADEON_QE:
363   case PCI_CHIP_RADEON_QF:
364   case PCI_CHIP_RADEON_QG:
365   case PCI_CHIP_RV200_QW:
366   case PCI_CHIP_RADEON_LW:
367      screen->chipset |= RADEON_CHIPSET_TCL;
368   case PCI_CHIP_RADEON_QY:
369   case PCI_CHIP_RADEON_QZ:
370   case PCI_CHIP_RADEON_LY:
371   case PCI_CHIP_RADEON_LZ:
372   case PCI_CHIP_RS100_4136: /* IGPs don't have TCL */
373   case PCI_CHIP_RS200_4137:
374   case PCI_CHIP_RS250_4237:
375   case PCI_CHIP_RS100_4336:
376   case PCI_CHIP_RS200_4337:
377   case PCI_CHIP_RS250_4437:
378      break;
379   }
380
381   screen->cpp = dri_priv->bpp / 8;
382   screen->AGPMode = dri_priv->AGPMode;
383
384   screen->fbLocation	= ( INREG( RADEON_MC_FB_LOCATION ) & 0xffff ) << 16;
385
386   if ( sPriv->drmMinor >= 10 ) {
387      drm_radeon_setparam_t sp;
388
389      sp.param = RADEON_SETPARAM_FB_LOCATION;
390      sp.value = screen->fbLocation;
391
392      drmCommandWrite( sPriv->fd, DRM_RADEON_SETPARAM,
393		       &sp, sizeof( sp ) );
394   }
395
396   screen->frontOffset	= dri_priv->frontOffset;
397   screen->frontPitch	= dri_priv->frontPitch;
398   screen->backOffset	= dri_priv->backOffset;
399   screen->backPitch	= dri_priv->backPitch;
400   screen->depthOffset	= dri_priv->depthOffset;
401   screen->depthPitch	= dri_priv->depthPitch;
402
403   screen->texOffset[RADEON_LOCAL_TEX_HEAP] = dri_priv->textureOffset
404				       + screen->fbLocation;
405   screen->texSize[RADEON_LOCAL_TEX_HEAP] = dri_priv->textureSize;
406   screen->logTexGranularity[RADEON_LOCAL_TEX_HEAP] =
407      dri_priv->log2TexGran;
408
409   if ( !screen->gartTextures.map
410	|| getenv( "RADEON_GARTTEXTURING_FORCE_DISABLE" ) ) {
411      screen->numTexHeaps = RADEON_NR_TEX_HEAPS - 1;
412      screen->texOffset[RADEON_GART_TEX_HEAP] = 0;
413      screen->texSize[RADEON_GART_TEX_HEAP] = 0;
414      screen->logTexGranularity[RADEON_GART_TEX_HEAP] = 0;
415   } else {
416      screen->numTexHeaps = RADEON_NR_TEX_HEAPS;
417      screen->texOffset[RADEON_GART_TEX_HEAP] = screen->gart_texture_offset;
418      screen->texSize[RADEON_GART_TEX_HEAP] = dri_priv->gartTexMapSize;
419      screen->logTexGranularity[RADEON_GART_TEX_HEAP] =
420	 dri_priv->log2GARTTexGran;
421   }
422#ifndef _SOLO
423   if ( driCompareGLXAPIVersion( 20030813 ) >= 0 ) {
424      PFNGLXSCRENABLEEXTENSIONPROC glx_enable_extension =
425          (PFNGLXSCRENABLEEXTENSIONPROC) glXGetProcAddress( (const GLubyte *) "__glXScrEnableExtension" );
426      void * const psc = sPriv->psc->screenConfigs;
427
428      if ( glx_enable_extension != NULL ) {
429	 if ( screen->irq != 0 ) {
430	    (*glx_enable_extension)( psc, "GLX_SGI_swap_control" );
431	    (*glx_enable_extension)( psc, "GLX_SGI_video_sync" );
432	    (*glx_enable_extension)( psc, "GLX_MESA_swap_control" );
433	 }
434
435	 (*glx_enable_extension)( psc, "GLX_MESA_swap_frame_usage" );
436
437         if ( driCompareGLXAPIVersion( 20030915 ) >= 0 ) {
438	    (*glx_enable_extension)( psc, "GLX_SGIX_fbconfig" );
439	    (*glx_enable_extension)( psc, "GLX_OML_swap_method" );
440	 }
441
442      }
443   }
444#endif
445   screen->driScreen = sPriv;
446   screen->sarea_priv_offset = dri_priv->sarea_priv_offset;
447   return screen;
448}
449
450/* Destroy the device specific screen private data struct.
451 */
452void radeonDestroyScreen( __DRIscreenPrivate *sPriv )
453{
454   radeonScreenPtr screen = (radeonScreenPtr)sPriv->private;
455
456   if (!screen)
457      return;
458
459   if ( screen->gartTextures.map ) {
460      drmUnmap( screen->gartTextures.map, screen->gartTextures.size );
461   }
462   drmUnmapBufs( screen->buffers );
463   drmUnmap( screen->status.map, screen->status.size );
464   drmUnmap( screen->mmio.map, screen->mmio.size );
465
466   /* free all option information */
467   driDestroyOptionInfo (&screen->optionCache);
468
469   FREE( screen );
470   sPriv->private = NULL;
471}
472
473
474/* Initialize the driver specific screen private data.
475 */
476static GLboolean
477radeonInitDriver( __DRIscreenPrivate *sPriv )
478{
479   sPriv->private = (void *) radeonCreateScreen( sPriv );
480   if ( !sPriv->private ) {
481      radeonDestroyScreen( sPriv );
482      return GL_FALSE;
483   }
484
485   return GL_TRUE;
486}
487
488
489
490/**
491 * Create and initialize the Mesa and driver specific pixmap buffer
492 * data.
493 *
494 * \todo This function (and its interface) will need to be updated to support
495 * pbuffers.
496 */
497static GLboolean
498radeonCreateBuffer( __DRIscreenPrivate *driScrnPriv,
499                    __DRIdrawablePrivate *driDrawPriv,
500                    const __GLcontextModes *mesaVis,
501                    GLboolean isPixmap )
502{
503   if (isPixmap) {
504      return GL_FALSE; /* not implemented */
505   }
506   else {
507      const GLboolean swDepth = GL_FALSE;
508      const GLboolean swAlpha = GL_FALSE;
509      const GLboolean swAccum = mesaVis->accumRedBits > 0;
510      const GLboolean swStencil = mesaVis->stencilBits > 0 &&
511         mesaVis->depthBits != 24;
512      driDrawPriv->driverPrivate = (void *)
513         _mesa_create_framebuffer( mesaVis,
514                                   swDepth,
515                                   swStencil,
516                                   swAccum,
517                                   swAlpha );
518      return (driDrawPriv->driverPrivate != NULL);
519   }
520}
521
522
523static void
524radeonDestroyBuffer(__DRIdrawablePrivate *driDrawPriv)
525{
526   _mesa_destroy_framebuffer((GLframebuffer *) (driDrawPriv->driverPrivate));
527}
528
529static struct __DriverAPIRec radeonAPI = {
530   .InitDriver      = radeonInitDriver,
531   .DestroyScreen   = radeonDestroyScreen,
532   .CreateContext   = radeonCreateContext,
533   .DestroyContext  = radeonDestroyContext,
534   .CreateBuffer    = radeonCreateBuffer,
535   .DestroyBuffer   = radeonDestroyBuffer,
536   .SwapBuffers     = radeonSwapBuffers,
537   .MakeCurrent     = radeonMakeCurrent,
538   .UnbindContext   = radeonUnbindContext,
539   .GetSwapInfo     = getSwapInfo,
540   .GetMSC          = driGetMSC32,
541   .WaitForMSC      = driWaitForMSC32,
542   .WaitForSBC      = NULL,
543   .SwapBuffersMSC  = NULL
544};
545
546
547/*
548 * This is the bootstrap function for the driver.
549 * The __driCreateScreen name is the symbol that libGL.so fetches.
550 * Return:  pointer to a __DRIscreenPrivate.
551 */
552#if !defined(DRI_NEW_INTERFACE_ONLY)
553#ifndef _SOLO
554void *__driCreateScreen(Display *dpy, int scrn, __DRIscreen *psc,
555                        int numConfigs, __GLXvisualConfig *config)
556{
557   __DRIscreenPrivate *psp;
558   psp = __driUtilCreateScreen(dpy, scrn, psc, numConfigs, config, &radeonAPI);
559   return (void *) psp;
560}
561#else
562void *__driCreateScreen(struct DRIDriverRec *driver,
563                        struct DRIDriverContextRec *driverContext)
564{
565   __DRIscreenPrivate *psp;
566   psp = __driUtilCreateScreen(driver, driverContext, &radeonAPI);
567   return (void *) psp;
568}
569#endif
570#endif /* !defined(DRI_NEW_INTERFACE_ONLY) */
571
572/**
573 * This is the bootstrap function for the driver.  libGL supplies all of the
574 * requisite information about the system, and the driver initializes itself.
575 * This routine also fills in the linked list pointed to by \c driver_modes
576 * with the \c __GLcontextModes that the driver can support for windows or
577 * pbuffers.
578 *
579 * \return A pointer to a \c __DRIscreenPrivate on success, or \c NULL on
580 *         failure.
581 */
582#ifdef USE_NEW_INTERFACE
583void * __driCreateNewScreen( __DRInativeDisplay *dpy, int scrn, __DRIscreen *psc,
584			     const __GLcontextModes * modes,
585			     const __DRIversion * ddx_version,
586			     const __DRIversion * dri_version,
587			     const __DRIversion * drm_version,
588			     const __DRIframebuffer * frame_buffer,
589			     drmAddress pSAREA, int fd,
590			     int internal_api_version,
591			     __GLcontextModes ** driver_modes )
592
593{
594   __DRIscreenPrivate *psp;
595   static const __DRIversion ddx_expected = { 4, 0, 0 };
596   static const __DRIversion dri_expected = { 4, 0, 0 };
597   static const __DRIversion drm_expected = { 1, 3, 0 };
598
599   if ( ! driCheckDriDdxDrmVersions2( "Radeon",
600				      dri_version, & dri_expected,
601				      ddx_version, & ddx_expected,
602				      drm_version, & drm_expected ) ) {
603      return NULL;
604   }
605
606   psp = __driUtilCreateNewScreen(dpy, scrn, psc, NULL,
607				  ddx_version, dri_version, drm_version,
608				  frame_buffer, pSAREA, fd,
609				  internal_api_version, &radeonAPI);
610   if ( psp != NULL ) {
611      create_context_modes = (PFNGLXCREATECONTEXTMODES)
612	  glXGetProcAddress( (const GLubyte *) "__glXCreateContextModes" );
613      if ( create_context_modes != NULL ) {
614	 RADEONDRIPtr dri_priv = (RADEONDRIPtr) psp->pDevPriv;
615	 *driver_modes = radeonFillInModes( dri_priv->bpp,
616					    (dri_priv->bpp == 16) ? 16 : 24,
617					    (dri_priv->bpp == 16) ? 0  : 8,
618					    (dri_priv->backOffset != dri_priv->depthOffset) );
619      }
620   }
621
622   return (void *) psp;
623}
624#endif /* USE_NEW_INTERFACE */
625
626/**
627 * Get information about previous buffer swaps.
628 */
629static int
630getSwapInfo( __DRIdrawablePrivate *dPriv, __DRIswapInfo * sInfo )
631{
632   radeonContextPtr  rmesa;
633
634   if ( (dPriv == NULL) || (dPriv->driContextPriv == NULL)
635	|| (dPriv->driContextPriv->driverPrivate == NULL)
636	|| (sInfo == NULL) ) {
637      return -1;
638   }
639
640   rmesa = (radeonContextPtr) dPriv->driContextPriv->driverPrivate;
641   sInfo->swap_count = rmesa->swap_count;
642   sInfo->swap_ust = rmesa->swap_ust;
643   sInfo->swap_missed_count = rmesa->swap_missed_count;
644
645   sInfo->swap_missed_usage = (sInfo->swap_missed_count != 0)
646       ? driCalculateSwapUsage( dPriv, 0, rmesa->swap_missed_ust )
647       : 0.0;
648
649   return 0;
650}
651