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