Bug #4900: Fix the non-fogcoord fog test on r100 (and rv200) at tcl_mode=1 by
[mesa.git] / src / mesa / drivers / dri / radeon / radeon_screen.c
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
4 Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
5 VA Linux Systems Inc., Fremont, California.
6
7 All Rights Reserved.
8
9 Permission is hereby granted, free of charge, to any person obtaining
10 a copy of this software and associated documentation files (the
11 "Software"), to deal in the Software without restriction, including
12 without limitation the rights to use, copy, modify, merge, publish,
13 distribute, sublicense, and/or sell copies of the Software, and to
14 permit persons to whom the Software is furnished to do so, subject to
15 the following conditions:
16
17 The above copyright notice and this permission notice (including the
18 next paragraph) shall be included in all copies or substantial
19 portions of the Software.
20
21 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
24 IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
25 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27 WITH 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_context.h"
47 #include "radeon_screen.h"
48 #include "radeon_macros.h"
49 #include "radeon_span.h"
50
51 #include "utils.h"
52 #include "context.h"
53 #include "vblank.h"
54 #include "drirenderbuffer.h"
55
56 #include "GL/internal/dri_interface.h"
57
58 /* Radeon configuration
59 */
60 #include "xmlpool.h"
61
62 PUBLIC const char __driConfigOptions[] =
63 DRI_CONF_BEGIN
64 DRI_CONF_SECTION_PERFORMANCE
65 DRI_CONF_TCL_MODE(DRI_CONF_TCL_CODEGEN)
66 DRI_CONF_FTHROTTLE_MODE(DRI_CONF_FTHROTTLE_IRQS)
67 DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_DEF_INTERVAL_0)
68 DRI_CONF_MAX_TEXTURE_UNITS(2,2,3)
69 DRI_CONF_HYPERZ(false)
70 DRI_CONF_SECTION_END
71 DRI_CONF_SECTION_QUALITY
72 DRI_CONF_TEXTURE_DEPTH(DRI_CONF_TEXTURE_DEPTH_FB)
73 DRI_CONF_DEF_MAX_ANISOTROPY(1.0,"1.0,2.0,4.0,8.0,16.0")
74 DRI_CONF_NO_NEG_LOD_BIAS(false)
75 DRI_CONF_FORCE_S3TC_ENABLE(false)
76 DRI_CONF_COLOR_REDUCTION(DRI_CONF_COLOR_REDUCTION_DITHER)
77 DRI_CONF_ROUND_MODE(DRI_CONF_ROUND_TRUNC)
78 DRI_CONF_DITHER_MODE(DRI_CONF_DITHER_XERRORDIFF)
79 DRI_CONF_TEXTURE_LEVEL_HACK(false)
80 DRI_CONF_SECTION_END
81 DRI_CONF_SECTION_DEBUG
82 DRI_CONF_NO_RAST(false)
83 DRI_CONF_SECTION_END
84 DRI_CONF_END;
85 static const GLuint __driNConfigOptions = 14;
86
87 extern const struct dri_extension card_extensions[];
88
89 #if 1
90 /* Including xf86PciInfo.h introduces a bunch of errors...
91 */
92 #define PCI_CHIP_RADEON_QD 0x5144
93 #define PCI_CHIP_RADEON_QE 0x5145
94 #define PCI_CHIP_RADEON_QF 0x5146
95 #define PCI_CHIP_RADEON_QG 0x5147
96
97 #define PCI_CHIP_RADEON_QY 0x5159
98 #define PCI_CHIP_RADEON_QZ 0x515A
99
100 #define PCI_CHIP_RN50_515E 0x515E
101 #define PCI_CHIP_RN50_5969 0x5969
102
103 #define PCI_CHIP_RADEON_LW 0x4C57 /* mobility 7 - has tcl */
104 #define PCI_CHIP_RADEON_LX 0x4C58 /* mobility FireGL 7800 m7 */
105
106 #define PCI_CHIP_RADEON_LY 0x4C59
107 #define PCI_CHIP_RADEON_LZ 0x4C5A
108
109 #define PCI_CHIP_RV200_QW 0x5157 /* Radeon 7500 - not an R200 at all */
110 #define PCI_CHIP_RV200_QX 0x5158
111
112 /* IGP Chipsets */
113 #define PCI_CHIP_RS100_4136 0x4136
114 #define PCI_CHIP_RS200_4137 0x4137
115 #define PCI_CHIP_RS250_4237 0x4237
116 #define PCI_CHIP_RS100_4336 0x4336
117 #define PCI_CHIP_RS200_4337 0x4337
118 #define PCI_CHIP_RS250_4437 0x4437
119 #endif
120
121
122 static int getSwapInfo( __DRIdrawablePrivate *dPriv, __DRIswapInfo * sInfo );
123
124 static __GLcontextModes *
125 radeonFillInModes( unsigned pixel_bits, unsigned depth_bits,
126 unsigned stencil_bits, GLboolean have_back_buffer )
127 {
128 __GLcontextModes * modes;
129 __GLcontextModes * m;
130 unsigned num_modes;
131 unsigned depth_buffer_factor;
132 unsigned back_buffer_factor;
133 GLenum fb_format;
134 GLenum fb_type;
135
136 /* Right now GLX_SWAP_COPY_OML isn't supported, but it would be easy
137 * enough to add support. Basically, if a context is created with an
138 * fbconfig where the swap method is GLX_SWAP_COPY_OML, pageflipping
139 * will never be used.
140 */
141 static const GLenum back_buffer_modes[] = {
142 GLX_NONE, GLX_SWAP_UNDEFINED_OML /*, GLX_SWAP_COPY_OML */
143 };
144
145 u_int8_t depth_bits_array[2];
146 u_int8_t stencil_bits_array[2];
147
148
149 depth_bits_array[0] = depth_bits;
150 depth_bits_array[1] = depth_bits;
151
152 /* Just like with the accumulation buffer, always provide some modes
153 * with a stencil buffer. It will be a sw fallback, but some apps won't
154 * care about that.
155 */
156 stencil_bits_array[0] = 0;
157 stencil_bits_array[1] = (stencil_bits == 0) ? 8 : stencil_bits;
158
159 depth_buffer_factor = ((depth_bits != 0) || (stencil_bits != 0)) ? 2 : 1;
160 back_buffer_factor = (have_back_buffer) ? 2 : 1;
161
162 num_modes = depth_buffer_factor * back_buffer_factor * 4;
163
164 if ( pixel_bits == 16 ) {
165 fb_format = GL_RGB;
166 fb_type = GL_UNSIGNED_SHORT_5_6_5;
167 }
168 else {
169 fb_format = GL_BGRA;
170 fb_type = GL_UNSIGNED_INT_8_8_8_8_REV;
171 }
172
173 modes = (*dri_interface->createContextModes)( num_modes, sizeof( __GLcontextModes ) );
174 m = modes;
175 if ( ! driFillInModes( & m, fb_format, fb_type,
176 depth_bits_array, stencil_bits_array, depth_buffer_factor,
177 back_buffer_modes, back_buffer_factor,
178 GLX_TRUE_COLOR ) ) {
179 fprintf( stderr, "[%s:%u] Error creating FBConfig!\n",
180 __func__, __LINE__ );
181 return NULL;
182 }
183
184 if ( ! driFillInModes( & m, fb_format, fb_type,
185 depth_bits_array, stencil_bits_array, depth_buffer_factor,
186 back_buffer_modes, back_buffer_factor,
187 GLX_DIRECT_COLOR ) ) {
188 fprintf( stderr, "[%s:%u] Error creating FBConfig!\n",
189 __func__, __LINE__ );
190 return NULL;
191 }
192
193 /* Mark the visual as slow if there are "fake" stencil bits.
194 */
195 for ( m = modes ; m != NULL ; m = m->next ) {
196 if ( (m->stencilBits != 0) && (m->stencilBits != stencil_bits) ) {
197 m->visualRating = GLX_SLOW_CONFIG;
198 }
199 }
200
201 return modes;
202 }
203
204
205 /* Create the device specific screen private data struct.
206 */
207 static radeonScreenPtr
208 radeonCreateScreen( __DRIscreenPrivate *sPriv )
209 {
210 radeonScreenPtr screen;
211 RADEONDRIPtr dri_priv = (RADEONDRIPtr)sPriv->pDevPriv;
212 unsigned char *RADEONMMIO;
213 PFNGLXSCRENABLEEXTENSIONPROC glx_enable_extension =
214 (PFNGLXSCRENABLEEXTENSIONPROC) (*dri_interface->getProcAddress("glxEnableExtension"));
215 void * const psc = sPriv->psc->screenConfigs;
216
217 if (sPriv->devPrivSize != sizeof(RADEONDRIRec)) {
218 fprintf(stderr,"\nERROR! sizeof(RADEONDRIRec) does not match passed size from device driver\n");
219 return GL_FALSE;
220 }
221
222 /* Allocate the private area */
223 screen = (radeonScreenPtr) CALLOC( sizeof(*screen) );
224 if ( !screen ) {
225 __driUtilMessage("%s: Could not allocate memory for screen structure",
226 __FUNCTION__);
227 return NULL;
228 }
229
230 /* parse information in __driConfigOptions */
231 driParseOptionInfo (&screen->optionCache,
232 __driConfigOptions, __driNConfigOptions);
233
234 /* This is first since which regions we map depends on whether or
235 * not we are using a PCI card.
236 */
237 screen->IsPCI = dri_priv->IsPCI;
238
239 {
240 int ret;
241 drm_radeon_getparam_t gp;
242
243 gp.param = RADEON_PARAM_GART_BUFFER_OFFSET;
244 gp.value = &screen->gart_buffer_offset;
245
246 ret = drmCommandWriteRead( sPriv->fd, DRM_RADEON_GETPARAM,
247 &gp, sizeof(gp));
248 if (ret) {
249 FREE( screen );
250 fprintf(stderr, "drm_radeon_getparam_t (RADEON_PARAM_GART_BUFFER_OFFSET): %d\n", ret);
251 return NULL;
252 }
253
254 if (sPriv->drmMinor >= 6) {
255 gp.param = RADEON_PARAM_IRQ_NR;
256 gp.value = &screen->irq;
257
258 ret = drmCommandWriteRead( sPriv->fd, DRM_RADEON_GETPARAM,
259 &gp, sizeof(gp));
260 if (ret) {
261 FREE( screen );
262 fprintf(stderr, "drm_radeon_getparam_t (RADEON_PARAM_IRQ_NR): %d\n", ret);
263 return NULL;
264 }
265 screen->drmSupportsCubeMaps = (sPriv->drmMinor >= 15);
266 }
267 }
268
269 screen->mmio.handle = dri_priv->registerHandle;
270 screen->mmio.size = dri_priv->registerSize;
271 if ( drmMap( sPriv->fd,
272 screen->mmio.handle,
273 screen->mmio.size,
274 &screen->mmio.map ) ) {
275 FREE( screen );
276 __driUtilMessage("%s: drmMap failed\n", __FUNCTION__ );
277 return NULL;
278 }
279
280 RADEONMMIO = screen->mmio.map;
281
282 screen->status.handle = dri_priv->statusHandle;
283 screen->status.size = dri_priv->statusSize;
284 if ( drmMap( sPriv->fd,
285 screen->status.handle,
286 screen->status.size,
287 &screen->status.map ) ) {
288 drmUnmap( screen->mmio.map, screen->mmio.size );
289 FREE( screen );
290 __driUtilMessage("%s: drmMap (2) failed\n", __FUNCTION__ );
291 return NULL;
292 }
293 screen->scratch = (__volatile__ u_int32_t *)
294 ((GLubyte *)screen->status.map + RADEON_SCRATCH_REG_OFFSET);
295
296 screen->buffers = drmMapBufs( sPriv->fd );
297 if ( !screen->buffers ) {
298 drmUnmap( screen->status.map, screen->status.size );
299 drmUnmap( screen->mmio.map, screen->mmio.size );
300 FREE( screen );
301 __driUtilMessage("%s: drmMapBufs failed\n", __FUNCTION__ );
302 return NULL;
303 }
304
305 if ( dri_priv->gartTexHandle && dri_priv->gartTexMapSize ) {
306 screen->gartTextures.handle = dri_priv->gartTexHandle;
307 screen->gartTextures.size = dri_priv->gartTexMapSize;
308 if ( drmMap( sPriv->fd,
309 screen->gartTextures.handle,
310 screen->gartTextures.size,
311 (drmAddressPtr)&screen->gartTextures.map ) ) {
312 drmUnmapBufs( screen->buffers );
313 drmUnmap( screen->status.map, screen->status.size );
314 drmUnmap( screen->mmio.map, screen->mmio.size );
315 FREE( screen );
316 __driUtilMessage("%s: drmMap failed for GART texture area\n", __FUNCTION__);
317 return NULL;
318 }
319
320 screen->gart_texture_offset = dri_priv->gartTexOffset + ( screen->IsPCI
321 ? INREG( RADEON_AIC_LO_ADDR )
322 : ( ( INREG( RADEON_MC_AGP_LOCATION ) & 0x0ffffU ) << 16 ) );
323 }
324
325 screen->chipset = 0;
326 switch ( dri_priv->deviceID ) {
327 default:
328 fprintf(stderr, "unknown chip id, assuming full radeon support\n");
329 case PCI_CHIP_RADEON_QD:
330 case PCI_CHIP_RADEON_QE:
331 case PCI_CHIP_RADEON_QF:
332 case PCI_CHIP_RADEON_QG:
333 /* all original radeons (7200) presumably have a stencil op bug */
334 screen->chipset |= RADEON_CHIPSET_BROKEN_STENCIL;
335 case PCI_CHIP_RV200_QW:
336 case PCI_CHIP_RV200_QX:
337 case PCI_CHIP_RADEON_LW:
338 case PCI_CHIP_RADEON_LX:
339 screen->chipset |= RADEON_CHIPSET_TCL;
340 case PCI_CHIP_RADEON_QY:
341 case PCI_CHIP_RADEON_QZ:
342 case PCI_CHIP_RN50_515E:
343 case PCI_CHIP_RN50_5969:
344 case PCI_CHIP_RADEON_LY:
345 case PCI_CHIP_RADEON_LZ:
346 case PCI_CHIP_RS100_4136: /* IGPs don't have TCL */
347 case PCI_CHIP_RS200_4137:
348 case PCI_CHIP_RS250_4237:
349 case PCI_CHIP_RS100_4336:
350 case PCI_CHIP_RS200_4337:
351 case PCI_CHIP_RS250_4437:
352 break;
353 }
354
355 screen->cpp = dri_priv->bpp / 8;
356 screen->AGPMode = dri_priv->AGPMode;
357
358 screen->fbLocation = ( INREG( RADEON_MC_FB_LOCATION ) & 0xffff ) << 16;
359
360 if ( sPriv->drmMinor >= 10 ) {
361 drm_radeon_setparam_t sp;
362
363 sp.param = RADEON_SETPARAM_FB_LOCATION;
364 sp.value = screen->fbLocation;
365
366 drmCommandWrite( sPriv->fd, DRM_RADEON_SETPARAM,
367 &sp, sizeof( sp ) );
368 }
369
370 screen->frontOffset = dri_priv->frontOffset;
371 screen->frontPitch = dri_priv->frontPitch;
372 screen->backOffset = dri_priv->backOffset;
373 screen->backPitch = dri_priv->backPitch;
374 screen->depthOffset = dri_priv->depthOffset;
375 screen->depthPitch = dri_priv->depthPitch;
376
377 /* Check if ddx has set up a surface reg to cover depth buffer */
378 screen->depthHasSurface = ((sPriv->ddxMajor > 4) &&
379 (screen->chipset & RADEON_CHIPSET_TCL));
380
381 screen->texOffset[RADEON_LOCAL_TEX_HEAP] = dri_priv->textureOffset
382 + screen->fbLocation;
383 screen->texSize[RADEON_LOCAL_TEX_HEAP] = dri_priv->textureSize;
384 screen->logTexGranularity[RADEON_LOCAL_TEX_HEAP] =
385 dri_priv->log2TexGran;
386
387 if ( !screen->gartTextures.map
388 || getenv( "RADEON_GARTTEXTURING_FORCE_DISABLE" ) ) {
389 screen->numTexHeaps = RADEON_NR_TEX_HEAPS - 1;
390 screen->texOffset[RADEON_GART_TEX_HEAP] = 0;
391 screen->texSize[RADEON_GART_TEX_HEAP] = 0;
392 screen->logTexGranularity[RADEON_GART_TEX_HEAP] = 0;
393 } else {
394 screen->numTexHeaps = RADEON_NR_TEX_HEAPS;
395 screen->texOffset[RADEON_GART_TEX_HEAP] = screen->gart_texture_offset;
396 screen->texSize[RADEON_GART_TEX_HEAP] = dri_priv->gartTexMapSize;
397 screen->logTexGranularity[RADEON_GART_TEX_HEAP] =
398 dri_priv->log2GARTTexGran;
399 }
400
401 if ( glx_enable_extension != NULL ) {
402 if ( screen->irq != 0 ) {
403 (*glx_enable_extension)( psc, "GLX_SGI_swap_control" );
404 (*glx_enable_extension)( psc, "GLX_SGI_video_sync" );
405 (*glx_enable_extension)( psc, "GLX_MESA_swap_control" );
406 }
407
408 (*glx_enable_extension)( psc, "GLX_MESA_swap_frame_usage" );
409 }
410
411 screen->driScreen = sPriv;
412 screen->sarea_priv_offset = dri_priv->sarea_priv_offset;
413 return screen;
414 }
415
416 /* Destroy the device specific screen private data struct.
417 */
418 static void
419 radeonDestroyScreen( __DRIscreenPrivate *sPriv )
420 {
421 radeonScreenPtr screen = (radeonScreenPtr)sPriv->private;
422
423 if (!screen)
424 return;
425
426 if ( screen->gartTextures.map ) {
427 drmUnmap( screen->gartTextures.map, screen->gartTextures.size );
428 }
429 drmUnmapBufs( screen->buffers );
430 drmUnmap( screen->status.map, screen->status.size );
431 drmUnmap( screen->mmio.map, screen->mmio.size );
432
433 /* free all option information */
434 driDestroyOptionInfo (&screen->optionCache);
435
436 FREE( screen );
437 sPriv->private = NULL;
438 }
439
440
441 /* Initialize the driver specific screen private data.
442 */
443 static GLboolean
444 radeonInitDriver( __DRIscreenPrivate *sPriv )
445 {
446 sPriv->private = (void *) radeonCreateScreen( sPriv );
447 if ( !sPriv->private ) {
448 radeonDestroyScreen( sPriv );
449 return GL_FALSE;
450 }
451
452 return GL_TRUE;
453 }
454
455
456 /**
457 * Create the Mesa framebuffer and renderbuffers for a given window/drawable.
458 *
459 * \todo This function (and its interface) will need to be updated to support
460 * pbuffers.
461 */
462 static GLboolean
463 radeonCreateBuffer( __DRIscreenPrivate *driScrnPriv,
464 __DRIdrawablePrivate *driDrawPriv,
465 const __GLcontextModes *mesaVis,
466 GLboolean isPixmap )
467 {
468 radeonScreenPtr screen = (radeonScreenPtr) driScrnPriv->private;
469
470 if (isPixmap) {
471 return GL_FALSE; /* not implemented */
472 }
473 else {
474 const GLboolean swDepth = GL_FALSE;
475 const GLboolean swAlpha = GL_FALSE;
476 const GLboolean swAccum = mesaVis->accumRedBits > 0;
477 const GLboolean swStencil = mesaVis->stencilBits > 0 &&
478 mesaVis->depthBits != 24;
479 struct gl_framebuffer *fb = _mesa_create_framebuffer(mesaVis);
480
481 /* front color renderbuffer */
482 {
483 driRenderbuffer *frontRb
484 = driNewRenderbuffer(GL_RGBA,
485 driScrnPriv->pFB + screen->frontOffset,
486 screen->cpp,
487 screen->frontOffset, screen->frontPitch,
488 driDrawPriv);
489 radeonSetSpanFunctions(frontRb, mesaVis);
490 _mesa_add_renderbuffer(fb, BUFFER_FRONT_LEFT, &frontRb->Base);
491 }
492
493 /* back color renderbuffer */
494 if (mesaVis->doubleBufferMode) {
495 driRenderbuffer *backRb
496 = driNewRenderbuffer(GL_RGBA,
497 driScrnPriv->pFB + screen->backOffset,
498 screen->cpp,
499 screen->backOffset, screen->backPitch,
500 driDrawPriv);
501 radeonSetSpanFunctions(backRb, mesaVis);
502 _mesa_add_renderbuffer(fb, BUFFER_BACK_LEFT, &backRb->Base);
503 }
504
505 /* depth renderbuffer */
506 if (mesaVis->depthBits == 16) {
507 driRenderbuffer *depthRb
508 = driNewRenderbuffer(GL_DEPTH_COMPONENT16,
509 driScrnPriv->pFB + screen->depthOffset,
510 screen->cpp,
511 screen->depthOffset, screen->depthPitch,
512 driDrawPriv);
513 radeonSetSpanFunctions(depthRb, mesaVis);
514 _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &depthRb->Base);
515 depthRb->depthHasSurface = screen->depthHasSurface;
516 }
517 else if (mesaVis->depthBits == 24) {
518 driRenderbuffer *depthRb
519 = driNewRenderbuffer(GL_DEPTH_COMPONENT24,
520 driScrnPriv->pFB + screen->depthOffset,
521 screen->cpp,
522 screen->depthOffset, screen->depthPitch,
523 driDrawPriv);
524 radeonSetSpanFunctions(depthRb, mesaVis);
525 _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &depthRb->Base);
526 depthRb->depthHasSurface = screen->depthHasSurface;
527 }
528
529 /* stencil renderbuffer */
530 if (mesaVis->stencilBits > 0 && !swStencil) {
531 driRenderbuffer *stencilRb
532 = driNewRenderbuffer(GL_STENCIL_INDEX8_EXT,
533 driScrnPriv->pFB + screen->depthOffset,
534 screen->cpp,
535 screen->depthOffset, screen->depthPitch,
536 driDrawPriv);
537 radeonSetSpanFunctions(stencilRb, mesaVis);
538 _mesa_add_renderbuffer(fb, BUFFER_STENCIL, &stencilRb->Base);
539 stencilRb->depthHasSurface = screen->depthHasSurface;
540 }
541
542 _mesa_add_soft_renderbuffers(fb,
543 GL_FALSE, /* color */
544 swDepth,
545 swStencil,
546 swAccum,
547 swAlpha,
548 GL_FALSE /* aux */);
549 driDrawPriv->driverPrivate = (void *) fb;
550
551 return (driDrawPriv->driverPrivate != NULL);
552 }
553 }
554
555
556 static void
557 radeonDestroyBuffer(__DRIdrawablePrivate *driDrawPriv)
558 {
559 _mesa_destroy_framebuffer((GLframebuffer *) (driDrawPriv->driverPrivate));
560 }
561
562 static struct __DriverAPIRec radeonAPI = {
563 .InitDriver = radeonInitDriver,
564 .DestroyScreen = radeonDestroyScreen,
565 .CreateContext = radeonCreateContext,
566 .DestroyContext = radeonDestroyContext,
567 .CreateBuffer = radeonCreateBuffer,
568 .DestroyBuffer = radeonDestroyBuffer,
569 .SwapBuffers = radeonSwapBuffers,
570 .MakeCurrent = radeonMakeCurrent,
571 .UnbindContext = radeonUnbindContext,
572 .GetSwapInfo = getSwapInfo,
573 .GetMSC = driGetMSC32,
574 .WaitForMSC = driWaitForMSC32,
575 .WaitForSBC = NULL,
576 .SwapBuffersMSC = NULL
577 };
578
579
580 /**
581 * This is the bootstrap function for the driver. libGL supplies all of the
582 * requisite information about the system, and the driver initializes itself.
583 * This routine also fills in the linked list pointed to by \c driver_modes
584 * with the \c __GLcontextModes that the driver can support for windows or
585 * pbuffers.
586 *
587 * \return A pointer to a \c __DRIscreenPrivate on success, or \c NULL on
588 * failure.
589 */
590 PUBLIC void *
591 __driCreateNewScreen_20050727( __DRInativeDisplay *dpy,
592 int scrn, __DRIscreen *psc,
593 const __GLcontextModes * modes,
594 const __DRIversion * ddx_version,
595 const __DRIversion * dri_version,
596 const __DRIversion * drm_version,
597 const __DRIframebuffer * frame_buffer,
598 drmAddress pSAREA, int fd,
599 int internal_api_version,
600 const __DRIinterfaceMethods * interface,
601 __GLcontextModes ** driver_modes )
602 {
603 __DRIscreenPrivate *psp;
604 static const __DRIutilversion2 ddx_expected = { 4, 5, 0, 0 };
605 static const __DRIversion dri_expected = { 4, 0, 0 };
606 static const __DRIversion drm_expected = { 1, 3, 0 };
607
608 dri_interface = interface;
609
610 if ( ! driCheckDriDdxDrmVersions3( "Radeon",
611 dri_version, & dri_expected,
612 ddx_version, & ddx_expected,
613 drm_version, & drm_expected ) ) {
614 return NULL;
615 }
616
617 psp = __driUtilCreateNewScreen(dpy, scrn, psc, NULL,
618 ddx_version, dri_version, drm_version,
619 frame_buffer, pSAREA, fd,
620 internal_api_version, &radeonAPI);
621 if ( psp != NULL ) {
622 RADEONDRIPtr dri_priv = (RADEONDRIPtr) psp->pDevPriv;
623 *driver_modes = radeonFillInModes( dri_priv->bpp,
624 (dri_priv->bpp == 16) ? 16 : 24,
625 (dri_priv->bpp == 16) ? 0 : 8,
626 (dri_priv->backOffset != dri_priv->depthOffset) );
627
628 /* Calling driInitExtensions here, with a NULL context pointer,
629 * does not actually enable the extensions. It just makes sure
630 * that all the dispatch offsets for all the extensions that
631 * *might* be enables are known. This is needed because the
632 * dispatch offsets need to be known when _mesa_context_create
633 * is called, but we can't enable the extensions until we have a
634 * context pointer.
635 *
636 * Hello chicken. Hello egg. How are you two today?
637 */
638 driInitExtensions( NULL, card_extensions, GL_FALSE );
639 }
640
641 return (void *) psp;
642 }
643
644
645 /**
646 * Get information about previous buffer swaps.
647 */
648 static int
649 getSwapInfo( __DRIdrawablePrivate *dPriv, __DRIswapInfo * sInfo )
650 {
651 radeonContextPtr rmesa;
652
653 if ( (dPriv == NULL) || (dPriv->driContextPriv == NULL)
654 || (dPriv->driContextPriv->driverPrivate == NULL)
655 || (sInfo == NULL) ) {
656 return -1;
657 }
658
659 rmesa = (radeonContextPtr) dPriv->driContextPriv->driverPrivate;
660 sInfo->swap_count = rmesa->swap_count;
661 sInfo->swap_ust = rmesa->swap_ust;
662 sInfo->swap_missed_count = rmesa->swap_missed_count;
663
664 sInfo->swap_missed_usage = (sInfo->swap_missed_count != 0)
665 ? driCalculateSwapUsage( dPriv, 0, rmesa->swap_missed_ust )
666 : 0.0;
667
668 return 0;
669 }