1/* 2 * The accel file for the Savage driver. 3 * 4 * Created 20/03/97 by Sebastien Marineau for 3.3.6 5 * Modified 17-Nov-2000 by Tim Roberts for 4.0.1 6 * Modified Feb-2004 by Alex Deucher - integrating DRI support 7 * Modified 2005-2006 by Alex Deucher - adding exa support 8 * Revision: 9 * 10 */ 11 12#ifdef HAVE_CONFIG_H 13#include "config.h" 14#endif 15 16#include <X11/Xarch.h> 17#include "savage_driver.h" 18#ifdef HAVE_XAA_H 19#include "xaalocal.h" 20#include "xaarop.h" 21 22#include "miline.h" 23 24#include "savage_bci.h" 25 26extern int gSavageEntityIndex; 27 28static void SavageSetupForScreenToScreenCopy( 29 ScrnInfoPtr pScrn, 30 int xdir, 31 int ydir, 32 int rop, 33 unsigned planemask, 34 int transparency_color); 35 36static void SavageSubsequentScreenToScreenCopy( 37 ScrnInfoPtr pScrn, 38 int x1, 39 int y1, 40 int x2, 41 int y2, 42 int w, 43 int h); 44 45static void SavageSetupForSolidFill( 46 ScrnInfoPtr pScrn, 47 int color, 48 int rop, 49 unsigned int planemask); 50 51static void SavageSubsequentSolidFillRect( 52 ScrnInfoPtr pScrn, 53 int x, 54 int y, 55 int w, 56 int h); 57 58static void SavageSubsequentSolidBresenhamLine( 59 ScrnInfoPtr pScrn, 60 int x1, 61 int y1, 62 int e1, 63 int e2, 64 int err, 65 int length, 66 int octant); 67 68static void SavageSetupForCPUToScreenColorExpandFill( 69 ScrnInfoPtr pScrn, 70 int fg, 71 int bg, 72 int rop, 73 unsigned int planemask); 74 75static void SavageSubsequentScanlineCPUToScreenColorExpandFill( 76 ScrnInfoPtr pScrn, 77 int x, 78 int y, 79 int w, 80 int h, 81 int skipleft); 82 83static void SavageSubsequentColorExpandScanline( 84 ScrnInfoPtr pScrn, 85 int buffer_no); 86 87static void SavageSetupForMono8x8PatternFill( 88 ScrnInfoPtr pScrn, 89 int patternx, 90 int patterny, 91 int fg, 92 int bg, 93 int rop, 94 unsigned int planemask); 95 96static void SavageSubsequentMono8x8PatternFillRect( 97 ScrnInfoPtr pScrn, 98 int pattern0, 99 int pattern1, 100 int x, 101 int y, 102 int w, 103 int h); 104 105static void SavageSetClippingRectangle( 106 ScrnInfoPtr pScrn, 107 int x1, 108 int y1, 109 int x2, 110 int y2); 111 112static void SavageDisableClipping( ScrnInfoPtr ); 113 114/* from savage_image.c: */ 115 116void SavageSetupForImageWrite( 117 ScrnInfoPtr pScrn, 118 int rop, 119 unsigned int planemask, 120 int transparency_color, 121 int bpp, 122 int depth); 123 124void SavageSubsequentImageWriteRect( 125 ScrnInfoPtr pScrn, 126 int x, 127 int y, 128 int w, 129 int h, 130 int skipleft); 131 132void SavageWriteBitmapCPUToScreenColorExpand ( 133 ScrnInfoPtr pScrn, 134 int x, int y, int w, int h, 135 unsigned char * src, 136 int srcwidth, 137 int skipleft, 138 int fg, int bg, 139 int rop, 140 unsigned int planemask 141); 142 143static 144void SavageRestoreAccelState(ScrnInfoPtr pScrn) 145{ 146 SavagePtr psav = SAVPTR(pScrn); 147 148 psav->WaitIdleEmpty(psav); 149 150 return; 151} 152#endif 153 154Bool 155SavageXAAInit(ScreenPtr pScreen) 156{ 157#ifdef HAVE_XAA_H 158 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 159 SavagePtr psav = SAVPTR(pScrn); 160 XAAInfoRecPtr xaaptr; 161 BoxRec AvailFBArea; 162 int tmp; 163 164 /* Set-up our GE command primitive */ 165 166 if (pScrn->depth == 8) { 167 psav->PlaneMask = 0xFF; 168 } 169 else if (pScrn->depth == 15) { 170 psav->PlaneMask = 0x7FFF; 171 } 172 else if (pScrn->depth == 16) { 173 psav->PlaneMask = 0xFFFF; 174 } 175 else if (pScrn->depth == 24) { 176 psav->PlaneMask = 0xFFFFFF; 177 } 178 179 /* General acceleration flags */ 180 181 if (!(xaaptr = psav->AccelInfoRec = XAACreateInfoRec())) { 182 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 183 "Failed to allocate XAAInfoRec.\n"); 184 return FALSE; 185 } 186 187 xaaptr->Flags = 0 188 | PIXMAP_CACHE 189 | OFFSCREEN_PIXMAPS 190 | LINEAR_FRAMEBUFFER 191 ; 192 193 194 if(xf86IsEntityShared(pScrn->entityList[0])) 195 { 196 DevUnion* pPriv; 197 SavageEntPtr pEnt; 198 pPriv = xf86GetEntityPrivate(pScrn->entityList[0], 199 gSavageEntityIndex); 200 pEnt = pPriv->ptr; 201 202 /*if there are more than one devices sharing this entity, we 203 have to assign this call back, otherwise the XAA will be 204 disabled */ 205 if(pEnt->HasSecondary) 206 xaaptr->RestoreAccelState = SavageRestoreAccelState; 207 } 208 209 /* Clipping */ 210 211 xaaptr->SetClippingRectangle = SavageSetClippingRectangle; 212 xaaptr->DisableClipping = SavageDisableClipping; 213 xaaptr->ClippingFlags = 0 214#if 0 215 | HARDWARE_CLIP_SOLID_FILL 216 | HARDWARE_CLIP_SOLID_LINE 217 | HARDWARE_CLIP_DASHED_LINE 218#endif 219 | HARDWARE_CLIP_SCREEN_TO_SCREEN_COPY 220 | HARDWARE_CLIP_MONO_8x8_FILL 221 | HARDWARE_CLIP_COLOR_8x8_FILL 222 ; 223 224 xaaptr->Sync = SavageAccelSync; 225 226 /* ScreenToScreen copies */ 227 228#if 1 229 230 xaaptr->SetupForScreenToScreenCopy = SavageSetupForScreenToScreenCopy; 231 xaaptr->SubsequentScreenToScreenCopy = SavageSubsequentScreenToScreenCopy; 232 xaaptr->ScreenToScreenCopyFlags = 0 233 | NO_TRANSPARENCY 234 | NO_PLANEMASK 235 | ROP_NEEDS_SOURCE; 236 237#endif 238 239 240 /* Solid filled rectangles */ 241 242#if 1 243 xaaptr->SetupForSolidFill = SavageSetupForSolidFill; 244 xaaptr->SubsequentSolidFillRect = SavageSubsequentSolidFillRect; 245 xaaptr->SolidFillFlags = NO_PLANEMASK | ROP_NEEDS_SOURCE; 246#endif 247 248 /* Mono 8x8 pattern fills */ 249 250#if 1 251 xaaptr->SetupForMono8x8PatternFill = SavageSetupForMono8x8PatternFill; 252 xaaptr->SubsequentMono8x8PatternFillRect 253 = SavageSubsequentMono8x8PatternFillRect; 254 xaaptr->Mono8x8PatternFillFlags = 0 255 | HARDWARE_PATTERN_PROGRAMMED_BITS 256 | HARDWARE_PATTERN_SCREEN_ORIGIN 257 | BIT_ORDER_IN_BYTE_MSBFIRST 258 | ROP_NEEDS_SOURCE 259 ; 260 if( psav->Chipset == S3_SAVAGE4 ) 261 xaaptr->Mono8x8PatternFillFlags |= NO_TRANSPARENCY; 262#endif 263 264 /* Solid lines */ 265 266#if 1 267 xaaptr->SolidLineFlags = NO_PLANEMASK; 268 xaaptr->SetupForSolidLine = SavageSetupForSolidFill; 269 xaaptr->SubsequentSolidBresenhamLine = SavageSubsequentSolidBresenhamLine; 270#if 0 271 xaaptr->SubsequentSolidFillTrap = SavageSubsequentSolidFillTrap; 272#endif 273 274 xaaptr->SolidBresenhamLineErrorTermBits = 13; 275#endif 276 277 /* ImageWrite */ 278 279 xaaptr->ImageWriteFlags = 0 280 | NO_PLANEMASK 281 | CPU_TRANSFER_PAD_DWORD 282 | SCANLINE_PAD_DWORD 283 | BIT_ORDER_IN_BYTE_MSBFIRST 284 | LEFT_EDGE_CLIPPING 285 ; 286 xaaptr->SetupForImageWrite = SavageSetupForImageWrite; 287 xaaptr->SubsequentImageWriteRect = SavageSubsequentImageWriteRect; 288 xaaptr->NumScanlineImageWriteBuffers = 1; 289 xaaptr->ImageWriteBase = psav->BciMem; 290 xaaptr->ImageWriteRange = 120 * 1024; 291 292 293 /* CPU to Screen color expansion */ 294 295 xaaptr->ScanlineCPUToScreenColorExpandFillFlags = 0 296 | NO_PLANEMASK 297 | CPU_TRANSFER_PAD_DWORD 298 | SCANLINE_PAD_DWORD 299 | BIT_ORDER_IN_BYTE_MSBFIRST 300 | LEFT_EDGE_CLIPPING 301 | ROP_NEEDS_SOURCE 302 ; 303 304 xaaptr->SetupForScanlineCPUToScreenColorExpandFill = 305 SavageSetupForCPUToScreenColorExpandFill; 306 xaaptr->SubsequentScanlineCPUToScreenColorExpandFill = 307 SavageSubsequentScanlineCPUToScreenColorExpandFill; 308 xaaptr->SubsequentColorExpandScanline = 309 SavageSubsequentColorExpandScanline; 310 xaaptr->ColorExpandBase = psav->BciMem; 311 xaaptr->ScanlineColorExpandBuffers = &xaaptr->ColorExpandBase; 312 xaaptr->NumScanlineColorExpandBuffers = 1; 313 314 /* Set up screen parameters. */ 315 316 psav->Bpp = pScrn->bitsPerPixel / 8; 317 psav->Bpl = pScrn->displayWidth * psav->Bpp; 318 psav->ScissB = (psav->CursorKByte << 10) / psav->Bpl; 319 if (psav->ScissB > 2047) 320 psav->ScissB = 2047; 321 322 /* 323 * Finally, we set up the video memory space available to the pixmap 324 * cache. In this case, all memory from the end of the virtual screen 325 * to the end of the command overflow buffer can be used. If you haven't 326 * enabled the PIXMAP_CACHE flag, then these lines can be omitted. 327 */ 328 329 AvailFBArea.x1 = 0; 330 AvailFBArea.y1 = 0; 331 AvailFBArea.x2 = psav->cxMemory; 332 AvailFBArea.y2 = psav->cyMemory; 333 xf86InitFBManager(pScreen, &AvailFBArea); 334 /* 335 * because the alignment requirement,the on-screen need more memory 336 * than (0,0,virtualX,virtualY), but xf86InitFBManager only subtract 337 * (pScrn->virtualX * pScrn->virtualY from (0,0,cxMemory,cyMemory),so 338 * here,we should reserver some memory for on-screen 339 */ 340 tmp = ((psav->cxMemory * pScrn->virtualY - pScrn->virtualX * pScrn->virtualY) 341 + psav->cxMemory -1) / (psav->cxMemory); 342 if (tmp) 343 xf86AllocateOffscreenArea(pScreen, psav->cxMemory,tmp, 0, NULL, NULL, NULL); 344 345 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 346 "Using %d lines for offscreen memory.\n", 347 psav->cyMemory - pScrn->virtualY ); 348 349 350 return XAAInit(pScreen, xaaptr); 351#else 352 return FALSE; 353#endif 354} 355 356/* The sync function for the GE */ 357void 358SavageAccelSync(ScrnInfoPtr pScrn) 359{ 360 SavagePtr psav = SAVPTR(pScrn); 361 psav->WaitIdleEmpty(psav); 362} 363 364#ifdef HAVE_XAA_H 365/* 366 * The XAA ROP helper routines all assume that a solid color is a 367 * "pattern". The Savage chips, however, apply a non-stippled solid 368 * color as "source". Thus, we use a slightly customized version. 369 */ 370 371static int 372SavageHelpPatternROP(ScrnInfoPtr pScrn, int *fg, int *bg, unsigned int pm, int *rop) 373{ 374 XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn); 375 int ret = 0; 376 377 pm &= infoRec->FullPlanemask; 378 379 if(pm == infoRec->FullPlanemask) { 380 if(!NO_SRC_ROP(*rop)) 381 ret |= ROP_PAT; 382 *rop = XAAGetCopyROP(*rop); 383 } else { 384 switch(*rop) { 385 case GXnoop: 386 break; 387 case GXset: 388 case GXclear: 389 case GXinvert: 390 ret |= ROP_PAT; 391 *fg = pm; 392 if(*bg != -1) 393 *bg = pm; 394 break; 395 default: 396 ret |= ROP_PAT | ROP_SRC; 397 break; 398 } 399 *rop = XAAGetCopyROP_PM(*rop); 400 } 401 402 return ret; 403} 404 405 406static int 407SavageHelpSolidROP(ScrnInfoPtr pScrn, int *fg, unsigned int pm, int *rop) 408{ 409 XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn); 410 int ret = 0; 411 412 pm &= infoRec->FullPlanemask; 413 414 if(pm == infoRec->FullPlanemask) { 415 if(!NO_SRC_ROP(*rop)) 416 ret |= ROP_PAT; 417 *rop = XAAGetCopyROP(*rop); 418 } else { 419 switch(*rop) { 420 case GXnoop: 421 break; 422 case GXset: 423 case GXclear: 424 case GXinvert: 425 ret |= ROP_PAT; 426 *fg = pm; 427 break; 428 default: 429 ret |= ROP_PAT | ROP_SRC; 430 break; 431 } 432 *rop = XAAGetCopyROP_PM(*rop); 433 } 434 435 return ret; 436} 437 438 439 440/* These are the ScreenToScreen bitblt functions. We support all ROPs, all 441 * directions, and a planemask by adjusting the ROP and using the mono pattern 442 * registers. 443 * 444 * (That's a lie; we don't really support planemask.) 445 */ 446 447static void 448SavageSetupForScreenToScreenCopy( 449 ScrnInfoPtr pScrn, 450 int xdir, 451 int ydir, 452 int rop, 453 unsigned planemask, 454 int transparency_color) 455{ 456 SavagePtr psav = SAVPTR(pScrn); 457 int cmd; 458 459 cmd = BCI_CMD_RECT | BCI_CMD_DEST_PBD_NEW | BCI_CMD_SRC_SBD_COLOR_NEW; 460 461 BCI_CMD_SET_ROP( cmd, XAAGetCopyROP(rop) ); 462 if (transparency_color != -1) 463 cmd |= BCI_CMD_SEND_COLOR | BCI_CMD_SRC_TRANSPARENT; 464 465 if (xdir == 1 ) cmd |= BCI_CMD_RECT_XP; 466 if (ydir == 1 ) cmd |= BCI_CMD_RECT_YP; 467 468 psav->SavedBciCmd = cmd; 469 psav->SavedBgColor = transparency_color; 470} 471 472static void 473SavageSubsequentScreenToScreenCopy( 474 ScrnInfoPtr pScrn, 475 int x1, 476 int y1, 477 int x2, 478 int y2, 479 int w, 480 int h) 481{ 482 SavagePtr psav = SAVPTR(pScrn); 483 484 BCI_GET_PTR; 485 486 if (!w || !h) return; 487 488 if (!(psav->SavedBciCmd & BCI_CMD_RECT_XP)) { 489 w --; 490 x1 += w; 491 x2 += w; 492 w ++; 493 } 494 if (!(psav->SavedBciCmd & BCI_CMD_RECT_YP)) { 495 h --; 496 y1 += h; 497 y2 += h; 498 h ++; 499 } 500 501 psav->WaitQueue(psav,9); 502 503 504 BCI_SEND(psav->SavedBciCmd); 505 506 BCI_SEND(psav->GlobalBD.bd2.LoPart); 507 BCI_SEND(psav->GlobalBD.bd2.HiPart); 508 509 BCI_SEND(psav->GlobalBD.bd2.LoPart); 510 BCI_SEND(psav->GlobalBD.bd2.HiPart); 511 512 if (psav->SavedBgColor != 0xffffffff) 513 BCI_SEND(psav->SavedBgColor); 514 BCI_SEND(BCI_X_Y(x1, y1)); 515 BCI_SEND(BCI_X_Y(x2, y2)); 516 BCI_SEND(BCI_W_H(w, h)); 517} 518 519 520/* 521 * SetupForSolidFill is also called to set up for lines. 522 */ 523 524static void 525SavageSetupForSolidFill( 526 ScrnInfoPtr pScrn, 527 int color, 528 int rop, 529 unsigned int planemask) 530{ 531 SavagePtr psav = SAVPTR(pScrn); 532 XAAInfoRecPtr xaaptr = GET_XAAINFORECPTR_FROM_SCRNINFOPTR( pScrn ); 533 int cmd; 534 int mix; 535 536 cmd = BCI_CMD_RECT 537 | BCI_CMD_RECT_XP | BCI_CMD_RECT_YP 538 | BCI_CMD_DEST_PBD_NEW | BCI_CMD_SRC_SOLID; 539 540 /* Don't send a color if we don't have to. */ 541 542 if( rop == GXcopy ) 543 { 544 if( color == 0 ) 545 rop = GXclear; 546 else if( (unsigned int)color == xaaptr->FullPlanemask ) 547 rop = GXset; 548 } 549 550 mix = SavageHelpSolidROP( pScrn, &color, planemask, &rop ); 551 552 if( mix & ROP_PAT ) 553 cmd |= BCI_CMD_SEND_COLOR; 554 555 BCI_CMD_SET_ROP( cmd, rop ); 556 557 psav->SavedBciCmd = cmd; 558 psav->SavedFgColor = color; 559} 560 561 562static void 563SavageSubsequentSolidFillRect( 564 ScrnInfoPtr pScrn, 565 int x, 566 int y, 567 int w, 568 int h) 569{ 570 SavagePtr psav = SAVPTR(pScrn); 571 BCI_GET_PTR; 572 573 if( !w || !h ) 574 return; 575 576 psav->WaitQueue(psav,7); 577 578 BCI_SEND(psav->SavedBciCmd); 579 580 BCI_SEND(psav->GlobalBD.bd2.LoPart); 581 BCI_SEND(psav->GlobalBD.bd2.HiPart); 582 583 if( psav->SavedBciCmd & BCI_CMD_SEND_COLOR ) 584 BCI_SEND(psav->SavedFgColor); 585 BCI_SEND(BCI_X_Y(x, y)); 586 BCI_SEND(BCI_W_H(w, h)); 587} 588 589static void 590SavageSetupForCPUToScreenColorExpandFill( 591 ScrnInfoPtr pScrn, 592 int fg, 593 int bg, 594 int rop, 595 unsigned int planemask) 596{ 597 SavagePtr psav = SAVPTR(pScrn); 598 int cmd; 599 int mix; 600 601 cmd = BCI_CMD_RECT | BCI_CMD_RECT_XP | BCI_CMD_RECT_YP 602 | BCI_CMD_CLIP_LR 603 | BCI_CMD_DEST_PBD_NEW | BCI_CMD_SRC_MONO; 604 605 mix = SavageHelpPatternROP( pScrn, &fg, &bg, planemask, &rop ); 606 607 if( mix & ROP_PAT ) 608 cmd |= BCI_CMD_SEND_COLOR; 609 610 BCI_CMD_SET_ROP( cmd, rop ); 611 612 if (bg != -1) 613 cmd |= BCI_CMD_SEND_COLOR; 614 else 615 cmd |= BCI_CMD_SRC_TRANSPARENT; 616 617 psav->SavedBciCmd = cmd; 618 psav->SavedFgColor = fg; 619 psav->SavedBgColor = bg; 620} 621 622 623static void 624SavageSubsequentScanlineCPUToScreenColorExpandFill( 625 ScrnInfoPtr pScrn, 626 int x, 627 int y, 628 int w, 629 int h, 630 int skipleft) 631{ 632 SavagePtr psav = SAVPTR(pScrn); 633 BCI_GET_PTR; 634 635 /* XAA will be sending bitmap data next. */ 636 /* We should probably wait for empty/idle here. */ 637 638 psav->WaitQueue(psav,22); 639 640 BCI_SEND(psav->SavedBciCmd); 641 642 BCI_SEND(psav->GlobalBD.bd2.LoPart); 643 BCI_SEND(psav->GlobalBD.bd2.HiPart); 644 645 BCI_SEND(BCI_CLIP_LR(x+skipleft, x+w-1)); 646 w = (w + 31) & ~31; 647 if( psav->SavedBciCmd & BCI_CMD_SEND_COLOR ) 648 BCI_SEND(psav->SavedFgColor); 649 if( psav->SavedBgColor != 0xffffffff ) 650 BCI_SEND(psav->SavedBgColor); 651 BCI_SEND(BCI_X_Y(x, y)); 652 BCI_SEND(BCI_W_H(w, 1)); 653 654 psav->Rect.x = x; 655 psav->Rect.y = y + 1; 656 psav->Rect.width = w; 657 psav->Rect.height = h - 1; 658} 659 660static void 661SavageSubsequentColorExpandScanline( 662 ScrnInfoPtr pScrn, 663 int buffer_no) 664{ 665 /* This gets call after each scanline's image data has been sent. */ 666 SavagePtr psav = SAVPTR(pScrn); 667 xRectangle xr = psav->Rect; 668 BCI_GET_PTR; 669 670 if( xr.height ) 671 { 672 psav->WaitQueue(psav,20); 673 BCI_SEND(BCI_X_Y( xr.x, xr.y)); 674 BCI_SEND(BCI_W_H( xr.width, 1 )); 675 psav->Rect.height--; 676 psav->Rect.y++; 677 } 678} 679 680 681/* 682 * The meaning of the two pattern parameters to Setup & Subsequent for 683 * Mono8x8Patterns varies depending on the flag bits. We specify 684 * HW_PROGRAMMED_BITS, which means our hardware can handle 8x8 patterns 685 * without caching in the frame buffer. Thus, Setup gets the pattern bits. 686 * There is no way with BCI to rotate an 8x8 pattern, so we do NOT specify 687 * HW_PROGRAMMED_ORIGIN. XAA will rotate it for us and pass the rotated 688 * pattern to both Setup and Subsequent. If we DID specify PROGRAMMED_ORIGIN, 689 * then Setup would get the unrotated pattern, and Subsequent gets the 690 * origin values. 691 */ 692 693static void 694SavageSetupForMono8x8PatternFill( 695 ScrnInfoPtr pScrn, 696 int patternx, 697 int patterny, 698 int fg, 699 int bg, 700 int rop, 701 unsigned int planemask) 702{ 703 SavagePtr psav = SAVPTR(pScrn); 704 int cmd; 705 int mix; 706 707 mix = XAAHelpPatternROP( pScrn, &fg, &bg, planemask, &rop ); 708 709 cmd = BCI_CMD_RECT | BCI_CMD_RECT_XP | BCI_CMD_RECT_YP 710 | BCI_CMD_DEST_PBD_NEW; 711 712 if( mix & ROP_PAT ) 713 cmd |= BCI_CMD_SEND_COLOR | BCI_CMD_PAT_MONO; 714 715 if (bg == -1) 716 cmd |= BCI_CMD_PAT_TRANSPARENT; 717 718 BCI_CMD_SET_ROP(cmd, rop); 719 720 psav->SavedBciCmd = cmd; 721 psav->SavedFgColor = fg; 722 psav->SavedBgColor = bg; 723} 724 725 726static void 727SavageSubsequentMono8x8PatternFillRect( 728 ScrnInfoPtr pScrn, 729 int pattern0, 730 int pattern1, 731 int x, 732 int y, 733 int w, 734 int h) 735{ 736 SavagePtr psav = SAVPTR(pScrn); 737 BCI_GET_PTR; 738 739 /* 740 * I didn't think it was my job to do trivial rejection, but 741 * miFillGeneralPolygon definitely generates null spans, and XAA 742 * just passes them through. 743 */ 744 745 if( !w || !h ) 746 return; 747 748 psav->WaitQueue(psav,9); 749 BCI_SEND(psav->SavedBciCmd); 750 751 BCI_SEND(psav->GlobalBD.bd2.LoPart); 752 BCI_SEND(psav->GlobalBD.bd2.HiPart); 753 754 if( psav->SavedBciCmd & BCI_CMD_SEND_COLOR ) 755 BCI_SEND(psav->SavedFgColor); 756 if( psav->SavedBgColor != 0xffffffff ) 757 BCI_SEND(psav->SavedBgColor); 758 BCI_SEND(BCI_X_Y(x, y)); 759 BCI_SEND(BCI_W_H(w, h)); 760 if( psav->SavedBciCmd & BCI_CMD_PAT_MONO ) 761 { 762 BCI_SEND(pattern0); 763 BCI_SEND(pattern1); 764 } 765} 766 767 768#if 0 769static void 770SavageSetupForColor8x8PatternFill( 771 ScrnInfoPtr pScrn, 772 int patternx, 773 int patterny, 774 int rop, 775 unsigned planemask, 776 int trans_col) 777{ 778 SavagePtr psav = SAVPTR(pScrn); 779 780 int cmd; 781 unsigned int bd; 782 int pat_offset; 783 784 /* ViRGEs and Savages do not support transparent color patterns. */ 785 /* We set the NO_TRANSPARENCY bit, so we should never receive one. */ 786 787 pat_offset = (int) (patternx * psav->Bpp + patterny * psav->Bpl); 788 789 cmd = BCI_CMD_RECT | BCI_CMD_RECT_XP | BCI_CMD_RECT_YP 790 | BCI_CMD_DEST_GBD | BCI_CMD_PAT_PBD_COLOR_NEW; 791 792 (void) XAAHelpSolidROP( pScrn, &trans_col, planemask, &rop ); 793 794 BCI_CMD_SET_ROP(cmd, rop); 795 bd = BCI_BD_BW_DISABLE; 796 BCI_BD_SET_BPP(bd, pScrn->bitsPerPixel); 797 BCI_BD_SET_STRIDE(bd, 8); 798 799 psav->SavedBciCmd = cmd; 800 psav->SavedSbdOffset = pat_offset; 801 psav->SavedSbd = bd; 802 psav->SavedBgColor = trans_col; 803} 804 805 806static void 807SavageSubsequentColor8x8PatternFillRect( 808 ScrnInfoPtr pScrn, 809 int patternx, 810 int patterny, 811 int x, 812 int y, 813 int w, 814 int h) 815{ 816 SavagePtr psav = SAVPTR(pScrn); 817 BCI_GET_PTR; 818 819 if( !w || !h ) 820 return; 821 822 psav->WaitQueue(psav,6); 823 BCI_SEND(psav->SavedBciCmd); 824 BCI_SEND(psav->SavedSbdOffset); 825 BCI_SEND(psav->SavedSbd); 826 BCI_SEND(BCI_X_Y(patternx,patterny)); 827 BCI_SEND(BCI_X_Y(x, y)); 828 BCI_SEND(BCI_W_H(w, h)); 829} 830#endif 831 832static void 833SavageSubsequentSolidBresenhamLine( 834 ScrnInfoPtr pScrn, 835 int x1, 836 int y1, 837 int e1, 838 int e2, 839 int err, 840 int length, 841 int octant) 842{ 843 SavagePtr psav = SAVPTR(pScrn); 844 BCI_GET_PTR; 845 int cmd; 846 847 cmd = (psav->SavedBciCmd & 0x00ffffff); 848 cmd |= BCI_CMD_LINE_LAST_PIXEL; 849 850#ifdef DEBUG_EXTRA 851 ErrorF("BresenhamLine, (%4d,%4d), len %4d, oct %d, err %4d,%4d,%4d clr %08x\n", 852 x1, y1, length, octant, e1, e2, err, psav->SavedFgColor ); 853#endif 854 855 psav->WaitQueue(psav, 7 ); 856 BCI_SEND(cmd); 857 858 BCI_SEND(psav->GlobalBD.bd2.LoPart); 859 BCI_SEND(psav->GlobalBD.bd2.HiPart); 860 861 if( cmd & BCI_CMD_SEND_COLOR ) 862 BCI_SEND( psav->SavedFgColor ); 863 BCI_SEND(BCI_LINE_X_Y(x1, y1)); 864 BCI_SEND(BCI_LINE_STEPS(e2-e1, e2)); 865 BCI_SEND(BCI_LINE_MISC(length, 866 (octant & YMAJOR), 867 !(octant & XDECREASING), 868 !(octant & YDECREASING), 869 e2+err)); 870} 871 872static void 873SavageSetClippingRectangle( 874 ScrnInfoPtr pScrn, 875 int x1, 876 int y1, 877 int x2, 878 int y2) 879{ 880 SavagePtr psav = SAVPTR(pScrn); 881 BCI_GET_PTR; 882 int cmd; 883 884#ifdef DEBUG_EXTRA 885 ErrorF("ClipRect, (%4d,%4d)-(%4d,%4d) \n", x1, y1, x2, y2 ); 886#endif 887 888 cmd = BCI_CMD_NOP | BCI_CMD_CLIP_NEW; 889 psav->WaitQueue(psav,3); 890 BCI_SEND(cmd); 891 BCI_SEND(BCI_CLIP_TL(y1, x1)); 892 BCI_SEND(BCI_CLIP_BR(y2, x2)); 893 psav->SavedBciCmd |= BCI_CMD_CLIP_CURRENT; 894} 895 896 897static void SavageDisableClipping( ScrnInfoPtr pScrn ) 898{ 899 SavagePtr psav = SAVPTR(pScrn); 900#ifdef DEBUG_EXTRA 901 ErrorF("Kill ClipRect\n"); 902#endif 903 psav->SavedBciCmd &= ~BCI_CMD_CLIP_CURRENT; 904} 905 906void 907SavageWriteBitmapCPUToScreenColorExpand ( 908 ScrnInfoPtr pScrn, 909 int x, int y, int w, int h, 910 unsigned char * src, 911 int srcwidth, 912 int skipleft, 913 int fg, int bg, 914 int rop, 915 unsigned int planemask 916) 917{ 918 SavagePtr psav = SAVPTR(pScrn); 919 BCI_GET_PTR; 920 int i, j, count, reset; 921 unsigned int cmd; 922 CARD32 * srcp; 923 924/* We aren't using planemask at all here... */ 925 926 if( !srcwidth ) 927 return; 928 929 cmd = BCI_CMD_RECT | BCI_CMD_RECT_XP | BCI_CMD_RECT_YP 930 | BCI_CMD_SEND_COLOR | BCI_CMD_CLIP_LR 931 | BCI_CMD_DEST_PBD_NEW | BCI_CMD_SRC_MONO; 932 cmd |= XAAGetCopyROP(rop) << 16; 933 934 if( bg == -1 ) 935 cmd |= BCI_CMD_SRC_TRANSPARENT; 936 937 BCI_SEND(cmd); 938 939 BCI_SEND(psav->GlobalBD.bd2.LoPart); 940 BCI_SEND(psav->GlobalBD.bd2.HiPart); 941 942 BCI_SEND(BCI_CLIP_LR(x+skipleft, x+w-1)); 943 BCI_SEND(fg); 944 if( bg != -1 ) 945 BCI_SEND(bg); 946 947 /* Bitmaps come in in units of DWORDS, LSBFirst. This is exactly */ 948 /* reversed of what we expect. */ 949 950 count = (w + 31) / 32; 951/* src += ((srcx & ~31) / 8); */ 952 953 /* The BCI region is 128k bytes. A screen-sized mono bitmap can */ 954 /* exceed that. */ 955 956 reset = 65536 / count; 957 958 for (j = 0; j < h; j ++) { 959 BCI_SEND(BCI_X_Y(x, y+j)); 960 BCI_SEND(BCI_W_H(w, 1)); 961 srcp = (CARD32 *) src; 962 for (i = count; i > 0; srcp ++, i --) { 963 /* We have to invert the bits in each byte. */ 964 CARD32 u = *srcp; 965 u = ((u & 0x0f0f0f0f) << 4) | ((u & 0xf0f0f0f0) >> 4); 966 u = ((u & 0x33333333) << 2) | ((u & 0xcccccccc) >> 2); 967 u = ((u & 0x55555555) << 1) | ((u & 0xaaaaaaaa) >> 1); 968 BCI_SEND(u); 969 } 970 src += srcwidth; 971 if( !--reset ) { 972 BCI_RESET; 973 reset = 65536 / count; 974 } 975 } 976} 977 978void 979SavageSetupForImageWrite( 980 ScrnInfoPtr pScrn, 981 int rop, 982 unsigned planemask, 983 int transparency_color, 984 int bpp, 985 int depth) 986{ 987 SavagePtr psav = SAVPTR(pScrn); 988 int cmd; 989 990 cmd = BCI_CMD_RECT | BCI_CMD_RECT_XP | BCI_CMD_RECT_YP 991 | BCI_CMD_CLIP_LR 992 | BCI_CMD_DEST_PBD_NEW | BCI_CMD_SRC_COLOR; 993 994 cmd |= XAAGetCopyROP(rop) << 16; 995 996 if( transparency_color != -1 ) 997 cmd |= BCI_CMD_SRC_TRANSPARENT; 998 999 psav->SavedBciCmd = cmd; 1000 psav->SavedBgColor = transparency_color; 1001} 1002 1003 1004void SavageSubsequentImageWriteRect 1005( 1006 ScrnInfoPtr pScrn, 1007 int x, 1008 int y, 1009 int w, 1010 int h, 1011 int skipleft) 1012{ 1013 SavagePtr psav = SAVPTR(pScrn); 1014 BCI_GET_PTR; 1015 1016 psav->WaitQueue( psav, 8 ); 1017 BCI_SEND(psav->SavedBciCmd); 1018 1019 BCI_SEND(psav->GlobalBD.bd2.LoPart); 1020 BCI_SEND(psav->GlobalBD.bd2.HiPart); 1021 1022 BCI_SEND(BCI_CLIP_LR(x+skipleft, x+w-1)); 1023 if( psav->SavedBgColor != 0xffffffff ) 1024 BCI_SEND(psav->SavedBgColor); 1025 BCI_SEND(BCI_X_Y(x, y)); 1026 BCI_SEND(BCI_W_H(w, h)); 1027} 1028 1029#endif 1030