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