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