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