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