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