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