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