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