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