radeon_screen.c revision 96ba38a450b77d56730fd293499cbeaa1f511507
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#include "mtypes.h"
42#include "framebuffer.h"
43#include "renderbuffer.h"
44
45#define STANDALONE_MMIO
46#include "radeon_chipset.h"
47#include "radeon_macros.h"
48#include "radeon_screen.h"
49#if !RADEON_COMMON
50#include "radeon_context.h"
51#include "radeon_span.h"
52#elif RADEON_COMMON && defined(RADEON_COMMON_FOR_R200)
53#include "r200_context.h"
54#include "r200_ioctl.h"
55#include "r200_span.h"
56#include "r200_tex.h"
57#elif RADEON_COMMON && defined(RADEON_COMMON_FOR_R300)
58#include "r300_context.h"
59#include "r300_fragprog.h"
60#include "r300_tex.h"
61#include "radeon_span.h"
62#endif
63
64#include "utils.h"
65#include "context.h"
66#include "vblank.h"
67#include "drirenderbuffer.h"
68
69#include "GL/internal/dri_interface.h"
70
71/* Radeon configuration
72 */
73#include "xmlpool.h"
74
75#if !RADEON_COMMON	/* R100 */
76PUBLIC const char __driConfigOptions[] =
77DRI_CONF_BEGIN
78    DRI_CONF_SECTION_PERFORMANCE
79        DRI_CONF_TCL_MODE(DRI_CONF_TCL_CODEGEN)
80        DRI_CONF_FTHROTTLE_MODE(DRI_CONF_FTHROTTLE_IRQS)
81        DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_DEF_INTERVAL_0)
82        DRI_CONF_MAX_TEXTURE_UNITS(3,2,3)
83        DRI_CONF_HYPERZ(false)
84    DRI_CONF_SECTION_END
85    DRI_CONF_SECTION_QUALITY
86        DRI_CONF_TEXTURE_DEPTH(DRI_CONF_TEXTURE_DEPTH_FB)
87        DRI_CONF_DEF_MAX_ANISOTROPY(1.0,"1.0,2.0,4.0,8.0,16.0")
88        DRI_CONF_NO_NEG_LOD_BIAS(false)
89        DRI_CONF_FORCE_S3TC_ENABLE(false)
90        DRI_CONF_COLOR_REDUCTION(DRI_CONF_COLOR_REDUCTION_DITHER)
91        DRI_CONF_ROUND_MODE(DRI_CONF_ROUND_TRUNC)
92        DRI_CONF_DITHER_MODE(DRI_CONF_DITHER_XERRORDIFF)
93        DRI_CONF_ALLOW_LARGE_TEXTURES(1)
94    DRI_CONF_SECTION_END
95    DRI_CONF_SECTION_DEBUG
96        DRI_CONF_NO_RAST(false)
97    DRI_CONF_SECTION_END
98DRI_CONF_END;
99static const GLuint __driNConfigOptions = 14;
100
101#elif RADEON_COMMON && defined(RADEON_COMMON_FOR_R200)
102
103PUBLIC const char __driConfigOptions[] =
104DRI_CONF_BEGIN
105    DRI_CONF_SECTION_PERFORMANCE
106        DRI_CONF_TCL_MODE(DRI_CONF_TCL_CODEGEN)
107        DRI_CONF_FTHROTTLE_MODE(DRI_CONF_FTHROTTLE_IRQS)
108        DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_DEF_INTERVAL_0)
109        DRI_CONF_MAX_TEXTURE_UNITS(6,2,6)
110        DRI_CONF_HYPERZ(false)
111    DRI_CONF_SECTION_END
112    DRI_CONF_SECTION_QUALITY
113        DRI_CONF_TEXTURE_DEPTH(DRI_CONF_TEXTURE_DEPTH_FB)
114        DRI_CONF_DEF_MAX_ANISOTROPY(1.0,"1.0,2.0,4.0,8.0,16.0")
115        DRI_CONF_NO_NEG_LOD_BIAS(false)
116        DRI_CONF_FORCE_S3TC_ENABLE(false)
117        DRI_CONF_COLOR_REDUCTION(DRI_CONF_COLOR_REDUCTION_DITHER)
118        DRI_CONF_ROUND_MODE(DRI_CONF_ROUND_TRUNC)
119        DRI_CONF_DITHER_MODE(DRI_CONF_DITHER_XERRORDIFF)
120        DRI_CONF_ALLOW_LARGE_TEXTURES(1)
121        DRI_CONF_TEXTURE_BLEND_QUALITY(1.0,"0.0:1.0")
122    DRI_CONF_SECTION_END
123    DRI_CONF_SECTION_DEBUG
124        DRI_CONF_NO_RAST(false)
125    DRI_CONF_SECTION_END
126    DRI_CONF_SECTION_SOFTWARE
127        DRI_CONF_NV_VERTEX_PROGRAM(false)
128    DRI_CONF_SECTION_END
129DRI_CONF_END;
130static const GLuint __driNConfigOptions = 16;
131
132extern const struct dri_extension blend_extensions[];
133extern const struct dri_extension ARB_vp_extension[];
134extern const struct dri_extension NV_vp_extension[];
135extern const struct dri_extension ATI_fs_extension[];
136extern const struct dri_extension point_extensions[];
137
138#elif RADEON_COMMON && defined(RADEON_COMMON_FOR_R300)
139
140/* TODO: integrate these into xmlpool.h! */
141#define DRI_CONF_MAX_TEXTURE_IMAGE_UNITS(def,min,max) \
142DRI_CONF_OPT_BEGIN_V(texture_image_units,int,def, # min ":" # max ) \
143        DRI_CONF_DESC(en,"Number of texture image units") \
144        DRI_CONF_DESC(de,"Anzahl der Textureinheiten") \
145DRI_CONF_OPT_END
146
147#define DRI_CONF_MAX_TEXTURE_COORD_UNITS(def,min,max) \
148DRI_CONF_OPT_BEGIN_V(texture_coord_units,int,def, # min ":" # max ) \
149        DRI_CONF_DESC(en,"Number of texture coordinate units") \
150        DRI_CONF_DESC(de,"Anzahl der Texturkoordinateneinheiten") \
151DRI_CONF_OPT_END
152
153#define DRI_CONF_COMMAND_BUFFER_SIZE(def,min,max) \
154DRI_CONF_OPT_BEGIN_V(command_buffer_size,int,def, # min ":" # max ) \
155        DRI_CONF_DESC(en,"Size of command buffer (in KB)") \
156        DRI_CONF_DESC(de,"Grösse des Befehlspuffers (in KB)") \
157DRI_CONF_OPT_END
158
159#define DRI_CONF_DISABLE_S3TC(def) \
160DRI_CONF_OPT_BEGIN(disable_s3tc,bool,def) \
161        DRI_CONF_DESC(en,"Disable S3TC compression") \
162DRI_CONF_OPT_END
163
164#define DRI_CONF_DISABLE_FALLBACK(def) \
165DRI_CONF_OPT_BEGIN(disable_lowimpact_fallback,bool,def) \
166        DRI_CONF_DESC(en,"Disable Low-impact fallback") \
167DRI_CONF_OPT_END
168
169#define DRI_CONF_DISABLE_DOUBLE_SIDE_STENCIL(def) \
170DRI_CONF_OPT_BEGIN(disable_stencil_two_side,bool,def) \
171        DRI_CONF_DESC(en,"Disable GL_EXT_stencil_two_side") \
172DRI_CONF_OPT_END
173
174#define DRI_CONF_FP_OPTIMIZATION(def) \
175DRI_CONF_OPT_BEGIN_V(fp_optimization,enum,def,"0:1") \
176	DRI_CONF_DESC_BEGIN(en,"Fragment Program optimization") \
177                DRI_CONF_ENUM(0,"Optimize for Speed") \
178                DRI_CONF_ENUM(1,"Optimize for Quality") \
179        DRI_CONF_DESC_END \
180DRI_CONF_OPT_END
181
182const char __driConfigOptions[] =
183DRI_CONF_BEGIN
184	DRI_CONF_SECTION_PERFORMANCE
185		DRI_CONF_TCL_MODE(DRI_CONF_TCL_CODEGEN)
186		DRI_CONF_FTHROTTLE_MODE(DRI_CONF_FTHROTTLE_IRQS)
187		DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_DEF_INTERVAL_0)
188		DRI_CONF_MAX_TEXTURE_IMAGE_UNITS(8, 2, 8)
189		DRI_CONF_MAX_TEXTURE_COORD_UNITS(8, 2, 8)
190		DRI_CONF_COMMAND_BUFFER_SIZE(8, 8, 32)
191		DRI_CONF_DISABLE_FALLBACK(false)
192		DRI_CONF_DISABLE_DOUBLE_SIDE_STENCIL(false)
193	DRI_CONF_SECTION_END
194	DRI_CONF_SECTION_QUALITY
195		DRI_CONF_TEXTURE_DEPTH(DRI_CONF_TEXTURE_DEPTH_FB)
196		DRI_CONF_DEF_MAX_ANISOTROPY(1.0, "1.0,2.0,4.0,8.0,16.0")
197		DRI_CONF_NO_NEG_LOD_BIAS(false)
198                DRI_CONF_FORCE_S3TC_ENABLE(false)
199		DRI_CONF_DISABLE_S3TC(false)
200		DRI_CONF_COLOR_REDUCTION(DRI_CONF_COLOR_REDUCTION_DITHER)
201		DRI_CONF_ROUND_MODE(DRI_CONF_ROUND_TRUNC)
202		DRI_CONF_DITHER_MODE(DRI_CONF_DITHER_XERRORDIFF)
203		DRI_CONF_FP_OPTIMIZATION(DRI_CONF_FP_OPTIMIZATION_SPEED)
204	DRI_CONF_SECTION_END
205	DRI_CONF_SECTION_DEBUG
206		DRI_CONF_NO_RAST(false)
207	DRI_CONF_SECTION_END
208DRI_CONF_END;
209static const GLuint __driNConfigOptions = 18;
210
211#ifndef RADEON_DEBUG
212int RADEON_DEBUG = 0;
213
214static const struct dri_debug_control debug_control[] = {
215	{"fall", DEBUG_FALLBACKS},
216	{"tex", DEBUG_TEXTURE},
217	{"ioctl", DEBUG_IOCTL},
218	{"prim", DEBUG_PRIMS},
219	{"vert", DEBUG_VERTS},
220	{"state", DEBUG_STATE},
221	{"code", DEBUG_CODEGEN},
222	{"vfmt", DEBUG_VFMT},
223	{"vtxf", DEBUG_VFMT},
224	{"verb", DEBUG_VERBOSE},
225	{"dri", DEBUG_DRI},
226	{"dma", DEBUG_DMA},
227	{"san", DEBUG_SANITY},
228	{"sync", DEBUG_SYNC},
229	{"pix", DEBUG_PIXEL},
230	{"mem", DEBUG_MEMORY},
231	{"allmsg", ~DEBUG_SYNC}, /* avoid the term "sync" because the parser uses strstr */
232	{NULL, 0}
233};
234#endif /* RADEON_DEBUG */
235
236#endif /* RADEON_COMMON && defined(RADEON_COMMON_FOR_R300) */
237
238extern const struct dri_extension card_extensions[];
239
240static int getSwapInfo( __DRIdrawablePrivate *dPriv, __DRIswapInfo * sInfo );
241
242static int
243radeonGetParam(int fd, int param, void *value)
244{
245  int ret;
246  drm_radeon_getparam_t gp;
247
248  gp.param = param;
249  gp.value = value;
250
251  ret = drmCommandWriteRead( fd, DRM_RADEON_GETPARAM, &gp, sizeof(gp));
252  return ret;
253}
254
255static __GLcontextModes *
256radeonFillInModes( unsigned pixel_bits, unsigned depth_bits,
257		 unsigned stencil_bits, GLboolean have_back_buffer )
258{
259    __GLcontextModes * modes;
260    __GLcontextModes * m;
261    unsigned num_modes;
262    unsigned depth_buffer_factor;
263    unsigned back_buffer_factor;
264    GLenum fb_format;
265    GLenum fb_type;
266
267    /* Right now GLX_SWAP_COPY_OML isn't supported, but it would be easy
268     * enough to add support.  Basically, if a context is created with an
269     * fbconfig where the swap method is GLX_SWAP_COPY_OML, pageflipping
270     * will never be used.
271     */
272    static const GLenum back_buffer_modes[] = {
273	GLX_NONE, GLX_SWAP_UNDEFINED_OML /*, GLX_SWAP_COPY_OML */
274    };
275
276    u_int8_t depth_bits_array[2];
277    u_int8_t stencil_bits_array[2];
278
279
280    depth_bits_array[0] = depth_bits;
281    depth_bits_array[1] = depth_bits;
282
283    /* Just like with the accumulation buffer, always provide some modes
284     * with a stencil buffer.  It will be a sw fallback, but some apps won't
285     * care about that.
286     */
287    stencil_bits_array[0] = 0;
288    stencil_bits_array[1] = (stencil_bits == 0) ? 8 : stencil_bits;
289
290    depth_buffer_factor = ((depth_bits != 0) || (stencil_bits != 0)) ? 2 : 1;
291    back_buffer_factor  = (have_back_buffer) ? 2 : 1;
292
293    num_modes = depth_buffer_factor * back_buffer_factor * 4;
294
295    if ( pixel_bits == 16 ) {
296        fb_format = GL_RGB;
297        fb_type = GL_UNSIGNED_SHORT_5_6_5;
298    }
299    else {
300        fb_format = GL_BGRA;
301        fb_type = GL_UNSIGNED_INT_8_8_8_8_REV;
302    }
303
304    modes = (*dri_interface->createContextModes)( num_modes, sizeof( __GLcontextModes ) );
305    m = modes;
306    if ( ! driFillInModes( & m, fb_format, fb_type,
307			   depth_bits_array, stencil_bits_array, depth_buffer_factor,
308			   back_buffer_modes, back_buffer_factor,
309			   GLX_TRUE_COLOR ) ) {
310	fprintf( stderr, "[%s:%u] Error creating FBConfig!\n",
311		 __func__, __LINE__ );
312	return NULL;
313    }
314
315    if ( ! driFillInModes( & m, fb_format, fb_type,
316			   depth_bits_array, stencil_bits_array, depth_buffer_factor,
317			   back_buffer_modes, back_buffer_factor,
318			   GLX_DIRECT_COLOR ) ) {
319	fprintf( stderr, "[%s:%u] Error creating FBConfig!\n",
320		 __func__, __LINE__ );
321	return NULL;
322    }
323
324    /* Mark the visual as slow if there are "fake" stencil bits.
325     */
326    for ( m = modes ; m != NULL ; m = m->next ) {
327	if ( (m->stencilBits != 0) && (m->stencilBits != stencil_bits) ) {
328	    m->visualRating = GLX_SLOW_CONFIG;
329	}
330    }
331
332    return modes;
333}
334
335#if RADEON_COMMON && defined(RADEON_COMMON_FOR_R200)
336static const __DRIallocateExtension r200AllocateExtension = {
337    { __DRI_ALLOCATE, __DRI_ALLOCATE_VERSION },
338    r200AllocateMemoryMESA,
339    r200FreeMemoryMESA,
340    r200GetMemoryOffsetMESA
341};
342
343static const __DRItexOffsetExtension r200texOffsetExtension = {
344    { __DRI_TEX_OFFSET, __DRI_TEX_OFFSET_VERSION },
345   r200SetTexOffset,
346};
347#endif
348
349#if RADEON_COMMON && defined(RADEON_COMMON_FOR_R300)
350static const __DRItexOffsetExtension r300texOffsetExtension = {
351    { __DRI_TEX_OFFSET, __DRI_TEX_OFFSET_VERSION },
352   r300SetTexOffset,
353};
354#endif
355
356/* Create the device specific screen private data struct.
357 */
358static radeonScreenPtr
359radeonCreateScreen( __DRIscreenPrivate *sPriv )
360{
361   radeonScreenPtr screen;
362   RADEONDRIPtr dri_priv = (RADEONDRIPtr)sPriv->pDevPriv;
363   unsigned char *RADEONMMIO;
364   int i;
365
366   if (sPriv->devPrivSize != sizeof(RADEONDRIRec)) {
367      fprintf(stderr,"\nERROR!  sizeof(RADEONDRIRec) does not match passed size from device driver\n");
368      return GL_FALSE;
369   }
370
371   /* Allocate the private area */
372   screen = (radeonScreenPtr) CALLOC( sizeof(*screen) );
373   if ( !screen ) {
374      __driUtilMessage("%s: Could not allocate memory for screen structure",
375		       __FUNCTION__);
376      return NULL;
377   }
378
379#if DO_DEBUG && RADEON_COMMON && defined(RADEON_COMMON_FOR_R300)
380	RADEON_DEBUG = driParseDebugString(getenv("RADEON_DEBUG"), debug_control);
381#endif
382
383   /* parse information in __driConfigOptions */
384   driParseOptionInfo (&screen->optionCache,
385		       __driConfigOptions, __driNConfigOptions);
386
387   /* This is first since which regions we map depends on whether or
388    * not we are using a PCI card.
389    */
390   screen->card_type = (dri_priv->IsPCI ? RADEON_CARD_PCI : RADEON_CARD_AGP);
391   {
392      int ret;
393      ret = radeonGetParam( sPriv->fd, RADEON_PARAM_GART_BUFFER_OFFSET,
394			    &screen->gart_buffer_offset);
395
396      if (ret) {
397	 FREE( screen );
398	 fprintf(stderr, "drm_radeon_getparam_t (RADEON_PARAM_GART_BUFFER_OFFSET): %d\n", ret);
399	 return NULL;
400      }
401
402      ret = radeonGetParam( sPriv->fd, RADEON_PARAM_GART_BASE,
403			    &screen->gart_base);
404      if (ret) {
405	 FREE( screen );
406	 fprintf(stderr, "drm_radeon_getparam_t (RADEON_PARAM_GART_BASE): %d\n", ret);
407	 return NULL;
408      }
409
410      ret = radeonGetParam( sPriv->fd, RADEON_PARAM_IRQ_NR,
411			    &screen->irq);
412      if (ret) {
413	 FREE( screen );
414	 fprintf(stderr, "drm_radeon_getparam_t (RADEON_PARAM_IRQ_NR): %d\n", ret);
415	 return NULL;
416      }
417      screen->drmSupportsCubeMapsR200 = (sPriv->drm_version.minor >= 7);
418      screen->drmSupportsBlendColor = (sPriv->drm_version.minor >= 11);
419      screen->drmSupportsTriPerf = (sPriv->drm_version.minor >= 16);
420      screen->drmSupportsFragShader = (sPriv->drm_version.minor >= 18);
421      screen->drmSupportsPointSprites = (sPriv->drm_version.minor >= 13);
422      screen->drmSupportsCubeMapsR100 = (sPriv->drm_version.minor >= 15);
423      screen->drmSupportsVertexProgram = (sPriv->drm_version.minor >= 25);
424   }
425
426   screen->mmio.handle = dri_priv->registerHandle;
427   screen->mmio.size   = dri_priv->registerSize;
428   if ( drmMap( sPriv->fd,
429		screen->mmio.handle,
430		screen->mmio.size,
431		&screen->mmio.map ) ) {
432      FREE( screen );
433      __driUtilMessage("%s: drmMap failed\n", __FUNCTION__ );
434      return NULL;
435   }
436
437   RADEONMMIO = screen->mmio.map;
438
439   screen->status.handle = dri_priv->statusHandle;
440   screen->status.size   = dri_priv->statusSize;
441   if ( drmMap( sPriv->fd,
442		screen->status.handle,
443		screen->status.size,
444		&screen->status.map ) ) {
445      drmUnmap( screen->mmio.map, screen->mmio.size );
446      FREE( screen );
447      __driUtilMessage("%s: drmMap (2) failed\n", __FUNCTION__ );
448      return NULL;
449   }
450   screen->scratch = (__volatile__ u_int32_t *)
451      ((GLubyte *)screen->status.map + RADEON_SCRATCH_REG_OFFSET);
452
453   screen->buffers = drmMapBufs( sPriv->fd );
454   if ( !screen->buffers ) {
455      drmUnmap( screen->status.map, screen->status.size );
456      drmUnmap( screen->mmio.map, screen->mmio.size );
457      FREE( screen );
458      __driUtilMessage("%s: drmMapBufs failed\n", __FUNCTION__ );
459      return NULL;
460   }
461
462   if ( dri_priv->gartTexHandle && dri_priv->gartTexMapSize ) {
463      screen->gartTextures.handle = dri_priv->gartTexHandle;
464      screen->gartTextures.size   = dri_priv->gartTexMapSize;
465      if ( drmMap( sPriv->fd,
466		   screen->gartTextures.handle,
467		   screen->gartTextures.size,
468		   (drmAddressPtr)&screen->gartTextures.map ) ) {
469	 drmUnmapBufs( screen->buffers );
470	 drmUnmap( screen->status.map, screen->status.size );
471	 drmUnmap( screen->mmio.map, screen->mmio.size );
472	 FREE( screen );
473	 __driUtilMessage("%s: drmMap failed for GART texture area\n", __FUNCTION__);
474	 return NULL;
475      }
476
477      screen->gart_texture_offset = dri_priv->gartTexOffset + screen->gart_base;
478   }
479
480   screen->chip_flags = 0;
481   /* XXX: add more chipsets */
482   switch ( dri_priv->deviceID ) {
483   case PCI_CHIP_RADEON_LY:
484   case PCI_CHIP_RADEON_LZ:
485   case PCI_CHIP_RADEON_QY:
486   case PCI_CHIP_RADEON_QZ:
487   case PCI_CHIP_RN50_515E:
488   case PCI_CHIP_RN50_5969:
489      screen->chip_family = CHIP_FAMILY_RV100;
490      break;
491
492   case PCI_CHIP_RS100_4136:
493   case PCI_CHIP_RS100_4336:
494      screen->chip_family = CHIP_FAMILY_RS100;
495      break;
496
497   case PCI_CHIP_RS200_4137:
498   case PCI_CHIP_RS200_4337:
499   case PCI_CHIP_RS250_4237:
500   case PCI_CHIP_RS250_4437:
501      screen->chip_family = CHIP_FAMILY_RS200;
502      break;
503
504   case PCI_CHIP_RADEON_QD:
505   case PCI_CHIP_RADEON_QE:
506   case PCI_CHIP_RADEON_QF:
507   case PCI_CHIP_RADEON_QG:
508      /* all original radeons (7200) presumably have a stencil op bug */
509      screen->chip_family = CHIP_FAMILY_R100;
510      screen->chip_flags = RADEON_CHIPSET_TCL | RADEON_CHIPSET_BROKEN_STENCIL;
511      break;
512
513   case PCI_CHIP_RV200_QW:
514   case PCI_CHIP_RV200_QX:
515   case PCI_CHIP_RADEON_LW:
516   case PCI_CHIP_RADEON_LX:
517      screen->chip_family = CHIP_FAMILY_RV200;
518      screen->chip_flags = RADEON_CHIPSET_TCL;
519      break;
520
521   case PCI_CHIP_R200_BB:
522   case PCI_CHIP_R200_BC:
523   case PCI_CHIP_R200_QH:
524   case PCI_CHIP_R200_QL:
525   case PCI_CHIP_R200_QM:
526      screen->chip_family = CHIP_FAMILY_R200;
527      screen->chip_flags = RADEON_CHIPSET_TCL;
528      break;
529
530   case PCI_CHIP_RV250_If:
531   case PCI_CHIP_RV250_Ig:
532   case PCI_CHIP_RV250_Ld:
533   case PCI_CHIP_RV250_Lf:
534   case PCI_CHIP_RV250_Lg:
535      screen->chip_family = CHIP_FAMILY_RV250;
536      screen->chip_flags = R200_CHIPSET_YCBCR_BROKEN | RADEON_CHIPSET_TCL;
537      break;
538
539   case PCI_CHIP_RV280_5960:
540   case PCI_CHIP_RV280_5961:
541   case PCI_CHIP_RV280_5962:
542   case PCI_CHIP_RV280_5964:
543   case PCI_CHIP_RV280_5965:
544   case PCI_CHIP_RV280_5C61:
545   case PCI_CHIP_RV280_5C63:
546      screen->chip_family = CHIP_FAMILY_RV280;
547      screen->chip_flags = RADEON_CHIPSET_TCL;
548      break;
549
550   case PCI_CHIP_RS300_5834:
551   case PCI_CHIP_RS300_5835:
552   case PCI_CHIP_RS350_7834:
553   case PCI_CHIP_RS350_7835:
554      screen->chip_family = CHIP_FAMILY_RS300;
555      break;
556
557   case PCI_CHIP_R300_AD:
558   case PCI_CHIP_R300_AE:
559   case PCI_CHIP_R300_AF:
560   case PCI_CHIP_R300_AG:
561   case PCI_CHIP_R300_ND:
562   case PCI_CHIP_R300_NE:
563   case PCI_CHIP_R300_NF:
564   case PCI_CHIP_R300_NG:
565      screen->chip_family = CHIP_FAMILY_R300;
566      screen->chip_flags = RADEON_CHIPSET_TCL;
567      break;
568
569   case PCI_CHIP_RV350_AP:
570   case PCI_CHIP_RV350_AQ:
571   case PCI_CHIP_RV350_AR:
572   case PCI_CHIP_RV350_AS:
573   case PCI_CHIP_RV350_AT:
574   case PCI_CHIP_RV350_AV:
575   case PCI_CHIP_RV350_AU:
576   case PCI_CHIP_RV350_NP:
577   case PCI_CHIP_RV350_NQ:
578   case PCI_CHIP_RV350_NR:
579   case PCI_CHIP_RV350_NS:
580   case PCI_CHIP_RV350_NT:
581   case PCI_CHIP_RV350_NV:
582      screen->chip_family = CHIP_FAMILY_RV350;
583      screen->chip_flags = RADEON_CHIPSET_TCL;
584      break;
585
586   case PCI_CHIP_R350_AH:
587   case PCI_CHIP_R350_AI:
588   case PCI_CHIP_R350_AJ:
589   case PCI_CHIP_R350_AK:
590   case PCI_CHIP_R350_NH:
591   case PCI_CHIP_R350_NI:
592   case PCI_CHIP_R360_NJ:
593   case PCI_CHIP_R350_NK:
594      screen->chip_family = CHIP_FAMILY_R350;
595      screen->chip_flags = RADEON_CHIPSET_TCL;
596      break;
597
598   case PCI_CHIP_RV370_5460:
599   case PCI_CHIP_RV370_5462:
600   case PCI_CHIP_RV370_5464:
601   case PCI_CHIP_RV370_5B60:
602   case PCI_CHIP_RV370_5B62:
603   case PCI_CHIP_RV370_5B63:
604   case PCI_CHIP_RV370_5B64:
605   case PCI_CHIP_RV370_5B65:
606   case PCI_CHIP_RV380_3150:
607   case PCI_CHIP_RV380_3152:
608   case PCI_CHIP_RV380_3154:
609   case PCI_CHIP_RV380_3E50:
610   case PCI_CHIP_RV380_3E54:
611      screen->chip_family = CHIP_FAMILY_RV380;
612      screen->chip_flags = RADEON_CHIPSET_TCL;
613      break;
614
615   case PCI_CHIP_R420_JN:
616   case PCI_CHIP_R420_JH:
617   case PCI_CHIP_R420_JI:
618   case PCI_CHIP_R420_JJ:
619   case PCI_CHIP_R420_JK:
620   case PCI_CHIP_R420_JL:
621   case PCI_CHIP_R420_JM:
622   case PCI_CHIP_R420_JO:
623   case PCI_CHIP_R420_JP:
624   case PCI_CHIP_R420_JT:
625   case PCI_CHIP_R481_4B49:
626   case PCI_CHIP_R481_4B4A:
627   case PCI_CHIP_R481_4B4B:
628   case PCI_CHIP_R481_4B4C:
629   case PCI_CHIP_R423_UH:
630   case PCI_CHIP_R423_UI:
631   case PCI_CHIP_R423_UJ:
632   case PCI_CHIP_R423_UK:
633   case PCI_CHIP_R430_554C:
634   case PCI_CHIP_R430_554D:
635   case PCI_CHIP_R430_554E:
636   case PCI_CHIP_R430_554F:
637   case PCI_CHIP_R423_5550:
638   case PCI_CHIP_R423_UQ:
639   case PCI_CHIP_R423_UR:
640   case PCI_CHIP_R423_UT:
641   case PCI_CHIP_R430_5D48:
642   case PCI_CHIP_R430_5D49:
643   case PCI_CHIP_R430_5D4A:
644   case PCI_CHIP_R480_5D4C:
645   case PCI_CHIP_R480_5D4D:
646   case PCI_CHIP_R480_5D4E:
647   case PCI_CHIP_R480_5D4F:
648   case PCI_CHIP_R480_5D50:
649   case PCI_CHIP_R480_5D52:
650   case PCI_CHIP_R423_5D57:
651      screen->chip_family = CHIP_FAMILY_R420;
652      screen->chip_flags = RADEON_CHIPSET_TCL;
653      break;
654
655   case PCI_CHIP_RV410_564A:
656   case PCI_CHIP_RV410_564B:
657   case PCI_CHIP_RV410_564F:
658   case PCI_CHIP_RV410_5652:
659   case PCI_CHIP_RV410_5653:
660   case PCI_CHIP_RV410_5E48:
661   case PCI_CHIP_RV410_5E4A:
662   case PCI_CHIP_RV410_5E4B:
663   case PCI_CHIP_RV410_5E4C:
664   case PCI_CHIP_RV410_5E4D:
665   case PCI_CHIP_RV410_5E4F:
666      screen->chip_family = CHIP_FAMILY_RV410;
667      screen->chip_flags = RADEON_CHIPSET_TCL;
668      break;
669
670   case PCI_CHIP_RS480_5954:
671   case PCI_CHIP_RS480_5955:
672   case PCI_CHIP_RS482_5974:
673   case PCI_CHIP_RS482_5975:
674   case PCI_CHIP_RS400_5A41:
675   case PCI_CHIP_RS400_5A42:
676   case PCI_CHIP_RC410_5A61:
677   case PCI_CHIP_RC410_5A62:
678      screen->chip_family = CHIP_FAMILY_RS400;
679      fprintf(stderr, "Warning, xpress200 detected.\n");
680      break;
681
682   default:
683      fprintf(stderr, "unknown chip id 0x%x, can't guess.\n",
684	      dri_priv->deviceID);
685      return NULL;
686   }
687   if ((screen->chip_family == CHIP_FAMILY_R350 || screen->chip_family == CHIP_FAMILY_R300) &&
688       sPriv->ddx_version.minor < 2) {
689      fprintf(stderr, "xf86-video-ati-6.6.2 or newer needed for Radeon 9500/9700/9800 cards.\n");
690      return NULL;
691   }
692
693   if (screen->chip_family <= CHIP_FAMILY_RS200)
694      screen->chip_flags |= RADEON_CLASS_R100;
695   else if (screen->chip_family <= CHIP_FAMILY_RV280)
696      screen->chip_flags |= RADEON_CLASS_R200;
697   else
698      screen->chip_flags |= RADEON_CLASS_R300;
699
700   screen->cpp = dri_priv->bpp / 8;
701   screen->AGPMode = dri_priv->AGPMode;
702
703   screen->fbLocation	= ( INREG( RADEON_MC_FB_LOCATION ) & 0xffff ) << 16;
704
705   if ( sPriv->drm_version.minor >= 10 ) {
706      drm_radeon_setparam_t sp;
707
708      sp.param = RADEON_SETPARAM_FB_LOCATION;
709      sp.value = screen->fbLocation;
710
711      drmCommandWrite( sPriv->fd, DRM_RADEON_SETPARAM,
712		       &sp, sizeof( sp ) );
713   }
714
715   screen->frontOffset	= dri_priv->frontOffset;
716   screen->frontPitch	= dri_priv->frontPitch;
717   screen->backOffset	= dri_priv->backOffset;
718   screen->backPitch	= dri_priv->backPitch;
719   screen->depthOffset	= dri_priv->depthOffset;
720   screen->depthPitch	= dri_priv->depthPitch;
721
722   /* Check if ddx has set up a surface reg to cover depth buffer */
723   screen->depthHasSurface = (sPriv->ddx_version.major > 4);
724
725   if ( dri_priv->textureSize == 0 ) {
726      screen->texOffset[RADEON_LOCAL_TEX_HEAP] = screen->gart_texture_offset;
727      screen->texSize[RADEON_LOCAL_TEX_HEAP] = dri_priv->gartTexMapSize;
728      screen->logTexGranularity[RADEON_LOCAL_TEX_HEAP] =
729	 dri_priv->log2GARTTexGran;
730   } else {
731      screen->texOffset[RADEON_LOCAL_TEX_HEAP] = dri_priv->textureOffset
732				               + screen->fbLocation;
733      screen->texSize[RADEON_LOCAL_TEX_HEAP] = dri_priv->textureSize;
734      screen->logTexGranularity[RADEON_LOCAL_TEX_HEAP] =
735	 dri_priv->log2TexGran;
736   }
737
738   if ( !screen->gartTextures.map || dri_priv->textureSize == 0
739	|| getenv( "RADEON_GARTTEXTURING_FORCE_DISABLE" ) ) {
740      screen->numTexHeaps = RADEON_NR_TEX_HEAPS - 1;
741      screen->texOffset[RADEON_GART_TEX_HEAP] = 0;
742      screen->texSize[RADEON_GART_TEX_HEAP] = 0;
743      screen->logTexGranularity[RADEON_GART_TEX_HEAP] = 0;
744   } else {
745      screen->numTexHeaps = RADEON_NR_TEX_HEAPS;
746      screen->texOffset[RADEON_GART_TEX_HEAP] = screen->gart_texture_offset;
747      screen->texSize[RADEON_GART_TEX_HEAP] = dri_priv->gartTexMapSize;
748      screen->logTexGranularity[RADEON_GART_TEX_HEAP] =
749	 dri_priv->log2GARTTexGran;
750   }
751
752   i = 0;
753   screen->extensions[i++] = &driCopySubBufferExtension.base;
754   screen->extensions[i++] = &driFrameTrackingExtension.base;
755   screen->extensions[i++] = &driReadDrawableExtension;
756
757   if ( screen->irq != 0 ) {
758       screen->extensions[i++] = &driSwapControlExtension.base;
759       screen->extensions[i++] = &driMediaStreamCounterExtension.base;
760   }
761
762#if RADEON_COMMON && defined(RADEON_COMMON_FOR_R200)
763   if (IS_R200_CLASS(screen))
764       screen->extensions[i++] = &r200AllocateExtension.base;
765
766   screen->extensions[i++] = &r200texOffsetExtension.base;
767#endif
768
769#if RADEON_COMMON && defined(RADEON_COMMON_FOR_R300)
770   screen->extensions[i++] = &r300texOffsetExtension.base;
771#endif
772
773   screen->extensions[i++] = NULL;
774   sPriv->extensions = screen->extensions;
775
776   screen->driScreen = sPriv;
777   screen->sarea_priv_offset = dri_priv->sarea_priv_offset;
778   return screen;
779}
780
781/* Destroy the device specific screen private data struct.
782 */
783static void
784radeonDestroyScreen( __DRIscreenPrivate *sPriv )
785{
786   radeonScreenPtr screen = (radeonScreenPtr)sPriv->private;
787
788   if (!screen)
789      return;
790
791   if ( screen->gartTextures.map ) {
792      drmUnmap( screen->gartTextures.map, screen->gartTextures.size );
793   }
794   drmUnmapBufs( screen->buffers );
795   drmUnmap( screen->status.map, screen->status.size );
796   drmUnmap( screen->mmio.map, screen->mmio.size );
797
798   /* free all option information */
799   driDestroyOptionInfo (&screen->optionCache);
800
801   FREE( screen );
802   sPriv->private = NULL;
803}
804
805
806/* Initialize the driver specific screen private data.
807 */
808static GLboolean
809radeonInitDriver( __DRIscreenPrivate *sPriv )
810{
811   sPriv->private = (void *) radeonCreateScreen( sPriv );
812   if ( !sPriv->private ) {
813      radeonDestroyScreen( sPriv );
814      return GL_FALSE;
815   }
816
817   return GL_TRUE;
818}
819
820
821/**
822 * Create the Mesa framebuffer and renderbuffers for a given window/drawable.
823 *
824 * \todo This function (and its interface) will need to be updated to support
825 * pbuffers.
826 */
827static GLboolean
828radeonCreateBuffer( __DRIscreenPrivate *driScrnPriv,
829                    __DRIdrawablePrivate *driDrawPriv,
830                    const __GLcontextModes *mesaVis,
831                    GLboolean isPixmap )
832{
833   radeonScreenPtr screen = (radeonScreenPtr) driScrnPriv->private;
834
835   if (isPixmap) {
836      return GL_FALSE; /* not implemented */
837   }
838   else {
839      const GLboolean swDepth = GL_FALSE;
840      const GLboolean swAlpha = GL_FALSE;
841      const GLboolean swAccum = mesaVis->accumRedBits > 0;
842      const GLboolean swStencil = mesaVis->stencilBits > 0 &&
843         mesaVis->depthBits != 24;
844      struct gl_framebuffer *fb = _mesa_create_framebuffer(mesaVis);
845
846      /* front color renderbuffer */
847      {
848         driRenderbuffer *frontRb
849            = driNewRenderbuffer(GL_RGBA,
850                                 driScrnPriv->pFB + screen->frontOffset,
851                                 screen->cpp,
852                                 screen->frontOffset, screen->frontPitch,
853                                 driDrawPriv);
854         radeonSetSpanFunctions(frontRb, mesaVis);
855         _mesa_add_renderbuffer(fb, BUFFER_FRONT_LEFT, &frontRb->Base);
856      }
857
858      /* back color renderbuffer */
859      if (mesaVis->doubleBufferMode) {
860         driRenderbuffer *backRb
861            = driNewRenderbuffer(GL_RGBA,
862                                 driScrnPriv->pFB + screen->backOffset,
863                                 screen->cpp,
864                                 screen->backOffset, screen->backPitch,
865                                 driDrawPriv);
866         radeonSetSpanFunctions(backRb, mesaVis);
867         _mesa_add_renderbuffer(fb, BUFFER_BACK_LEFT, &backRb->Base);
868      }
869
870      /* depth renderbuffer */
871      if (mesaVis->depthBits == 16) {
872         driRenderbuffer *depthRb
873            = driNewRenderbuffer(GL_DEPTH_COMPONENT16,
874                                 driScrnPriv->pFB + screen->depthOffset,
875                                 screen->cpp,
876                                 screen->depthOffset, screen->depthPitch,
877                                 driDrawPriv);
878         radeonSetSpanFunctions(depthRb, mesaVis);
879         _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &depthRb->Base);
880	 depthRb->depthHasSurface = screen->depthHasSurface;
881      }
882      else if (mesaVis->depthBits == 24) {
883         driRenderbuffer *depthRb
884            = driNewRenderbuffer(GL_DEPTH_COMPONENT24,
885                                 driScrnPriv->pFB + screen->depthOffset,
886                                 screen->cpp,
887                                 screen->depthOffset, screen->depthPitch,
888                                 driDrawPriv);
889         radeonSetSpanFunctions(depthRb, mesaVis);
890         _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &depthRb->Base);
891	 depthRb->depthHasSurface = screen->depthHasSurface;
892      }
893
894      /* stencil renderbuffer */
895      if (mesaVis->stencilBits > 0 && !swStencil) {
896         driRenderbuffer *stencilRb
897            = driNewRenderbuffer(GL_STENCIL_INDEX8_EXT,
898                                 driScrnPriv->pFB + screen->depthOffset,
899                                 screen->cpp,
900                                 screen->depthOffset, screen->depthPitch,
901                                 driDrawPriv);
902         radeonSetSpanFunctions(stencilRb, mesaVis);
903         _mesa_add_renderbuffer(fb, BUFFER_STENCIL, &stencilRb->Base);
904	 stencilRb->depthHasSurface = screen->depthHasSurface;
905      }
906
907      _mesa_add_soft_renderbuffers(fb,
908                                   GL_FALSE, /* color */
909                                   swDepth,
910                                   swStencil,
911                                   swAccum,
912                                   swAlpha,
913                                   GL_FALSE /* aux */);
914      driDrawPriv->driverPrivate = (void *) fb;
915
916      return (driDrawPriv->driverPrivate != NULL);
917   }
918}
919
920
921static void
922radeonDestroyBuffer(__DRIdrawablePrivate *driDrawPriv)
923{
924   _mesa_unreference_framebuffer((GLframebuffer **)(&(driDrawPriv->driverPrivate)));
925}
926
927#if RADEON_COMMON && defined(RADEON_COMMON_FOR_R300)
928/**
929 * Choose the appropriate CreateContext function based on the chipset.
930 * Eventually, all drivers will go through this process.
931 */
932static GLboolean radeonCreateContext(const __GLcontextModes * glVisual,
933				     __DRIcontextPrivate * driContextPriv,
934				     void *sharedContextPriv)
935{
936	__DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
937	radeonScreenPtr screen = (radeonScreenPtr) (sPriv->private);
938
939	if (IS_R300_CLASS(screen))
940		return r300CreateContext(glVisual, driContextPriv, sharedContextPriv);
941        return GL_FALSE;
942}
943
944/**
945 * Choose the appropriate DestroyContext function based on the chipset.
946 */
947static void radeonDestroyContext(__DRIcontextPrivate * driContextPriv)
948{
949	radeonContextPtr radeon = (radeonContextPtr) driContextPriv->driverPrivate;
950
951	if (IS_R300_CLASS(radeon->radeonScreen))
952		return r300DestroyContext(driContextPriv);
953}
954
955
956#endif
957
958#if !RADEON_COMMON || (RADEON_COMMON && defined(RADEON_COMMON_FOR_R300))
959static struct __DriverAPIRec radeonAPI = {
960   .DestroyScreen   = radeonDestroyScreen,
961   .CreateContext   = radeonCreateContext,
962   .DestroyContext  = radeonDestroyContext,
963   .CreateBuffer    = radeonCreateBuffer,
964   .DestroyBuffer   = radeonDestroyBuffer,
965   .SwapBuffers     = radeonSwapBuffers,
966   .MakeCurrent     = radeonMakeCurrent,
967   .UnbindContext   = radeonUnbindContext,
968   .GetSwapInfo     = getSwapInfo,
969   .GetMSC          = driGetMSC32,
970   .GetDrawableMSC  = driDrawableGetMSC32,
971   .WaitForMSC      = driWaitForMSC32,
972   .WaitForSBC      = NULL,
973   .SwapBuffersMSC  = NULL,
974   .CopySubBuffer   = radeonCopySubBuffer,
975};
976#else
977static const struct __DriverAPIRec r200API = {
978   .DestroyScreen   = radeonDestroyScreen,
979   .CreateContext   = r200CreateContext,
980   .DestroyContext  = r200DestroyContext,
981   .CreateBuffer    = radeonCreateBuffer,
982   .DestroyBuffer   = radeonDestroyBuffer,
983   .SwapBuffers     = r200SwapBuffers,
984   .MakeCurrent     = r200MakeCurrent,
985   .UnbindContext   = r200UnbindContext,
986   .GetSwapInfo     = getSwapInfo,
987   .GetMSC          = driGetMSC32,
988   .GetDrawableMSC  = driDrawableGetMSC32,
989   .WaitForMSC      = driWaitForMSC32,
990   .WaitForSBC      = NULL,
991   .SwapBuffersMSC  = NULL,
992   .CopySubBuffer   = r200CopySubBuffer,
993};
994#endif
995
996
997/**
998 * This is the driver specific part of the createNewScreen entry point.
999 *
1000 * \todo maybe fold this into intelInitDriver
1001 *
1002 * \return the __GLcontextModes supported by this driver
1003 */
1004__GLcontextModes *__driDriverInitScreen(__DRIscreenPrivate *psp)
1005{
1006#if !RADEON_COMMON
1007   static const char *driver_name = "Radeon";
1008   static const __DRIutilversion2 ddx_expected = { 4, 5, 0, 0 };
1009   static const __DRIversion dri_expected = { 4, 0, 0 };
1010   static const __DRIversion drm_expected = { 1, 6, 0 };
1011#elif RADEON_COMMON && defined(RADEON_COMMON_FOR_R200)
1012   static const char *driver_name = "R200";
1013   static const __DRIutilversion2 ddx_expected = { 4, 5, 0, 0 };
1014   static const __DRIversion dri_expected = { 4, 0, 0 };
1015   static const __DRIversion drm_expected = { 1, 6, 0 };
1016#elif RADEON_COMMON && defined(RADEON_COMMON_FOR_R300)
1017   static const char *driver_name = "R300";
1018   static const __DRIutilversion2 ddx_expected = { 4, 5, 0, 0 };
1019   static const __DRIversion dri_expected = { 4, 0, 0 };
1020   static const __DRIversion drm_expected = { 1, 24, 0 };
1021#endif
1022   RADEONDRIPtr dri_priv = (RADEONDRIPtr) psp->pDevPriv;
1023
1024   if ( ! driCheckDriDdxDrmVersions3( driver_name,
1025				      &psp->dri_version, & dri_expected,
1026				      &psp->ddx_version, & ddx_expected,
1027				      &psp->drm_version, & drm_expected ) ) {
1028      return NULL;
1029   }
1030#if !RADEON_COMMON || (RADEON_COMMON && defined(RADEON_COMMON_FOR_R300))
1031   psp->DriverAPI = radeonAPI;
1032#elif RADEON_COMMON && defined(RADEON_COMMON_FOR_R200)
1033   psp->DriverAPI = r200API;
1034#endif
1035
1036   /* Calling driInitExtensions here, with a NULL context pointer,
1037    * does not actually enable the extensions.  It just makes sure
1038    * that all the dispatch offsets for all the extensions that
1039    * *might* be enables are known.  This is needed because the
1040    * dispatch offsets need to be known when _mesa_context_create
1041    * is called, but we can't enable the extensions until we have a
1042    * context pointer.
1043    *
1044    * Hello chicken.  Hello egg.  How are you two today?
1045    */
1046   driInitExtensions( NULL, card_extensions, GL_FALSE );
1047#if RADEON_COMMON && defined(RADEON_COMMON_FOR_R200)
1048   driInitExtensions( NULL, blend_extensions, GL_FALSE );
1049   driInitSingleExtension( NULL, ARB_vp_extension );
1050   driInitSingleExtension( NULL, NV_vp_extension );
1051   driInitSingleExtension( NULL, ATI_fs_extension );
1052   driInitExtensions( NULL, point_extensions, GL_FALSE );
1053#endif
1054
1055   if (!radeonInitDriver(psp))
1056       return NULL;
1057
1058   return radeonFillInModes( dri_priv->bpp,
1059			     (dri_priv->bpp == 16) ? 16 : 24,
1060			     (dri_priv->bpp == 16) ? 0  : 8,
1061			     (dri_priv->backOffset != dri_priv->depthOffset) );
1062}
1063
1064
1065/**
1066 * Get information about previous buffer swaps.
1067 */
1068static int
1069getSwapInfo( __DRIdrawablePrivate *dPriv, __DRIswapInfo * sInfo )
1070{
1071#if !RADEON_COMMON || (RADEON_COMMON && defined(RADEON_COMMON_FOR_R300))
1072   radeonContextPtr  rmesa;
1073#elif RADEON_COMMON && defined(RADEON_COMMON_FOR_R200)
1074   r200ContextPtr  rmesa;
1075#endif
1076
1077   if ( (dPriv == NULL) || (dPriv->driContextPriv == NULL)
1078	|| (dPriv->driContextPriv->driverPrivate == NULL)
1079	|| (sInfo == NULL) ) {
1080      return -1;
1081   }
1082
1083   rmesa = dPriv->driContextPriv->driverPrivate;
1084   sInfo->swap_count = rmesa->swap_count;
1085   sInfo->swap_ust = rmesa->swap_ust;
1086   sInfo->swap_missed_count = rmesa->swap_missed_count;
1087
1088   sInfo->swap_missed_usage = (sInfo->swap_missed_count != 0)
1089       ? driCalculateSwapUsage( dPriv, 0, rmesa->swap_missed_ust )
1090       : 0.0;
1091
1092   return 0;
1093}
1094