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