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