Open/Close FullScreen die. unichrome and savage implemented, code is ifdef'd out
[mesa.git] / src / mesa / drivers / dri / radeon / radeon_screen.c
1 /* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_screen.c,v 1.7 2003/03/26 20:43:51 tsi Exp $ */
2 /**************************************************************************
3
4 Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
5 VA Linux Systems Inc., Fremont, California.
6
7 All Rights Reserved.
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 radeon_screen.c
33 * Screen initialization functions for the Radeon driver.
34 *
35 * \author Kevin E. Martin <martin@valinux.com>
36 * \author Gareth Hughes <gareth@valinux.com>
37 */
38
39 #include "glheader.h"
40 #include "imports.h"
41
42 #define STANDALONE_MMIO
43 #include "radeon_context.h"
44 #include "radeon_screen.h"
45 #include "radeon_macros.h"
46
47 #include "utils.h"
48 #include "context.h"
49 #include "vblank.h"
50
51 #ifndef _SOLO
52 #include "GL/internal/dri_interface.h"
53 #endif
54
55 /* Radeon 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_SECTION_END
66 DRI_CONF_SECTION_QUALITY
67 DRI_CONF_TEXTURE_DEPTH(DRI_CONF_TEXTURE_DEPTH_FB)
68 DRI_CONF_DEF_MAX_ANISOTROPY(1.0,"1.0,2.0,4.0,8.0,16.0")
69 DRI_CONF_NO_NEG_LOD_BIAS(false)
70 DRI_CONF_COLOR_REDUCTION(DRI_CONF_COLOR_REDUCTION_DITHER)
71 DRI_CONF_ROUND_MODE(DRI_CONF_ROUND_TRUNC)
72 DRI_CONF_DITHER_MODE(DRI_CONF_DITHER_XERRORDIFF)
73 DRI_CONF_SECTION_END
74 DRI_CONF_SECTION_DEBUG
75 DRI_CONF_NO_RAST(false)
76 DRI_CONF_SECTION_END
77 DRI_CONF_END;
78 static const GLuint __driNConfigOptions = 10;
79
80 #if 1
81 /* Including xf86PciInfo.h introduces a bunch of errors...
82 */
83 #define PCI_CHIP_RADEON_QD 0x5144
84 #define PCI_CHIP_RADEON_QE 0x5145
85 #define PCI_CHIP_RADEON_QF 0x5146
86 #define PCI_CHIP_RADEON_QG 0x5147
87
88 #define PCI_CHIP_RADEON_QY 0x5159
89 #define PCI_CHIP_RADEON_QZ 0x515A
90
91 #define PCI_CHIP_RADEON_LW 0x4C57 /* mobility 7 - has tcl */
92
93 #define PCI_CHIP_RADEON_LY 0x4C59
94 #define PCI_CHIP_RADEON_LZ 0x4C5A
95
96 #define PCI_CHIP_RV200_QW 0x5157 /* Radeon 7500 - not an R200 at all */
97 /* IGP Chipsets */
98 #define PCI_CHIP_RS100_4136 0x4136
99 #define PCI_CHIP_RS200_4137 0x4137
100 #define PCI_CHIP_RS250_4237 0x4237
101 #define PCI_CHIP_RS100_4336 0x4336
102 #define PCI_CHIP_RS200_4337 0x4337
103 #define PCI_CHIP_RS250_4437 0x4437
104 #endif
105
106 #ifdef USE_NEW_INTERFACE
107 static PFNGLXCREATECONTEXTMODES create_context_modes = NULL;
108 #endif /* USE_NEW_INTERFACE */
109
110 static int getSwapInfo( __DRIdrawablePrivate *dPriv, __DRIswapInfo * sInfo );
111
112 #ifdef USE_NEW_INTERFACE
113 static __GLcontextModes * fill_in_modes( __GLcontextModes * modes,
114 unsigned pixel_bits,
115 unsigned depth_bits,
116 unsigned stencil_bits,
117 const GLenum * db_modes,
118 unsigned num_db_modes,
119 int visType )
120 {
121 static const uint8_t bits[2][4] = {
122 { 5, 6, 5, 0 },
123 { 8, 8, 8, 8 }
124 };
125
126 static const uint32_t masks[2][4] = {
127 { 0x0000F800, 0x000007E0, 0x0000001F, 0x00000000 },
128 { 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000 }
129 };
130
131 unsigned i;
132 unsigned j;
133 const unsigned index = ((pixel_bits + 15) / 16) - 1;
134
135 for ( i = 0 ; i < num_db_modes ; i++ ) {
136 for ( j = 0 ; j < 2 ; j++ ) {
137
138 modes->redBits = bits[index][0];
139 modes->greenBits = bits[index][1];
140 modes->blueBits = bits[index][2];
141 modes->alphaBits = bits[index][3];
142 modes->redMask = masks[index][0];
143 modes->greenMask = masks[index][1];
144 modes->blueMask = masks[index][2];
145 modes->alphaMask = masks[index][3];
146 modes->rgbBits = modes->redBits + modes->greenBits
147 + modes->blueBits + modes->alphaBits;
148
149 modes->accumRedBits = 16 * j;
150 modes->accumGreenBits = 16 * j;
151 modes->accumBlueBits = 16 * j;
152 modes->accumAlphaBits = (masks[index][3] != 0) ? 16 * j : 0;
153 modes->visualRating = (j == 0) ? GLX_NONE : GLX_SLOW_CONFIG;
154
155 modes->stencilBits = stencil_bits;
156 modes->depthBits = depth_bits;
157
158 modes->visualType = visType;
159 modes->renderType = GLX_RGBA_BIT;
160 modes->drawableType = GLX_WINDOW_BIT;
161 modes->rgbMode = GL_TRUE;
162
163 if ( db_modes[i] == GLX_NONE ) {
164 modes->doubleBufferMode = GL_FALSE;
165 }
166 else {
167 modes->doubleBufferMode = GL_TRUE;
168 modes->swapMethod = db_modes[i];
169 }
170
171 modes = modes->next;
172 }
173 }
174
175 return modes;
176 }
177 #endif /* USE_NEW_INTERFACE */
178
179 #ifdef USE_NEW_INTERFACE
180 static __GLcontextModes *
181 radeonFillInModes( unsigned pixel_bits, unsigned depth_bits,
182 unsigned stencil_bits, GLboolean have_back_buffer )
183 {
184 __GLcontextModes * modes;
185 __GLcontextModes * m;
186 unsigned num_modes;
187 unsigned depth_buffer_factor;
188 unsigned back_buffer_factor;
189 unsigned i;
190
191 /* Right now GLX_SWAP_COPY_OML isn't supported, but it would be easy
192 * enough to add support. Basically, if a context is created with an
193 * fbconfig where the swap method is GLX_SWAP_COPY_OML, pageflipping
194 * will never be used.
195 */
196 static const GLenum back_buffer_modes[] = {
197 GLX_NONE, GLX_SWAP_UNDEFINED_OML /*, GLX_SWAP_COPY_OML */
198 };
199
200 int depth_buffer_modes[2][2];
201
202
203 depth_buffer_modes[0][0] = depth_bits;
204 depth_buffer_modes[1][0] = depth_bits;
205
206 /* Just like with the accumulation buffer, always provide some modes
207 * with a stencil buffer. It will be a sw fallback, but some apps won't
208 * care about that.
209 */
210 depth_buffer_modes[0][1] = 0;
211 depth_buffer_modes[1][1] = (stencil_bits == 0) ? 8 : stencil_bits;
212
213 depth_buffer_factor = ((depth_bits != 0) || (stencil_bits != 0)) ? 2 : 1;
214 back_buffer_factor = (have_back_buffer) ? 2 : 1;
215
216 num_modes = depth_buffer_factor * back_buffer_factor * 4;
217
218 modes = (*create_context_modes)( num_modes, sizeof( __GLcontextModes ) );
219 m = modes;
220 for ( i = 0 ; i < depth_buffer_factor ; i++ ) {
221 m = fill_in_modes( m, pixel_bits,
222 depth_buffer_modes[i][0], depth_buffer_modes[i][1],
223 back_buffer_modes, back_buffer_factor,
224 GLX_TRUE_COLOR );
225 }
226
227 for ( i = 0 ; i < depth_buffer_factor ; i++ ) {
228 m = fill_in_modes( m, pixel_bits,
229 depth_buffer_modes[i][0], depth_buffer_modes[i][1],
230 back_buffer_modes, back_buffer_factor,
231 GLX_DIRECT_COLOR );
232 }
233
234 /* Mark the visual as slow if there are "fake" stencil bits.
235 */
236 for ( m = modes ; m != NULL ; m = m->next ) {
237 if ( (m->stencilBits != 0) && (m->stencilBits != stencil_bits) ) {
238 m->visualRating = GLX_SLOW_CONFIG;
239 }
240 }
241
242 return modes;
243 }
244 #endif /* USE_NEW_INTERFACE */
245
246 /* Create the device specific screen private data struct.
247 */
248 radeonScreenPtr radeonCreateScreen( __DRIscreenPrivate *sPriv )
249 {
250 radeonScreenPtr screen;
251 RADEONDRIPtr dri_priv = (RADEONDRIPtr)sPriv->pDevPriv;
252 unsigned char *RADEONMMIO;
253
254
255 /* Allocate the private area */
256 screen = (radeonScreenPtr) CALLOC( sizeof(*screen) );
257 if ( !screen ) {
258 __driUtilMessage("%s: Could not allocate memory for screen structure",
259 __FUNCTION__);
260 return NULL;
261 }
262
263 /* parse information in __driConfigOptions */
264 driParseOptionInfo (&screen->optionCache,
265 __driConfigOptions, __driNConfigOptions);
266
267 /* This is first since which regions we map depends on whether or
268 * not we are using a PCI card.
269 */
270 screen->IsPCI = dri_priv->IsPCI;
271
272 {
273 int ret;
274 drm_radeon_getparam_t gp;
275
276 gp.param = RADEON_PARAM_GART_BUFFER_OFFSET;
277 gp.value = &screen->gart_buffer_offset;
278
279 ret = drmCommandWriteRead( sPriv->fd, DRM_RADEON_GETPARAM,
280 &gp, sizeof(gp));
281 if (ret) {
282 FREE( screen );
283 fprintf(stderr, "drm_radeon_getparam_t (RADEON_PARAM_GART_BUFFER_OFFSET): %d\n", ret);
284 return NULL;
285 }
286
287 if (sPriv->drmMinor >= 6) {
288 gp.param = RADEON_PARAM_IRQ_NR;
289 gp.value = &screen->irq;
290
291 ret = drmCommandWriteRead( sPriv->fd, DRM_RADEON_GETPARAM,
292 &gp, sizeof(gp));
293 if (ret) {
294 FREE( screen );
295 fprintf(stderr, "drm_radeon_getparam_t (RADEON_PARAM_IRQ_NR): %d\n", ret);
296 return NULL;
297 }
298 }
299 }
300
301 screen->mmio.handle = dri_priv->registerHandle;
302 screen->mmio.size = dri_priv->registerSize;
303 if ( drmMap( sPriv->fd,
304 screen->mmio.handle,
305 screen->mmio.size,
306 &screen->mmio.map ) ) {
307 FREE( screen );
308 __driUtilMessage("%s: drmMap failed\n", __FUNCTION__ );
309 return NULL;
310 }
311
312 RADEONMMIO = screen->mmio.map;
313
314 screen->status.handle = dri_priv->statusHandle;
315 screen->status.size = dri_priv->statusSize;
316 if ( drmMap( sPriv->fd,
317 screen->status.handle,
318 screen->status.size,
319 &screen->status.map ) ) {
320 drmUnmap( screen->mmio.map, screen->mmio.size );
321 FREE( screen );
322 __driUtilMessage("%s: drmMap (2) failed\n", __FUNCTION__ );
323 return NULL;
324 }
325 screen->scratch = (__volatile__ uint32_t *)
326 ((GLubyte *)screen->status.map + RADEON_SCRATCH_REG_OFFSET);
327
328 screen->buffers = drmMapBufs( sPriv->fd );
329 if ( !screen->buffers ) {
330 drmUnmap( screen->status.map, screen->status.size );
331 drmUnmap( screen->mmio.map, screen->mmio.size );
332 FREE( screen );
333 __driUtilMessage("%s: drmMapBufs failed\n", __FUNCTION__ );
334 return NULL;
335 }
336
337 if ( dri_priv->gartTexHandle && dri_priv->gartTexMapSize ) {
338 screen->gartTextures.handle = dri_priv->gartTexHandle;
339 screen->gartTextures.size = dri_priv->gartTexMapSize;
340 if ( drmMap( sPriv->fd,
341 screen->gartTextures.handle,
342 screen->gartTextures.size,
343 (drmAddressPtr)&screen->gartTextures.map ) ) {
344 drmUnmapBufs( screen->buffers );
345 drmUnmap( screen->status.map, screen->status.size );
346 drmUnmap( screen->mmio.map, screen->mmio.size );
347 FREE( screen );
348 __driUtilMessage("%s: drmMap failed for GART texture area\n", __FUNCTION__);
349 return NULL;
350 }
351
352 screen->gart_texture_offset = dri_priv->gartTexOffset + ( screen->IsPCI
353 ? INREG( RADEON_AIC_LO_ADDR )
354 : ( ( INREG( RADEON_MC_AGP_LOCATION ) & 0x0ffffU ) << 16 ) );
355 }
356
357 screen->chipset = 0;
358 switch ( dri_priv->deviceID ) {
359 default:
360 fprintf(stderr, "unknown chip id, assuming full radeon support\n");
361 case PCI_CHIP_RADEON_QD:
362 case PCI_CHIP_RADEON_QE:
363 case PCI_CHIP_RADEON_QF:
364 case PCI_CHIP_RADEON_QG:
365 case PCI_CHIP_RV200_QW:
366 case PCI_CHIP_RADEON_LW:
367 screen->chipset |= RADEON_CHIPSET_TCL;
368 case PCI_CHIP_RADEON_QY:
369 case PCI_CHIP_RADEON_QZ:
370 case PCI_CHIP_RADEON_LY:
371 case PCI_CHIP_RADEON_LZ:
372 case PCI_CHIP_RS100_4136: /* IGPs don't have TCL */
373 case PCI_CHIP_RS200_4137:
374 case PCI_CHIP_RS250_4237:
375 case PCI_CHIP_RS100_4336:
376 case PCI_CHIP_RS200_4337:
377 case PCI_CHIP_RS250_4437:
378 break;
379 }
380
381 screen->cpp = dri_priv->bpp / 8;
382 screen->AGPMode = dri_priv->AGPMode;
383
384 screen->fbLocation = ( INREG( RADEON_MC_FB_LOCATION ) & 0xffff ) << 16;
385
386 if ( sPriv->drmMinor >= 10 ) {
387 drm_radeon_setparam_t sp;
388
389 sp.param = RADEON_SETPARAM_FB_LOCATION;
390 sp.value = screen->fbLocation;
391
392 drmCommandWrite( sPriv->fd, DRM_RADEON_SETPARAM,
393 &sp, sizeof( sp ) );
394 }
395
396 screen->frontOffset = dri_priv->frontOffset;
397 screen->frontPitch = dri_priv->frontPitch;
398 screen->backOffset = dri_priv->backOffset;
399 screen->backPitch = dri_priv->backPitch;
400 screen->depthOffset = dri_priv->depthOffset;
401 screen->depthPitch = dri_priv->depthPitch;
402
403 screen->texOffset[RADEON_LOCAL_TEX_HEAP] = dri_priv->textureOffset
404 + screen->fbLocation;
405 screen->texSize[RADEON_LOCAL_TEX_HEAP] = dri_priv->textureSize;
406 screen->logTexGranularity[RADEON_LOCAL_TEX_HEAP] =
407 dri_priv->log2TexGran;
408
409 if ( !screen->gartTextures.map
410 || getenv( "RADEON_GARTTEXTURING_FORCE_DISABLE" ) ) {
411 screen->numTexHeaps = RADEON_NR_TEX_HEAPS - 1;
412 screen->texOffset[RADEON_GART_TEX_HEAP] = 0;
413 screen->texSize[RADEON_GART_TEX_HEAP] = 0;
414 screen->logTexGranularity[RADEON_GART_TEX_HEAP] = 0;
415 } else {
416 screen->numTexHeaps = RADEON_NR_TEX_HEAPS;
417 screen->texOffset[RADEON_GART_TEX_HEAP] = screen->gart_texture_offset;
418 screen->texSize[RADEON_GART_TEX_HEAP] = dri_priv->gartTexMapSize;
419 screen->logTexGranularity[RADEON_GART_TEX_HEAP] =
420 dri_priv->log2GARTTexGran;
421 }
422 #ifndef _SOLO
423 if ( driCompareGLXAPIVersion( 20030813 ) >= 0 ) {
424 PFNGLXSCRENABLEEXTENSIONPROC glx_enable_extension =
425 (PFNGLXSCRENABLEEXTENSIONPROC) glXGetProcAddress( (const GLubyte *) "__glXScrEnableExtension" );
426 void * const psc = sPriv->psc->screenConfigs;
427
428 if ( glx_enable_extension != NULL ) {
429 if ( screen->irq != 0 ) {
430 (*glx_enable_extension)( psc, "GLX_SGI_swap_control" );
431 (*glx_enable_extension)( psc, "GLX_SGI_video_sync" );
432 (*glx_enable_extension)( psc, "GLX_MESA_swap_control" );
433 }
434
435 (*glx_enable_extension)( psc, "GLX_MESA_swap_frame_usage" );
436
437 if ( driCompareGLXAPIVersion( 20030915 ) >= 0 ) {
438 (*glx_enable_extension)( psc, "GLX_SGIX_fbconfig" );
439 (*glx_enable_extension)( psc, "GLX_OML_swap_method" );
440 }
441
442 }
443 }
444 #endif
445 screen->driScreen = sPriv;
446 screen->sarea_priv_offset = dri_priv->sarea_priv_offset;
447 return screen;
448 }
449
450 /* Destroy the device specific screen private data struct.
451 */
452 void radeonDestroyScreen( __DRIscreenPrivate *sPriv )
453 {
454 radeonScreenPtr screen = (radeonScreenPtr)sPriv->private;
455
456 if (!screen)
457 return;
458
459 if ( screen->gartTextures.map ) {
460 drmUnmap( screen->gartTextures.map, screen->gartTextures.size );
461 }
462 drmUnmapBufs( screen->buffers );
463 drmUnmap( screen->status.map, screen->status.size );
464 drmUnmap( screen->mmio.map, screen->mmio.size );
465
466 /* free all option information */
467 driDestroyOptionInfo (&screen->optionCache);
468
469 FREE( screen );
470 sPriv->private = NULL;
471 }
472
473
474 /* Initialize the driver specific screen private data.
475 */
476 static GLboolean
477 radeonInitDriver( __DRIscreenPrivate *sPriv )
478 {
479 sPriv->private = (void *) radeonCreateScreen( sPriv );
480 if ( !sPriv->private ) {
481 radeonDestroyScreen( sPriv );
482 return GL_FALSE;
483 }
484
485 return GL_TRUE;
486 }
487
488
489
490 /**
491 * Create and initialize the Mesa and driver specific pixmap buffer
492 * data.
493 *
494 * \todo This function (and its interface) will need to be updated to support
495 * pbuffers.
496 */
497 static GLboolean
498 radeonCreateBuffer( __DRIscreenPrivate *driScrnPriv,
499 __DRIdrawablePrivate *driDrawPriv,
500 const __GLcontextModes *mesaVis,
501 GLboolean isPixmap )
502 {
503 if (isPixmap) {
504 return GL_FALSE; /* not implemented */
505 }
506 else {
507 const GLboolean swDepth = GL_FALSE;
508 const GLboolean swAlpha = GL_FALSE;
509 const GLboolean swAccum = mesaVis->accumRedBits > 0;
510 const GLboolean swStencil = mesaVis->stencilBits > 0 &&
511 mesaVis->depthBits != 24;
512 driDrawPriv->driverPrivate = (void *)
513 _mesa_create_framebuffer( mesaVis,
514 swDepth,
515 swStencil,
516 swAccum,
517 swAlpha );
518 return (driDrawPriv->driverPrivate != NULL);
519 }
520 }
521
522
523 static void
524 radeonDestroyBuffer(__DRIdrawablePrivate *driDrawPriv)
525 {
526 _mesa_destroy_framebuffer((GLframebuffer *) (driDrawPriv->driverPrivate));
527 }
528
529 static struct __DriverAPIRec radeonAPI = {
530 .InitDriver = radeonInitDriver,
531 .DestroyScreen = radeonDestroyScreen,
532 .CreateContext = radeonCreateContext,
533 .DestroyContext = radeonDestroyContext,
534 .CreateBuffer = radeonCreateBuffer,
535 .DestroyBuffer = radeonDestroyBuffer,
536 .SwapBuffers = radeonSwapBuffers,
537 .MakeCurrent = radeonMakeCurrent,
538 .UnbindContext = radeonUnbindContext,
539 .GetSwapInfo = getSwapInfo,
540 .GetMSC = driGetMSC32,
541 .WaitForMSC = driWaitForMSC32,
542 .WaitForSBC = NULL,
543 .SwapBuffersMSC = NULL
544 };
545
546
547 /*
548 * This is the bootstrap function for the driver.
549 * The __driCreateScreen name is the symbol that libGL.so fetches.
550 * Return: pointer to a __DRIscreenPrivate.
551 */
552 #if !defined(DRI_NEW_INTERFACE_ONLY)
553 #ifndef _SOLO
554 void *__driCreateScreen(Display *dpy, int scrn, __DRIscreen *psc,
555 int numConfigs, __GLXvisualConfig *config)
556 {
557 __DRIscreenPrivate *psp;
558 psp = __driUtilCreateScreen(dpy, scrn, psc, numConfigs, config, &radeonAPI);
559 return (void *) psp;
560 }
561 #else
562 void *__driCreateScreen(struct DRIDriverRec *driver,
563 struct DRIDriverContextRec *driverContext)
564 {
565 __DRIscreenPrivate *psp;
566 psp = __driUtilCreateScreen(driver, driverContext, &radeonAPI);
567 return (void *) psp;
568 }
569 #endif
570 #endif /* !defined(DRI_NEW_INTERFACE_ONLY) */
571
572 /**
573 * This is the bootstrap function for the driver. libGL supplies all of the
574 * requisite information about the system, and the driver initializes itself.
575 * This routine also fills in the linked list pointed to by \c driver_modes
576 * with the \c __GLcontextModes that the driver can support for windows or
577 * pbuffers.
578 *
579 * \return A pointer to a \c __DRIscreenPrivate on success, or \c NULL on
580 * failure.
581 */
582 #ifdef USE_NEW_INTERFACE
583 void * __driCreateNewScreen( __DRInativeDisplay *dpy, int scrn, __DRIscreen *psc,
584 const __GLcontextModes * modes,
585 const __DRIversion * ddx_version,
586 const __DRIversion * dri_version,
587 const __DRIversion * drm_version,
588 const __DRIframebuffer * frame_buffer,
589 drmAddress pSAREA, int fd,
590 int internal_api_version,
591 __GLcontextModes ** driver_modes )
592
593 {
594 __DRIscreenPrivate *psp;
595 static const __DRIversion ddx_expected = { 4, 0, 0 };
596 static const __DRIversion dri_expected = { 4, 0, 0 };
597 static const __DRIversion drm_expected = { 1, 3, 0 };
598
599 if ( ! driCheckDriDdxDrmVersions2( "Radeon",
600 dri_version, & dri_expected,
601 ddx_version, & ddx_expected,
602 drm_version, & drm_expected ) ) {
603 return NULL;
604 }
605
606 psp = __driUtilCreateNewScreen(dpy, scrn, psc, NULL,
607 ddx_version, dri_version, drm_version,
608 frame_buffer, pSAREA, fd,
609 internal_api_version, &radeonAPI);
610 if ( psp != NULL ) {
611 create_context_modes = (PFNGLXCREATECONTEXTMODES)
612 glXGetProcAddress( (const GLubyte *) "__glXCreateContextModes" );
613 if ( create_context_modes != NULL ) {
614 RADEONDRIPtr dri_priv = (RADEONDRIPtr) psp->pDevPriv;
615 *driver_modes = radeonFillInModes( dri_priv->bpp,
616 (dri_priv->bpp == 16) ? 16 : 24,
617 (dri_priv->bpp == 16) ? 0 : 8,
618 (dri_priv->backOffset != dri_priv->depthOffset) );
619 }
620 }
621
622 return (void *) psp;
623 }
624 #endif /* USE_NEW_INTERFACE */
625
626 /**
627 * Get information about previous buffer swaps.
628 */
629 static int
630 getSwapInfo( __DRIdrawablePrivate *dPriv, __DRIswapInfo * sInfo )
631 {
632 radeonContextPtr rmesa;
633
634 if ( (dPriv == NULL) || (dPriv->driContextPriv == NULL)
635 || (dPriv->driContextPriv->driverPrivate == NULL)
636 || (sInfo == NULL) ) {
637 return -1;
638 }
639
640 rmesa = (radeonContextPtr) dPriv->driContextPriv->driverPrivate;
641 sInfo->swap_count = rmesa->swap_count;
642 sInfo->swap_ust = rmesa->swap_ust;
643 sInfo->swap_missed_count = rmesa->swap_missed_count;
644
645 sInfo->swap_missed_usage = (sInfo->swap_missed_count != 0)
646 ? driCalculateSwapUsage( dPriv, 0, rmesa->swap_missed_ust )
647 : 0.0;
648
649 return 0;
650 }