bring over build fixes from stable branch
[mesa.git] / src / mesa / drivers / dri / r200 / r200_screen.c
1 /* $XFree86: xc/lib/GL/mesa/src/drv/r200/r200_screen.c,v 1.4 2003/05/08 09:25:35 herrb Exp $ */
2 /*
3 Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
4
5 The Weather Channel (TM) funded Tungsten Graphics to develop the
6 initial release of the Radeon 8500 driver under the XFree86 license.
7 This notice must be preserved.
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 r200_screen.c
33 * Screen initialization functions for the R200 driver.
34 *
35 * \author Keith Whitwell <keith@tungstengraphics.com>
36 */
37
38 #include <dlfcn.h>
39
40 #include "glheader.h"
41 #include "imports.h"
42 #include "context.h"
43
44 #define STANDALONE_MMIO
45 #include "r200_screen.h"
46 #include "r200_context.h"
47 #include "r200_ioctl.h"
48 #include "radeon_macros.h"
49 #include "radeon_reg.h"
50
51 #include "utils.h"
52 #include "vblank.h"
53 #ifndef _SOLO
54 #include "glxextensions.h"
55 #endif
56
57 /* R200 configuration
58 */
59 #include "xmlpool.h"
60
61 const char __driConfigOptions[] =
62 DRI_CONF_BEGIN
63 DRI_CONF_SECTION_PERFORMANCE
64 DRI_CONF_TCL_MODE(DRI_CONF_TCL_CODEGEN)
65 DRI_CONF_FTHROTTLE_MODE(DRI_CONF_FTHROTTLE_IRQS)
66 DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_DEF_INTERVAL_0)
67 DRI_CONF_SECTION_END
68 DRI_CONF_SECTION_QUALITY
69 DRI_CONF_TEXTURE_DEPTH(DRI_CONF_TEXTURE_DEPTH_FB)
70 DRI_CONF_DEF_MAX_ANISOTROPY(1.0,"1.0,2.0,4.0,8.0,16.0")
71 DRI_CONF_NO_NEG_LOD_BIAS(false)
72 DRI_CONF_COLOR_REDUCTION(DRI_CONF_COLOR_REDUCTION_DITHER)
73 DRI_CONF_ROUND_MODE(DRI_CONF_ROUND_TRUNC)
74 DRI_CONF_DITHER_MODE(DRI_CONF_DITHER_XERRORDIFF)
75 DRI_CONF_SECTION_END
76 DRI_CONF_SECTION_DEBUG
77 DRI_CONF_NO_RAST(false)
78 DRI_CONF_SECTION_END
79 DRI_CONF_END;
80 static const GLuint __driNConfigOptions = 10;
81
82 #if 1
83 /* Including xf86PciInfo.h introduces a bunch of errors...
84 */
85 #define PCI_CHIP_R200_QD 0x5144
86 #define PCI_CHIP_R200_QE 0x5145
87 #define PCI_CHIP_R200_QF 0x5146
88 #define PCI_CHIP_R200_QG 0x5147
89 #define PCI_CHIP_R200_QY 0x5159
90 #define PCI_CHIP_R200_QZ 0x515A
91 #define PCI_CHIP_R200_LW 0x4C57
92 #define PCI_CHIP_R200_LY 0x4C59
93 #define PCI_CHIP_R200_LZ 0x4C5A
94 #define PCI_CHIP_RV200_QW 0x5157 /* Radeon 7500 - not an R200 at all */
95 #define PCI_CHIP_RS100_4136 0x4136 /* IGP RS100, RS200, RS250 are not R200 */
96 #define PCI_CHIP_RS200_4137 0x4137
97 #define PCI_CHIP_RS250_4237 0x4237
98 #define PCI_CHIP_RS100_4336 0x4336
99 #define PCI_CHIP_RS200_4337 0x4337
100 #define PCI_CHIP_RS250_4437 0x4437
101 #define PCI_CHIP_RS300_5834 0x5834 /* All RS300's are R200 */
102 #define PCI_CHIP_RS300_5835 0x5835
103 #define PCI_CHIP_RS300_5836 0x5836
104 #define PCI_CHIP_RS300_5837 0x5837
105 #endif
106
107 #ifdef USE_NEW_INTERFACE
108 static PFNGLXCREATECONTEXTMODES create_context_modes = NULL;
109 #endif /* USE_NEW_INTERFACE */
110
111 static r200ScreenPtr __r200Screen;
112
113 static int getSwapInfo( __DRIdrawablePrivate *dPriv, __DRIswapInfo * sInfo );
114
115 #ifdef USE_NEW_INTERFACE
116 static __GLcontextModes * fill_in_modes( __GLcontextModes * modes,
117 unsigned pixel_bits,
118 unsigned depth_bits,
119 unsigned stencil_bits,
120 const GLenum * db_modes,
121 unsigned num_db_modes,
122 int visType )
123 {
124 static const uint8_t bits[2][4] = {
125 { 5, 6, 5, 0 },
126 { 8, 8, 8, 8 }
127 };
128
129 static const uint32_t masks[2][4] = {
130 { 0x0000F800, 0x000007E0, 0x0000001F, 0x00000000 },
131 { 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000 }
132 };
133
134 unsigned i;
135 unsigned j;
136 const unsigned index = ((pixel_bits + 15) / 16) - 1;
137
138 for ( i = 0 ; i < num_db_modes ; i++ ) {
139 for ( j = 0 ; j < 2 ; j++ ) {
140
141 modes->redBits = bits[index][0];
142 modes->greenBits = bits[index][1];
143 modes->blueBits = bits[index][2];
144 modes->alphaBits = bits[index][3];
145 modes->redMask = masks[index][0];
146 modes->greenMask = masks[index][1];
147 modes->blueMask = masks[index][2];
148 modes->alphaMask = masks[index][3];
149 modes->rgbBits = modes->redBits + modes->greenBits
150 + modes->blueBits + modes->alphaBits;
151
152 modes->accumRedBits = 16 * j;
153 modes->accumGreenBits = 16 * j;
154 modes->accumBlueBits = 16 * j;
155 modes->accumAlphaBits = (masks[index][3] != 0) ? 16 * j : 0;
156 modes->visualRating = (j == 0) ? GLX_NONE : GLX_SLOW_CONFIG;
157
158 modes->stencilBits = stencil_bits;
159 modes->depthBits = depth_bits;
160
161 modes->visualType = visType;
162 modes->renderType = GLX_RGBA_BIT;
163 modes->drawableType = GLX_WINDOW_BIT;
164 modes->rgbMode = GL_TRUE;
165
166 if ( db_modes[i] == GLX_NONE ) {
167 modes->doubleBufferMode = GL_FALSE;
168 }
169 else {
170 modes->doubleBufferMode = GL_TRUE;
171 modes->swapMethod = db_modes[i];
172 }
173
174 modes = modes->next;
175 }
176 }
177
178 return modes;
179 }
180 #endif /* USE_NEW_INTERFACE */
181
182
183 #ifdef USE_NEW_INTERFACE
184 static __GLcontextModes *
185 r200FillInModes( unsigned pixel_bits, unsigned depth_bits,
186 unsigned stencil_bits, GLboolean have_back_buffer )
187 {
188 __GLcontextModes * modes;
189 __GLcontextModes * m;
190 unsigned num_modes;
191 unsigned depth_buffer_factor;
192 unsigned back_buffer_factor;
193 unsigned i;
194
195 /* Right now GLX_SWAP_COPY_OML isn't supported, but it would be easy
196 * enough to add support. Basically, if a context is created with an
197 * fbconfig where the swap method is GLX_SWAP_COPY_OML, pageflipping
198 * will never be used.
199 */
200 static const GLenum back_buffer_modes[] = {
201 GLX_NONE, GLX_SWAP_UNDEFINED_OML /*, GLX_SWAP_COPY_OML */
202 };
203
204 int depth_buffer_modes[2][2];
205
206
207 depth_buffer_modes[0][0] = depth_bits;
208 depth_buffer_modes[1][0] = depth_bits;
209
210 /* Just like with the accumulation buffer, always provide some modes
211 * with a stencil buffer. It will be a sw fallback, but some apps won't
212 * care about that.
213 */
214 depth_buffer_modes[0][1] = 0;
215 depth_buffer_modes[1][1] = (stencil_bits == 0) ? 8 : stencil_bits;
216
217 depth_buffer_factor = ((depth_bits != 0) || (stencil_bits != 0)) ? 2 : 1;
218 back_buffer_factor = (have_back_buffer) ? 2 : 1;
219
220 num_modes = depth_buffer_factor * back_buffer_factor * 4;
221
222 modes = (*create_context_modes)( num_modes, sizeof( __GLcontextModes ) );
223 m = modes;
224 for ( i = 0 ; i < depth_buffer_factor ; i++ ) {
225 m = fill_in_modes( m, pixel_bits,
226 depth_buffer_modes[i][0], depth_buffer_modes[i][1],
227 back_buffer_modes, back_buffer_factor,
228 GLX_TRUE_COLOR );
229 }
230
231 for ( i = 0 ; i < depth_buffer_factor ; i++ ) {
232 m = fill_in_modes( m, pixel_bits,
233 depth_buffer_modes[i][0], depth_buffer_modes[i][1],
234 back_buffer_modes, back_buffer_factor,
235 GLX_DIRECT_COLOR );
236 }
237
238 /* Mark the visual as slow if there are "fake" stencil bits.
239 */
240 for ( m = modes ; m != NULL ; m = m->next ) {
241 if ( (m->stencilBits != 0) && (m->stencilBits != stencil_bits) ) {
242 m->visualRating = GLX_SLOW_CONFIG;
243 }
244 }
245
246 return modes;
247 }
248 #endif /* USE_NEW_INTERFACE */
249
250
251 /* Create the device specific screen private data struct.
252 */
253 static r200ScreenPtr
254 r200CreateScreen( __DRIscreenPrivate *sPriv )
255 {
256 r200ScreenPtr screen;
257 RADEONDRIPtr dri_priv = (RADEONDRIPtr)sPriv->pDevPriv;
258 unsigned char *RADEONMMIO;
259
260 if ( ! driCheckDriDdxDrmVersions( sPriv, "R200", 4, 0, 4, 0, 1, 5 ) )
261 return NULL;
262
263 /* Allocate the private area */
264 screen = (r200ScreenPtr) CALLOC( sizeof(*screen) );
265 if ( !screen ) {
266 __driUtilMessage("%s: Could not allocate memory for screen structure",
267 __FUNCTION__);
268 return NULL;
269 }
270
271 screen->chipset = 0;
272 switch ( dri_priv->deviceID ) {
273 case PCI_CHIP_R200_QD:
274 case PCI_CHIP_R200_QE:
275 case PCI_CHIP_R200_QF:
276 case PCI_CHIP_R200_QG:
277 case PCI_CHIP_R200_QY:
278 case PCI_CHIP_R200_QZ:
279 case PCI_CHIP_RV200_QW:
280 case PCI_CHIP_R200_LW:
281 case PCI_CHIP_R200_LY:
282 case PCI_CHIP_R200_LZ:
283 case PCI_CHIP_RS100_4136:
284 case PCI_CHIP_RS200_4137:
285 case PCI_CHIP_RS250_4237:
286 case PCI_CHIP_RS100_4336:
287 case PCI_CHIP_RS200_4337:
288 case PCI_CHIP_RS250_4437:
289 __driUtilMessage("r200CreateScreen(): Device isn't an r200!\n");
290 FREE( screen );
291 return NULL;
292
293 case PCI_CHIP_RS300_5834:
294 case PCI_CHIP_RS300_5835:
295 case PCI_CHIP_RS300_5836:
296 case PCI_CHIP_RS300_5837:
297 break;
298
299 default:
300 screen->chipset |= R200_CHIPSET_TCL;
301 break;
302 }
303
304 /* parse information in __driConfigOptions */
305 driParseOptionInfo (&screen->optionCache,
306 __driConfigOptions, __driNConfigOptions);
307
308 /* This is first since which regions we map depends on whether or
309 * not we are using a PCI card.
310 */
311 screen->IsPCI = dri_priv->IsPCI;
312
313 {
314 int ret;
315 drm_radeon_getparam_t gp;
316
317 gp.param = RADEON_PARAM_GART_BUFFER_OFFSET;
318 gp.value = &screen->gart_buffer_offset;
319
320 ret = drmCommandWriteRead( sPriv->fd, DRM_RADEON_GETPARAM,
321 &gp, sizeof(gp));
322 if (ret) {
323 FREE( screen );
324 fprintf(stderr, "drmRadeonGetParam (RADEON_PARAM_GART_BUFFER_OFFSET): %d\n", ret);
325 return NULL;
326 }
327
328 if (sPriv->drmMinor >= 6) {
329 gp.param = RADEON_PARAM_GART_BASE;
330 gp.value = &screen->gart_base;
331
332 ret = drmCommandWriteRead( sPriv->fd, DRM_RADEON_GETPARAM,
333 &gp, sizeof(gp));
334 if (ret) {
335 FREE( screen );
336 fprintf(stderr, "drmR200GetParam (RADEON_PARAM_GART_BASE): %d\n", ret);
337 return NULL;
338 }
339
340
341 gp.param = RADEON_PARAM_IRQ_NR;
342 gp.value = &screen->irq;
343
344 ret = drmCommandWriteRead( sPriv->fd, DRM_RADEON_GETPARAM,
345 &gp, sizeof(gp));
346 if (ret) {
347 FREE( screen );
348 fprintf(stderr, "drmRadeonGetParam (RADEON_PARAM_IRQ_NR): %d\n", ret);
349 return NULL;
350 }
351
352 /* Check if kernel module is new enough to support cube maps */
353 screen->drmSupportsCubeMaps = (sPriv->drmMinor >= 7);
354 }
355 }
356
357 screen->mmio.handle = dri_priv->registerHandle;
358 screen->mmio.size = dri_priv->registerSize;
359 if ( drmMap( sPriv->fd,
360 screen->mmio.handle,
361 screen->mmio.size,
362 &screen->mmio.map ) ) {
363 FREE( screen );
364 __driUtilMessage("%s: drmMap failed\n", __FUNCTION__ );
365 return NULL;
366 }
367
368 RADEONMMIO = screen->mmio.map;
369
370 screen->status.handle = dri_priv->statusHandle;
371 screen->status.size = dri_priv->statusSize;
372 if ( drmMap( sPriv->fd,
373 screen->status.handle,
374 screen->status.size,
375 &screen->status.map ) ) {
376 drmUnmap( screen->mmio.map, screen->mmio.size );
377 FREE( screen );
378 __driUtilMessage("%s: drmMap (2) failed\n", __FUNCTION__ );
379 return NULL;
380 }
381 screen->scratch = (__volatile__ uint32_t *)
382 ((GLubyte *)screen->status.map + RADEON_SCRATCH_REG_OFFSET);
383
384 screen->buffers = drmMapBufs( sPriv->fd );
385 if ( !screen->buffers ) {
386 drmUnmap( screen->status.map, screen->status.size );
387 drmUnmap( screen->mmio.map, screen->mmio.size );
388 FREE( screen );
389 __driUtilMessage("%s: drmMapBufs failed\n", __FUNCTION__ );
390 return NULL;
391 }
392
393 RADEONMMIO = screen->mmio.map;
394
395 if ( dri_priv->gartTexHandle && dri_priv->gartTexMapSize ) {
396
397 screen->gartTextures.handle = dri_priv->gartTexHandle;
398 screen->gartTextures.size = dri_priv->gartTexMapSize;
399 if ( drmMap( sPriv->fd,
400 screen->gartTextures.handle,
401 screen->gartTextures.size,
402 (drmAddressPtr)&screen->gartTextures.map ) ) {
403 drmUnmapBufs( screen->buffers );
404 drmUnmap( screen->status.map, screen->status.size );
405 drmUnmap( screen->mmio.map, screen->mmio.size );
406 FREE( screen );
407 __driUtilMessage("%s: drmMAP failed for GART texture area\n", __FUNCTION__);
408 return NULL;
409 }
410
411 screen->gart_texture_offset = dri_priv->gartTexOffset + ( screen->IsPCI
412 ? INREG( RADEON_AIC_LO_ADDR )
413 : ( ( INREG( RADEON_MC_AGP_LOCATION ) & 0x0ffffU ) << 16 ) );
414 }
415
416 screen->cpp = dri_priv->bpp / 8;
417 screen->AGPMode = dri_priv->AGPMode;
418
419 screen->fbLocation = ( INREG( RADEON_MC_FB_LOCATION ) & 0xffff ) << 16;
420
421 if ( sPriv->drmMinor >= 10 ) {
422 drm_radeon_setparam_t sp;
423
424 sp.param = RADEON_SETPARAM_FB_LOCATION;
425 sp.value = screen->fbLocation;
426
427 drmCommandWrite( sPriv->fd, DRM_RADEON_SETPARAM,
428 &sp, sizeof( sp ) );
429 }
430
431 screen->frontOffset = dri_priv->frontOffset;
432 screen->frontPitch = dri_priv->frontPitch;
433 screen->backOffset = dri_priv->backOffset;
434 screen->backPitch = dri_priv->backPitch;
435 screen->depthOffset = dri_priv->depthOffset;
436 screen->depthPitch = dri_priv->depthPitch;
437
438 screen->texOffset[RADEON_LOCAL_TEX_HEAP] = dri_priv->textureOffset
439 + screen->fbLocation;
440 screen->texSize[RADEON_LOCAL_TEX_HEAP] = dri_priv->textureSize;
441 screen->logTexGranularity[RADEON_LOCAL_TEX_HEAP] =
442 dri_priv->log2TexGran;
443
444 if ( !screen->gartTextures.map ) {
445 screen->numTexHeaps = RADEON_NR_TEX_HEAPS - 1;
446 screen->texOffset[RADEON_GART_TEX_HEAP] = 0;
447 screen->texSize[RADEON_GART_TEX_HEAP] = 0;
448 screen->logTexGranularity[RADEON_GART_TEX_HEAP] = 0;
449 } else {
450 screen->numTexHeaps = RADEON_NR_TEX_HEAPS;
451 screen->texOffset[RADEON_GART_TEX_HEAP] = screen->gart_texture_offset;
452 screen->texSize[RADEON_GART_TEX_HEAP] = dri_priv->gartTexMapSize;
453 screen->logTexGranularity[RADEON_GART_TEX_HEAP] =
454 dri_priv->log2GARTTexGran;
455 }
456
457 screen->driScreen = sPriv;
458 screen->sarea_priv_offset = dri_priv->sarea_priv_offset;
459 #ifndef _SOLO
460 if ( driCompareGLXAPIVersion( 20030813 ) >= 0 ) {
461 PFNGLXSCRENABLEEXTENSIONPROC glx_enable_extension =
462 (PFNGLXSCRENABLEEXTENSIONPROC) glXGetProcAddress( (const GLubyte *) "__glXScrEnableExtension" );
463 void * const psc = sPriv->psc->screenConfigs;
464
465 if ( glx_enable_extension != NULL ) {
466 if ( screen->irq != 0 ) {
467 (*glx_enable_extension)( psc, "GLX_SGI_swap_control" );
468 (*glx_enable_extension)( psc, "GLX_SGI_video_sync" );
469 (*glx_enable_extension)( psc, "GLX_MESA_swap_control" );
470 }
471
472 (*glx_enable_extension)( psc, "GLX_MESA_swap_frame_usage" );
473
474 if ( driCompareGLXAPIVersion( 20030818 ) >= 0 ) {
475 sPriv->psc->allocateMemory = (void *) r200AllocateMemoryMESA;
476 sPriv->psc->freeMemory = (void *) r200FreeMemoryMESA;
477 sPriv->psc->memoryOffset = (void *) r200GetMemoryOffsetMESA;
478
479 (*glx_enable_extension)( psc, "GLX_MESA_allocate_memory" );
480 }
481
482 if ( driCompareGLXAPIVersion( 20030915 ) >= 0 ) {
483 (*glx_enable_extension)( psc, "GLX_SGIX_fbconfig" );
484 (*glx_enable_extension)( psc, "GLX_OML_swap_method" );
485 }
486 }
487 }
488 #endif
489 return screen;
490 }
491
492 /* Destroy the device specific screen private data struct.
493 */
494 static void
495 r200DestroyScreen( __DRIscreenPrivate *sPriv )
496 {
497 r200ScreenPtr screen = (r200ScreenPtr)sPriv->private;
498
499 if (!screen)
500 return;
501
502 if ( screen->gartTextures.map ) {
503 drmUnmap( screen->gartTextures.map, screen->gartTextures.size );
504 }
505 drmUnmapBufs( screen->buffers );
506 drmUnmap( screen->status.map, screen->status.size );
507 drmUnmap( screen->mmio.map, screen->mmio.size );
508
509 /* free all option information */
510 driDestroyOptionInfo (&screen->optionCache);
511
512 FREE( screen );
513 sPriv->private = NULL;
514 }
515
516
517 /* Initialize the driver specific screen private data.
518 */
519 static GLboolean
520 r200InitDriver( __DRIscreenPrivate *sPriv )
521 {
522 __r200Screen = r200CreateScreen( sPriv );
523
524 sPriv->private = (void *) __r200Screen;
525
526 return sPriv->private ? GL_TRUE : GL_FALSE;
527 }
528
529
530
531 /**
532 * Create and initialize the Mesa and driver specific pixmap buffer
533 * data.
534 *
535 * \todo This function (and its interface) will need to be updated to support
536 * pbuffers.
537 */
538 static GLboolean
539 r200CreateBuffer( __DRIscreenPrivate *driScrnPriv,
540 __DRIdrawablePrivate *driDrawPriv,
541 const __GLcontextModes *mesaVis,
542 GLboolean isPixmap )
543 {
544 if (isPixmap) {
545 return GL_FALSE; /* not implemented */
546 }
547 else {
548 const GLboolean swDepth = GL_FALSE;
549 const GLboolean swAlpha = GL_FALSE;
550 const GLboolean swAccum = mesaVis->accumRedBits > 0;
551 const GLboolean swStencil = mesaVis->stencilBits > 0 &&
552 mesaVis->depthBits != 24;
553 driDrawPriv->driverPrivate = (void *)
554 _mesa_create_framebuffer( mesaVis,
555 swDepth,
556 swStencil,
557 swAccum,
558 swAlpha );
559 return (driDrawPriv->driverPrivate != NULL);
560 }
561 }
562
563
564 static void
565 r200DestroyBuffer(__DRIdrawablePrivate *driDrawPriv)
566 {
567 _mesa_destroy_framebuffer((GLframebuffer *) (driDrawPriv->driverPrivate));
568 }
569
570
571
572
573 static const struct __DriverAPIRec r200API = {
574 .InitDriver = r200InitDriver,
575 .DestroyScreen = r200DestroyScreen,
576 .CreateContext = r200CreateContext,
577 .DestroyContext = r200DestroyContext,
578 .CreateBuffer = r200CreateBuffer,
579 .DestroyBuffer = r200DestroyBuffer,
580 .SwapBuffers = r200SwapBuffers,
581 .MakeCurrent = r200MakeCurrent,
582 .UnbindContext = r200UnbindContext,
583 .OpenFullScreen = NULL,
584 .CloseFullScreen = NULL,
585 .GetSwapInfo = getSwapInfo,
586 .GetMSC = driGetMSC32,
587 .WaitForMSC = driWaitForMSC32,
588 .WaitForSBC = NULL,
589 .SwapBuffersMSC = NULL
590 };
591
592
593 /*
594 * This is the bootstrap function for the driver.
595 * The __driCreateScreen name is the symbol that libGL.so fetches.
596 * Return: pointer to a __DRIscreenPrivate.
597 *
598 */
599 #ifndef _SOLO
600 void *__driCreateScreen(Display *dpy, int scrn, __DRIscreen *psc,
601 int numConfigs, __GLXvisualConfig *config)
602 {
603 __DRIscreenPrivate *psp;
604 psp = __driUtilCreateScreen(dpy, scrn, psc, numConfigs, config, &r200API);
605 return (void *) psp;
606 }
607 #else
608 void *__driCreateScreen(struct DRIDriverRec *driver,
609 struct DRIDriverContextRec *driverContext)
610 {
611 __DRIscreenPrivate *psp;
612 psp = __driUtilCreateScreen(driver, driverContext, &r200API);
613 return (void *) psp;
614 }
615 #endif
616
617
618 /**
619 * This is the bootstrap function for the driver. libGL supplies all of the
620 * requisite information about the system, and the driver initializes itself.
621 * This routine also fills in the linked list pointed to by \c driver_modes
622 * with the \c __GLcontextModes that the driver can support for windows or
623 * pbuffers.
624 *
625 * \return A pointer to a \c __DRIscreenPrivate on success, or \c NULL on
626 * failure.
627 */
628 #ifdef USE_NEW_INTERFACE
629 void * __driCreateNewScreen( Display *dpy, int scrn, __DRIscreen *psc,
630 const __GLcontextModes * modes,
631 const __DRIversion * ddx_version,
632 const __DRIversion * dri_version,
633 const __DRIversion * drm_version,
634 const __DRIframebuffer * frame_buffer,
635 drmAddress pSAREA, int fd,
636 int internal_api_version,
637 __GLcontextModes ** driver_modes )
638
639 {
640 __DRIscreenPrivate *psp;
641
642 psp = __driUtilCreateNewScreen(dpy, scrn, psc, NULL,
643 ddx_version, dri_version, drm_version,
644 frame_buffer, pSAREA, fd,
645 internal_api_version, &r200API);
646 if ( psp != NULL ) {
647 create_context_modes = (PFNGLXCREATECONTEXTMODES)
648 glXGetProcAddress( (const GLubyte *) "__glXCreateContextModes" );
649 if ( create_context_modes != NULL ) {
650 RADEONDRIPtr dri_priv = (RADEONDRIPtr) psp->pDevPriv;
651 *driver_modes = r200FillInModes( dri_priv->bpp,
652 (dri_priv->bpp == 16) ? 16 : 24,
653 (dri_priv->bpp == 16) ? 0 : 8,
654 (dri_priv->backOffset != dri_priv->depthOffset) );
655 }
656 }
657
658 return (void *) psp;
659 }
660 #endif /* USE_NEW_INTERFACE */
661
662
663 /**
664 * Get information about previous buffer swaps.
665 */
666 static int
667 getSwapInfo( __DRIdrawablePrivate *dPriv, __DRIswapInfo * sInfo )
668 {
669 r200ContextPtr rmesa;
670
671 if ( (dPriv == NULL) || (dPriv->driContextPriv == NULL)
672 || (dPriv->driContextPriv->driverPrivate == NULL)
673 || (sInfo == NULL) ) {
674 return -1;
675 }
676
677 rmesa = (r200ContextPtr) dPriv->driContextPriv->driverPrivate;
678 sInfo->swap_count = rmesa->swap_count;
679 sInfo->swap_ust = rmesa->swap_ust;
680 sInfo->swap_missed_count = rmesa->swap_missed_count;
681
682 sInfo->swap_missed_usage = (sInfo->swap_missed_count != 0)
683 ? driCalculateSwapUsage( dPriv, 0, rmesa->swap_missed_ust )
684 : 0.0;
685
686 return 0;
687 }