radeon_screen.c revision c39bf5e273a4995a279ae2af59fc29e06ab47e29
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 4Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and 5 VA Linux Systems Inc., Fremont, California. 6 7All Rights Reserved. 8 9Permission is hereby granted, free of charge, to any person obtaining 10a copy of this software and associated documentation files (the 11"Software"), to deal in the Software without restriction, including 12without limitation the rights to use, copy, modify, merge, publish, 13distribute, sublicense, and/or sell copies of the Software, and to 14permit persons to whom the Software is furnished to do so, subject to 15the following conditions: 16 17The above copyright notice and this permission notice (including the 18next paragraph) shall be included in all copies or substantial 19portions of the Software. 20 21THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 22EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 23MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 24IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE 25LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 26OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 27WITH 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#include "mtypes.h" 42#include "framebuffer.h" 43#include "renderbuffer.h" 44 45#define STANDALONE_MMIO 46#include "radeon_context.h" 47#include "radeon_screen.h" 48#include "radeon_macros.h" 49#include "radeon_span.h" 50 51#include "utils.h" 52#include "context.h" 53#include "vblank.h" 54#include "drirenderbuffer.h" 55 56#include "GL/internal/dri_interface.h" 57 58/* Radeon configuration 59 */ 60#include "xmlpool.h" 61 62PUBLIC const char __driConfigOptions[] = 63DRI_CONF_BEGIN 64 DRI_CONF_SECTION_PERFORMANCE 65 DRI_CONF_TCL_MODE(DRI_CONF_TCL_CODEGEN) 66 DRI_CONF_FTHROTTLE_MODE(DRI_CONF_FTHROTTLE_IRQS) 67 DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_DEF_INTERVAL_0) 68 DRI_CONF_HYPERZ(false) 69 DRI_CONF_SECTION_END 70 DRI_CONF_SECTION_QUALITY 71 DRI_CONF_TEXTURE_DEPTH(DRI_CONF_TEXTURE_DEPTH_FB) 72 DRI_CONF_DEF_MAX_ANISOTROPY(1.0,"1.0,2.0,4.0,8.0,16.0") 73 DRI_CONF_NO_NEG_LOD_BIAS(false) 74 DRI_CONF_FORCE_S3TC_ENABLE(false) 75 DRI_CONF_COLOR_REDUCTION(DRI_CONF_COLOR_REDUCTION_DITHER) 76 DRI_CONF_ROUND_MODE(DRI_CONF_ROUND_TRUNC) 77 DRI_CONF_DITHER_MODE(DRI_CONF_DITHER_XERRORDIFF) 78 DRI_CONF_TEXTURE_LEVEL_HACK(false) 79 DRI_CONF_SECTION_END 80 DRI_CONF_SECTION_DEBUG 81 DRI_CONF_NO_RAST(false) 82 DRI_CONF_SECTION_END 83DRI_CONF_END; 84static const GLuint __driNConfigOptions = 13; 85 86#if 1 87/* Including xf86PciInfo.h introduces a bunch of errors... 88 */ 89#define PCI_CHIP_RADEON_QD 0x5144 90#define PCI_CHIP_RADEON_QE 0x5145 91#define PCI_CHIP_RADEON_QF 0x5146 92#define PCI_CHIP_RADEON_QG 0x5147 93 94#define PCI_CHIP_RADEON_QY 0x5159 95#define PCI_CHIP_RADEON_QZ 0x515A 96 97#define PCI_CHIP_RN50_515E 0x515E 98#define PCI_CHIP_RN50_5969 0x5969 99 100#define PCI_CHIP_RADEON_LW 0x4C57 /* mobility 7 - has tcl */ 101#define PCI_CHIP_RADEON_LX 0x4C58 /* mobility FireGL 7800 m7 */ 102 103#define PCI_CHIP_RADEON_LY 0x4C59 104#define PCI_CHIP_RADEON_LZ 0x4C5A 105 106#define PCI_CHIP_RV200_QW 0x5157 /* Radeon 7500 - not an R200 at all */ 107#define PCI_CHIP_RV200_QX 0x5158 108 109/* IGP Chipsets */ 110#define PCI_CHIP_RS100_4136 0x4136 111#define PCI_CHIP_RS200_4137 0x4137 112#define PCI_CHIP_RS250_4237 0x4237 113#define PCI_CHIP_RS100_4336 0x4336 114#define PCI_CHIP_RS200_4337 0x4337 115#define PCI_CHIP_RS250_4437 0x4437 116#endif 117 118static PFNGLXCREATECONTEXTMODES create_context_modes = NULL; 119 120static int getSwapInfo( __DRIdrawablePrivate *dPriv, __DRIswapInfo * sInfo ); 121 122static __GLcontextModes * 123radeonFillInModes( unsigned pixel_bits, unsigned depth_bits, 124 unsigned stencil_bits, GLboolean have_back_buffer ) 125{ 126 __GLcontextModes * modes; 127 __GLcontextModes * m; 128 unsigned num_modes; 129 unsigned depth_buffer_factor; 130 unsigned back_buffer_factor; 131 GLenum fb_format; 132 GLenum fb_type; 133 134 /* Right now GLX_SWAP_COPY_OML isn't supported, but it would be easy 135 * enough to add support. Basically, if a context is created with an 136 * fbconfig where the swap method is GLX_SWAP_COPY_OML, pageflipping 137 * will never be used. 138 */ 139 static const GLenum back_buffer_modes[] = { 140 GLX_NONE, GLX_SWAP_UNDEFINED_OML /*, GLX_SWAP_COPY_OML */ 141 }; 142 143 u_int8_t depth_bits_array[2]; 144 u_int8_t stencil_bits_array[2]; 145 146 147 depth_bits_array[0] = depth_bits; 148 depth_bits_array[1] = depth_bits; 149 150 /* Just like with the accumulation buffer, always provide some modes 151 * with a stencil buffer. It will be a sw fallback, but some apps won't 152 * care about that. 153 */ 154 stencil_bits_array[0] = 0; 155 stencil_bits_array[1] = (stencil_bits == 0) ? 8 : stencil_bits; 156 157 depth_buffer_factor = ((depth_bits != 0) || (stencil_bits != 0)) ? 2 : 1; 158 back_buffer_factor = (have_back_buffer) ? 2 : 1; 159 160 num_modes = depth_buffer_factor * back_buffer_factor * 4; 161 162 if ( pixel_bits == 16 ) { 163 fb_format = GL_RGB; 164 fb_type = GL_UNSIGNED_SHORT_5_6_5; 165 } 166 else { 167 fb_format = GL_BGRA; 168 fb_type = GL_UNSIGNED_INT_8_8_8_8_REV; 169 } 170 171 modes = (*create_context_modes)( num_modes, sizeof( __GLcontextModes ) ); 172 m = modes; 173 if ( ! driFillInModes( & m, fb_format, fb_type, 174 depth_bits_array, stencil_bits_array, depth_buffer_factor, 175 back_buffer_modes, back_buffer_factor, 176 GLX_TRUE_COLOR ) ) { 177 fprintf( stderr, "[%s:%u] Error creating FBConfig!\n", 178 __func__, __LINE__ ); 179 return NULL; 180 } 181 182 if ( ! driFillInModes( & m, fb_format, fb_type, 183 depth_bits_array, stencil_bits_array, depth_buffer_factor, 184 back_buffer_modes, back_buffer_factor, 185 GLX_DIRECT_COLOR ) ) { 186 fprintf( stderr, "[%s:%u] Error creating FBConfig!\n", 187 __func__, __LINE__ ); 188 return NULL; 189 } 190 191 /* Mark the visual as slow if there are "fake" stencil bits. 192 */ 193 for ( m = modes ; m != NULL ; m = m->next ) { 194 if ( (m->stencilBits != 0) && (m->stencilBits != stencil_bits) ) { 195 m->visualRating = GLX_SLOW_CONFIG; 196 } 197 } 198 199 return modes; 200} 201 202 203/* Create the device specific screen private data struct. 204 */ 205radeonScreenPtr radeonCreateScreen( __DRIscreenPrivate *sPriv ) 206{ 207 radeonScreenPtr screen; 208 RADEONDRIPtr dri_priv = (RADEONDRIPtr)sPriv->pDevPriv; 209 unsigned char *RADEONMMIO; 210 PFNGLXSCRENABLEEXTENSIONPROC glx_enable_extension = 211 (PFNGLXSCRENABLEEXTENSIONPROC) glXGetProcAddress( (const GLubyte *) "__glXScrEnableExtension" ); 212 void * const psc = sPriv->psc->screenConfigs; 213 214 215 if ( glx_enable_extension == NULL ) { 216 return NULL; 217 } 218 219 /* Allocate the private area */ 220 screen = (radeonScreenPtr) CALLOC( sizeof(*screen) ); 221 if ( !screen ) { 222 __driUtilMessage("%s: Could not allocate memory for screen structure", 223 __FUNCTION__); 224 return NULL; 225 } 226 227 /* parse information in __driConfigOptions */ 228 driParseOptionInfo (&screen->optionCache, 229 __driConfigOptions, __driNConfigOptions); 230 231 /* This is first since which regions we map depends on whether or 232 * not we are using a PCI card. 233 */ 234 screen->IsPCI = dri_priv->IsPCI; 235 236 { 237 int ret; 238 drm_radeon_getparam_t gp; 239 240 gp.param = RADEON_PARAM_GART_BUFFER_OFFSET; 241 gp.value = &screen->gart_buffer_offset; 242 243 ret = drmCommandWriteRead( sPriv->fd, DRM_RADEON_GETPARAM, 244 &gp, sizeof(gp)); 245 if (ret) { 246 FREE( screen ); 247 fprintf(stderr, "drm_radeon_getparam_t (RADEON_PARAM_GART_BUFFER_OFFSET): %d\n", ret); 248 return NULL; 249 } 250 251 if (sPriv->drmMinor >= 6) { 252 gp.param = RADEON_PARAM_IRQ_NR; 253 gp.value = &screen->irq; 254 255 ret = drmCommandWriteRead( sPriv->fd, DRM_RADEON_GETPARAM, 256 &gp, sizeof(gp)); 257 if (ret) { 258 FREE( screen ); 259 fprintf(stderr, "drm_radeon_getparam_t (RADEON_PARAM_IRQ_NR): %d\n", ret); 260 return NULL; 261 } 262 } 263 } 264 265 screen->mmio.handle = dri_priv->registerHandle; 266 screen->mmio.size = dri_priv->registerSize; 267 if ( drmMap( sPriv->fd, 268 screen->mmio.handle, 269 screen->mmio.size, 270 &screen->mmio.map ) ) { 271 FREE( screen ); 272 __driUtilMessage("%s: drmMap failed\n", __FUNCTION__ ); 273 return NULL; 274 } 275 276 RADEONMMIO = screen->mmio.map; 277 278 screen->status.handle = dri_priv->statusHandle; 279 screen->status.size = dri_priv->statusSize; 280 if ( drmMap( sPriv->fd, 281 screen->status.handle, 282 screen->status.size, 283 &screen->status.map ) ) { 284 drmUnmap( screen->mmio.map, screen->mmio.size ); 285 FREE( screen ); 286 __driUtilMessage("%s: drmMap (2) failed\n", __FUNCTION__ ); 287 return NULL; 288 } 289 screen->scratch = (__volatile__ u_int32_t *) 290 ((GLubyte *)screen->status.map + RADEON_SCRATCH_REG_OFFSET); 291 292 screen->buffers = drmMapBufs( sPriv->fd ); 293 if ( !screen->buffers ) { 294 drmUnmap( screen->status.map, screen->status.size ); 295 drmUnmap( screen->mmio.map, screen->mmio.size ); 296 FREE( screen ); 297 __driUtilMessage("%s: drmMapBufs failed\n", __FUNCTION__ ); 298 return NULL; 299 } 300 301 if ( dri_priv->gartTexHandle && dri_priv->gartTexMapSize ) { 302 screen->gartTextures.handle = dri_priv->gartTexHandle; 303 screen->gartTextures.size = dri_priv->gartTexMapSize; 304 if ( drmMap( sPriv->fd, 305 screen->gartTextures.handle, 306 screen->gartTextures.size, 307 (drmAddressPtr)&screen->gartTextures.map ) ) { 308 drmUnmapBufs( screen->buffers ); 309 drmUnmap( screen->status.map, screen->status.size ); 310 drmUnmap( screen->mmio.map, screen->mmio.size ); 311 FREE( screen ); 312 __driUtilMessage("%s: drmMap failed for GART texture area\n", __FUNCTION__); 313 return NULL; 314 } 315 316 screen->gart_texture_offset = dri_priv->gartTexOffset + ( screen->IsPCI 317 ? INREG( RADEON_AIC_LO_ADDR ) 318 : ( ( INREG( RADEON_MC_AGP_LOCATION ) & 0x0ffffU ) << 16 ) ); 319 } 320 321 screen->chipset = 0; 322 switch ( dri_priv->deviceID ) { 323 default: 324 fprintf(stderr, "unknown chip id, assuming full radeon support\n"); 325 case PCI_CHIP_RADEON_QD: 326 case PCI_CHIP_RADEON_QE: 327 case PCI_CHIP_RADEON_QF: 328 case PCI_CHIP_RADEON_QG: 329 /* all original radeons (7200) presumably have a stencil op bug */ 330 screen->chipset |= RADEON_CHIPSET_BROKEN_STENCIL; 331 case PCI_CHIP_RV200_QW: 332 case PCI_CHIP_RV200_QX: 333 case PCI_CHIP_RADEON_LW: 334 case PCI_CHIP_RADEON_LX: 335 screen->chipset |= RADEON_CHIPSET_TCL; 336 case PCI_CHIP_RADEON_QY: 337 case PCI_CHIP_RADEON_QZ: 338 case PCI_CHIP_RN50_515E: 339 case PCI_CHIP_RN50_5969: 340 case PCI_CHIP_RADEON_LY: 341 case PCI_CHIP_RADEON_LZ: 342 case PCI_CHIP_RS100_4136: /* IGPs don't have TCL */ 343 case PCI_CHIP_RS200_4137: 344 case PCI_CHIP_RS250_4237: 345 case PCI_CHIP_RS100_4336: 346 case PCI_CHIP_RS200_4337: 347 case PCI_CHIP_RS250_4437: 348 break; 349 } 350 351 screen->cpp = dri_priv->bpp / 8; 352 screen->AGPMode = dri_priv->AGPMode; 353 354 screen->fbLocation = ( INREG( RADEON_MC_FB_LOCATION ) & 0xffff ) << 16; 355 356 if ( sPriv->drmMinor >= 10 ) { 357 drm_radeon_setparam_t sp; 358 359 sp.param = RADEON_SETPARAM_FB_LOCATION; 360 sp.value = screen->fbLocation; 361 362 drmCommandWrite( sPriv->fd, DRM_RADEON_SETPARAM, 363 &sp, sizeof( sp ) ); 364 } 365 366 screen->frontOffset = dri_priv->frontOffset; 367 screen->frontPitch = dri_priv->frontPitch; 368 screen->backOffset = dri_priv->backOffset; 369 screen->backPitch = dri_priv->backPitch; 370 screen->depthOffset = dri_priv->depthOffset; 371 screen->depthPitch = dri_priv->depthPitch; 372 373 /* Check if ddx has set up a surface reg to cover depth buffer */ 374 screen->depthHasSurface = ((sPriv->ddxMajor > 4) && 375 (screen->chipset & RADEON_CHIPSET_TCL)); 376 377 screen->texOffset[RADEON_LOCAL_TEX_HEAP] = dri_priv->textureOffset 378 + screen->fbLocation; 379 screen->texSize[RADEON_LOCAL_TEX_HEAP] = dri_priv->textureSize; 380 screen->logTexGranularity[RADEON_LOCAL_TEX_HEAP] = 381 dri_priv->log2TexGran; 382 383 if ( !screen->gartTextures.map 384 || getenv( "RADEON_GARTTEXTURING_FORCE_DISABLE" ) ) { 385 screen->numTexHeaps = RADEON_NR_TEX_HEAPS - 1; 386 screen->texOffset[RADEON_GART_TEX_HEAP] = 0; 387 screen->texSize[RADEON_GART_TEX_HEAP] = 0; 388 screen->logTexGranularity[RADEON_GART_TEX_HEAP] = 0; 389 } else { 390 screen->numTexHeaps = RADEON_NR_TEX_HEAPS; 391 screen->texOffset[RADEON_GART_TEX_HEAP] = screen->gart_texture_offset; 392 screen->texSize[RADEON_GART_TEX_HEAP] = dri_priv->gartTexMapSize; 393 screen->logTexGranularity[RADEON_GART_TEX_HEAP] = 394 dri_priv->log2GARTTexGran; 395 } 396 397 if ( screen->irq != 0 ) { 398 (*glx_enable_extension)( psc, "GLX_SGI_swap_control" ); 399 (*glx_enable_extension)( psc, "GLX_SGI_video_sync" ); 400 (*glx_enable_extension)( psc, "GLX_MESA_swap_control" ); 401 } 402 403 (*glx_enable_extension)( psc, "GLX_MESA_swap_frame_usage" ); 404 405 screen->driScreen = sPriv; 406 screen->sarea_priv_offset = dri_priv->sarea_priv_offset; 407 return screen; 408} 409 410/* Destroy the device specific screen private data struct. 411 */ 412void radeonDestroyScreen( __DRIscreenPrivate *sPriv ) 413{ 414 radeonScreenPtr screen = (radeonScreenPtr)sPriv->private; 415 416 if (!screen) 417 return; 418 419 if ( screen->gartTextures.map ) { 420 drmUnmap( screen->gartTextures.map, screen->gartTextures.size ); 421 } 422 drmUnmapBufs( screen->buffers ); 423 drmUnmap( screen->status.map, screen->status.size ); 424 drmUnmap( screen->mmio.map, screen->mmio.size ); 425 426 /* free all option information */ 427 driDestroyOptionInfo (&screen->optionCache); 428 429 FREE( screen ); 430 sPriv->private = NULL; 431} 432 433 434/* Initialize the driver specific screen private data. 435 */ 436static GLboolean 437radeonInitDriver( __DRIscreenPrivate *sPriv ) 438{ 439 sPriv->private = (void *) radeonCreateScreen( sPriv ); 440 if ( !sPriv->private ) { 441 radeonDestroyScreen( sPriv ); 442 return GL_FALSE; 443 } 444 445 return GL_TRUE; 446} 447 448 449/** 450 * Create the Mesa framebuffer and renderbuffers for a given window/drawable. 451 * 452 * \todo This function (and its interface) will need to be updated to support 453 * pbuffers. 454 */ 455static GLboolean 456radeonCreateBuffer( __DRIscreenPrivate *driScrnPriv, 457 __DRIdrawablePrivate *driDrawPriv, 458 const __GLcontextModes *mesaVis, 459 GLboolean isPixmap ) 460{ 461 radeonScreenPtr screen = (radeonScreenPtr) driScrnPriv->private; 462 463 if (isPixmap) { 464 return GL_FALSE; /* not implemented */ 465 } 466 else { 467 const GLboolean swDepth = GL_FALSE; 468 const GLboolean swAlpha = GL_FALSE; 469 const GLboolean swAccum = mesaVis->accumRedBits > 0; 470 const GLboolean swStencil = mesaVis->stencilBits > 0 && 471 mesaVis->depthBits != 24; 472#if 0 473 driDrawPriv->driverPrivate = (void *) 474 _mesa_create_framebuffer( mesaVis, 475 swDepth, 476 swStencil, 477 swAccum, 478 swAlpha ); 479#else 480 struct gl_framebuffer *fb = _mesa_create_framebuffer(mesaVis); 481 482 { 483 driRenderbuffer *frontRb 484 = driNewRenderbuffer(GL_RGBA, screen->cpp, 485 screen->frontOffset, screen->frontPitch); 486 radeonSetSpanFunctions(frontRb, mesaVis); 487 _mesa_add_renderbuffer(fb, BUFFER_FRONT_LEFT, &frontRb->Base); 488 } 489 490 if (mesaVis->doubleBufferMode) { 491 driRenderbuffer *backRb 492 = driNewRenderbuffer(GL_RGBA, screen->cpp, 493 screen->backOffset, screen->backPitch); 494 radeonSetSpanFunctions(backRb, mesaVis); 495 _mesa_add_renderbuffer(fb, BUFFER_BACK_LEFT, &backRb->Base); 496 } 497 498 if (mesaVis->depthBits == 16) { 499 driRenderbuffer *depthRb 500 = driNewRenderbuffer(GL_DEPTH_COMPONENT16, screen->cpp, 501 screen->depthOffset, screen->depthPitch); 502 radeonSetSpanFunctions(depthRb, mesaVis); 503 _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &depthRb->Base); 504 } 505 else if (mesaVis->depthBits == 24) { 506 driRenderbuffer *depthRb 507 = driNewRenderbuffer(GL_DEPTH_COMPONENT24, screen->cpp, 508 screen->depthOffset, screen->depthPitch); 509 radeonSetSpanFunctions(depthRb, mesaVis); 510 _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &depthRb->Base); 511 } 512 513 if (mesaVis->stencilBits > 0 && !swStencil) { 514 driRenderbuffer *stencilRb 515 = driNewRenderbuffer(GL_STENCIL_INDEX8_EXT, screen->cpp, 516 screen->depthOffset, screen->depthPitch); 517 radeonSetSpanFunctions(stencilRb, mesaVis); 518 _mesa_add_renderbuffer(fb, BUFFER_STENCIL, &stencilRb->Base); 519 } 520 521 _mesa_add_soft_renderbuffers(fb, 522 GL_FALSE, /* color */ 523 swDepth, 524 swStencil, 525 swAccum, 526 swAlpha, 527 GL_FALSE /* aux */); 528 driDrawPriv->driverPrivate = (void *) fb; 529#endif 530 return (driDrawPriv->driverPrivate != NULL); 531 } 532} 533 534 535static void 536radeonDestroyBuffer(__DRIdrawablePrivate *driDrawPriv) 537{ 538 _mesa_destroy_framebuffer((GLframebuffer *) (driDrawPriv->driverPrivate)); 539} 540 541static struct __DriverAPIRec radeonAPI = { 542 .InitDriver = radeonInitDriver, 543 .DestroyScreen = radeonDestroyScreen, 544 .CreateContext = radeonCreateContext, 545 .DestroyContext = radeonDestroyContext, 546 .CreateBuffer = radeonCreateBuffer, 547 .DestroyBuffer = radeonDestroyBuffer, 548 .SwapBuffers = radeonSwapBuffers, 549 .MakeCurrent = radeonMakeCurrent, 550 .UnbindContext = radeonUnbindContext, 551 .GetSwapInfo = getSwapInfo, 552 .GetMSC = driGetMSC32, 553 .WaitForMSC = driWaitForMSC32, 554 .WaitForSBC = NULL, 555 .SwapBuffersMSC = NULL 556}; 557 558 559/** 560 * This is the bootstrap function for the driver. libGL supplies all of the 561 * requisite information about the system, and the driver initializes itself. 562 * This routine also fills in the linked list pointed to by \c driver_modes 563 * with the \c __GLcontextModes that the driver can support for windows or 564 * pbuffers. 565 * 566 * \return A pointer to a \c __DRIscreenPrivate on success, or \c NULL on 567 * failure. 568 */ 569PUBLIC 570void * __driCreateNewScreen_20050722( __DRInativeDisplay *dpy, int scrn, __DRIscreen *psc, 571 const __GLcontextModes * modes, 572 const __DRIversion * ddx_version, 573 const __DRIversion * dri_version, 574 const __DRIversion * drm_version, 575 const __DRIframebuffer * frame_buffer, 576 drmAddress pSAREA, int fd, 577 int internal_api_version, 578 __GLcontextModes ** driver_modes ) 579 580{ 581 __DRIscreenPrivate *psp; 582 static const __DRIutilversion2 ddx_expected = { 4, 5, 0, 0 }; 583 static const __DRIversion dri_expected = { 4, 0, 0 }; 584 static const __DRIversion drm_expected = { 1, 3, 0 }; 585 586 if ( ! driCheckDriDdxDrmVersions3( "Radeon", 587 dri_version, & dri_expected, 588 ddx_version, & ddx_expected, 589 drm_version, & drm_expected ) ) { 590 return NULL; 591 } 592 593 psp = __driUtilCreateNewScreen(dpy, scrn, psc, NULL, 594 ddx_version, dri_version, drm_version, 595 frame_buffer, pSAREA, fd, 596 internal_api_version, &radeonAPI); 597 if ( psp != NULL ) { 598 create_context_modes = (PFNGLXCREATECONTEXTMODES) 599 glXGetProcAddress( (const GLubyte *) "__glXCreateContextModes" ); 600 if ( create_context_modes != NULL ) { 601 RADEONDRIPtr dri_priv = (RADEONDRIPtr) psp->pDevPriv; 602 *driver_modes = radeonFillInModes( dri_priv->bpp, 603 (dri_priv->bpp == 16) ? 16 : 24, 604 (dri_priv->bpp == 16) ? 0 : 8, 605 (dri_priv->backOffset != dri_priv->depthOffset) ); 606 } 607 } 608 609 return (void *) psp; 610} 611 612 613/** 614 * Get information about previous buffer swaps. 615 */ 616static int 617getSwapInfo( __DRIdrawablePrivate *dPriv, __DRIswapInfo * sInfo ) 618{ 619 radeonContextPtr rmesa; 620 621 if ( (dPriv == NULL) || (dPriv->driContextPriv == NULL) 622 || (dPriv->driContextPriv->driverPrivate == NULL) 623 || (sInfo == NULL) ) { 624 return -1; 625 } 626 627 rmesa = (radeonContextPtr) dPriv->driContextPriv->driverPrivate; 628 sInfo->swap_count = rmesa->swap_count; 629 sInfo->swap_ust = rmesa->swap_ust; 630 sInfo->swap_missed_count = rmesa->swap_missed_count; 631 632 sInfo->swap_missed_usage = (sInfo->swap_missed_count != 0) 633 ? driCalculateSwapUsage( dPriv, 0, rmesa->swap_missed_ust ) 634 : 0.0; 635 636 return 0; 637} 638