savage_dri.c revision ab47cfaa
1/* 2 * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved. 3 * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved. 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a 6 * copy of this software and associated documentation files (the "Software"), 7 * to deal in the Software without restriction, including without limitation 8 * the rights to use, copy, modify, merge, publish, distribute, sub license, 9 * and/or sell copies of the Software, and to permit persons to whom the 10 * Software is furnished to do so, subject to the following conditions: 11 * 12 * The above copyright notice and this permission notice (including the 13 * next paragraph) shall be included in all copies or substantial portions 14 * of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 19 * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22 * DEALINGS IN THE SOFTWARE. 23 */ 24 25#ifdef HAVE_CONFIG_H 26#include "config.h" 27#endif 28 29#ifdef XF86DRI 30 31#include "xf86.h" 32#include "xf86_OSproc.h" 33#include "xf86Priv.h" 34 35#include "xaalocal.h" 36#include "xaarop.h" 37 38#include "xf86PciInfo.h" 39#include "xf86Pci.h" 40#include "xf86fbman.h" 41 42#include "miline.h" 43 44 45/*#include "savage_vbe.h"*/ 46#include "savage_regs.h" 47#include "savage_driver.h" 48#include "savage_bci.h" 49#include "savage_streams.h" 50#include "savage_common.h" 51 52#define _XF86DRI_SERVER_ 53#include "GL/glxtokens.h" 54#include "sarea.h" 55#include "savage_dri.h" 56#include "savage_sarea.h" 57 58static char SAVAGEKernelDriverName[] = "savage"; 59static char SAVAGEClientDriverName[] = "savage"; 60 61static Bool SAVAGEDRIOpenFullScreen(ScreenPtr pScreen); 62static Bool SAVAGEDRICloseFullScreen(ScreenPtr pScreen); 63/* DRI buffer management 64 */ 65void SAVAGEDRIInitBuffers( WindowPtr pWin, RegionPtr prgn, 66 CARD32 index ); 67void SAVAGEDRIMoveBuffers( WindowPtr pParent, DDXPointRec ptOldOrg, 68 RegionPtr prgnSrc, CARD32 index ); 69 70/* almost the same besides set src/desc to */ 71/* Primary Bitmap Description */ 72 73static void 74SAVAGEDRISetupForScreenToScreenCopy( 75 ScrnInfoPtr pScrn, int xdir, int ydir, 76 int rop, unsigned planemask, int transparency_color); 77 78 79static void 80SAVAGEDRISubsequentScreenToScreenCopy( 81 ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2, 82 int w, int h); 83 84 85/* Initialize the visual configs that are supported by the hardware. 86 * These are combined with the visual configs that the indirect 87 * rendering core supports, and the intersection is exported to the 88 * client. 89 */ 90static Bool SAVAGEInitVisualConfigs( ScreenPtr pScreen ) 91{ 92 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 93 SavagePtr psav = SAVPTR(pScrn); 94 int numConfigs = 0; 95 __GLXvisualConfig *pConfigs = 0; 96 SAVAGEConfigPrivPtr pSAVAGEConfigs = 0; 97 SAVAGEConfigPrivPtr *pSAVAGEConfigPtrs = 0; 98 int i, db, depth, stencil, accum; 99 100 switch ( pScrn->bitsPerPixel ) { 101 case 8: 102 case 24: 103 break; 104 105 case 16: 106 numConfigs = 8; 107 108 pConfigs = (__GLXvisualConfig*)xcalloc( sizeof(__GLXvisualConfig), 109 numConfigs ); 110 if ( !pConfigs ) { 111 return FALSE; 112 } 113 114 pSAVAGEConfigs = (SAVAGEConfigPrivPtr)xcalloc( sizeof(SAVAGEConfigPrivRec), 115 numConfigs ); 116 if ( !pSAVAGEConfigs ) { 117 xfree( pConfigs ); 118 return FALSE; 119 } 120 121 pSAVAGEConfigPtrs = (SAVAGEConfigPrivPtr*)xcalloc( sizeof(SAVAGEConfigPrivPtr), 122 numConfigs ); 123 if ( !pSAVAGEConfigPtrs ) { 124 xfree( pConfigs ); 125 xfree( pSAVAGEConfigs ); 126 return FALSE; 127 } 128 129 for ( i = 0 ; i < numConfigs ; i++ ) { 130 pSAVAGEConfigPtrs[i] = &pSAVAGEConfigs[i]; 131 } 132 133 i = 0; 134 depth = 1; 135 for ( accum = 0 ; accum <= 1 ; accum++ ) { 136 for ( stencil = 0 ; stencil <= 1 ; stencil++ ) { 137 for ( db = 1 ; db >= 0 ; db-- ) { 138 pConfigs[i].vid = -1; 139 pConfigs[i].class = -1; 140 pConfigs[i].rgba = TRUE; 141 pConfigs[i].redSize = 5; 142 pConfigs[i].greenSize = 6; 143 pConfigs[i].blueSize = 5; 144 pConfigs[i].alphaSize = 0; 145 pConfigs[i].redMask = 0x0000F800; 146 pConfigs[i].greenMask = 0x000007E0; 147 pConfigs[i].blueMask = 0x0000001F; 148 pConfigs[i].alphaMask = 0; 149 if ( accum ) { 150 pConfigs[i].accumRedSize = 16; 151 pConfigs[i].accumGreenSize = 16; 152 pConfigs[i].accumBlueSize = 16; 153 pConfigs[i].accumAlphaSize = 0; 154 } else { 155 pConfigs[i].accumRedSize = 0; 156 pConfigs[i].accumGreenSize = 0; 157 pConfigs[i].accumBlueSize = 0; 158 pConfigs[i].accumAlphaSize = 0; 159 } 160 if ( db ) { 161 pConfigs[i].doubleBuffer = TRUE; 162 } else { 163 pConfigs[i].doubleBuffer = FALSE; 164 } 165 pConfigs[i].stereo = FALSE; 166 pConfigs[i].bufferSize = 16; 167 if ( depth ) { 168 pConfigs[i].depthSize = 16; 169 } else { 170 pConfigs[i].depthSize = 0; 171 } 172 if ( stencil ) { 173 pConfigs[i].stencilSize = 8; 174 } else { 175 pConfigs[i].stencilSize = 0; 176 } 177 pConfigs[i].auxBuffers = 0; 178 pConfigs[i].level = 0; 179 if ( accum || stencil ) { 180 pConfigs[i].visualRating = GLX_SLOW_CONFIG; 181 } else { 182 pConfigs[i].visualRating = GLX_NONE; 183 } 184 pConfigs[i].transparentPixel = GLX_NONE; 185 pConfigs[i].transparentRed = 0; 186 pConfigs[i].transparentGreen = 0; 187 pConfigs[i].transparentBlue = 0; 188 pConfigs[i].transparentAlpha = 0; 189 pConfigs[i].transparentIndex = 0; 190 i++; 191 } 192 } 193 } 194 if ( i != numConfigs ) { 195 xf86DrvMsg( pScrn->scrnIndex, X_ERROR, 196 "[drm] Incorrect initialization of visuals\n" ); 197 return FALSE; 198 } 199 break; 200 201 case 32: 202 numConfigs = 8; 203 204 pConfigs = (__GLXvisualConfig*)xcalloc( sizeof(__GLXvisualConfig), 205 numConfigs ); 206 if ( !pConfigs ) { 207 return FALSE; 208 } 209 210 pSAVAGEConfigs = (SAVAGEConfigPrivPtr)xcalloc( sizeof(SAVAGEConfigPrivRec), 211 numConfigs ); 212 if ( !pSAVAGEConfigs ) { 213 xfree( pConfigs ); 214 return FALSE; 215 } 216 217 pSAVAGEConfigPtrs = (SAVAGEConfigPrivPtr*)xcalloc( sizeof(SAVAGEConfigPrivPtr), 218 numConfigs ); 219 if ( !pSAVAGEConfigPtrs ) { 220 xfree( pConfigs ); 221 xfree( pSAVAGEConfigs ); 222 return FALSE; 223 } 224 225 for ( i = 0 ; i < numConfigs ; i++ ) { 226 pSAVAGEConfigPtrs[i] = &pSAVAGEConfigs[i]; 227 } 228 229 i = 0; 230 for ( accum = 0 ; accum <= 1 ; accum++ ) { 231 for ( stencil = 0 ; stencil <= 1 ; stencil++ ) { 232 for ( db = 1 ; db >= 0 ; db-- ) { 233 pConfigs[i].vid = -1; 234 pConfigs[i].class = -1; 235 pConfigs[i].rgba = TRUE; 236 pConfigs[i].redSize = 8; 237 pConfigs[i].greenSize = 8; 238 pConfigs[i].blueSize = 8; 239 pConfigs[i].alphaSize = 0; 240 pConfigs[i].redMask = 0x00FF0000; 241 pConfigs[i].greenMask = 0x0000FF00; 242 pConfigs[i].blueMask = 0x000000FF; 243 pConfigs[i].alphaMask = 0; 244 if ( accum ) { 245 pConfigs[i].accumRedSize = 16; 246 pConfigs[i].accumGreenSize = 16; 247 pConfigs[i].accumBlueSize = 16; 248 pConfigs[i].accumAlphaSize = 0; 249 } else { 250 pConfigs[i].accumRedSize = 0; 251 pConfigs[i].accumGreenSize = 0; 252 pConfigs[i].accumBlueSize = 0; 253 pConfigs[i].accumAlphaSize = 0; 254 } 255 if ( db ) { 256 pConfigs[i].doubleBuffer = TRUE; 257 } else { 258 pConfigs[i].doubleBuffer = FALSE; 259 } 260 pConfigs[i].stereo = FALSE; 261 pConfigs[i].bufferSize = 32; 262 if ( stencil ) { 263 pConfigs[i].depthSize = 24; 264 pConfigs[i].stencilSize = 8; 265 } 266 else { 267 pConfigs[i].depthSize = 24; 268 pConfigs[i].stencilSize = 0; 269 } 270 pConfigs[i].auxBuffers = 0; 271 pConfigs[i].level = 0; 272 if ( accum ) { 273 pConfigs[i].visualRating = GLX_SLOW_VISUAL_EXT; 274 } else { 275 pConfigs[i].visualRating = GLX_NONE; 276 } 277 pConfigs[i].transparentPixel = GLX_NONE; 278 pConfigs[i].transparentRed = 0; 279 pConfigs[i].transparentGreen = 0; 280 pConfigs[i].transparentBlue = 0; 281 pConfigs[i].transparentAlpha = 0; 282 pConfigs[i].transparentIndex = 0; 283 i++; 284 } 285 } 286 } 287 if ( i != numConfigs ) { 288 xf86DrvMsg( pScrn->scrnIndex, X_ERROR, 289 "[drm] Incorrect initialization of visuals\n" ); 290 return FALSE; 291 } 292 break; 293 294 default: 295 /* Unexpected bits/pixels */ 296 break; 297 } 298 299 psav->numVisualConfigs = numConfigs; 300 psav->pVisualConfigs = pConfigs; 301 psav->pVisualConfigsPriv = pSAVAGEConfigs; 302 303 GlxSetVisualConfigs( numConfigs, pConfigs, (void **)pSAVAGEConfigPtrs ); 304 305 return TRUE; 306} 307 308static Bool SAVAGECreateContext( ScreenPtr pScreen, VisualPtr visual, 309 drm_context_t hwContext, void *pVisualConfigPriv, 310 DRIContextType contextStore ) 311{ 312 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 313 SavagePtr psav = SAVPTR(pScrn); 314 315 if(psav->xvmcContext) 316 return FALSE; 317 else 318 { 319 psav->DRIrunning++; 320 } 321 322 return TRUE; 323} 324 325static void SAVAGEDestroyContext( ScreenPtr pScreen, drm_context_t hwContext, 326 DRIContextType contextStore ) 327{ 328 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 329 SavagePtr psav = SAVPTR(pScrn); 330 331 psav->DRIrunning--; 332} 333 334static void SAVAGEWakeupHandler( int screenNum, pointer wakeupData, 335 unsigned long result, pointer pReadmask ) 336{ 337 ScreenPtr pScreen = screenInfo.screens[screenNum]; 338 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 339 SavagePtr psav = SAVPTR(pScrn); 340 341 psav->pDRIInfo->wrap.WakeupHandler = psav->coreWakeupHandler; 342 (*psav->pDRIInfo->wrap.WakeupHandler) (screenNum, wakeupData, result, pReadmask); 343 psav->pDRIInfo->wrap.WakeupHandler = SAVAGEWakeupHandler; 344 psav->LockHeld = 1; 345 if (psav->ShadowStatus) { 346 /* fetch the global shadow counter */ 347#if 0 348 if (psav->ShadowCounter != (psav->ShadowVirtual[1023] & 0xffff)) 349 xf86DrvMsg( pScrn->scrnIndex, X_INFO, 350 "[dri] WakeupHandler: shadowCounter adjusted from %04x to %04lx\n", 351 psav->ShadowCounter, psav->ShadowVirtual[1023] & 0xffff); 352#endif 353 psav->ShadowCounter = psav->ShadowVirtual[1023] & 0xffff; 354 } 355 if (psav->useEXA) 356 exaMarkSync(pScreen); 357 else 358 psav->AccelInfoRec->NeedToSync = TRUE; 359 /* FK: this flag doesn't seem to be used. */ 360} 361 362static void SAVAGEBlockHandler( int screenNum, pointer blockData, 363 pointer pTimeout, pointer pReadmask) 364{ 365 ScreenPtr pScreen = screenInfo.screens[screenNum]; 366 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 367 SavagePtr psav = SAVPTR(pScrn); 368 369 if (psav->ShadowStatus) { 370 /* update the global shadow counter */ 371 CARD32 globalShadowCounter = psav->ShadowVirtual[1023]; 372 globalShadowCounter = (globalShadowCounter & 0xffff0000) | 373 ((CARD32)psav->ShadowCounter & 0x0000ffff); 374 375#if 0 376 if (globalShadowCounter != psav->ShadowVirtual[1023]) 377 xf86DrvMsg( pScrn->scrnIndex, X_INFO, 378 "[dri] BlockHandler: shadowCounter adjusted from %08lx to %08x\n", 379 psav->ShadowVirtual[1023], globalShadowCounter); 380#endif 381 psav->ShadowVirtual[1023] = globalShadowCounter; 382 } 383 psav->LockHeld = 0; 384 psav->pDRIInfo->wrap.BlockHandler = psav->coreBlockHandler; 385 (*psav->pDRIInfo->wrap.BlockHandler) (screenNum, blockData, pTimeout, pReadmask); 386 psav->pDRIInfo->wrap.BlockHandler = SAVAGEBlockHandler; 387} 388 389void SAVAGESelectBuffer( ScrnInfoPtr pScrn, int which ) 390{ 391 SavagePtr psav = SAVPTR(pScrn); 392 SAVAGEDRIServerPrivatePtr pSAVAGEDRIServer = psav->DRIServerInfo; 393 394 psav->WaitIdleEmpty(psav); 395 396 OUTREG(0x48C18,INREG(0x48C18)&(~0x00000008)); 397 398 switch ( which ) { 399 case SAVAGE_BACK: 400 OUTREG( 0x8170, pSAVAGEDRIServer->backOffset ); 401 OUTREG( 0x8174, pSAVAGEDRIServer->backBitmapDesc ); 402 break; 403 case SAVAGE_DEPTH: 404 OUTREG( 0x8170, pSAVAGEDRIServer->depthOffset ); 405 OUTREG( 0x8174, pSAVAGEDRIServer->depthBitmapDesc ); 406 break; 407 default: 408 case SAVAGE_FRONT: 409 OUTREG( 0x8170, pSAVAGEDRIServer->frontOffset ); 410 OUTREG( 0x8174, pSAVAGEDRIServer->frontBitmapDesc ); 411 break; 412 } 413 OUTREG(0x48C18,INREG(0x48C18)|(0x00000008)); 414 psav->WaitIdleEmpty(psav); 415 416} 417 418 419static unsigned int mylog2( unsigned int n ) 420{ 421 unsigned int log2 = 1; 422 423 n--; 424 while ( n > 1 ) n >>= 1, log2++; 425 426 return log2; 427} 428 429static Bool SAVAGEDRIAgpInit(ScreenPtr pScreen) 430{ 431 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 432 SavagePtr psav = SAVPTR(pScrn); 433 SAVAGEDRIServerPrivatePtr pSAVAGEDRIServer = psav->DRIServerInfo; 434 unsigned long mode; 435 unsigned int vendor, device; 436 unsigned int offset; 437 int ret; 438 439 if (psav->agpSize < 2) psav->agpSize = 2; /* at least 2MB for DMA buffers */ 440 441 pSAVAGEDRIServer->agp.size = psav->agpSize * 1024 * 1024; 442 pSAVAGEDRIServer->agp.offset = pSAVAGEDRIServer->agp.size; /* ? */ 443 444 if ( drmAgpAcquire( psav->drmFD ) < 0 ) { 445 xf86DrvMsg( pScreen->myNum, X_ERROR, "[agp] AGP not available\n" ); 446 return FALSE; 447 } 448 449 mode = drmAgpGetMode( psav->drmFD ); /* Default mode */ 450 vendor = drmAgpVendorId( psav->drmFD ); 451 device = drmAgpDeviceId( psav->drmFD ); 452 453 mode &= ~SAVAGE_AGP_MODE_MASK; 454 455 switch ( psav->agpMode ) { 456 case 4: 457 mode |= SAVAGE_AGP_4X_MODE; 458 case 2: 459 mode |= SAVAGE_AGP_2X_MODE; 460 case 1: 461 default: 462 mode |= SAVAGE_AGP_1X_MODE; 463 } 464 465 /* mode |= SAVAGE_AGP_1X_MODE;*/ 466 467 xf86DrvMsg( pScreen->myNum, X_INFO, 468 "[agp] Mode 0x%08lx [AGP 0x%04x/0x%04x; Card 0x%04x/0x%04x]\n", 469 mode, vendor, device, 470 psav->PciInfo->vendor, 471 psav->PciInfo->chipType ); 472 473 if ( drmAgpEnable( psav->drmFD, mode ) < 0 ) { 474 xf86DrvMsg( pScreen->myNum, X_ERROR, "[agp] AGP not enabled\n" ); 475 drmAgpRelease( psav->drmFD ); 476 pSAVAGEDRIServer->agp.handle = 0; /* indicate that AGP init failed */ 477 return FALSE; 478 } 479 480 ret = drmAgpAlloc( psav->drmFD, pSAVAGEDRIServer->agp.size, 481 0, NULL, &pSAVAGEDRIServer->agp.handle ); 482 if ( ret < 0 ) { 483 xf86DrvMsg( pScreen->myNum, X_ERROR, "[agp] Out of memory (%d)\n", ret ); 484 drmAgpRelease( psav->drmFD ); 485 pSAVAGEDRIServer->agp.handle = 0; /* indicate that AGP init failed */ 486 return FALSE; 487 } 488 xf86DrvMsg( pScreen->myNum, X_INFO, 489 "[agp] %d kB allocated with handle 0x%08lx\n", 490 pSAVAGEDRIServer->agp.size/1024, pSAVAGEDRIServer->agp.handle ); 491 492 if ( drmAgpBind( psav->drmFD, pSAVAGEDRIServer->agp.handle, 0 ) < 0 ) { 493 xf86DrvMsg( pScreen->myNum, X_ERROR, "[agp] Could not bind memory\n" ); 494 drmAgpFree( psav->drmFD, pSAVAGEDRIServer->agp.handle ); 495 drmAgpRelease( psav->drmFD ); 496 pSAVAGEDRIServer->agp.handle = 0; /* indicate that AGP init failed */ 497 return FALSE; 498 } 499 500 /* AGP initialization failures above are not fatal, we can fall 501 * back to PCI mode. Failures while adding AGP mappings below are 502 * fatal though. DRI must be disabled in that case. 503 * pSAVAGEDRIServer->agp.handle can be used to distinguish these 504 * two cases. 505 */ 506 507 /* AGP memory layout 508 */ 509 offset = 0; 510 511 if ( psav->AgpDMA ) { 512 if ( psav->CommandDMA ) { 513 pSAVAGEDRIServer->cmdDma.offset = offset; 514 pSAVAGEDRIServer->cmdDma.size = SAVAGE_CMDDMA_SIZE; 515 offset += pSAVAGEDRIServer->cmdDma.size; 516 } else if ( psav->VertexDMA ) { 517 pSAVAGEDRIServer->buffers.offset = 0; 518 pSAVAGEDRIServer->buffers.size = SAVAGE_NUM_BUFFERS * SAVAGE_BUFFER_SIZE; 519 offset += pSAVAGEDRIServer->buffers.size; 520 } 521 } 522 523 pSAVAGEDRIServer->agpTextures.offset = offset; 524 pSAVAGEDRIServer->agpTextures.size = (pSAVAGEDRIServer->agp.size - offset); 525 526 /* DMA buffers 527 */ 528 if ( psav->AgpDMA ) { 529 if ( psav->CommandDMA ) { 530 if ( drmAddMap( psav->drmFD, 531 pSAVAGEDRIServer->cmdDma.offset, 532 pSAVAGEDRIServer->cmdDma.size, 533 DRM_AGP, DRM_RESTRICTED | DRM_KERNEL, 534 &pSAVAGEDRIServer->cmdDma.handle ) < 0 ) { 535 xf86DrvMsg( pScreen->myNum, X_ERROR, 536 "[agp] Could not add command DMA mapping\n" ); 537 return FALSE; 538 } 539 xf86DrvMsg( pScreen->myNum, X_INFO, 540 "[agp] command DMA handle = 0x%08lx\n", 541 pSAVAGEDRIServer->cmdDma.handle ); 542 /* not needed in the server 543 if ( drmMap( psav->drmFD, 544 pSAVAGEDRIServer->cmdDma.handle, 545 pSAVAGEDRIServer->cmdDma.size, 546 &pSAVAGEDRIServer->cmdDma.map ) < 0 ) { 547 xf86DrvMsg( pScreen->myNum, X_ERROR, 548 "[agp] Could not map command DMA\n" ); 549 return FALSE; 550 } 551 xf86DrvMsg( pScreen->myNum, X_INFO, 552 "[agp] command DMA mapped at 0x%08lx\n", 553 (unsigned long)pSAVAGEDRIServer->cmdDma.map ); 554 */ 555 } else if ( psav->VertexDMA ) { 556 if ( drmAddMap( psav->drmFD, 557 pSAVAGEDRIServer->buffers.offset, 558 pSAVAGEDRIServer->buffers.size, 559 DRM_AGP, 0, 560 &pSAVAGEDRIServer->buffers.handle ) < 0 ) { 561 xf86DrvMsg( pScreen->myNum, X_ERROR, 562 "[agp] Could not add DMA buffers mapping\n" ); 563 return FALSE; 564 } 565 xf86DrvMsg( pScreen->myNum, X_INFO, 566 "[agp] DMA buffers handle = 0x%08lx\n", 567 pSAVAGEDRIServer->buffers.handle ); 568 /* not needed in the server 569 if ( drmMap( psav->drmFD, 570 pSAVAGEDRIServer->buffers.handle, 571 pSAVAGEDRIServer->buffers.size, 572 &pSAVAGEDRIServer->buffers.map ) < 0 ) { 573 xf86DrvMsg( pScreen->myNum, X_ERROR, 574 "[agp] Could not map DMA buffers\n" ); 575 return FALSE; 576 } 577 xf86DrvMsg( pScreen->myNum, X_INFO, 578 "[agp] DMA buffers mapped at 0x%08lx\n", 579 (unsigned long)pSAVAGEDRIServer->buffers.map ); 580 */ 581 } 582 } 583 584 /* AGP textures 585 */ 586 if ( drmAddMap( psav->drmFD, 587 pSAVAGEDRIServer->agpTextures.offset, 588 pSAVAGEDRIServer->agpTextures.size, 589 DRM_AGP, 0, 590 &pSAVAGEDRIServer->agpTextures.handle ) < 0 ) { 591 xf86DrvMsg( pScreen->myNum, X_ERROR, 592 "[agp] Could not add agpTextures \n" ); 593 return FALSE; 594 } 595 /* pSAVAGEDRIServer->agp_offset=pSAVAGEDRIServer->agpTexture.size;*/ 596 xf86DrvMsg( pScreen->myNum, X_INFO, 597 "[agp] agpTextures handle = 0x%08lx\n", 598 pSAVAGEDRIServer->agpTextures.handle ); 599 600 /* not needed in the server 601 if ( drmMap( psav->drmFD, 602 pSAVAGEDRIServer->agpTextures.handle, 603 pSAVAGEDRIServer->agpTextures.size, 604 &pSAVAGEDRIServer->agpTextures.map ) < 0 ) { 605 xf86DrvMsg( pScreen->myNum, X_ERROR, 606 "[agp] Could not map agpTextures \n" ); 607 return FALSE; 608 } 609 610 xf86DrvMsg( pScreen->myNum, X_INFO, 611 "[agp] agpTextures mapped at 0x%08lx\n", 612 (unsigned long)pSAVAGEDRIServer->agpTextures.map ); 613 */ 614 615 return TRUE; 616} 617 618static Bool SAVAGEDRIMapInit( ScreenPtr pScreen ) 619{ 620 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 621 SavagePtr psav = SAVPTR(pScrn); 622 SAVAGEDRIServerPrivatePtr pSAVAGEDRIServer = psav->DRIServerInfo; 623 624 pSAVAGEDRIServer->registers.size = SAVAGEIOMAPSIZE; 625 626 if ( drmAddMap( psav->drmFD, 627 (drm_handle_t)psav->MmioBase, 628 pSAVAGEDRIServer->registers.size, 629 DRM_REGISTERS,0, 630 &pSAVAGEDRIServer->registers.handle ) < 0 ) { 631 xf86DrvMsg( pScreen->myNum, X_ERROR, 632 "[drm] Could not add MMIO registers mapping\n" ); 633 return FALSE; 634 } 635 636 pSAVAGEDRIServer->aperture.size = 5 * 0x01000000; 637 638 if ( drmAddMap( psav->drmFD, 639 (drm_handle_t)(psav->ApertureBase), 640 pSAVAGEDRIServer->aperture.size, 641 DRM_FRAME_BUFFER,0, 642 &pSAVAGEDRIServer->aperture.handle ) < 0 ) { 643 xf86DrvMsg( pScreen->myNum, X_ERROR, 644 "[drm] Could not add aperture mapping\n" ); 645 return FALSE; 646 } 647 648 xf86DrvMsg( pScreen->myNum, X_INFO, 649 "[drm] aperture handle = 0x%08lx\n", 650 pSAVAGEDRIServer->aperture.handle ); 651 652 /*if(drmMap(psav->drmFD, 653 pSAVAGEDRIServer->registers.handle, 654 pSAVAGEDRIServer->registers.size, 655 &pSAVAGEDRIServer->registers.map)<0) 656 { 657 xf86DrvMsg( pScreen->myNum, X_ERROR, 658 "[drm] Could not map MMIO registers region to virtual\n" ); 659 return FALSE; 660 661 }*/ 662 663 if ( !psav->AgpDMA && psav->CommandDMA ) { 664 pSAVAGEDRIServer->cmdDma.size = SAVAGE_CMDDMA_SIZE; 665 if ( drmAddMap( psav->drmFD, 0, pSAVAGEDRIServer->cmdDma.size, 666 DRM_CONSISTENT, DRM_RESTRICTED | DRM_LOCKED | 667 DRM_KERNEL | DRM_WRITE_COMBINING, 668 &pSAVAGEDRIServer->cmdDma.handle ) < 0 ) { 669 psav->CommandDMA = FALSE; 670 xf86DrvMsg( pScreen->myNum, X_WARNING, 671 "[drm] Could not add PCI command DMA mapping\n" ); 672 } else 673 xf86DrvMsg( pScreen->myNum, X_INFO, 674 "[drm] PCI command DMA handle = 0x%08lx\n", 675 pSAVAGEDRIServer->cmdDma.handle ); 676 } 677 678 /* Enable ShadowStatus by default for direct rendering. */ 679 if ( !psav->ShadowStatus && !psav->ForceShadowStatus ) { 680 psav->ShadowStatus = TRUE; 681 xf86DrvMsg( pScreen->myNum, X_INFO, 682 "[drm] Enabling ShadowStatus for DRI.\n" ); 683 } 684 685 /* If shadow status is manually or automatically enabled, use a 686 * page in system memory. */ 687 if ( psav->ShadowStatus ) { 688 pSAVAGEDRIServer->status.size = 4096; /* 1 page */ 689 690 if ( drmAddMap( psav->drmFD, 0, pSAVAGEDRIServer->status.size, 691 DRM_CONSISTENT, DRM_READ_ONLY | DRM_LOCKED | DRM_KERNEL, 692 &pSAVAGEDRIServer->status.handle ) < 0 ) { 693 xf86DrvMsg( pScreen->myNum, X_ERROR, 694 "[drm] Could not add status page mapping\n" ); 695 return FALSE; 696 } 697 xf86DrvMsg( pScreen->myNum, X_INFO, 698 "[drm] Status handle = 0x%08lx\n", 699 pSAVAGEDRIServer->status.handle ); 700 701 if ( drmMap( psav->drmFD, 702 pSAVAGEDRIServer->status.handle, 703 pSAVAGEDRIServer->status.size, 704 &pSAVAGEDRIServer->status.map ) < 0 ) { 705 xf86DrvMsg( pScreen->myNum, X_ERROR, 706 "[drm] Could not map status page\n" ); 707 return FALSE; 708 } 709 xf86DrvMsg( pScreen->myNum, X_INFO, 710 "[drm] Status page mapped at 0x%08lx\n", 711 (unsigned long)pSAVAGEDRIServer->status.map ); 712 713 psav->ShadowPhysical = pSAVAGEDRIServer->status.handle; 714 psav->ShadowVirtual = pSAVAGEDRIServer->status.map; 715 } 716 717 return TRUE; 718} 719 720static Bool SAVAGEDRIBuffersInit( ScreenPtr pScreen ) 721{ 722 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 723 SavagePtr psav = SAVPTR(pScrn); 724 SAVAGEDRIServerPrivatePtr pSAVAGEDRIServer = psav->DRIServerInfo; 725 int count; 726 727 if ( !psav->VertexDMA || psav->CommandDMA ) { 728 /* At this point psav->CommandDMA == TRUE means that CommandDMA 729 * allocation was actually successful. */ 730 psav->VertexDMA = FALSE; 731 return TRUE; 732 } 733 734 if ( psav->AgpDMA ) { 735 count = drmAddBufs( psav->drmFD, 736 SAVAGE_NUM_BUFFERS, SAVAGE_BUFFER_SIZE, 737 DRM_AGP_BUFFER, pSAVAGEDRIServer->buffers.offset ); 738 } else { 739 count = drmAddBufs( psav->drmFD, 740 SAVAGE_NUM_BUFFERS, SAVAGE_BUFFER_SIZE, 741 0, 0 ); 742 } 743 if ( count <= 0 ) { 744 xf86DrvMsg( pScrn->scrnIndex, X_INFO, 745 "[drm] failure adding %d %d byte DMA buffers (%d)\n", 746 SAVAGE_NUM_BUFFERS, SAVAGE_BUFFER_SIZE, count ); 747 return FALSE; 748 } 749 xf86DrvMsg( pScreen->myNum, X_INFO, 750 "[drm] Added %d %d byte DMA buffers\n", 751 count, SAVAGE_BUFFER_SIZE ); 752 753 /* not needed in the server 754 pSAVAGEDRIServer->drmBuffers = drmMapBufs( psav->drmFD ); 755 if ( !pSAVAGEDRIServer->drmBuffers ) { 756 xf86DrvMsg( pScreen->myNum, X_ERROR, 757 "[drm] Failed to map DMA buffers list\n" ); 758 return FALSE; 759 } 760 xf86DrvMsg( pScreen->myNum, X_INFO, 761 "[drm] Mapped %d DMA buffers\n", 762 pSAVAGEDRIServer->drmBuffers->count ); 763 */ 764 765 return TRUE; 766} 767 768static Bool SAVAGEDRIKernelInit( ScreenPtr pScreen ) 769{ 770 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 771 SavagePtr psav = SAVPTR(pScrn); 772 SAVAGEDRIServerPrivatePtr pSAVAGEDRIServer = psav->DRIServerInfo; 773 drmSAVAGEInit init; 774 int ret; 775 776 memset( &init, 0, sizeof(drmSAVAGEInit) ); 777 778 init.func = SAVAGE_INIT_BCI; 779 init.sarea_priv_offset = sizeof(XF86DRISAREARec); 780 781 init.cob_size = psav->cobSize/4; /* size in 32-bit entries */ 782 init.bci_threshold_lo = psav->bciThresholdLo; 783 init.bci_threshold_hi = psav->bciThresholdHi; 784 init.dma_type = psav->AgpDMA ? SAVAGE_DMA_AGP : SAVAGE_DMA_PCI; 785 786 init.fb_bpp = pScrn->bitsPerPixel; 787 init.front_offset = pSAVAGEDRIServer->frontOffset; 788 init.front_pitch = pSAVAGEDRIServer->frontPitch; 789 init.back_offset = pSAVAGEDRIServer->backOffset; 790 init.back_pitch = pSAVAGEDRIServer->backPitch; 791 792 init.depth_bpp = pScrn->bitsPerPixel; 793 init.depth_offset = pSAVAGEDRIServer->depthOffset; 794 init.depth_pitch = pSAVAGEDRIServer->depthPitch; 795 796 init.texture_offset = pSAVAGEDRIServer->textureOffset; 797 init.texture_size = pSAVAGEDRIServer->textureSize; 798 799 init.status_offset = pSAVAGEDRIServer->status.handle; 800 init.agp_textures_offset = pSAVAGEDRIServer->agpTextures.handle; 801 802 /* Savage4-based chips with DRM version >= 2.4 support command DMA, 803 * which is preferred because it works with all vertex 804 * formats. Command DMA and vertex DMA don't work at the same 805 * time. */ 806 init.buffers_offset = 0; 807 init.cmd_dma_offset = 0; 808 if ( psav->CommandDMA ) 809 init.cmd_dma_offset = pSAVAGEDRIServer->cmdDma.handle; 810 else if ( psav->VertexDMA ) 811 init.buffers_offset = pSAVAGEDRIServer->buffers.handle; 812 813 ret = drmCommandWrite( psav->drmFD, DRM_SAVAGE_BCI_INIT, &init, sizeof(init) ); 814 if ( ret < 0 ) { 815 xf86DrvMsg( pScrn->scrnIndex, X_ERROR, 816 "[drm] Failed to initialize BCI! (%d)\n", ret ); 817 return FALSE; 818 } 819 820 return TRUE; 821} 822 823Bool SAVAGEDRIScreenInit( ScreenPtr pScreen ) 824{ 825 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 826 SavagePtr psav = SAVPTR(pScrn); 827 DRIInfoPtr pDRIInfo; 828 SAVAGEDRIPtr pSAVAGEDRI; 829 SAVAGEDRIServerPrivatePtr pSAVAGEDRIServer; 830 831 /* Check that the GLX, DRI, and DRM modules have been loaded by testing 832 * for canonical symbols in each module. 833 */ 834 if ( !xf86LoaderCheckSymbol( "GlxSetVisualConfigs" ) ) return FALSE; 835 if ( !xf86LoaderCheckSymbol( "drmAvailable" ) ) return FALSE; 836 if ( !xf86LoaderCheckSymbol( "DRIQueryVersion" ) ) { 837 xf86DrvMsg( pScreen->myNum, X_ERROR, 838 "[dri] SAVAGEDRIScreenInit failed (libdri.a too old)\n" ); 839 return FALSE; 840 } 841 842 /* Check the DRI version */ 843 { 844 int major, minor, patch; 845 DRIQueryVersion( &major, &minor, &patch ); 846 if ( major != DRIINFO_MAJOR_VERSION || minor < DRIINFO_MINOR_VERSION ) { 847 xf86DrvMsg( pScreen->myNum, X_ERROR, 848 "[dri] SAVAGEDRIScreenInit failed because of a version mismatch.\n" 849 "[dri] libdri version = %d.%d.%d but version %d.%d.x is needed.\n" 850 "[dri] Disabling the DRI.\n", 851 major, minor, patch, 852 DRIINFO_MAJOR_VERSION, DRIINFO_MINOR_VERSION ); 853 return FALSE; 854 } 855 } 856 857 xf86DrvMsg( pScreen->myNum, X_INFO, 858 "[drm] bpp: %d depth: %d\n", 859 pScrn->bitsPerPixel, pScrn->depth ); 860 861 if ( (pScrn->bitsPerPixel / 8) != 2 && 862 (pScrn->bitsPerPixel / 8) != 4 ) { 863 xf86DrvMsg( pScreen->myNum, X_ERROR, 864 "[dri] Direct rendering only supported in 16 and 32 bpp modes\n" ); 865 return FALSE; 866 } 867 868 pDRIInfo = DRICreateInfoRec(); 869 if ( !pDRIInfo ) { 870 xf86DrvMsg( pScreen->myNum, X_ERROR, 871 "[dri] DRICreateInfoRec() failed\n" ); 872 return FALSE; 873 } 874 psav->pDRIInfo = pDRIInfo; 875 876 pDRIInfo->drmDriverName = SAVAGEKernelDriverName; 877 pDRIInfo->clientDriverName = SAVAGEClientDriverName; 878 if (xf86LoaderCheckSymbol("DRICreatePCIBusID")) { 879 pDRIInfo->busIdString = DRICreatePCIBusID(psav->PciInfo); 880 } else { 881 pDRIInfo->busIdString = xalloc(64); 882 sprintf(pDRIInfo->busIdString, 883 "PCI:%d:%d:%d", 884 psav->PciInfo->bus, 885 psav->PciInfo->device, 886 psav->PciInfo->func); 887 } 888 pDRIInfo->ddxDriverMajorVersion = SAVAGE_VERSION_MAJOR; 889 pDRIInfo->ddxDriverMinorVersion = SAVAGE_VERSION_MINOR; 890 pDRIInfo->ddxDriverPatchVersion = SAVAGE_PATCHLEVEL; 891 892 pDRIInfo->frameBufferPhysicalAddress = (pointer) psav->FrameBufferBase; 893 pDRIInfo->frameBufferSize = psav->videoRambytes; 894 pDRIInfo->frameBufferStride = pScrn->displayWidth*(pScrn->bitsPerPixel/8); 895 pDRIInfo->ddxDrawableTableEntry = SAVAGE_MAX_DRAWABLES; 896 897 /* override default DRI block and wakeup handler */ 898 psav->coreBlockHandler = pDRIInfo->wrap.BlockHandler; 899 pDRIInfo->wrap.BlockHandler = SAVAGEBlockHandler; 900 psav->coreWakeupHandler = pDRIInfo->wrap.WakeupHandler; 901 pDRIInfo->wrap.WakeupHandler = SAVAGEWakeupHandler; 902 903 pDRIInfo->wrap.ValidateTree = NULL; 904 pDRIInfo->wrap.PostValidateTree = NULL; 905 906 pDRIInfo->createDummyCtx = TRUE; 907 pDRIInfo->createDummyCtxPriv = FALSE; 908 909 if ( SAREA_MAX_DRAWABLES < SAVAGE_MAX_DRAWABLES ) { 910 pDRIInfo->maxDrawableTableEntry = SAREA_MAX_DRAWABLES; 911 } else { 912 pDRIInfo->maxDrawableTableEntry = SAVAGE_MAX_DRAWABLES; 913 } 914 915 /* For now the mapping works by using a fixed size defined 916 * in the SAREA header. 917 */ 918 if ( sizeof(XF86DRISAREARec) + sizeof(SAVAGESAREAPrivRec) > SAREA_MAX ) { 919 xf86DrvMsg( pScrn->scrnIndex, X_ERROR, 920 "[drm] Data does not fit in SAREA\n" ); 921 return FALSE; 922 } 923 924 xf86DrvMsg( pScrn->scrnIndex, X_INFO, 925 "[drm] Sarea %d+%d: %d\n", 926 sizeof(XF86DRISAREARec), sizeof(SAVAGESAREAPrivRec), 927 sizeof(XF86DRISAREARec) + sizeof(SAVAGESAREAPrivRec) ); 928 929 pDRIInfo->SAREASize = SAREA_MAX; 930 931 pSAVAGEDRI = (SAVAGEDRIPtr)xcalloc( sizeof(SAVAGEDRIRec), 1 ); 932 if ( !pSAVAGEDRI ) { 933 DRIDestroyInfoRec( psav->pDRIInfo ); 934 psav->pDRIInfo = 0; 935 xf86DrvMsg( pScrn->scrnIndex, X_ERROR, 936 "[drm] Failed to allocate memory for private record\n" ); 937 return FALSE; 938 } 939 940 pSAVAGEDRIServer = (SAVAGEDRIServerPrivatePtr) 941 xcalloc( sizeof(SAVAGEDRIServerPrivateRec), 1 ); 942 if ( !pSAVAGEDRIServer ) { 943 xfree( pSAVAGEDRI ); 944 DRIDestroyInfoRec( psav->pDRIInfo ); 945 psav->pDRIInfo = 0; 946 xf86DrvMsg( pScrn->scrnIndex, X_ERROR, 947 "[drm] Failed to allocate memory for private record\n" ); 948 return FALSE; 949 } 950 psav->DRIServerInfo = pSAVAGEDRIServer; 951 952 pDRIInfo->devPrivate = pSAVAGEDRI; 953 pDRIInfo->devPrivateSize = sizeof(SAVAGEDRIRec); 954 pDRIInfo->contextSize = sizeof(SAVAGEDRIContextRec); 955 956 pDRIInfo->CreateContext = SAVAGECreateContext; 957 pDRIInfo->DestroyContext = SAVAGEDestroyContext; 958 959 /* FK: SwapContext is not used with KERNEL_SWAP. */ 960 pDRIInfo->SwapContext = NULL; 961 962 pDRIInfo->InitBuffers = SAVAGEDRIInitBuffers; 963 pDRIInfo->MoveBuffers = SAVAGEDRIMoveBuffers; 964 pDRIInfo->OpenFullScreen = SAVAGEDRIOpenFullScreen; 965 pDRIInfo->CloseFullScreen = SAVAGEDRICloseFullScreen; 966 pDRIInfo->bufferRequests = DRI_ALL_WINDOWS; 967 968 if ( !DRIScreenInit( pScreen, pDRIInfo, &psav->drmFD ) ) { 969 xfree( pSAVAGEDRIServer ); 970 psav->DRIServerInfo = 0; 971 xfree( pDRIInfo->devPrivate ); 972 pDRIInfo->devPrivate = 0; 973 DRIDestroyInfoRec( psav->pDRIInfo ); 974 psav->pDRIInfo = 0; 975 xf86DrvMsg( pScreen->myNum, X_ERROR, 976 "[drm] DRIScreenInit failed. Disabling DRI.\n" ); 977 return FALSE; 978 } 979 980 /* Check the SAVAGE DRM version */ 981 { 982 drmVersionPtr version = drmGetVersion(psav->drmFD); 983 if ( version ) { 984 if ( version->version_major != 2 || 985 version->version_minor < 0 ) { 986 /* incompatible drm version */ 987 xf86DrvMsg( pScreen->myNum, X_ERROR, 988 "[dri] SAVAGEDRIScreenInit failed because of a version mismatch.\n" 989 "[dri] savage.ko kernel module version is %d.%d.%d but version 2.0.x is needed.\n" 990 "[dri] Disabling DRI.\n", 991 version->version_major, 992 version->version_minor, 993 version->version_patchlevel ); 994 drmFreeVersion( version ); 995 SAVAGEDRICloseScreen( pScreen ); /* FIXME: ??? */ 996 return FALSE; 997 } 998 if ( psav->CommandDMA && version->version_minor < 4 ) { 999 xf86DrvMsg( pScreen->myNum, X_WARNING, 1000 "[drm] DRM version < 2.4.0 does not support command DMA.\n"); 1001 psav->CommandDMA = FALSE; 1002 } 1003 if ( !psav->VertexDMA && version->version_minor < 4 ) { 1004 xf86DrvMsg( pScreen->myNum, X_ERROR, 1005 "[drm] DRM version < 2.4.0 requires vertex DMA.\n"); 1006 drmFreeVersion( version ); 1007 SAVAGEDRICloseScreen( pScreen ); 1008 return FALSE; 1009 } 1010 drmFreeVersion( version ); 1011 } 1012 } 1013 1014 if ( !psav->IsPCI && !SAVAGEDRIAgpInit( pScreen ) ) { 1015 if (pSAVAGEDRIServer->agp.handle != 0) { 1016 /* AGP initialization succeeded, but adding AGP mappings failed. */ 1017 SAVAGEDRICloseScreen( pScreen ); 1018 return FALSE; 1019 } 1020 /* AGP initialization failed, fall back to PCI mode. */ 1021 psav->IsPCI = TRUE; 1022 psav->AgpDMA = FALSE; 1023 xf86DrvMsg( pScrn->scrnIndex, X_WARNING, 1024 "[agp] AGP failed to initialize -- falling back to PCI mode.\n"); 1025 xf86DrvMsg( pScrn->scrnIndex, X_WARNING, 1026 "[agp] Make sure you have the agpgart kernel module loaded.\n"); 1027 } 1028 1029 if ( !SAVAGEDRIMapInit( pScreen ) ) { 1030 SAVAGEDRICloseScreen( pScreen ); 1031 return FALSE; 1032 } 1033 1034 if ( !SAVAGEDRIBuffersInit( pScreen ) ) { 1035 SAVAGEDRICloseScreen( pScreen ); 1036 return FALSE; 1037 } 1038 1039 if ( !SAVAGEInitVisualConfigs( pScreen ) ) { 1040 SAVAGEDRICloseScreen( pScreen ); 1041 return FALSE; 1042 } 1043 xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[dri] visual configs initialized\n" ); 1044 1045 return TRUE; 1046} 1047 1048 1049Bool SAVAGEDRIFinishScreenInit( ScreenPtr pScreen ) 1050{ 1051 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 1052 SavagePtr psav = SAVPTR(pScrn); 1053 SAVAGEDRIServerPrivatePtr pSAVAGEDRIServer = psav->DRIServerInfo; 1054 SAVAGEDRIPtr pSAVAGEDRI = (SAVAGEDRIPtr)psav->pDRIInfo->devPrivate; 1055 int i; 1056 1057 if ( !psav->pDRIInfo ) 1058 return FALSE; 1059 1060 psav->pDRIInfo->driverSwapMethod = DRI_KERNEL_SWAP; 1061 1062 /* NOTE: DRIFinishScreenInit must be called before *DRIKernelInit 1063 * because *DRIKernelInit requires that the hardware lock is held by 1064 * the X server, and the first time the hardware lock is grabbed is 1065 * in DRIFinishScreenInit. 1066 */ 1067 if ( !DRIFinishScreenInit( pScreen ) ) { 1068 SAVAGEDRICloseScreen( pScreen ); 1069 return FALSE; 1070 } 1071 psav->LockHeld = 1; 1072 1073 if ( !SAVAGEDRIKernelInit( pScreen ) ) { 1074 SAVAGEDRICloseScreen( pScreen ); 1075 return FALSE; 1076 } 1077 1078 pSAVAGEDRI->chipset = psav->Chipset; 1079 pSAVAGEDRI->width = pScrn->virtualX; 1080 pSAVAGEDRI->height = pScrn->virtualY; 1081 pSAVAGEDRI->mem = pScrn->videoRam * 1024; 1082 pSAVAGEDRI->cpp = pScrn->bitsPerPixel / 8; 1083 pSAVAGEDRI->zpp = pSAVAGEDRI->cpp; 1084 1085 pSAVAGEDRI->agpMode = psav->IsPCI ? 0 : psav->agpMode; 1086 1087 pSAVAGEDRI->bufferSize = SAVAGE_BUFFER_SIZE; 1088 1089 pSAVAGEDRI->frontOffset = pSAVAGEDRIServer->frontOffset; 1090 pSAVAGEDRI->frontbufferSize = pSAVAGEDRIServer->frontbufferSize; 1091 1092 pSAVAGEDRI->backOffset = pSAVAGEDRIServer->backOffset; 1093 pSAVAGEDRI->backbufferSize = pSAVAGEDRIServer->backbufferSize; 1094 1095 pSAVAGEDRI->depthOffset = pSAVAGEDRIServer->depthOffset; 1096 pSAVAGEDRI->depthbufferSize = pSAVAGEDRIServer->depthbufferSize; 1097 1098 pSAVAGEDRI->textureOffset = pSAVAGEDRIServer->textureOffset; 1099 1100 i = mylog2( pSAVAGEDRIServer->textureSize / SAVAGE_NR_TEX_REGIONS ); 1101 if ( i < SAVAGE_LOG_MIN_TEX_REGION_SIZE ) 1102 i = SAVAGE_LOG_MIN_TEX_REGION_SIZE; 1103 1104 pSAVAGEDRI->logTextureGranularity = i; 1105 pSAVAGEDRI->textureSize = (pSAVAGEDRIServer->textureSize >> i) << i; /* truncate */ 1106 1107 pSAVAGEDRI->agpTextureHandle = pSAVAGEDRIServer->agpTextures.handle; 1108 1109 i = mylog2( pSAVAGEDRIServer->agpTextures.size / SAVAGE_NR_TEX_REGIONS ); 1110 if ( i < SAVAGE_LOG_MIN_TEX_REGION_SIZE ) 1111 i = SAVAGE_LOG_MIN_TEX_REGION_SIZE; 1112 1113 pSAVAGEDRI->logAgpTextureGranularity = i; 1114 pSAVAGEDRI->agpTextureSize = (pSAVAGEDRIServer->agpTextures.size >> i) << i; /* truncate */ 1115 1116 pSAVAGEDRI->apertureHandle = pSAVAGEDRIServer->aperture.handle; 1117 pSAVAGEDRI->apertureSize = pSAVAGEDRIServer->aperture.size; 1118 { 1119 unsigned int shift = 0; 1120 1121 if(pSAVAGEDRI->width > 1024) 1122 shift = 1; 1123 1124 pSAVAGEDRI->aperturePitch = psav->ulAperturePitch; 1125 } 1126 1127 { 1128 unsigned int value = 0; 1129 1130 OUTREG(0x850C,(INREG(0x850C) | 0x00008000)); /* AGD: I don't think this does anything on 3D/MX/IX */ 1131 /* maybe savage4 too... */ 1132 /* we don't use Y range flag,so comment it */ 1133 /* 1134 if(pSAVAGEDRI->width <= 1024) 1135 value |= (1<<29); 1136 */ 1137 if ((psav->Chipset == S3_SAVAGE_MX) /* 3D/MX/IX seem to set up the tile stride differently */ 1138 || (psav->Chipset == S3_SAVAGE3D)) { 1139 if(pSAVAGEDRI->cpp == 2) 1140 { 1141 value |= ((psav->lDelta / 4) >> 5) << 24; 1142 value |= 2<<30; 1143 } else { 1144 value |= ((psav->lDelta / 4) >> 5) << 24; 1145 value |= 3<<30; 1146 } 1147 1148 OUTREG(TILED_SURFACE_REGISTER_0, value|(pSAVAGEDRI->frontOffset) ); /* front */ 1149 OUTREG(TILED_SURFACE_REGISTER_1, value|(pSAVAGEDRI->backOffset) ); /* back */ 1150 OUTREG(TILED_SURFACE_REGISTER_2, value|(pSAVAGEDRI->depthOffset) ); /* depth */ 1151 } else { 1152 int offset_shift = 5; 1153 if(pSAVAGEDRI->cpp == 2) 1154 { 1155 value |= (((pSAVAGEDRI->width + 0x3F) & 0xFFC0) >> 6) << 20; 1156 value |= 2<<30; 1157 } else { 1158 value |= (((pSAVAGEDRI->width + 0x1F) & 0xFFE0) >> 5) << 20; 1159 value |= 3<<30; 1160 } 1161 if (psav->Chipset == S3_SUPERSAVAGE) /* supersavages have a different shift */ 1162 offset_shift = 6; 1163 OUTREG(TILED_SURFACE_REGISTER_0, value|(pSAVAGEDRI->frontOffset >> offset_shift) ); /* front */ 1164 OUTREG(TILED_SURFACE_REGISTER_1, value|(pSAVAGEDRI->backOffset >> offset_shift) ); /* back */ 1165 OUTREG(TILED_SURFACE_REGISTER_2, value|(pSAVAGEDRI->depthOffset >> offset_shift) ); /* depth */ 1166 } 1167 } 1168 1169 pSAVAGEDRI->statusHandle = pSAVAGEDRIServer->status.handle; 1170 pSAVAGEDRI->statusSize = pSAVAGEDRIServer->status.size; 1171 1172 pSAVAGEDRI->sarea_priv_offset = sizeof(XF86DRISAREARec); 1173 1174 xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]pSAVAGEDRIServer:\n" ); 1175 xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] reserved_map_agpstart:0x%08x\n",pSAVAGEDRIServer->reserved_map_agpstart); 1176 xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] reserved_map_idx:0x%08x\n",pSAVAGEDRIServer->reserved_map_idx); 1177 xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] sarea_priv_offset:0x%08x\n",pSAVAGEDRIServer->sarea_priv_offset); 1178 xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] chipset:0x%08x\n",pSAVAGEDRIServer->chipset); 1179 xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] sgram:0x%08x\n",pSAVAGEDRIServer->sgram); 1180 xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] frontbufferSize:0x%08x\n",pSAVAGEDRIServer->frontbufferSize); 1181 xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] frontOffset:0x%08x\n",pSAVAGEDRIServer->frontOffset); 1182 xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] frontPitch:0x%08x\n",pSAVAGEDRIServer->frontPitch); 1183 xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] backbufferSize:0x%08x\n",pSAVAGEDRIServer->backbufferSize); 1184 xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] backOffset:0x%08x\n",pSAVAGEDRIServer->backOffset); 1185 xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] backPitch:0x%08x\n",pSAVAGEDRIServer->backPitch); 1186 xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] depthbufferSize:0x%08x\n",pSAVAGEDRIServer->depthbufferSize); 1187 xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] depthOffset:0x%08x\n",pSAVAGEDRIServer->depthOffset); 1188 xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] depthPitch:0x%08x\n",pSAVAGEDRIServer->depthPitch); 1189 xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] textureOffset:0x%08x\n",pSAVAGEDRIServer->textureOffset); 1190 xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] textureSize:0x%08x\n",pSAVAGEDRIServer->textureSize); 1191 xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] textureSize:0x%08x\n",pSAVAGEDRIServer->textureSize); 1192 xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] logTextureGranularity:0x%08x\n",pSAVAGEDRIServer->logTextureGranularity); 1193 1194 xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] agp:handle:0x%08lx\n",pSAVAGEDRIServer->agp.handle); 1195 xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] agp:offset:0x%08x\n",pSAVAGEDRIServer->agp.offset); 1196 xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] agp:size:0x%08x\n",pSAVAGEDRIServer->agp.size); 1197 xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] agp:map:0x%08lx\n",(unsigned long)pSAVAGEDRIServer->agp.map); 1198 1199 xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] registers:handle:0x%08lx\n",pSAVAGEDRIServer->registers.handle); 1200 xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] registers:offset:0x%08x\n",pSAVAGEDRIServer->registers.offset); 1201 xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] registers:size:0x%08x\n",pSAVAGEDRIServer->registers.size); 1202 xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] registers:map:0x%08lx\n",(unsigned long)pSAVAGEDRIServer->registers.map); 1203 1204 xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] status:handle:0x%08lx\n",pSAVAGEDRIServer->status.handle); 1205 xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] status:offset:0x%08x\n",pSAVAGEDRIServer->status.offset); 1206 xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] status:size:0x%08x\n",pSAVAGEDRIServer->status.size); 1207 xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] status:map:0x%08lx\n",(unsigned long)pSAVAGEDRIServer->status.map); 1208 1209 xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] agpTextures:handle:0x%08lx\n",pSAVAGEDRIServer->agpTextures.handle); 1210 xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] agpTextures:offset:0x%08x\n",pSAVAGEDRIServer->agpTextures.offset); 1211 xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] agpTextures:size:0x%08x\n",pSAVAGEDRIServer->agpTextures.size); 1212 xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] apgTextures:map:0x%08lx\n",(unsigned long)pSAVAGEDRIServer->agpTextures.map); 1213 1214 xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] logAgpTextureGranularity:0x%08x\n",pSAVAGEDRIServer->logAgpTextureGranularity); 1215 1216 xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] cmdDma:handle:0x%08lx\n",pSAVAGEDRIServer->cmdDma.handle); 1217 xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] cmdDma:offset:0x%08x\n",pSAVAGEDRIServer->cmdDma.offset); 1218 xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] cmdDma:size:0x%08x\n",pSAVAGEDRIServer->cmdDma.size); 1219 xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] cmdDma:map:0x%08lx\n",(unsigned long)pSAVAGEDRIServer->cmdDma.map); 1220 1221 xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]pSAVAGEDRI:\n" ); 1222 xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] chipset:0x%08x\n",pSAVAGEDRI->chipset ); 1223 xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] width:0x%08x\n",pSAVAGEDRI->width ); 1224 xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] height:0x%08x\n",pSAVAGEDRI->height ); 1225 xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] mem:0x%08x\n",pSAVAGEDRI->mem ); 1226 xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] cpp:%d\n",pSAVAGEDRI->cpp ); 1227 xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] zpp:%d\n",pSAVAGEDRI->zpp ); 1228 1229 xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] agpMode:%d\n",pSAVAGEDRI->agpMode ); 1230 1231 xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] bufferSize:%u\n",pSAVAGEDRI->bufferSize ); 1232 1233 xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] frontbufferSize:0x%08x\n",pSAVAGEDRI->frontbufferSize); 1234 xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] frontOffset:0x%08x\n",pSAVAGEDRI->frontOffset ); 1235 1236 xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] backbufferSize:0x%08x\n",pSAVAGEDRI->backbufferSize); 1237 xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] backOffset:0x%08x\n",pSAVAGEDRI->backOffset ); 1238 1239 xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] depthbufferSize:0x%08x\n",pSAVAGEDRI->depthbufferSize); 1240 xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] depthOffset:0x%08x\n",pSAVAGEDRI->depthOffset ); 1241 1242 xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] textureOffset:0x%08x\n",pSAVAGEDRI->textureOffset ); 1243 xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] textureSize:0x%08x\n",pSAVAGEDRI->textureSize ); 1244 xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] logTextureGranularity:0x%08x\n",pSAVAGEDRI->logTextureGranularity ); 1245 1246 xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] agpTextureHandle:0x%08lx\n",pSAVAGEDRI->agpTextureHandle ); 1247 xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] agpTextureSize:0x%08x\n",pSAVAGEDRI->agpTextureSize ); 1248 xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] logAgpTextureGranularity:0x%08x\n",pSAVAGEDRI->logAgpTextureGranularity ); 1249 1250 xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] apertureHandle:0x%08lx\n",pSAVAGEDRI->apertureHandle); 1251 xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] apertureSize:0x%08x\n",pSAVAGEDRI->apertureSize); 1252 xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] aperturePitch:0x%08x\n",pSAVAGEDRI->aperturePitch); 1253 1254 xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] statusHandle:0x%08lx\n",pSAVAGEDRI->statusHandle); 1255 xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] statusSize:0x%08x\n",pSAVAGEDRI->statusSize); 1256 1257 xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] sarea_priv_offset:0x%08x\n",pSAVAGEDRI->sarea_priv_offset); 1258 1259 return TRUE; 1260} 1261 1262 1263void SAVAGEDRICloseScreen( ScreenPtr pScreen ) 1264{ 1265 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 1266 SavagePtr psav = SAVPTR(pScrn); 1267 SAVAGEDRIServerPrivatePtr pSAVAGEDRIServer = psav->DRIServerInfo; 1268 1269 if ( pSAVAGEDRIServer->status.map ) { 1270 drmUnmap( pSAVAGEDRIServer->status.map, pSAVAGEDRIServer->status.size ); 1271 pSAVAGEDRIServer->status.map = NULL; 1272 } 1273 1274 if ( pSAVAGEDRIServer->registers.map ) { 1275 drmUnmap( pSAVAGEDRIServer->registers.map, pSAVAGEDRIServer->registers.size ); 1276 pSAVAGEDRIServer->registers.map = NULL; 1277 } 1278 1279 if ( pSAVAGEDRIServer->aperture.map ) { 1280 drmUnmap( pSAVAGEDRIServer->aperture.map, pSAVAGEDRIServer->aperture.size ); 1281 pSAVAGEDRIServer->aperture.map = NULL; 1282 } 1283 1284 if ( pSAVAGEDRIServer->agpTextures.map ) { 1285 drmUnmap( pSAVAGEDRIServer->agpTextures.map, 1286 pSAVAGEDRIServer->agpTextures.size ); 1287 pSAVAGEDRIServer->agpTextures.map = NULL; 1288 } 1289 1290 if (pSAVAGEDRIServer->status.handle) 1291 drmRmMap(psav->drmFD,pSAVAGEDRIServer->status.handle); 1292 1293 if (pSAVAGEDRIServer->registers.handle) 1294 drmRmMap(psav->drmFD,pSAVAGEDRIServer->registers.handle); 1295 1296 if (pSAVAGEDRIServer->aperture.handle) 1297 drmRmMap(psav->drmFD,pSAVAGEDRIServer->registers.handle); 1298 1299 if (pSAVAGEDRIServer->agpTextures.handle) 1300 drmRmMap(psav->drmFD,pSAVAGEDRIServer->agpTextures.handle); 1301 1302 if (pSAVAGEDRIServer->cmdDma.handle) 1303 drmRmMap(psav->drmFD,pSAVAGEDRIServer->cmdDma.handle); 1304 1305 if ( pSAVAGEDRIServer->buffers.map ) { 1306 drmUnmap( pSAVAGEDRIServer->buffers.map, pSAVAGEDRIServer->buffers.size ); 1307 pSAVAGEDRIServer->buffers.map = NULL; 1308 } 1309 1310 if ( pSAVAGEDRIServer->agp.handle ) { 1311 drmAgpUnbind( psav->drmFD, pSAVAGEDRIServer->agp.handle ); 1312 drmAgpFree( psav->drmFD, pSAVAGEDRIServer->agp.handle ); 1313 pSAVAGEDRIServer->agp.handle = 0; 1314 drmAgpRelease( psav->drmFD ); 1315 } 1316 1317 DRICloseScreen( pScreen ); 1318 1319 /* Don't use shadow status any more. If this happens due to failed 1320 * DRI initialization then SavageScreenInit will do the real 1321 * cleanup and restore ShadowStatus to sane settings. */ 1322 psav->ShadowVirtual = NULL; 1323 psav->ShadowPhysical = 0; 1324 1325 if(psav->reserved) 1326 xf86FreeOffscreenLinear(psav->reserved); 1327 1328 if ( psav->pDRIInfo ) { 1329 if ( psav->pDRIInfo->devPrivate ) { 1330 xfree( psav->pDRIInfo->devPrivate ); 1331 psav->pDRIInfo->devPrivate = 0; 1332 } 1333 DRIDestroyInfoRec( psav->pDRIInfo ); 1334 psav->pDRIInfo = 0; 1335 } 1336 if ( psav->DRIServerInfo ) { 1337 xfree( psav->DRIServerInfo ); 1338 psav->DRIServerInfo = 0; 1339 } 1340 if ( psav->pVisualConfigs ) { 1341 xfree( psav->pVisualConfigs ); 1342 } 1343 if ( psav->pVisualConfigsPriv ) { 1344 xfree( psav->pVisualConfigsPriv ); 1345 } 1346} 1347 1348void 1349SAVAGEDRIInitBuffers(WindowPtr pWin, RegionPtr prgn, CARD32 index) 1350{ 1351 ScreenPtr pScreen = pWin->drawable.pScreen; 1352 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 1353 SavagePtr psav = SAVPTR(pScrn); 1354 BoxPtr pbox = REGION_RECTS(prgn); 1355 int nbox = REGION_NUM_RECTS(prgn); 1356 drmSAVAGECmdHeader cmd[2]; 1357 drmSAVAGECmdbuf cmdBuf; 1358 int ret; 1359 1360 if (!psav->LockHeld) { 1361 xf86DrvMsg( pScrn->scrnIndex, X_WARNING, 1362 "Not holding the lock in InitBuffers.\n"); 1363 return; 1364 } 1365 1366 cmd[0].clear0.cmd = SAVAGE_CMD_CLEAR; 1367 cmd[0].clear0.flags = SAVAGE_BACK|SAVAGE_DEPTH; 1368 cmd[1].clear1.mask = 0xffffffff; 1369 cmd[1].clear1.value = 0; 1370 1371 cmdBuf.cmd_addr = cmd; 1372 cmdBuf.size = 2; 1373 cmdBuf.dma_idx = 0; 1374 cmdBuf.discard = 0; 1375 cmdBuf.vb_addr = NULL; 1376 cmdBuf.vb_size = 0; 1377 cmdBuf.vb_stride = 0; 1378 cmdBuf.box_addr = (drm_clip_rect_t*)pbox; 1379 cmdBuf.nbox = nbox; 1380 1381 ret = drmCommandWrite(psav->drmFD, DRM_SAVAGE_BCI_CMDBUF, 1382 &cmdBuf, sizeof(cmdBuf)); 1383 if (ret < 0) { 1384 xf86DrvMsg( pScrn->scrnIndex, X_ERROR, 1385 "SAVAGEDRIInitBuffers: drmCommandWrite returned %d.\n", 1386 ret); 1387 } 1388} 1389 1390/* 1391 This routine is a modified form of XAADoBitBlt with the calls to 1392 ScreenToScreenBitBlt built in. My routine has the prgnSrc as source 1393 instead of destination. My origin is upside down so the ydir cases 1394 are reversed. 1395*/ 1396 1397void 1398SAVAGEDRIMoveBuffers(WindowPtr pParent, DDXPointRec ptOldOrg, 1399 RegionPtr prgnSrc, CARD32 index) 1400{ 1401 ScreenPtr pScreen = pParent->drawable.pScreen; 1402 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 1403 SavagePtr psav = SAVPTR(pScrn); 1404 int nbox; 1405 BoxPtr pbox, pboxTmp, pboxNext, pboxBase, pboxNew1, pboxNew2; 1406 DDXPointPtr pptTmp, pptNew1, pptNew2; 1407 int xdir, ydir; 1408 int dx, dy; 1409 DDXPointPtr pptSrc; 1410 int screenwidth = pScrn->virtualX; 1411 int screenheight = pScrn->virtualY; 1412 BCI_GET_PTR; 1413 1414 if (!psav->LockHeld) { 1415 xf86DrvMsg( pScrn->scrnIndex, X_INFO, "Not holding lock in MoveBuffers\n"); 1416 } 1417 1418 pbox = REGION_RECTS(prgnSrc); 1419 nbox = REGION_NUM_RECTS(prgnSrc); 1420 pboxNew1 = 0; 1421 pptNew1 = 0; 1422 pboxNew2 = 0; 1423 pboxNew2 = 0; 1424 pptSrc = &ptOldOrg; 1425 1426 dx = pParent->drawable.x - ptOldOrg.x; 1427 dy = pParent->drawable.y - ptOldOrg.y; 1428 1429 /* If the copy will overlap in Y, reverse the order */ 1430 if (dy>0) { 1431 ydir = -1; 1432 1433 if (nbox>1) { 1434 /* Keep ordering in each band, reverse order of bands */ 1435 pboxNew1 = (BoxPtr)ALLOCATE_LOCAL(sizeof(BoxRec)*nbox); 1436 if (!pboxNew1) return; 1437 pptNew1 = (DDXPointPtr)ALLOCATE_LOCAL(sizeof(DDXPointRec)*nbox); 1438 if (!pptNew1) { 1439 DEALLOCATE_LOCAL(pboxNew1); 1440 return; 1441 } 1442 pboxBase = pboxNext = pbox+nbox-1; 1443 while (pboxBase >= pbox) { 1444 while ((pboxNext >= pbox) && (pboxBase->y1 == pboxNext->y1)) 1445 pboxNext--; 1446 pboxTmp = pboxNext+1; 1447 pptTmp = pptSrc + (pboxTmp - pbox); 1448 while (pboxTmp <= pboxBase) { 1449 *pboxNew1++ = *pboxTmp++; 1450 *pptNew1++ = *pptTmp++; 1451 } 1452 pboxBase = pboxNext; 1453 } 1454 pboxNew1 -= nbox; 1455 pbox = pboxNew1; 1456 pptNew1 -= nbox; 1457 pptSrc = pptNew1; 1458 } 1459 } else { 1460 /* No changes required */ 1461 ydir = 1; 1462 } 1463 1464 /* If the regions will overlap in X, reverse the order */ 1465 if (dx>0) { 1466 xdir = -1; 1467 1468 if (nbox > 1) { 1469 /*reverse orderof rects in each band */ 1470 pboxNew2 = (BoxPtr)ALLOCATE_LOCAL(sizeof(BoxRec)*nbox); 1471 pptNew2 = (DDXPointPtr)ALLOCATE_LOCAL(sizeof(DDXPointRec)*nbox); 1472 if (!pboxNew2 || !pptNew2) { 1473 if (pptNew2) DEALLOCATE_LOCAL(pptNew2); 1474 if (pboxNew2) DEALLOCATE_LOCAL(pboxNew2); 1475 if (pboxNew1) { 1476 DEALLOCATE_LOCAL(pptNew1); 1477 DEALLOCATE_LOCAL(pboxNew1); 1478 } 1479 return; 1480 } 1481 pboxBase = pboxNext = pbox; 1482 while (pboxBase < pbox+nbox) { 1483 while ((pboxNext < pbox+nbox) && 1484 (pboxNext->y1 == pboxBase->y1)) 1485 pboxNext++; 1486 pboxTmp = pboxNext; 1487 pptTmp = pptSrc + (pboxTmp - pbox); 1488 while (pboxTmp != pboxBase) { 1489 *pboxNew2++ = *--pboxTmp; 1490 *pptNew2++ = *--pptTmp; 1491 } 1492 pboxBase = pboxNext; 1493 } 1494 pboxNew2 -= nbox; 1495 pbox = pboxNew2; 1496 pptNew2 -= nbox; 1497 pptSrc = pptNew2; 1498 } 1499 } else { 1500 /* No changes are needed */ 1501 xdir = 1; 1502 } 1503 1504 BCI_SEND(0xc0030000); /* wait for 2D+3D idle */ 1505 SAVAGEDRISetupForScreenToScreenCopy(pScrn, xdir, ydir, GXcopy, -1, -1); 1506 for ( ; nbox-- ; pbox++) 1507 { 1508 int x1 = pbox->x1; 1509 int y1 = pbox->y1; 1510 int destx = x1 + dx; 1511 int desty = y1 + dy; 1512 int w = pbox->x2 - x1 + 1; 1513 int h = pbox->y2 - y1 + 1; 1514 1515 if ( destx < 0 ) x1 -= destx, w += destx, destx = 0; 1516 if ( desty < 0 ) y1 -= desty, h += desty, desty = 0; 1517 if ( destx + w > screenwidth ) w = screenwidth - destx; 1518 if ( desty + h > screenheight ) h = screenheight - desty; 1519 if ( w <= 0 ) continue; 1520 if ( h <= 0 ) continue; 1521 1522 SAVAGESelectBuffer(pScrn, SAVAGE_BACK); 1523 SAVAGEDRISubsequentScreenToScreenCopy(pScrn, x1, y1, 1524 destx,desty, w, h); 1525 SAVAGESelectBuffer(pScrn, SAVAGE_DEPTH); 1526 SAVAGEDRISubsequentScreenToScreenCopy(pScrn, x1,y1, 1527 destx,desty, w, h); 1528 } 1529 SAVAGESelectBuffer(pScrn, SAVAGE_FRONT); 1530 1531 if (pboxNew2) { 1532 DEALLOCATE_LOCAL(pptNew2); 1533 DEALLOCATE_LOCAL(pboxNew2); 1534 } 1535 if (pboxNew1) { 1536 DEALLOCATE_LOCAL(pptNew1); 1537 DEALLOCATE_LOCAL(pboxNew1); 1538 } 1539 1540 BCI_SEND(0xc0020000); /* wait for 2D idle */ 1541 if (psav->useEXA) 1542 exaMarkSync(pScreen); 1543 else 1544 psav->AccelInfoRec->NeedToSync = TRUE; 1545} 1546 1547static void 1548SAVAGEDRISetupForScreenToScreenCopy( 1549 ScrnInfoPtr pScrn, 1550 int xdir, 1551 int ydir, 1552 int rop, 1553 unsigned planemask, 1554 int transparency_color) 1555{ 1556 SavagePtr psav = SAVPTR(pScrn); 1557 int cmd =0; 1558 1559 cmd = BCI_CMD_RECT | BCI_CMD_DEST_PBD | BCI_CMD_SRC_PBD_COLOR; 1560 BCI_CMD_SET_ROP( cmd, XAAGetCopyROP(rop) ); 1561 if (transparency_color != -1) 1562 cmd |= BCI_CMD_SEND_COLOR | BCI_CMD_SRC_TRANSPARENT; 1563 1564 if (xdir == 1 ) cmd |= BCI_CMD_RECT_XP; 1565 if (ydir == 1 ) cmd |= BCI_CMD_RECT_YP; 1566 1567 psav->SavedBciCmd = cmd; 1568 psav->SavedBgColor = transparency_color; 1569 1570} 1571 1572static void 1573SAVAGEDRISubsequentScreenToScreenCopy( 1574 ScrnInfoPtr pScrn, 1575 int x1, 1576 int y1, 1577 int x2, 1578 int y2, 1579 int w, 1580 int h) 1581{ 1582 SavagePtr psav = SAVPTR(pScrn); 1583 BCI_GET_PTR; 1584 1585 if (!w || !h) return; 1586 if (!(psav->SavedBciCmd & BCI_CMD_RECT_XP)) { 1587 w --; 1588 x1 += w; 1589 x2 += w; 1590 w ++; 1591 } 1592 if (!(psav->SavedBciCmd & BCI_CMD_RECT_YP)) { 1593 h --; 1594 y1 += h; 1595 y2 += h; 1596 h ++; 1597 } 1598 1599 psav->WaitQueue(psav,6); 1600 BCI_SEND(psav->SavedBciCmd); 1601 if (psav->SavedBgColor != -1) 1602 BCI_SEND(psav->SavedBgColor); 1603 BCI_SEND(BCI_X_Y(x1, y1)); 1604 BCI_SEND(BCI_X_Y(x2, y2)); 1605 BCI_SEND(BCI_W_H(w, h)); 1606 1607} 1608 1609/* 1610 * the FullScreen DRI code is dead, this is just left in place to show how 1611 * to set up pageflipping. 1612 */ 1613static Bool 1614SAVAGEDRIOpenFullScreen(ScreenPtr pScreen) 1615{ 1616 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 1617 vgaHWPtr hwp = VGAHWPTR(pScrn); 1618 SavagePtr psav = SAVPTR(pScrn); 1619 unsigned int vgaCRIndex = hwp->IOBase + 4; 1620 unsigned int vgaCRReg = hwp->IOBase + 5; 1621 SAVAGEDRIPtr pSAVAGEDRI = (SAVAGEDRIPtr)psav->pDRIInfo->devPrivate; 1622 unsigned int TileStride; 1623 unsigned int WidthinTiles; 1624 unsigned int depth; 1625 1626 OUTREG(0x48C18, INREG(0x48C18) & 0xFFFFFFF7); 1627 /*VGAOUT8(vgaCRIndex,0x66); 1628 VGAOUT8(vgaCRReg, VGAIN8(vgaCRReg)|0x10);*/ 1629 VGAOUT8(vgaCRIndex,0x69); 1630 VGAOUT8(vgaCRReg, 0x80); 1631 1632 depth = pScrn->bitsPerPixel; 1633 1634 if(depth == 16) 1635 { 1636 WidthinTiles = (pSAVAGEDRI->width+63)>>6; 1637 TileStride = (pSAVAGEDRI->width+63)&(~63); 1638 1639 } 1640 else 1641 { 1642 WidthinTiles = (pSAVAGEDRI->width+31)>>5; 1643 TileStride = (pSAVAGEDRI->width+31)&(~31); 1644 1645 } 1646 1647 1648 /* set primary stream stride */ 1649 { 1650 unsigned int value; 1651 1652 /*value = 0x80000000|(WidthinTiles<<24)|(TileStride*depth/8);*/ 1653 value = 0x80000000|(WidthinTiles<<24); 1654 if(depth == 32) 1655 value |= 0x40000000; 1656 1657 OUTREG(PRI_STREAM_STRIDE, value); 1658 1659 } 1660 1661 /* set global bitmap descriptor */ 1662 { 1663 unsigned int value; 1664 value = 0x10000000| 1665 0x00000009| 1666 0x01000000| 1667 (depth<<16) | TileStride; 1668 1669 OUTREG(0x816C,value); 1670 1671 } 1672 1673 OUTREG(0x48C18, INREG(0x48C18) | 0x8); 1674 1675 return TRUE; 1676} 1677 1678static Bool 1679SAVAGEDRICloseFullScreen(ScreenPtr pScreen) 1680{ 1681 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 1682 SavagePtr psav = SAVPTR(pScrn); 1683 BCI_GET_PTR; 1684 1685 BCI_SEND(0xC0FF0000); 1686 psav->WaitIdleEmpty(psav); 1687 OUTREG(0x48C18, INREG(0x48C18) & 0xFFFFFFF7); 1688 /* set primary stream stride */ 1689 { 1690 /* MM81C0 and 81C4 are used to control primary stream. */ 1691 OUTREG32(PRI_STREAM_FBUF_ADDR0,0x00000000); 1692 OUTREG32(PRI_STREAM_FBUF_ADDR1,0x00000000); 1693 1694 /* FIFO control */ 1695 OUTREG32(0X81EC,0Xffffffff); 1696 1697 if (!psav->bTiled) { 1698 OUTREG32(PRI_STREAM_STRIDE, 1699 (((psav->lDelta * 2) << 16) & 0x3FFFE000) | 1700 (psav->lDelta & 0x00001fff)); 1701 } 1702 else if (pScrn->bitsPerPixel == 16) { 1703 /* Scanline-length-in-bytes/128-bytes-per-tile * 256 Qwords/tile */ 1704 OUTREG32(PRI_STREAM_STRIDE, 1705 (((psav->lDelta * 2) << 16) & 0x3FFFE000) 1706 | 0x80000000 | (psav->lDelta & 0x00001fff)); 1707 } 1708 else if (pScrn->bitsPerPixel == 32) { 1709 OUTREG32(PRI_STREAM_STRIDE, 1710 (((psav->lDelta * 2) << 16) & 0x3FFFE000) 1711 | 0xC0000000 | (psav->lDelta & 0x00001fff)); 1712 } 1713 1714 1715 } 1716 1717 /* set global bitmap descriptor */ 1718 { 1719 OUTREG32(S3_GLB_BD_LOW,psav->GlobalBD.bd2.LoPart ); 1720 OUTREG32(S3_GLB_BD_HIGH,psav->GlobalBD.bd2.HiPart | BCI_ENABLE | S3_LITTLE_ENDIAN | S3_BD64); 1721 1722 } 1723 1724 OUTREG(0x48C18, INREG(0x48C18) | 0x8); 1725 return TRUE; 1726} 1727 1728#endif 1729