radeon_screen.c revision ac3e838fa748c8c8a6ffc04d1ab13da71f75f103
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
335static const __DRIextension *radeonExtensions[] = {
336    &driCopySubBufferExtension.base,
337    NULL
338};
339
340/* Create the device specific screen private data struct.
341 */
342static radeonScreenPtr
343radeonCreateScreen( __DRIscreenPrivate *sPriv )
344{
345   radeonScreenPtr screen;
346   RADEONDRIPtr dri_priv = (RADEONDRIPtr)sPriv->pDevPriv;
347   unsigned char *RADEONMMIO;
348   PFNGLXSCRENABLEEXTENSIONPROC glx_enable_extension =
349     (PFNGLXSCRENABLEEXTENSIONPROC) (*dri_interface->getProcAddress("glxEnableExtension"));
350
351   if (sPriv->devPrivSize != sizeof(RADEONDRIRec)) {
352      fprintf(stderr,"\nERROR!  sizeof(RADEONDRIRec) does not match passed size from device driver\n");
353      return GL_FALSE;
354   }
355
356   /* Allocate the private area */
357   screen = (radeonScreenPtr) CALLOC( sizeof(*screen) );
358   if ( !screen ) {
359      __driUtilMessage("%s: Could not allocate memory for screen structure",
360		       __FUNCTION__);
361      return NULL;
362   }
363
364#if DO_DEBUG && RADEON_COMMON && defined(RADEON_COMMON_FOR_R300)
365	RADEON_DEBUG = driParseDebugString(getenv("RADEON_DEBUG"), debug_control);
366#endif
367
368   /* parse information in __driConfigOptions */
369   driParseOptionInfo (&screen->optionCache,
370		       __driConfigOptions, __driNConfigOptions);
371
372   /* This is first since which regions we map depends on whether or
373    * not we are using a PCI card.
374    */
375   screen->card_type = (dri_priv->IsPCI ? RADEON_CARD_PCI : RADEON_CARD_AGP);
376   {
377      int ret;
378      ret = radeonGetParam( sPriv->fd, RADEON_PARAM_GART_BUFFER_OFFSET,
379			    &screen->gart_buffer_offset);
380
381      if (ret) {
382	 FREE( screen );
383	 fprintf(stderr, "drm_radeon_getparam_t (RADEON_PARAM_GART_BUFFER_OFFSET): %d\n", ret);
384	 return NULL;
385      }
386
387      ret = radeonGetParam( sPriv->fd, RADEON_PARAM_GART_BASE,
388			    &screen->gart_base);
389      if (ret) {
390	 FREE( screen );
391	 fprintf(stderr, "drm_radeon_getparam_t (RADEON_PARAM_GART_BASE): %d\n", ret);
392	 return NULL;
393      }
394
395      ret = radeonGetParam( sPriv->fd, RADEON_PARAM_IRQ_NR,
396			    &screen->irq);
397      if (ret) {
398	 FREE( screen );
399	 fprintf(stderr, "drm_radeon_getparam_t (RADEON_PARAM_IRQ_NR): %d\n", ret);
400	 return NULL;
401      }
402      screen->drmSupportsCubeMapsR200 = (sPriv->drm_version.minor >= 7);
403      screen->drmSupportsBlendColor = (sPriv->drm_version.minor >= 11);
404      screen->drmSupportsTriPerf = (sPriv->drm_version.minor >= 16);
405      screen->drmSupportsFragShader = (sPriv->drm_version.minor >= 18);
406      screen->drmSupportsPointSprites = (sPriv->drm_version.minor >= 13);
407      screen->drmSupportsCubeMapsR100 = (sPriv->drm_version.minor >= 15);
408      screen->drmSupportsVertexProgram = (sPriv->drm_version.minor >= 25);
409   }
410
411   screen->mmio.handle = dri_priv->registerHandle;
412   screen->mmio.size   = dri_priv->registerSize;
413   if ( drmMap( sPriv->fd,
414		screen->mmio.handle,
415		screen->mmio.size,
416		&screen->mmio.map ) ) {
417      FREE( screen );
418      __driUtilMessage("%s: drmMap failed\n", __FUNCTION__ );
419      return NULL;
420   }
421
422   RADEONMMIO = screen->mmio.map;
423
424   screen->status.handle = dri_priv->statusHandle;
425   screen->status.size   = dri_priv->statusSize;
426   if ( drmMap( sPriv->fd,
427		screen->status.handle,
428		screen->status.size,
429		&screen->status.map ) ) {
430      drmUnmap( screen->mmio.map, screen->mmio.size );
431      FREE( screen );
432      __driUtilMessage("%s: drmMap (2) failed\n", __FUNCTION__ );
433      return NULL;
434   }
435   screen->scratch = (__volatile__ u_int32_t *)
436      ((GLubyte *)screen->status.map + RADEON_SCRATCH_REG_OFFSET);
437
438   screen->buffers = drmMapBufs( sPriv->fd );
439   if ( !screen->buffers ) {
440      drmUnmap( screen->status.map, screen->status.size );
441      drmUnmap( screen->mmio.map, screen->mmio.size );
442      FREE( screen );
443      __driUtilMessage("%s: drmMapBufs failed\n", __FUNCTION__ );
444      return NULL;
445   }
446
447   if ( dri_priv->gartTexHandle && dri_priv->gartTexMapSize ) {
448      screen->gartTextures.handle = dri_priv->gartTexHandle;
449      screen->gartTextures.size   = dri_priv->gartTexMapSize;
450      if ( drmMap( sPriv->fd,
451		   screen->gartTextures.handle,
452		   screen->gartTextures.size,
453		   (drmAddressPtr)&screen->gartTextures.map ) ) {
454	 drmUnmapBufs( screen->buffers );
455	 drmUnmap( screen->status.map, screen->status.size );
456	 drmUnmap( screen->mmio.map, screen->mmio.size );
457	 FREE( screen );
458	 __driUtilMessage("%s: drmMap failed for GART texture area\n", __FUNCTION__);
459	 return NULL;
460      }
461
462      screen->gart_texture_offset = dri_priv->gartTexOffset + screen->gart_base;
463   }
464
465   screen->chip_flags = 0;
466   /* XXX: add more chipsets */
467   switch ( dri_priv->deviceID ) {
468   case PCI_CHIP_RADEON_LY:
469   case PCI_CHIP_RADEON_LZ:
470   case PCI_CHIP_RADEON_QY:
471   case PCI_CHIP_RADEON_QZ:
472   case PCI_CHIP_RN50_515E:
473   case PCI_CHIP_RN50_5969:
474      screen->chip_family = CHIP_FAMILY_RV100;
475      break;
476
477   case PCI_CHIP_RS100_4136:
478   case PCI_CHIP_RS100_4336:
479      screen->chip_family = CHIP_FAMILY_RS100;
480      break;
481
482   case PCI_CHIP_RS200_4137:
483   case PCI_CHIP_RS200_4337:
484   case PCI_CHIP_RS250_4237:
485   case PCI_CHIP_RS250_4437:
486      screen->chip_family = CHIP_FAMILY_RS200;
487      break;
488
489   case PCI_CHIP_RADEON_QD:
490   case PCI_CHIP_RADEON_QE:
491   case PCI_CHIP_RADEON_QF:
492   case PCI_CHIP_RADEON_QG:
493      /* all original radeons (7200) presumably have a stencil op bug */
494      screen->chip_family = CHIP_FAMILY_R100;
495      screen->chip_flags = RADEON_CHIPSET_TCL | RADEON_CHIPSET_BROKEN_STENCIL;
496      break;
497
498   case PCI_CHIP_RV200_QW:
499   case PCI_CHIP_RV200_QX:
500   case PCI_CHIP_RADEON_LW:
501   case PCI_CHIP_RADEON_LX:
502      screen->chip_family = CHIP_FAMILY_RV200;
503      screen->chip_flags = RADEON_CHIPSET_TCL;
504      break;
505
506   case PCI_CHIP_R200_BB:
507   case PCI_CHIP_R200_BC:
508   case PCI_CHIP_R200_QH:
509   case PCI_CHIP_R200_QL:
510   case PCI_CHIP_R200_QM:
511      screen->chip_family = CHIP_FAMILY_R200;
512      screen->chip_flags = RADEON_CHIPSET_TCL;
513      break;
514
515   case PCI_CHIP_RV250_If:
516   case PCI_CHIP_RV250_Ig:
517   case PCI_CHIP_RV250_Ld:
518   case PCI_CHIP_RV250_Lf:
519   case PCI_CHIP_RV250_Lg:
520      screen->chip_family = CHIP_FAMILY_RV250;
521      screen->chip_flags = R200_CHIPSET_YCBCR_BROKEN | RADEON_CHIPSET_TCL;
522      break;
523
524   case PCI_CHIP_RV280_5960:
525   case PCI_CHIP_RV280_5961:
526   case PCI_CHIP_RV280_5962:
527   case PCI_CHIP_RV280_5964:
528   case PCI_CHIP_RV280_5965:
529   case PCI_CHIP_RV280_5C61:
530   case PCI_CHIP_RV280_5C63:
531      screen->chip_family = CHIP_FAMILY_RV280;
532      screen->chip_flags = RADEON_CHIPSET_TCL;
533      break;
534
535   case PCI_CHIP_RS300_5834:
536   case PCI_CHIP_RS300_5835:
537   case PCI_CHIP_RS350_7834:
538   case PCI_CHIP_RS350_7835:
539      screen->chip_family = CHIP_FAMILY_RS300;
540      break;
541
542   case PCI_CHIP_R300_AD:
543   case PCI_CHIP_R300_AE:
544   case PCI_CHIP_R300_AF:
545   case PCI_CHIP_R300_AG:
546   case PCI_CHIP_R300_ND:
547   case PCI_CHIP_R300_NE:
548   case PCI_CHIP_R300_NF:
549   case PCI_CHIP_R300_NG:
550      screen->chip_family = CHIP_FAMILY_R300;
551      screen->chip_flags = RADEON_CHIPSET_TCL;
552      break;
553
554   case PCI_CHIP_RV350_AP:
555   case PCI_CHIP_RV350_AQ:
556   case PCI_CHIP_RV350_AR:
557   case PCI_CHIP_RV350_AS:
558   case PCI_CHIP_RV350_AT:
559   case PCI_CHIP_RV350_AV:
560   case PCI_CHIP_RV350_AU:
561   case PCI_CHIP_RV350_NP:
562   case PCI_CHIP_RV350_NQ:
563   case PCI_CHIP_RV350_NR:
564   case PCI_CHIP_RV350_NS:
565   case PCI_CHIP_RV350_NT:
566   case PCI_CHIP_RV350_NV:
567      screen->chip_family = CHIP_FAMILY_RV350;
568      screen->chip_flags = RADEON_CHIPSET_TCL;
569      break;
570
571   case PCI_CHIP_R350_AH:
572   case PCI_CHIP_R350_AI:
573   case PCI_CHIP_R350_AJ:
574   case PCI_CHIP_R350_AK:
575   case PCI_CHIP_R350_NH:
576   case PCI_CHIP_R350_NI:
577   case PCI_CHIP_R360_NJ:
578   case PCI_CHIP_R350_NK:
579      screen->chip_family = CHIP_FAMILY_R350;
580      screen->chip_flags = RADEON_CHIPSET_TCL;
581      break;
582
583   case PCI_CHIP_RV370_5460:
584   case PCI_CHIP_RV370_5462:
585   case PCI_CHIP_RV370_5464:
586   case PCI_CHIP_RV370_5B60:
587   case PCI_CHIP_RV370_5B62:
588   case PCI_CHIP_RV370_5B63:
589   case PCI_CHIP_RV370_5B64:
590   case PCI_CHIP_RV370_5B65:
591   case PCI_CHIP_RV380_3150:
592   case PCI_CHIP_RV380_3152:
593   case PCI_CHIP_RV380_3154:
594   case PCI_CHIP_RV380_3E50:
595   case PCI_CHIP_RV380_3E54:
596      screen->chip_family = CHIP_FAMILY_RV380;
597      screen->chip_flags = RADEON_CHIPSET_TCL;
598      break;
599
600   case PCI_CHIP_R420_JN:
601   case PCI_CHIP_R420_JH:
602   case PCI_CHIP_R420_JI:
603   case PCI_CHIP_R420_JJ:
604   case PCI_CHIP_R420_JK:
605   case PCI_CHIP_R420_JL:
606   case PCI_CHIP_R420_JM:
607   case PCI_CHIP_R420_JO:
608   case PCI_CHIP_R420_JP:
609   case PCI_CHIP_R420_JT:
610   case PCI_CHIP_R481_4B49:
611   case PCI_CHIP_R481_4B4A:
612   case PCI_CHIP_R481_4B4B:
613   case PCI_CHIP_R481_4B4C:
614   case PCI_CHIP_R423_UH:
615   case PCI_CHIP_R423_UI:
616   case PCI_CHIP_R423_UJ:
617   case PCI_CHIP_R423_UK:
618   case PCI_CHIP_R430_554C:
619   case PCI_CHIP_R430_554D:
620   case PCI_CHIP_R430_554E:
621   case PCI_CHIP_R430_554F:
622   case PCI_CHIP_R423_5550:
623   case PCI_CHIP_R423_UQ:
624   case PCI_CHIP_R423_UR:
625   case PCI_CHIP_R423_UT:
626   case PCI_CHIP_R430_5D48:
627   case PCI_CHIP_R430_5D49:
628   case PCI_CHIP_R430_5D4A:
629   case PCI_CHIP_R480_5D4C:
630   case PCI_CHIP_R480_5D4D:
631   case PCI_CHIP_R480_5D4E:
632   case PCI_CHIP_R480_5D4F:
633   case PCI_CHIP_R480_5D50:
634   case PCI_CHIP_R480_5D52:
635   case PCI_CHIP_R423_5D57:
636      screen->chip_family = CHIP_FAMILY_R420;
637      screen->chip_flags = RADEON_CHIPSET_TCL;
638      break;
639
640   case PCI_CHIP_RV410_564A:
641   case PCI_CHIP_RV410_564B:
642   case PCI_CHIP_RV410_564F:
643   case PCI_CHIP_RV410_5652:
644   case PCI_CHIP_RV410_5653:
645   case PCI_CHIP_RV410_5E48:
646   case PCI_CHIP_RV410_5E4A:
647   case PCI_CHIP_RV410_5E4B:
648   case PCI_CHIP_RV410_5E4C:
649   case PCI_CHIP_RV410_5E4D:
650   case PCI_CHIP_RV410_5E4F:
651      screen->chip_family = CHIP_FAMILY_RV410;
652      screen->chip_flags = RADEON_CHIPSET_TCL;
653      break;
654
655   case PCI_CHIP_RS480_5954:
656   case PCI_CHIP_RS480_5955:
657   case PCI_CHIP_RS482_5974:
658   case PCI_CHIP_RS482_5975:
659   case PCI_CHIP_RS400_5A41:
660   case PCI_CHIP_RS400_5A42:
661   case PCI_CHIP_RC410_5A61:
662   case PCI_CHIP_RC410_5A62:
663      screen->chip_family = CHIP_FAMILY_RS400;
664      fprintf(stderr, "Warning, xpress200 detected.\n");
665      break;
666
667   default:
668      fprintf(stderr, "unknown chip id 0x%x, can't guess.\n",
669	      dri_priv->deviceID);
670      return NULL;
671   }
672   if ((screen->chip_family == CHIP_FAMILY_R350 || screen->chip_family == CHIP_FAMILY_R300) &&
673       sPriv->ddx_version.minor < 2) {
674      fprintf(stderr, "xf86-video-ati-6.6.2 or newer needed for Radeon 9500/9700/9800 cards.\n");
675      return NULL;
676   }
677
678   if (screen->chip_family <= CHIP_FAMILY_RS200)
679      screen->chip_flags |= RADEON_CLASS_R100;
680   else if (screen->chip_family <= CHIP_FAMILY_RV280)
681      screen->chip_flags |= RADEON_CLASS_R200;
682   else
683      screen->chip_flags |= RADEON_CLASS_R300;
684
685   screen->cpp = dri_priv->bpp / 8;
686   screen->AGPMode = dri_priv->AGPMode;
687
688   screen->fbLocation	= ( INREG( RADEON_MC_FB_LOCATION ) & 0xffff ) << 16;
689
690   if ( sPriv->drm_version.minor >= 10 ) {
691      drm_radeon_setparam_t sp;
692
693      sp.param = RADEON_SETPARAM_FB_LOCATION;
694      sp.value = screen->fbLocation;
695
696      drmCommandWrite( sPriv->fd, DRM_RADEON_SETPARAM,
697		       &sp, sizeof( sp ) );
698   }
699
700   screen->frontOffset	= dri_priv->frontOffset;
701   screen->frontPitch	= dri_priv->frontPitch;
702   screen->backOffset	= dri_priv->backOffset;
703   screen->backPitch	= dri_priv->backPitch;
704   screen->depthOffset	= dri_priv->depthOffset;
705   screen->depthPitch	= dri_priv->depthPitch;
706
707   /* Check if ddx has set up a surface reg to cover depth buffer */
708   screen->depthHasSurface = ((sPriv->ddx_version.major > 4) &&
709      (screen->chip_flags & RADEON_CHIPSET_TCL));
710
711   if ( dri_priv->textureSize == 0 ) {
712      screen->texOffset[RADEON_LOCAL_TEX_HEAP] = screen->gart_texture_offset;
713      screen->texSize[RADEON_LOCAL_TEX_HEAP] = dri_priv->gartTexMapSize;
714      screen->logTexGranularity[RADEON_LOCAL_TEX_HEAP] =
715	 dri_priv->log2GARTTexGran;
716   } else {
717      screen->texOffset[RADEON_LOCAL_TEX_HEAP] = dri_priv->textureOffset
718				               + screen->fbLocation;
719      screen->texSize[RADEON_LOCAL_TEX_HEAP] = dri_priv->textureSize;
720      screen->logTexGranularity[RADEON_LOCAL_TEX_HEAP] =
721	 dri_priv->log2TexGran;
722   }
723
724   if ( !screen->gartTextures.map || dri_priv->textureSize == 0
725	|| getenv( "RADEON_GARTTEXTURING_FORCE_DISABLE" ) ) {
726      screen->numTexHeaps = RADEON_NR_TEX_HEAPS - 1;
727      screen->texOffset[RADEON_GART_TEX_HEAP] = 0;
728      screen->texSize[RADEON_GART_TEX_HEAP] = 0;
729      screen->logTexGranularity[RADEON_GART_TEX_HEAP] = 0;
730   } else {
731      screen->numTexHeaps = RADEON_NR_TEX_HEAPS;
732      screen->texOffset[RADEON_GART_TEX_HEAP] = screen->gart_texture_offset;
733      screen->texSize[RADEON_GART_TEX_HEAP] = dri_priv->gartTexMapSize;
734      screen->logTexGranularity[RADEON_GART_TEX_HEAP] =
735	 dri_priv->log2GARTTexGran;
736   }
737
738   sPriv->extensions = radeonExtensions;
739
740   if ( glx_enable_extension != NULL ) {
741      if ( screen->irq != 0 ) {
742	 (*glx_enable_extension)( sPriv->psc, "GLX_SGI_swap_control" );
743	 (*glx_enable_extension)( sPriv->psc, "GLX_SGI_video_sync" );
744	 (*glx_enable_extension)( sPriv->psc, "GLX_MESA_swap_control" );
745      }
746
747      (*glx_enable_extension)( sPriv->psc, "GLX_MESA_swap_frame_usage" );
748      if (IS_R200_CLASS(screen))
749	 (*glx_enable_extension)( sPriv->psc, "GLX_MESA_allocate_memory" );
750
751      (*glx_enable_extension)( sPriv->psc, "GLX_SGI_make_current_read" );
752   }
753
754#if RADEON_COMMON && defined(RADEON_COMMON_FOR_R200)
755   if (IS_R200_CLASS(screen)) {
756      sPriv->psc->allocateMemory = (void *) r200AllocateMemoryMESA;
757      sPriv->psc->freeMemory     = (void *) r200FreeMemoryMESA;
758      sPriv->psc->memoryOffset   = (void *) r200GetMemoryOffsetMESA;
759   }
760#endif
761
762   screen->driScreen = sPriv;
763   screen->sarea_priv_offset = dri_priv->sarea_priv_offset;
764   return screen;
765}
766
767/* Destroy the device specific screen private data struct.
768 */
769static void
770radeonDestroyScreen( __DRIscreenPrivate *sPriv )
771{
772   radeonScreenPtr screen = (radeonScreenPtr)sPriv->private;
773
774   if (!screen)
775      return;
776
777   if ( screen->gartTextures.map ) {
778      drmUnmap( screen->gartTextures.map, screen->gartTextures.size );
779   }
780   drmUnmapBufs( screen->buffers );
781   drmUnmap( screen->status.map, screen->status.size );
782   drmUnmap( screen->mmio.map, screen->mmio.size );
783
784   /* free all option information */
785   driDestroyOptionInfo (&screen->optionCache);
786
787   FREE( screen );
788   sPriv->private = NULL;
789}
790
791
792/* Initialize the driver specific screen private data.
793 */
794static GLboolean
795radeonInitDriver( __DRIscreenPrivate *sPriv )
796{
797   sPriv->private = (void *) radeonCreateScreen( sPriv );
798   if ( !sPriv->private ) {
799      radeonDestroyScreen( sPriv );
800      return GL_FALSE;
801   }
802
803   return GL_TRUE;
804}
805
806
807/**
808 * Create the Mesa framebuffer and renderbuffers for a given window/drawable.
809 *
810 * \todo This function (and its interface) will need to be updated to support
811 * pbuffers.
812 */
813static GLboolean
814radeonCreateBuffer( __DRIscreenPrivate *driScrnPriv,
815                    __DRIdrawablePrivate *driDrawPriv,
816                    const __GLcontextModes *mesaVis,
817                    GLboolean isPixmap )
818{
819   radeonScreenPtr screen = (radeonScreenPtr) driScrnPriv->private;
820
821   if (isPixmap) {
822      return GL_FALSE; /* not implemented */
823   }
824   else {
825      const GLboolean swDepth = GL_FALSE;
826      const GLboolean swAlpha = GL_FALSE;
827      const GLboolean swAccum = mesaVis->accumRedBits > 0;
828      const GLboolean swStencil = mesaVis->stencilBits > 0 &&
829         mesaVis->depthBits != 24;
830      struct gl_framebuffer *fb = _mesa_create_framebuffer(mesaVis);
831
832      /* front color renderbuffer */
833      {
834         driRenderbuffer *frontRb
835            = driNewRenderbuffer(GL_RGBA,
836                                 driScrnPriv->pFB + screen->frontOffset,
837                                 screen->cpp,
838                                 screen->frontOffset, screen->frontPitch,
839                                 driDrawPriv);
840         radeonSetSpanFunctions(frontRb, mesaVis);
841         _mesa_add_renderbuffer(fb, BUFFER_FRONT_LEFT, &frontRb->Base);
842      }
843
844      /* back color renderbuffer */
845      if (mesaVis->doubleBufferMode) {
846         driRenderbuffer *backRb
847            = driNewRenderbuffer(GL_RGBA,
848                                 driScrnPriv->pFB + screen->backOffset,
849                                 screen->cpp,
850                                 screen->backOffset, screen->backPitch,
851                                 driDrawPriv);
852         radeonSetSpanFunctions(backRb, mesaVis);
853         _mesa_add_renderbuffer(fb, BUFFER_BACK_LEFT, &backRb->Base);
854      }
855
856      /* depth renderbuffer */
857      if (mesaVis->depthBits == 16) {
858         driRenderbuffer *depthRb
859            = driNewRenderbuffer(GL_DEPTH_COMPONENT16,
860                                 driScrnPriv->pFB + screen->depthOffset,
861                                 screen->cpp,
862                                 screen->depthOffset, screen->depthPitch,
863                                 driDrawPriv);
864         radeonSetSpanFunctions(depthRb, mesaVis);
865         _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &depthRb->Base);
866	 depthRb->depthHasSurface = screen->depthHasSurface;
867      }
868      else if (mesaVis->depthBits == 24) {
869         driRenderbuffer *depthRb
870            = driNewRenderbuffer(GL_DEPTH_COMPONENT24,
871                                 driScrnPriv->pFB + screen->depthOffset,
872                                 screen->cpp,
873                                 screen->depthOffset, screen->depthPitch,
874                                 driDrawPriv);
875         radeonSetSpanFunctions(depthRb, mesaVis);
876         _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &depthRb->Base);
877	 depthRb->depthHasSurface = screen->depthHasSurface;
878      }
879
880      /* stencil renderbuffer */
881      if (mesaVis->stencilBits > 0 && !swStencil) {
882         driRenderbuffer *stencilRb
883            = driNewRenderbuffer(GL_STENCIL_INDEX8_EXT,
884                                 driScrnPriv->pFB + screen->depthOffset,
885                                 screen->cpp,
886                                 screen->depthOffset, screen->depthPitch,
887                                 driDrawPriv);
888         radeonSetSpanFunctions(stencilRb, mesaVis);
889         _mesa_add_renderbuffer(fb, BUFFER_STENCIL, &stencilRb->Base);
890	 stencilRb->depthHasSurface = screen->depthHasSurface;
891      }
892
893      _mesa_add_soft_renderbuffers(fb,
894                                   GL_FALSE, /* color */
895                                   swDepth,
896                                   swStencil,
897                                   swAccum,
898                                   swAlpha,
899                                   GL_FALSE /* aux */);
900      driDrawPriv->driverPrivate = (void *) fb;
901
902      return (driDrawPriv->driverPrivate != NULL);
903   }
904}
905
906
907static void
908radeonDestroyBuffer(__DRIdrawablePrivate *driDrawPriv)
909{
910   _mesa_unreference_framebuffer((GLframebuffer **)(&(driDrawPriv->driverPrivate)));
911}
912
913#if RADEON_COMMON && defined(RADEON_COMMON_FOR_R300)
914/**
915 * Choose the appropriate CreateContext function based on the chipset.
916 * Eventually, all drivers will go through this process.
917 */
918static GLboolean radeonCreateContext(const __GLcontextModes * glVisual,
919				     __DRIcontextPrivate * driContextPriv,
920				     void *sharedContextPriv)
921{
922	__DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
923	radeonScreenPtr screen = (radeonScreenPtr) (sPriv->private);
924
925	if (IS_R300_CLASS(screen))
926		return r300CreateContext(glVisual, driContextPriv, sharedContextPriv);
927        return GL_FALSE;
928}
929
930/**
931 * Choose the appropriate DestroyContext function based on the chipset.
932 */
933static void radeonDestroyContext(__DRIcontextPrivate * driContextPriv)
934{
935	radeonContextPtr radeon = (radeonContextPtr) driContextPriv->driverPrivate;
936
937	if (IS_R300_CLASS(radeon->radeonScreen))
938		return r300DestroyContext(driContextPriv);
939}
940
941
942#endif
943
944#if !RADEON_COMMON || (RADEON_COMMON && defined(RADEON_COMMON_FOR_R300))
945static struct __DriverAPIRec radeonAPI = {
946   .DestroyScreen   = radeonDestroyScreen,
947   .CreateContext   = radeonCreateContext,
948   .DestroyContext  = radeonDestroyContext,
949   .CreateBuffer    = radeonCreateBuffer,
950   .DestroyBuffer   = radeonDestroyBuffer,
951   .SwapBuffers     = radeonSwapBuffers,
952   .MakeCurrent     = radeonMakeCurrent,
953   .UnbindContext   = radeonUnbindContext,
954   .GetSwapInfo     = getSwapInfo,
955   .GetMSC          = driGetMSC32,
956   .WaitForMSC      = driWaitForMSC32,
957   .WaitForSBC      = NULL,
958   .SwapBuffersMSC  = NULL,
959   .CopySubBuffer   = radeonCopySubBuffer,
960#if RADEON_COMMON && defined(RADEON_COMMON_FOR_R300)
961   .setTexOffset    = r300SetTexOffset,
962#endif
963};
964#else
965static const struct __DriverAPIRec r200API = {
966   .DestroyScreen   = radeonDestroyScreen,
967   .CreateContext   = r200CreateContext,
968   .DestroyContext  = r200DestroyContext,
969   .CreateBuffer    = radeonCreateBuffer,
970   .DestroyBuffer   = radeonDestroyBuffer,
971   .SwapBuffers     = r200SwapBuffers,
972   .MakeCurrent     = r200MakeCurrent,
973   .UnbindContext   = r200UnbindContext,
974   .GetSwapInfo     = getSwapInfo,
975   .GetMSC          = driGetMSC32,
976   .WaitForMSC      = driWaitForMSC32,
977   .WaitForSBC      = NULL,
978   .SwapBuffersMSC  = NULL,
979   .CopySubBuffer   = r200CopySubBuffer,
980   .setTexOffset    = r200SetTexOffset
981};
982#endif
983
984
985/**
986 * This is the driver specific part of the createNewScreen entry point.
987 *
988 * \todo maybe fold this into intelInitDriver
989 *
990 * \return the __GLcontextModes supported by this driver
991 */
992__GLcontextModes *__driDriverInitScreen(__DRIscreenPrivate *psp)
993{
994#if !RADEON_COMMON
995   static const char *driver_name = "Radeon";
996   static const __DRIutilversion2 ddx_expected = { 4, 5, 0, 0 };
997   static const __DRIversion dri_expected = { 4, 0, 0 };
998   static const __DRIversion drm_expected = { 1, 6, 0 };
999#elif RADEON_COMMON && defined(RADEON_COMMON_FOR_R200)
1000   static const char *driver_name = "R200";
1001   static const __DRIutilversion2 ddx_expected = { 4, 5, 0, 0 };
1002   static const __DRIversion dri_expected = { 4, 0, 0 };
1003   static const __DRIversion drm_expected = { 1, 6, 0 };
1004#elif RADEON_COMMON && defined(RADEON_COMMON_FOR_R300)
1005   static const char *driver_name = "R300";
1006   static const __DRIutilversion2 ddx_expected = { 4, 5, 0, 0 };
1007   static const __DRIversion dri_expected = { 4, 0, 0 };
1008   static const __DRIversion drm_expected = { 1, 24, 0 };
1009#endif
1010   RADEONDRIPtr dri_priv = (RADEONDRIPtr) psp->pDevPriv;
1011
1012   if ( ! driCheckDriDdxDrmVersions3( driver_name,
1013				      &psp->dri_version, & dri_expected,
1014				      &psp->ddx_version, & ddx_expected,
1015				      &psp->drm_version, & drm_expected ) ) {
1016      return NULL;
1017   }
1018#if !RADEON_COMMON || (RADEON_COMMON && defined(RADEON_COMMON_FOR_R300))
1019   psp->DriverAPI = radeonAPI;
1020#elif RADEON_COMMON && defined(RADEON_COMMON_FOR_R200)
1021   psp->DriverAPI = r200API;
1022#endif
1023
1024   /* Calling driInitExtensions here, with a NULL context pointer,
1025    * does not actually enable the extensions.  It just makes sure
1026    * that all the dispatch offsets for all the extensions that
1027    * *might* be enables are known.  This is needed because the
1028    * dispatch offsets need to be known when _mesa_context_create
1029    * is called, but we can't enable the extensions until we have a
1030    * context pointer.
1031    *
1032    * Hello chicken.  Hello egg.  How are you two today?
1033    */
1034   driInitExtensions( NULL, card_extensions, GL_FALSE );
1035#if RADEON_COMMON && defined(RADEON_COMMON_FOR_R200)
1036   driInitExtensions( NULL, blend_extensions, GL_FALSE );
1037   driInitSingleExtension( NULL, ARB_vp_extension );
1038   driInitSingleExtension( NULL, NV_vp_extension );
1039   driInitSingleExtension( NULL, ATI_fs_extension );
1040   driInitExtensions( NULL, point_extensions, GL_FALSE );
1041#endif
1042
1043   if (!radeonInitDriver(psp))
1044       return NULL;
1045
1046   return radeonFillInModes( dri_priv->bpp,
1047			     (dri_priv->bpp == 16) ? 16 : 24,
1048			     (dri_priv->bpp == 16) ? 0  : 8,
1049			     (dri_priv->backOffset != dri_priv->depthOffset) );
1050}
1051
1052
1053/**
1054 * Get information about previous buffer swaps.
1055 */
1056static int
1057getSwapInfo( __DRIdrawablePrivate *dPriv, __DRIswapInfo * sInfo )
1058{
1059#if !RADEON_COMMON || (RADEON_COMMON && defined(RADEON_COMMON_FOR_R300))
1060   radeonContextPtr  rmesa;
1061#elif RADEON_COMMON && defined(RADEON_COMMON_FOR_R200)
1062   r200ContextPtr  rmesa;
1063#endif
1064
1065   if ( (dPriv == NULL) || (dPriv->driContextPriv == NULL)
1066	|| (dPriv->driContextPriv->driverPrivate == NULL)
1067	|| (sInfo == NULL) ) {
1068      return -1;
1069   }
1070
1071   rmesa = dPriv->driContextPriv->driverPrivate;
1072   sInfo->swap_count = rmesa->swap_count;
1073   sInfo->swap_ust = rmesa->swap_ust;
1074   sInfo->swap_missed_count = rmesa->swap_missed_count;
1075
1076   sInfo->swap_missed_usage = (sInfo->swap_missed_count != 0)
1077       ? driCalculateSwapUsage( dPriv, 0, rmesa->swap_missed_ust )
1078       : 0.0;
1079
1080   return 0;
1081}
1082