45d7c1699e0ac5e784d662eb05e5fa4ee2509572
[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 { 0, 0 },
205 { 0, 0 }
206 };
207
208 depth_buffer_modes[0][0] = depth_bits;
209 depth_buffer_modes[1][0] = depth_bits;
210
211 /* Just like with the accumulation buffer, always provide some modes
212 * with a stencil buffer. It will be a sw fallback, but some apps won't
213 * care about that.
214 */
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 != 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 drmRadeonGetParam 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 screen->status.handle = dri_priv->statusHandle;
369 screen->status.size = dri_priv->statusSize;
370 if ( drmMap( sPriv->fd,
371 screen->status.handle,
372 screen->status.size,
373 &screen->status.map ) ) {
374 drmUnmap( screen->mmio.map, screen->mmio.size );
375 FREE( screen );
376 __driUtilMessage("%s: drmMap (2) failed\n", __FUNCTION__ );
377 return NULL;
378 }
379 screen->scratch = (__volatile__ CARD32 *)
380 ((GLubyte *)screen->status.map + RADEON_SCRATCH_REG_OFFSET);
381
382 screen->buffers = drmMapBufs( sPriv->fd );
383 if ( !screen->buffers ) {
384 drmUnmap( screen->status.map, screen->status.size );
385 drmUnmap( screen->mmio.map, screen->mmio.size );
386 FREE( screen );
387 __driUtilMessage("%s: drmMapBufs failed\n", __FUNCTION__ );
388 return NULL;
389 }
390
391 RADEONMMIO = screen->mmio.map;
392
393 if ( dri_priv->gartTexHandle && dri_priv->gartTexMapSize ) {
394
395 screen->gartTextures.handle = dri_priv->gartTexHandle;
396 screen->gartTextures.size = dri_priv->gartTexMapSize;
397 if ( drmMap( sPriv->fd,
398 screen->gartTextures.handle,
399 screen->gartTextures.size,
400 (drmAddressPtr)&screen->gartTextures.map ) ) {
401 drmUnmapBufs( screen->buffers );
402 drmUnmap( screen->status.map, screen->status.size );
403 drmUnmap( screen->mmio.map, screen->mmio.size );
404 FREE( screen );
405 __driUtilMessage("%s: drmMAP failed for GART texture area\n", __FUNCTION__);
406 return NULL;
407 }
408
409 screen->gart_texture_offset = dri_priv->gartTexOffset + ( screen->IsPCI
410 ? INREG( RADEON_AIC_LO_ADDR )
411 : ( ( INREG( RADEON_MC_AGP_LOCATION ) & 0x0ffffU ) << 16 ) );
412 }
413
414 screen->cpp = dri_priv->bpp / 8;
415 screen->AGPMode = dri_priv->AGPMode;
416
417 screen->fbLocation = ( INREG( RADEON_MC_FB_LOCATION ) & 0xffff ) << 16;
418
419 if ( sPriv->drmMinor >= 10 ) {
420 drmRadeonSetParam sp;
421
422 sp.param = RADEON_SETPARAM_FB_LOCATION;
423 sp.value = screen->fbLocation;
424
425 drmCommandWrite( sPriv->fd, DRM_RADEON_SETPARAM,
426 &sp, sizeof( sp ) );
427 }
428
429 screen->frontOffset = dri_priv->frontOffset;
430 screen->frontPitch = dri_priv->frontPitch;
431 screen->backOffset = dri_priv->backOffset;
432 screen->backPitch = dri_priv->backPitch;
433 screen->depthOffset = dri_priv->depthOffset;
434 screen->depthPitch = dri_priv->depthPitch;
435
436 screen->texOffset[RADEON_CARD_HEAP] = dri_priv->textureOffset
437 + screen->fbLocation;
438 screen->texSize[RADEON_CARD_HEAP] = dri_priv->textureSize;
439 screen->logTexGranularity[RADEON_CARD_HEAP] =
440 dri_priv->log2TexGran;
441
442 if ( !screen->gartTextures.map ) {
443 screen->numTexHeaps = RADEON_NR_TEX_HEAPS - 1;
444 screen->texOffset[RADEON_GART_HEAP] = 0;
445 screen->texSize[RADEON_GART_HEAP] = 0;
446 screen->logTexGranularity[RADEON_GART_HEAP] = 0;
447 } else {
448 screen->numTexHeaps = RADEON_NR_TEX_HEAPS;
449 screen->texOffset[RADEON_GART_HEAP] = screen->gart_texture_offset;
450 screen->texSize[RADEON_GART_HEAP] = dri_priv->gartTexMapSize;
451 screen->logTexGranularity[RADEON_GART_HEAP] =
452 dri_priv->log2GARTTexGran;
453 }
454
455 screen->driScreen = sPriv;
456 screen->sarea_priv_offset = dri_priv->sarea_priv_offset;
457 #ifndef _SOLO
458 if ( driCompareGLXAPIVersion( 20030813 ) >= 0 ) {
459 PFNGLXSCRENABLEEXTENSIONPROC glx_enable_extension =
460 (PFNGLXSCRENABLEEXTENSIONPROC) glXGetProcAddress( (const GLubyte *) "__glXScrEnableExtension" );
461 void * const psc = sPriv->psc->screenConfigs;
462
463 if ( glx_enable_extension != NULL ) {
464 if ( screen->irq != 0 ) {
465 (*glx_enable_extension)( psc, "GLX_SGI_swap_control" );
466 (*glx_enable_extension)( psc, "GLX_SGI_video_sync" );
467 (*glx_enable_extension)( psc, "GLX_MESA_swap_control" );
468 }
469
470 (*glx_enable_extension)( psc, "GLX_MESA_swap_frame_usage" );
471
472 if ( driCompareGLXAPIVersion( 20030818 ) >= 0 ) {
473 sPriv->psc->allocateMemory = (void *) r200AllocateMemoryMESA;
474 sPriv->psc->freeMemory = (void *) r200FreeMemoryMESA;
475 sPriv->psc->memoryOffset = (void *) r200GetMemoryOffsetMESA;
476
477 (*glx_enable_extension)( psc, "GLX_MESA_allocate_memory" );
478 }
479
480 if ( driCompareGLXAPIVersion( 20030915 ) >= 0 ) {
481 (*glx_enable_extension)( psc, "GLX_SGIX_fbconfig" );
482 (*glx_enable_extension)( psc, "GLX_OML_swap_method" );
483 }
484 }
485 }
486 #endif
487 return screen;
488 }
489
490 /* Destroy the device specific screen private data struct.
491 */
492 static void
493 r200DestroyScreen( __DRIscreenPrivate *sPriv )
494 {
495 r200ScreenPtr screen = (r200ScreenPtr)sPriv->private;
496
497 if (!screen)
498 return;
499
500 if ( screen->gartTextures.map ) {
501 drmUnmap( screen->gartTextures.map, screen->gartTextures.size );
502 }
503 drmUnmapBufs( screen->buffers );
504 drmUnmap( screen->status.map, screen->status.size );
505 drmUnmap( screen->mmio.map, screen->mmio.size );
506
507 /* free all option information */
508 driDestroyOptionInfo (&screen->optionCache);
509
510 FREE( screen );
511 sPriv->private = NULL;
512 }
513
514
515 /* Initialize the driver specific screen private data.
516 */
517 static GLboolean
518 r200InitDriver( __DRIscreenPrivate *sPriv )
519 {
520 __r200Screen = r200CreateScreen( sPriv );
521
522 sPriv->private = (void *) __r200Screen;
523
524 return sPriv->private ? GL_TRUE : GL_FALSE;
525 }
526
527
528
529 /**
530 * Create and initialize the Mesa and driver specific pixmap buffer
531 * data.
532 *
533 * \todo This function (and its interface) will need to be updated to support
534 * pbuffers.
535 */
536 static GLboolean
537 r200CreateBuffer( __DRIscreenPrivate *driScrnPriv,
538 __DRIdrawablePrivate *driDrawPriv,
539 const __GLcontextModes *mesaVis,
540 GLboolean isPixmap )
541 {
542 if (isPixmap) {
543 return GL_FALSE; /* not implemented */
544 }
545 else {
546 const GLboolean swDepth = GL_FALSE;
547 const GLboolean swAlpha = GL_FALSE;
548 const GLboolean swAccum = mesaVis->accumRedBits > 0;
549 const GLboolean swStencil = mesaVis->stencilBits > 0 &&
550 mesaVis->depthBits != 24;
551 driDrawPriv->driverPrivate = (void *)
552 _mesa_create_framebuffer( mesaVis,
553 swDepth,
554 swStencil,
555 swAccum,
556 swAlpha );
557 return (driDrawPriv->driverPrivate != NULL);
558 }
559 }
560
561
562 static void
563 r200DestroyBuffer(__DRIdrawablePrivate *driDrawPriv)
564 {
565 _mesa_destroy_framebuffer((GLframebuffer *) (driDrawPriv->driverPrivate));
566 }
567
568
569
570
571 static const struct __DriverAPIRec r200API = {
572 .InitDriver = r200InitDriver,
573 .DestroyScreen = r200DestroyScreen,
574 .CreateContext = r200CreateContext,
575 .DestroyContext = r200DestroyContext,
576 .CreateBuffer = r200CreateBuffer,
577 .DestroyBuffer = r200DestroyBuffer,
578 .SwapBuffers = r200SwapBuffers,
579 .MakeCurrent = r200MakeCurrent,
580 .UnbindContext = r200UnbindContext,
581 .OpenFullScreen = NULL,
582 .CloseFullScreen = NULL,
583 .GetSwapInfo = getSwapInfo,
584 .GetMSC = driGetMSC32,
585 .WaitForMSC = driWaitForMSC32,
586 .WaitForSBC = NULL,
587 .SwapBuffersMSC = NULL
588 };
589
590
591 /*
592 * This is the bootstrap function for the driver.
593 * The __driCreateScreen name is the symbol that libGL.so fetches.
594 * Return: pointer to a __DRIscreenPrivate.
595 *
596 */
597 #ifndef _SOLO
598 void *__driCreateScreen(Display *dpy, int scrn, __DRIscreen *psc,
599 int numConfigs, __GLXvisualConfig *config)
600 {
601 __DRIscreenPrivate *psp;
602 psp = __driUtilCreateScreen(dpy, scrn, psc, numConfigs, config, &r200API);
603 return (void *) psp;
604 }
605 #else
606 void *__driCreateScreen(struct DRIDriverRec *driver,
607 struct DRIDriverContextRec *driverContext)
608 {
609 __DRIscreenPrivate *psp;
610 psp = __driUtilCreateScreen(driver, driverContext, &r200API);
611 return (void *) psp;
612 }
613 #endif
614
615
616 /**
617 * This is the bootstrap function for the driver. libGL supplies all of the
618 * requisite information about the system, and the driver initializes itself.
619 * This routine also fills in the linked list pointed to by \c driver_modes
620 * with the \c __GLcontextModes that the driver can support for windows or
621 * pbuffers.
622 *
623 * \return A pointer to a \c __DRIscreenPrivate on success, or \c NULL on
624 * failure.
625 */
626 #ifdef USE_NEW_INTERFACE
627 void * __driCreateNewScreen( Display *dpy, int scrn, __DRIscreen *psc,
628 const __GLcontextModes * modes,
629 const __DRIversion * ddx_version,
630 const __DRIversion * dri_version,
631 const __DRIversion * drm_version,
632 const __DRIframebuffer * frame_buffer,
633 drmAddress pSAREA, int fd,
634 int internal_api_version,
635 __GLcontextModes ** driver_modes )
636
637 {
638 __DRIscreenPrivate *psp;
639
640 psp = __driUtilCreateNewScreen(dpy, scrn, psc, NULL,
641 ddx_version, dri_version, drm_version,
642 frame_buffer, pSAREA, fd,
643 internal_api_version, &r200API);
644
645
646 create_context_modes =
647 (PFNGLXCREATECONTEXTMODES) glXGetProcAddress( (const GLubyte *) "__glXCreateContextModes" );
648 if ( create_context_modes != NULL ) {
649 RADEONDRIPtr dri_priv = (RADEONDRIPtr) psp->pDevPriv;
650 *driver_modes = r200FillInModes( dri_priv->bpp,
651 (dri_priv->bpp == 16) ? 16 : 24,
652 (dri_priv->bpp == 16) ? 0 : 8,
653 (dri_priv->backOffset != dri_priv->depthOffset) );
654 }
655
656 return (void *) psp;
657 }
658 #endif /* USE_NEW_INTERFACE */
659
660
661 /**
662 * Get information about previous buffer swaps.
663 */
664 static int
665 getSwapInfo( __DRIdrawablePrivate *dPriv, __DRIswapInfo * sInfo )
666 {
667 r200ContextPtr rmesa;
668
669 if ( (dPriv == NULL) || (dPriv->driContextPriv == NULL)
670 || (dPriv->driContextPriv->driverPrivate == NULL)
671 || (sInfo == NULL) ) {
672 return -1;
673 }
674
675 rmesa = (r200ContextPtr) dPriv->driContextPriv->driverPrivate;
676 sInfo->swap_count = rmesa->swap_count;
677 sInfo->swap_ust = rmesa->swap_ust;
678 sInfo->swap_missed_count = rmesa->swap_missed_count;
679
680 sInfo->swap_missed_usage = (sInfo->swap_missed_count != 0)
681 ? driCalculateSwapUsage( dPriv, 0, rmesa->swap_missed_ust )
682 : 0.0;
683
684 return 0;
685 }