radeon_screen.c revision eb06704a7c0027136d5ced74d67a83ddaf1f82aa
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   case PCI_CHIP_RV410_5E4B:
578      screen->chip_family = CHIP_FAMILY_R420;
579      screen->chip_flags = RADEON_CHIPSET_TCL;
580      break;
581
582   default:
583      fprintf(stderr, "unknown chip id 0x%x, can't guess.\n",
584	      dri_priv->deviceID);
585      return NULL;
586   }
587
588   if (screen->chip_family <= CHIP_FAMILY_RS200)
589      screen->chip_flags |= RADEON_CLASS_R200;
590   else if (screen->chip_family <= CHIP_FAMILY_RV280)
591      screen->chip_flags |= RADEON_CLASS_R200;
592   else
593      screen->chip_flags |= RADEON_CLASS_R300;
594
595   screen->cpp = dri_priv->bpp / 8;
596   screen->AGPMode = dri_priv->AGPMode;
597
598   screen->fbLocation	= ( INREG( RADEON_MC_FB_LOCATION ) & 0xffff ) << 16;
599
600   if ( sPriv->drmMinor >= 10 ) {
601      drm_radeon_setparam_t sp;
602
603      sp.param = RADEON_SETPARAM_FB_LOCATION;
604      sp.value = screen->fbLocation;
605
606      drmCommandWrite( sPriv->fd, DRM_RADEON_SETPARAM,
607		       &sp, sizeof( sp ) );
608   }
609
610   screen->frontOffset	= dri_priv->frontOffset;
611   screen->frontPitch	= dri_priv->frontPitch;
612   screen->backOffset	= dri_priv->backOffset;
613   screen->backPitch	= dri_priv->backPitch;
614   screen->depthOffset	= dri_priv->depthOffset;
615   screen->depthPitch	= dri_priv->depthPitch;
616
617   /* Check if ddx has set up a surface reg to cover depth buffer */
618   screen->depthHasSurface = ((sPriv->ddxMajor > 4) &&
619      (screen->chip_flags & RADEON_CHIPSET_TCL));
620
621   if ( dri_priv->textureSize == 0 ) {
622      screen->texOffset[RADEON_LOCAL_TEX_HEAP] = screen->gart_texture_offset;
623      screen->texSize[RADEON_LOCAL_TEX_HEAP] = dri_priv->gartTexMapSize;
624      screen->logTexGranularity[RADEON_LOCAL_TEX_HEAP] =
625	 dri_priv->log2GARTTexGran;
626   } else {
627      screen->texOffset[RADEON_LOCAL_TEX_HEAP] = dri_priv->textureOffset
628				               + screen->fbLocation;
629      screen->texSize[RADEON_LOCAL_TEX_HEAP] = dri_priv->textureSize;
630      screen->logTexGranularity[RADEON_LOCAL_TEX_HEAP] =
631	 dri_priv->log2TexGran;
632   }
633
634   if ( !screen->gartTextures.map || dri_priv->textureSize == 0
635	|| getenv( "RADEON_GARTTEXTURING_FORCE_DISABLE" ) ) {
636      screen->numTexHeaps = RADEON_NR_TEX_HEAPS - 1;
637      screen->texOffset[RADEON_GART_TEX_HEAP] = 0;
638      screen->texSize[RADEON_GART_TEX_HEAP] = 0;
639      screen->logTexGranularity[RADEON_GART_TEX_HEAP] = 0;
640   } else {
641      screen->numTexHeaps = RADEON_NR_TEX_HEAPS;
642      screen->texOffset[RADEON_GART_TEX_HEAP] = screen->gart_texture_offset;
643      screen->texSize[RADEON_GART_TEX_HEAP] = dri_priv->gartTexMapSize;
644      screen->logTexGranularity[RADEON_GART_TEX_HEAP] =
645	 dri_priv->log2GARTTexGran;
646   }
647
648   if ( glx_enable_extension != NULL ) {
649      if ( screen->irq != 0 ) {
650	 (*glx_enable_extension)( psc, "GLX_SGI_swap_control" );
651	 (*glx_enable_extension)( psc, "GLX_SGI_video_sync" );
652	 (*glx_enable_extension)( psc, "GLX_MESA_swap_control" );
653      }
654
655      (*glx_enable_extension)( psc, "GLX_MESA_swap_frame_usage" );
656      if (IS_R200_CLASS(screen))
657	 (*glx_enable_extension)( psc, "GLX_MESA_allocate_memory" );
658   }
659
660#if RADEON_COMMON && defined(RADEON_COMMON_FOR_R200)
661   if (IS_R200_CLASS(screen)) {
662      sPriv->psc->allocateMemory = (void *) r200AllocateMemoryMESA;
663      sPriv->psc->freeMemory     = (void *) r200FreeMemoryMESA;
664      sPriv->psc->memoryOffset   = (void *) r200GetMemoryOffsetMESA;
665   }
666#endif
667
668   screen->driScreen = sPriv;
669   screen->sarea_priv_offset = dri_priv->sarea_priv_offset;
670   return screen;
671}
672
673/* Destroy the device specific screen private data struct.
674 */
675static void
676radeonDestroyScreen( __DRIscreenPrivate *sPriv )
677{
678   radeonScreenPtr screen = (radeonScreenPtr)sPriv->private;
679
680   if (!screen)
681      return;
682
683   if ( screen->gartTextures.map ) {
684      drmUnmap( screen->gartTextures.map, screen->gartTextures.size );
685   }
686   drmUnmapBufs( screen->buffers );
687   drmUnmap( screen->status.map, screen->status.size );
688   drmUnmap( screen->mmio.map, screen->mmio.size );
689
690   /* free all option information */
691   driDestroyOptionInfo (&screen->optionCache);
692
693   FREE( screen );
694   sPriv->private = NULL;
695}
696
697
698/* Initialize the driver specific screen private data.
699 */
700static GLboolean
701radeonInitDriver( __DRIscreenPrivate *sPriv )
702{
703   sPriv->private = (void *) radeonCreateScreen( sPriv );
704   if ( !sPriv->private ) {
705      radeonDestroyScreen( sPriv );
706      return GL_FALSE;
707   }
708
709   return GL_TRUE;
710}
711
712
713/**
714 * Create the Mesa framebuffer and renderbuffers for a given window/drawable.
715 *
716 * \todo This function (and its interface) will need to be updated to support
717 * pbuffers.
718 */
719static GLboolean
720radeonCreateBuffer( __DRIscreenPrivate *driScrnPriv,
721                    __DRIdrawablePrivate *driDrawPriv,
722                    const __GLcontextModes *mesaVis,
723                    GLboolean isPixmap )
724{
725   radeonScreenPtr screen = (radeonScreenPtr) driScrnPriv->private;
726
727   if (isPixmap) {
728      return GL_FALSE; /* not implemented */
729   }
730   else {
731      const GLboolean swDepth = GL_FALSE;
732      const GLboolean swAlpha = GL_FALSE;
733      const GLboolean swAccum = mesaVis->accumRedBits > 0;
734      const GLboolean swStencil = mesaVis->stencilBits > 0 &&
735         mesaVis->depthBits != 24;
736      struct gl_framebuffer *fb = _mesa_create_framebuffer(mesaVis);
737
738      /* front color renderbuffer */
739      {
740         driRenderbuffer *frontRb
741            = driNewRenderbuffer(GL_RGBA,
742                                 driScrnPriv->pFB + screen->frontOffset,
743                                 screen->cpp,
744                                 screen->frontOffset, screen->frontPitch,
745                                 driDrawPriv);
746         radeonSetSpanFunctions(frontRb, mesaVis);
747         _mesa_add_renderbuffer(fb, BUFFER_FRONT_LEFT, &frontRb->Base);
748      }
749
750      /* back color renderbuffer */
751      if (mesaVis->doubleBufferMode) {
752         driRenderbuffer *backRb
753            = driNewRenderbuffer(GL_RGBA,
754                                 driScrnPriv->pFB + screen->backOffset,
755                                 screen->cpp,
756                                 screen->backOffset, screen->backPitch,
757                                 driDrawPriv);
758         radeonSetSpanFunctions(backRb, mesaVis);
759         _mesa_add_renderbuffer(fb, BUFFER_BACK_LEFT, &backRb->Base);
760      }
761
762      /* depth renderbuffer */
763      if (mesaVis->depthBits == 16) {
764         driRenderbuffer *depthRb
765            = driNewRenderbuffer(GL_DEPTH_COMPONENT16,
766                                 driScrnPriv->pFB + screen->depthOffset,
767                                 screen->cpp,
768                                 screen->depthOffset, screen->depthPitch,
769                                 driDrawPriv);
770         radeonSetSpanFunctions(depthRb, mesaVis);
771         _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &depthRb->Base);
772	 depthRb->depthHasSurface = screen->depthHasSurface;
773      }
774      else if (mesaVis->depthBits == 24) {
775         driRenderbuffer *depthRb
776            = driNewRenderbuffer(GL_DEPTH_COMPONENT24,
777                                 driScrnPriv->pFB + screen->depthOffset,
778                                 screen->cpp,
779                                 screen->depthOffset, screen->depthPitch,
780                                 driDrawPriv);
781         radeonSetSpanFunctions(depthRb, mesaVis);
782         _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &depthRb->Base);
783	 depthRb->depthHasSurface = screen->depthHasSurface;
784      }
785
786      /* stencil renderbuffer */
787      if (mesaVis->stencilBits > 0 && !swStencil) {
788         driRenderbuffer *stencilRb
789            = driNewRenderbuffer(GL_STENCIL_INDEX8_EXT,
790                                 driScrnPriv->pFB + screen->depthOffset,
791                                 screen->cpp,
792                                 screen->depthOffset, screen->depthPitch,
793                                 driDrawPriv);
794         radeonSetSpanFunctions(stencilRb, mesaVis);
795         _mesa_add_renderbuffer(fb, BUFFER_STENCIL, &stencilRb->Base);
796	 stencilRb->depthHasSurface = screen->depthHasSurface;
797      }
798
799      _mesa_add_soft_renderbuffers(fb,
800                                   GL_FALSE, /* color */
801                                   swDepth,
802                                   swStencil,
803                                   swAccum,
804                                   swAlpha,
805                                   GL_FALSE /* aux */);
806      driDrawPriv->driverPrivate = (void *) fb;
807
808      return (driDrawPriv->driverPrivate != NULL);
809   }
810}
811
812
813static void
814radeonDestroyBuffer(__DRIdrawablePrivate *driDrawPriv)
815{
816   _mesa_destroy_framebuffer((GLframebuffer *) (driDrawPriv->driverPrivate));
817}
818
819#if RADEON_COMMON && defined(RADEON_COMMON_FOR_R300)
820/**
821 * Choose the appropriate CreateContext function based on the chipset.
822 * Eventually, all drivers will go through this process.
823 */
824static GLboolean radeonCreateContext(const __GLcontextModes * glVisual,
825				     __DRIcontextPrivate * driContextPriv,
826				     void *sharedContextPriv)
827{
828	__DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
829	radeonScreenPtr screen = (radeonScreenPtr) (sPriv->private);
830
831	if (IS_R300_CLASS(screen))
832		return r300CreateContext(glVisual, driContextPriv, sharedContextPriv);
833        return GL_FALSE;
834}
835
836/**
837 * Choose the appropriate DestroyContext function based on the chipset.
838 */
839static void radeonDestroyContext(__DRIcontextPrivate * driContextPriv)
840{
841	radeonContextPtr radeon = (radeonContextPtr) driContextPriv->driverPrivate;
842
843	if (IS_R300_CLASS(radeon->radeonScreen))
844		return r300DestroyContext(driContextPriv);
845}
846
847
848#endif
849
850#if !RADEON_COMMON || (RADEON_COMMON && defined(RADEON_COMMON_FOR_R300))
851static struct __DriverAPIRec radeonAPI = {
852   .InitDriver      = radeonInitDriver,
853   .DestroyScreen   = radeonDestroyScreen,
854   .CreateContext   = radeonCreateContext,
855   .DestroyContext  = radeonDestroyContext,
856   .CreateBuffer    = radeonCreateBuffer,
857   .DestroyBuffer   = radeonDestroyBuffer,
858   .SwapBuffers     = radeonSwapBuffers,
859   .MakeCurrent     = radeonMakeCurrent,
860   .UnbindContext   = radeonUnbindContext,
861   .GetSwapInfo     = getSwapInfo,
862   .GetMSC          = driGetMSC32,
863   .WaitForMSC      = driWaitForMSC32,
864   .WaitForSBC      = NULL,
865   .SwapBuffersMSC  = NULL
866};
867#else
868static const struct __DriverAPIRec r200API = {
869   .InitDriver      = radeonInitDriver,
870   .DestroyScreen   = radeonDestroyScreen,
871   .CreateContext   = r200CreateContext,
872   .DestroyContext  = r200DestroyContext,
873   .CreateBuffer    = radeonCreateBuffer,
874   .DestroyBuffer   = radeonDestroyBuffer,
875   .SwapBuffers     = r200SwapBuffers,
876   .MakeCurrent     = r200MakeCurrent,
877   .UnbindContext   = r200UnbindContext,
878   .GetSwapInfo     = getSwapInfo,
879   .GetMSC          = driGetMSC32,
880   .WaitForMSC      = driWaitForMSC32,
881   .WaitForSBC      = NULL,
882   .SwapBuffersMSC  = NULL
883};
884#endif
885
886/**
887 * This is the bootstrap function for the driver.  libGL supplies all of the
888 * requisite information about the system, and the driver initializes itself.
889 * This routine also fills in the linked list pointed to by \c driver_modes
890 * with the \c __GLcontextModes that the driver can support for windows or
891 * pbuffers.
892 *
893 * \return A pointer to a \c __DRIscreenPrivate on success, or \c NULL on
894 *         failure.
895 */
896PUBLIC void *
897__driCreateNewScreen_20050727( __DRInativeDisplay *dpy,
898                             int scrn, __DRIscreen *psc,
899			     const __GLcontextModes * modes,
900			     const __DRIversion * ddx_version,
901			     const __DRIversion * dri_version,
902			     const __DRIversion * drm_version,
903			     const __DRIframebuffer * frame_buffer,
904			     drmAddress pSAREA, int fd,
905			     int internal_api_version,
906			     const __DRIinterfaceMethods * interface,
907			     __GLcontextModes ** driver_modes )
908{
909   __DRIscreenPrivate *psp;
910#if !RADEON_COMMON
911   static const char *driver_name = "Radeon";
912   static const __DRIutilversion2 ddx_expected = { 4, 5, 0, 0 };
913   static const __DRIversion dri_expected = { 4, 0, 0 };
914   static const __DRIversion drm_expected = { 1, 3, 0 };
915#elif RADEON_COMMON && defined(RADEON_COMMON_FOR_R200)
916   static const char *driver_name = "R200";
917   static const __DRIutilversion2 ddx_expected = { 4, 5, 0, 0 };
918   static const __DRIversion dri_expected = { 4, 0, 0 };
919   static const __DRIversion drm_expected = { 1, 5, 0 };
920#elif RADEON_COMMON && defined(RADEON_COMMON_FOR_R300)
921   static const char *driver_name = "R300";
922   static const __DRIutilversion2 ddx_expected = { 4, 5, 0, 0 };
923   static const __DRIversion dri_expected = { 4, 0, 0 };
924   static const __DRIversion drm_expected = { 1, 17, 0 };
925#endif
926
927   dri_interface = interface;
928
929   if ( ! driCheckDriDdxDrmVersions3( driver_name,
930				      dri_version, & dri_expected,
931				      ddx_version, & ddx_expected,
932				      drm_version, & drm_expected ) ) {
933      return NULL;
934   }
935#if !RADEON_COMMON || (RADEON_COMMON && defined(RADEON_COMMON_FOR_R300))
936   psp = __driUtilCreateNewScreen(dpy, scrn, psc, NULL,
937				  ddx_version, dri_version, drm_version,
938				  frame_buffer, pSAREA, fd,
939				  internal_api_version, &radeonAPI);
940#elif RADEON_COMMON && defined(RADEON_COMMON_FOR_R200)
941   psp = __driUtilCreateNewScreen(dpy, scrn, psc, NULL,
942				  ddx_version, dri_version, drm_version,
943				  frame_buffer, pSAREA, fd,
944				  internal_api_version, &r200API);
945#endif
946
947   if ( psp != NULL ) {
948      RADEONDRIPtr dri_priv = (RADEONDRIPtr) psp->pDevPriv;
949      if (driver_modes) {
950         *driver_modes = radeonFillInModes( dri_priv->bpp,
951                                            (dri_priv->bpp == 16) ? 16 : 24,
952                                            (dri_priv->bpp == 16) ? 0  : 8,
953                                            (dri_priv->backOffset != dri_priv->depthOffset) );
954      }
955
956      /* Calling driInitExtensions here, with a NULL context pointer,
957       * does not actually enable the extensions.  It just makes sure
958       * that all the dispatch offsets for all the extensions that
959       * *might* be enables are known.  This is needed because the
960       * dispatch offsets need to be known when _mesa_context_create
961       * is called, but we can't enable the extensions until we have a
962       * context pointer.
963       *
964       * Hello chicken.  Hello egg.  How are you two today?
965       */
966      driInitExtensions( NULL, card_extensions, GL_FALSE );
967#if RADEON_COMMON && defined(RADEON_COMMON_FOR_R200)
968      driInitExtensions( NULL, blend_extensions, GL_FALSE );
969      driInitSingleExtension( NULL, ARB_vp_extension );
970      driInitSingleExtension( NULL, NV_vp_extension );
971      driInitSingleExtension( NULL, ATI_fs_extension );
972#endif
973   }
974
975   return (void *) psp;
976}
977
978
979/**
980 * Get information about previous buffer swaps.
981 */
982static int
983getSwapInfo( __DRIdrawablePrivate *dPriv, __DRIswapInfo * sInfo )
984{
985#if !RADEON_COMMON || (RADEON_COMMON && defined(RADEON_COMMON_FOR_R300))
986   radeonContextPtr  rmesa;
987#elif RADEON_COMMON && defined(RADEON_COMMON_FOR_R200)
988   r200ContextPtr  rmesa;
989#endif
990
991   if ( (dPriv == NULL) || (dPriv->driContextPriv == NULL)
992	|| (dPriv->driContextPriv->driverPrivate == NULL)
993	|| (sInfo == NULL) ) {
994      return -1;
995   }
996
997   rmesa = dPriv->driContextPriv->driverPrivate;
998   sInfo->swap_count = rmesa->swap_count;
999   sInfo->swap_ust = rmesa->swap_ust;
1000   sInfo->swap_missed_count = rmesa->swap_missed_count;
1001
1002   sInfo->swap_missed_usage = (sInfo->swap_missed_count != 0)
1003       ? driCalculateSwapUsage( dPriv, 0, rmesa->swap_missed_ust )
1004       : 0.0;
1005
1006   return 0;
1007}
1008