newport_accel.c revision ba0eab60
1/* 2 * Accelerated Driver for the SGI Indy's Newport graphics card 3 * 4 * (c) 2004 Dominik Behr <dominikbehr@yahoo.com> 5 * this code is released under xfree 4.3.0 and xorg 6.8.0 license 6 * 7 */ 8 9#ifdef HAVE_CONFIG_H 10#include "config.h" 11#endif 12 13#include "newport.h" 14#include <limits.h> 15 16#ifdef NEWPORT_ACCEL 17 18#include "mi.h" 19#include "mizerarc.h" 20 21#define BARF(a) xf86DrvMsg(0, X_INFO, (a)) 22#define BARF1(a,b) xf86DrvMsg(0, X_INFO, (a), (b)) 23#define BARF2(a,b,c) xf86DrvMsg(0, X_INFO, (a), (b), (c)) 24#define BARF3(a,b,c,d) xf86DrvMsg(0, X_INFO, (a), (b), (c), (d)) 25#define BARF4(a,b,c,d,e) xf86DrvMsg(0, X_INFO, (a), (b), (c), (d), (e)) 26#define BARF5(a,b,c,d,e,f) xf86DrvMsg(0, X_INFO, (a), (b), (c), (d), (e), (f)) 27#define BARF6(a,b,c,d,e,f,g) xf86DrvMsg(0, X_INFO, (a), (b), (c), (d), (e), (f), (g)) 28 29/* XAA Functions */ 30 31#define NEWPORT_PREROTATE 32/* 33 there is a bug in XAA which causes it to reference NULL pointer to pattern cache when 34 using HARDWARE_PROGRAMMED_PATTERN only (try x11perf -strap1) 35 thus we have to also set HARDWARE_PROGRAMMED_ORIGIN and prerotate the pattern 36 in the setup function 37*/ 38 39#define NEWPORT_GFIFO_ENTRIES 30 40/* 41 I dont know how many entries are in the gfx FIFO, judging by 6 bits in the GFIFO 42 level status register it can be at most 63. it must be at least 32 because 43 otherwise they would use less bits for status 44 45 for now 16 seems to be safe value 46*/ 47#define NEWPORT_DELAY 128 48 49/******************************************************************************* 50 51*******************************************************************************/ 52static void 53NewportWaitIdle(NewportPtr pNewport, unsigned int uEntries) 54{ 55 NewportRegsPtr pNewportRegs; 56 pNewportRegs = pNewport->pNewportRegs; 57 /* wait for the GFIFO to drain */ 58 while ((pNewportRegs->cset.stat & NPORT_STAT_GLMSK)) 59 { 60 int i; 61 volatile int x; 62 for (x = 0, i = 0; i < NEWPORT_DELAY; i++) 63 { 64 x += i; 65 } 66 } 67 /* and then wait for the graphic to be idle */ 68 while (pNewportRegs->cset.stat & NPORT_STAT_GBUSY) 69 { 70 int i; 71 volatile int x; 72 for (x = 0, i = 0; i < NEWPORT_DELAY; i++) 73 { 74 x += i; 75 } 76 } 77 pNewport->fifoleft = NEWPORT_GFIFO_ENTRIES-uEntries; 78} 79 80 81#if 0 82/******************************************************************************* 83 84*******************************************************************************/ 85static void 86NewportWaitGFIFO(NewportPtr pNewport, unsigned int uEntries) 87{ 88 unsigned int uWaitLevel; 89 90/* NewportWaitIdle(pNewport, NEWPORT_GFIFO_ENTRIES); 91 return;*/ 92 93 if (uEntries >= NEWPORT_GFIFO_ENTRIES) 94 { 95 uWaitLevel = 0; 96 } 97 else 98 { 99 uWaitLevel = NEWPORT_GFIFO_ENTRIES-uEntries; 100 } 101 /* HACK */ 102 /*uWaitLevel = 0;*/ 103 while (((pNewport->pNewportRegs->cset.stat & NPORT_STAT_GLMSK) >> 7) > uWaitLevel) 104 { 105 int i; 106 volatile int x; 107 for (x = 0, i = 0; i < NEWPORT_DELAY; i++) 108 { 109 x += i; 110 } 111 } 112} 113#endif 114#if 1 115/******************************************************************************* 116 117*******************************************************************************/ 118static void 119NewportWaitGFIFO(NewportPtr pNewport, unsigned int uEntries) 120{ 121 if (uEntries > NEWPORT_GFIFO_ENTRIES) 122 { 123 uEntries = NEWPORT_GFIFO_ENTRIES; 124 } 125 126 if (uEntries <= pNewport->fifoleft) 127 { 128 pNewport->fifoleft -= uEntries; 129 return; 130 } 131 132 while (1) 133 { 134 unsigned int fifolevel; 135 int i; 136 volatile int x; 137 138 fifolevel = (pNewport->pNewportRegs->cset.stat & NPORT_STAT_GLMSK) >> 7; 139 if (fifolevel < NEWPORT_GFIFO_ENTRIES) 140 { 141 pNewport->fifoleft = NEWPORT_GFIFO_ENTRIES - fifolevel; 142 } 143 else 144 { 145 pNewport->fifoleft = 0; 146 } 147 if (uEntries <= pNewport->fifoleft) 148 { 149 pNewport->fifoleft -= uEntries; 150 return; 151 } 152 153 for (x = 0, i = 0; i < NEWPORT_DELAY; i++) 154 { 155 x += i; 156 } 157 } 158} 159#endif 160 161 162/******************************************************************************* 163 164*******************************************************************************/ 165static void 166NewportXAASync(ScrnInfoPtr pScrn) 167{ 168 NewportPtr pNewport; 169 pNewport = NEWPORTPTR(pScrn); 170 171 NewportWaitIdle(pNewport, 0); 172} 173 174 175/******************************************************************************* 176 177*******************************************************************************/ 178static unsigned int 179Rop2LogicOp(int rop) 180{ 181 return (unsigned int)rop << 28; 182} 183 184/******************************************************************************* 185 186*******************************************************************************/ 187static void 188NewportUpdateClipping(NewportPtr pNewport) 189{ 190 unsigned int smask0x, smask0y; 191 192 if (pNewport->skipleft > pNewport->clipsx) 193 { 194 smask0x = ((pNewport->skipleft & 0xFFFF) << 16) | (pNewport->clipex & 0xFFFF); 195 } 196 else 197 { 198 smask0x = ((pNewport->clipsx & 0xFFFF) << 16) | (pNewport->clipex & 0xFFFF); 199 } 200 201 if (smask0x != pNewport->shadow_smask0x) 202 { 203 NewportWaitGFIFO(pNewport, 1); 204 pNewport->shadow_smask0x = smask0x; 205 pNewport->pNewportRegs->set.smask0x = smask0x; 206 } 207 208 smask0y = ((pNewport->clipsy & 0xFFFF) << 16) | (pNewport->clipey & 0xFFFF); 209 if (smask0y != pNewport->shadow_smask0y) 210 { 211 NewportWaitGFIFO(pNewport, 1); 212 pNewport->shadow_smask0y = smask0y; 213 pNewport->pNewportRegs->set.smask0y = smask0y; 214 } 215} 216 217/******************************************************************************* 218 219*******************************************************************************/ 220static unsigned int 221NewportColor2HOSTRW(unsigned int color) 222{ 223 /* 224 default XAA color is 0,R,G,B 225 */ 226#if 0 227 return ((color & 0x0000FF) << 16) 228 | ((color & 0xFF0000) >> 16) 229 | ((color & 0x00FF00)) 230 ; 231#endif 232/* but we changed masks to match the native format */ 233 return color; 234} 235 236/******************************************************************************* 237 238*******************************************************************************/ 239static unsigned int 240NewportColor2Planes24(unsigned int color) 241{ 242 unsigned int res; 243 unsigned int i; 244 unsigned int mr, mg, mb; 245 unsigned int sr, sg, sb; 246 247 /* 248 XAA color is 0,R,G,B 249 */ 250 251 res = 0; 252#if 0 253 mr = 0x800000; 254 mg = 0x008000; 255 mb = 0x000080; 256#endif 257 mr = 0x000080; 258 mg = 0x008000; 259 mb = 0x800000; 260 sr = 2; 261 sg = 1; 262 sb = 4; 263 264 for (i = 0; i < 8; i++) 265 { 266 res |= (color & mr)?sr:0; 267 res |= (color & mg)?sg:0; 268 res |= (color & mb)?sb:0; 269 270 sr <<= 3; 271 sg <<= 3; 272 sb <<= 3; 273 mr >>= 1; 274 mg >>= 1; 275 mb >>= 1; 276 } 277 278 return res; 279} 280 281/******************************************************************************* 282 283*******************************************************************************/ 284static unsigned int 285NewportColor2Planes8(unsigned int color) 286{ 287 return color; 288} 289 290/******************************************************************************* 291 292*******************************************************************************/ 293static void 294NewportUpdateCOLORI(NewportPtr pNewport, unsigned long colori) 295{ 296 if (colori != pNewport->shadow_colori) 297 { 298 NewportWaitGFIFO(pNewport, 1); 299 pNewport->shadow_colori = colori; 300 pNewport->pNewportRegs->set.colori = colori; 301 } 302} 303 304 305/******************************************************************************* 306 307*******************************************************************************/ 308static void 309NewportUpdateDRAWMODE0(NewportPtr pNewport, unsigned long drawmode0) 310{ 311 if (drawmode0 != pNewport->shadow_drawmode0) 312 { 313 NewportWaitGFIFO(pNewport, 1); 314 pNewport->shadow_drawmode0 = drawmode0; 315 pNewport->pNewportRegs->set.drawmode0 = drawmode0; 316 } 317} 318 319 320/******************************************************************************* 321 322*******************************************************************************/ 323static void 324NewportUpdateDRAWMODE1(NewportPtr pNewport, unsigned long drawmode1) 325{ 326 if (drawmode1 != pNewport->shadow_drawmode1) 327 { 328 NewportWaitIdle(pNewport, 1); 329 pNewport->shadow_drawmode1 = drawmode1; 330 pNewport->pNewportRegs->set.drawmode1 = drawmode1; 331 } 332} 333 334/******************************************************************************* 335 336*******************************************************************************/ 337static void 338NewportUpdateCOLORVRAM(NewportPtr pNewport, unsigned long colorvram) 339{ 340 if (colorvram != pNewport->shadow_colorvram) 341 { 342 NewportWaitIdle(pNewport, 1); 343 pNewport->shadow_colorvram = colorvram; 344 pNewport->pNewportRegs->set.colorvram = colorvram; 345 } 346} 347 348/******************************************************************************* 349 350*******************************************************************************/ 351static void 352NewportUpdateCOLORBACK(NewportPtr pNewport, unsigned long colorback) 353{ 354 if (colorback != pNewport->shadow_colorback) 355 { 356 NewportWaitIdle(pNewport, 1); 357 pNewport->shadow_colorback = colorback; 358 pNewport->pNewportRegs->set.colorback = colorback; 359 } 360} 361 362/******************************************************************************* 363 364*******************************************************************************/ 365static void 366NewportUpdateWRMASK(NewportPtr pNewport, unsigned long wrmask) 367{ 368 if (wrmask != pNewport->shadow_wrmask) 369 { 370 NewportWaitIdle(pNewport, 1); 371 pNewport->shadow_wrmask = wrmask; 372 pNewport->pNewportRegs->set.wrmask = wrmask; 373 } 374} 375 376/******************************************************************************* 377 378*******************************************************************************/ 379static void 380NewportUpdateXYMOVE(NewportPtr pNewport, unsigned long xymove) 381{ 382 if (xymove != pNewport->shadow_xymove) 383 { 384 NewportWaitIdle(pNewport, 1); 385 pNewport->shadow_xymove = xymove; 386 pNewport->pNewportRegs->set.xymove = xymove; 387 } 388} 389 390 391/******************************************************************************* 392 393*******************************************************************************/ 394static void 395NewportXAASetupForScreenToScreenCopy(ScrnInfoPtr pScrn, 396 int xdir, 397 int ydir, 398 int rop, 399 unsigned int planemask, 400 int trans_color) 401{ 402 NewportRegsPtr pNewportRegs; 403 NewportPtr pNewport; 404 pNewport = NEWPORTPTR(pScrn); 405 pNewportRegs = NEWPORTREGSPTR(pScrn); 406 407 NewportUpdateDRAWMODE1(pNewport, pNewport->setup_drawmode1 | Rop2LogicOp(rop)); 408 NewportUpdateWRMASK(pNewport, pNewport->Color2Planes(planemask)); 409 pNewport->skipleft = 0; 410 NewportUpdateClipping(pNewport); 411 NewportUpdateDRAWMODE0(pNewport, 412 0 413 | NPORT_DMODE0_S2S 414 | NPORT_DMODE0_BLOCK 415 | NPORT_DMODE0_DOSETUP 416 | NPORT_DMODE0_STOPX 417 | NPORT_DMODE0_STOPY 418 ); 419 420 421} 422 423/******************************************************************************* 424 425*******************************************************************************/ 426static void 427NewportXAASubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, 428 int x1, int y1, 429 int x2, int y2, 430 int width, int height) 431{ 432 int dx, dy; 433 unsigned int sx, sy, ex, ey; 434 NewportRegsPtr pNewportRegs; 435 NewportPtr pNewport; 436 pNewport = NEWPORTPTR(pScrn); 437 pNewportRegs = NEWPORTREGSPTR(pScrn); 438 439 dx = x2 - x1; 440 dy = y2 - y1; 441 if (!dx && !dy) 442 return; 443 444 if (width) 445 x2 = x1 + width - 1; 446 else 447 x2 = x1; 448 449 if (height) 450 y2 = y1 + height - 1; 451 else 452 y2 = y1; 453 454 if (dx < 0) 455 { 456 sx = x1 & 0xFFFF; 457 ex = x2 & 0xFFFF; 458 } 459 else 460 { 461 sx = x2 & 0xFFFF; 462 ex = x1 & 0xFFFF; 463 } 464 465 if (dy < 0) 466 { 467 sy = y1 & 0xFFFF; 468 ey = y2 & 0xFFFF; 469 } 470 else 471 { 472 sy = y2 & 0xFFFF; 473 ey = y1 & 0xFFFF; 474 } 475 476 dx &= 0xFFFF; 477 dy &= 0xFFFF; 478 479 NewportUpdateXYMOVE(pNewport, (dx << 16) | dy); /* this is bad because it stalls the pipeline but nothing can be done about it */ 480 NewportWaitGFIFO(pNewport, 2); 481 pNewportRegs->set.xystarti = (sx << 16) | sy; 482 pNewportRegs->go.xyendi = (ex << 16) | ey; 483} 484 485/******************************************************************************* 486 487*******************************************************************************/ 488static void 489NewportXAASetupForSolidFill(ScrnInfoPtr pScrn, 490 int Color, 491 int rop, 492 unsigned int planemask) 493{ 494 NewportRegsPtr pNewportRegs; 495 NewportPtr pNewport; 496 pNewport = NEWPORTPTR(pScrn); 497 pNewportRegs = NEWPORTREGSPTR(pScrn); 498 499 if (rop == GXcopy 500 || rop == GXclear 501 || rop == GXset) 502 { 503 /* if possible try to set up a fast clear which is 4x faster */ 504 NewportUpdateDRAWMODE1(pNewport, pNewport->setup_drawmode1 | NPORT_DMODE1_FCLR | Rop2LogicOp(GXcopy)); 505 if (rop == GXclear) 506 NewportUpdateCOLORVRAM(pNewport, 0); 507 else 508 if (rop == GXset) 509 NewportUpdateCOLORVRAM(pNewport, 0xFFFFFF); 510 else 511 NewportUpdateCOLORVRAM(pNewport, pNewport->Color2Planes((unsigned int)Color)); 512 } 513 else 514 { 515 NewportUpdateDRAWMODE1(pNewport, pNewport->setup_drawmode1 | Rop2LogicOp(rop)); 516 NewportUpdateCOLORI(pNewport, NewportColor2HOSTRW(Color)); 517 } 518 519 NewportUpdateWRMASK(pNewport, pNewport->Color2Planes(planemask)); 520 pNewport->skipleft = 0; 521 NewportUpdateClipping(pNewport); 522 NewportUpdateDRAWMODE0(pNewport, 523 0 524 | NPORT_DMODE0_DRAW 525 | NPORT_DMODE0_BLOCK 526 | NPORT_DMODE0_DOSETUP 527 | NPORT_DMODE0_STOPX 528 | NPORT_DMODE0_STOPY 529 ); 530} 531 532/******************************************************************************* 533 534*******************************************************************************/ 535static void 536NewportXAASubsequentSolidFillRect(ScrnInfoPtr pScrn, 537 int x, 538 int y, 539 int w, 540 int h) 541{ 542 int ex, ey; 543 NewportRegsPtr pNewportRegs; 544 NewportPtr pNewport; 545 pNewport = NEWPORTPTR(pScrn); 546 pNewportRegs = NEWPORTREGSPTR(pScrn); 547 548 if (w == 0) w = 1; 549 if (h == 0) h = 1; 550 ex = x + w - 1; 551 ey = y + h - 1; 552 553 NewportWaitGFIFO(pNewport, 2); 554 pNewportRegs->set.xystarti = ((x & 0xFFFF) << 16) | (y & 0xFFFF); 555 pNewportRegs->go.xyendi = ((ex & 0xFFFF) << 16) | (ey & 0xFFFF); 556} 557 558/******************************************************************************* 559 560*******************************************************************************/ 561static void 562NewportXAASetupForSolidLine(ScrnInfoPtr pScrn, 563 int Color, 564 int rop, 565 unsigned int planemask) 566{ 567 NewportRegsPtr pNewportRegs; 568 NewportPtr pNewport; 569 pNewport = NEWPORTPTR(pScrn); 570 pNewportRegs = NEWPORTREGSPTR(pScrn); 571 572 NewportUpdateDRAWMODE1(pNewport, pNewport->setup_drawmode1 | Rop2LogicOp(rop)); 573 NewportUpdateWRMASK(pNewport, pNewport->Color2Planes(planemask)); 574 NewportUpdateCOLORI(pNewport, NewportColor2HOSTRW(Color)); 575 576 pNewport->skipleft = 0; 577 NewportUpdateClipping(pNewport); 578 pNewport->setup_drawmode0 = (0 579 | NPORT_DMODE0_DRAW 580 | NPORT_DMODE0_ILINE 581 | NPORT_DMODE0_DOSETUP 582 | NPORT_DMODE0_STOPX 583 | NPORT_DMODE0_STOPY 584 ); 585} 586 587/******************************************************************************* 588 589*******************************************************************************/ 590static void 591NewportXAASubsequentSolidTwoPointLine(ScrnInfoPtr pScrn, 592 int x1, 593 int y1, 594 int x2, 595 int y2, 596 int flags) 597{ 598 NewportRegsPtr pNewportRegs; 599 NewportPtr pNewport; 600 pNewport = NEWPORTPTR(pScrn); 601 pNewportRegs = NEWPORTREGSPTR(pScrn); 602 603 NewportUpdateDRAWMODE0(pNewport, 604 pNewport->setup_drawmode0 605 | ((flags & OMIT_LAST) ? NPORT_DMODE0_SKLST : 0) 606 ); 607 NewportWaitGFIFO(pNewport, 2); 608 pNewportRegs->set.xystarti = ((x1 & 0xFFFF) << 16) | (y1 & 0xFFFF); 609 pNewportRegs->go.xyendi = ((x2 & 0xFFFF) << 16) | (y2 & 0xFFFF); 610} 611 612 613/******************************************************************************* 614 615*******************************************************************************/ 616static void 617NewportXAASetupForDashedLine(ScrnInfoPtr pScrn, 618 int fg, 619 int bg, 620 int rop, 621 unsigned int planemask, 622 int length, 623 unsigned char *pattern) 624{ 625 NewportRegsPtr pNewportRegs; 626 NewportPtr pNewport; 627 int i; 628 629 pNewport = NEWPORTPTR(pScrn); 630 pNewportRegs = NEWPORTREGSPTR(pScrn); 631 632 pNewport->dashline_patlen = length; 633 for (i = 0; i < (length+7)>>3; i++) 634 pNewport->dashline_pat[i] = pattern[i]; 635 636 NewportUpdateDRAWMODE1(pNewport, pNewport->setup_drawmode1 | Rop2LogicOp(rop)); 637 NewportUpdateWRMASK(pNewport, pNewport->Color2Planes(planemask)); 638 if (bg != -1) 639 NewportUpdateCOLORBACK(pNewport, NewportColor2HOSTRW(bg)); 640 NewportUpdateCOLORI(pNewport, NewportColor2HOSTRW(fg)); 641 pNewport->skipleft = 0; 642 NewportUpdateClipping(pNewport); 643 pNewport->setup_drawmode0 = (0 644 | NPORT_DMODE0_DRAW 645 | NPORT_DMODE0_ILINE 646 | NPORT_DMODE0_DOSETUP 647 | NPORT_DMODE0_STOPX 648 | NPORT_DMODE0_STOPY 649 | NPORT_DMODE0_L32 650 | NPORT_DMODE0_ZPENAB 651 | ((bg == -1) ? 0 : NPORT_DMODE0_ZOPQ) 652 ); 653} 654 655/******************************************************************************* 656 657*******************************************************************************/ 658static void 659NewportXAASubsequentDashedTwoPointLine(ScrnInfoPtr pScrn, 660 int x1, 661 int y1, 662 int x2, 663 int y2, 664 int flags, 665 int phase) 666{ 667 NewportRegsPtr pNewportRegs; 668 NewportPtr pNewport; 669 int dx, dy; 670 unsigned int linelen; 671 unsigned int dwords; 672 673 pNewport = NEWPORTPTR(pScrn); 674 pNewportRegs = NEWPORTREGSPTR(pScrn); 675 676 dx = x2 - x1; if (dx < 0) dx = -dx; dx++; 677 dy = y2 - y1; if (dy < 0) dy = -dy; dy++; 678 if (dx > dy) 679 linelen = dx; 680 else 681 linelen = dy; 682 dwords = (linelen + 31) >> 5; 683 684 NewportUpdateDRAWMODE0(pNewport, 685 pNewport->setup_drawmode0 686 | ((flags & OMIT_LAST) ? NPORT_DMODE0_SKLST : 0) 687 ); 688 689 NewportWaitGFIFO(pNewport, 3); 690 pNewportRegs->set.xystarti = ((x1 & 0xFFFF) << 16) | (y1 & 0xFFFF); 691 pNewportRegs->set.xyendi = ((x2 & 0xFFFF) << 16) | (y2 & 0xFFFF); 692 pNewportRegs->set._setup = 1; 693 694 phase %= pNewport->dashline_patlen; 695 while (dwords--) { 696 unsigned int bit; 697 unsigned int pat; 698 unsigned int mask; 699 pat = 0; 700 mask = 0x80000000; 701 for (bit = 0; bit < 32; bit++) 702 { 703 if (pNewport->dashline_pat[phase >> 3] & (0x80 >> (phase & 7))) 704 pat |= mask; 705 phase = (phase + 1) % pNewport->dashline_patlen; 706 mask >>= 1; 707 } 708 NewportWaitGFIFO(pNewport, 1); 709 pNewportRegs->go.zpattern = pat; 710 } 711 712} 713 714/******************************************************************************* 715 716*******************************************************************************/ 717static void 718NewportXAASetupForCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, 719 int fg, 720 int bg, 721 int rop, 722 unsigned int planemask) 723{ 724 NewportRegsPtr pNewportRegs; 725 NewportPtr pNewport; 726 pNewport = NEWPORTPTR(pScrn); 727 pNewportRegs = NEWPORTREGSPTR(pScrn); 728 729 NewportUpdateDRAWMODE1(pNewport, pNewport->setup_drawmode1 | Rop2LogicOp(rop)); 730 NewportUpdateWRMASK(pNewport, pNewport->Color2Planes(planemask)); 731 if (bg != -1) 732 NewportUpdateCOLORBACK(pNewport, NewportColor2HOSTRW(bg)); 733 NewportUpdateCOLORI(pNewport, NewportColor2HOSTRW(fg)); 734 NewportUpdateDRAWMODE0(pNewport, 735 0 736 | NPORT_DMODE0_DRAW 737 | NPORT_DMODE0_BLOCK 738 | NPORT_DMODE0_DOSETUP 739 | NPORT_DMODE0_STOPX 740 | NPORT_DMODE0_ZPENAB 741 | ((bg == -1) ? 0 : NPORT_DMODE0_ZOPQ) 742 | NPORT_DMODE0_L32 743 ); 744} 745 746/******************************************************************************* 747 748*******************************************************************************/ 749static void 750NewportXAASubsequentCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, 751 int x, 752 int y, 753 int w, 754 int h, 755 int skipleft) 756{ 757 int ex, ey; 758 NewportRegsPtr pNewportRegs; 759 NewportPtr pNewport; 760 pNewport = NEWPORTPTR(pScrn); 761 pNewportRegs = NEWPORTREGSPTR(pScrn); 762 763 if (w == 0) w = 1; 764 if (h == 0) h = 1; 765 ex = x + w - 1; 766 ey = y + h - 1; 767 768 if (skipleft) 769 { 770 pNewport->skipleft = x + skipleft; 771 } 772 else 773 { 774 pNewport->skipleft = 0; 775 } 776 NewportUpdateClipping(pNewport); 777 778 NewportWaitGFIFO(pNewport, 3); 779 pNewportRegs->set.xystarti = ((x & 0xFFFF) << 16) | (y & 0xFFFF); 780 pNewportRegs->set.xyendi = ((ex & 0xFFFF) << 16) | (ey & 0xFFFF); 781 pNewportRegs->set._setup = 1; 782 783 /* after return XAA will start blasting the pattern to go.zpattern register */ 784 /* we have to wait here for idle because if there is something in the pipeline that will take 785 long time to complete and if following cpu transfers will overflow the FIFO causing GIO bus 786 stall it will end up in bus error */ 787 NewportWaitIdle(pNewport, NEWPORT_GFIFO_ENTRIES); 788 789} 790 791/******************************************************************************* 792 793*******************************************************************************/ 794static void 795NewportXAASetupForImageWrite(ScrnInfoPtr pScrn, 796 int rop, 797 unsigned int planemask, 798 int trans_color, 799 int bpp, 800 int depth) 801{ 802 NewportRegsPtr pNewportRegs; 803 NewportPtr pNewport; 804 pNewport = NEWPORTPTR(pScrn); 805 pNewportRegs = NEWPORTREGSPTR(pScrn); 806 807 NewportUpdateDRAWMODE1(pNewport, pNewport->setup_drawmode1 | Rop2LogicOp(rop)); 808 NewportUpdateWRMASK(pNewport, pNewport->Color2Planes(planemask)); 809 NewportUpdateDRAWMODE0(pNewport, 810 0 811 | NPORT_DMODE0_DRAW 812 | NPORT_DMODE0_BLOCK 813 | NPORT_DMODE0_CHOST 814 | NPORT_DMODE0_DOSETUP 815 ); 816 817} 818 819/******************************************************************************* 820 821*******************************************************************************/ 822static void 823NewportXAASubsequentImageWriteRect(ScrnInfoPtr pScrn, 824 int x, 825 int y, 826 int w, 827 int h, 828 int skipleft) 829{ 830 int ex, ey; 831 NewportRegsPtr pNewportRegs; 832 NewportPtr pNewport; 833 pNewport = NEWPORTPTR(pScrn); 834 pNewportRegs = NEWPORTREGSPTR(pScrn); 835 836 if (w == 0) w = 1; 837 if (h == 0) h = 1; 838 839 ex = x + w - 1; 840 ey = y + h - 1; 841 842 if (skipleft) 843 { 844 pNewport->skipleft = x + skipleft; 845 } 846 else 847 { 848 pNewport->skipleft = 0; 849 } 850 NewportUpdateClipping(pNewport); 851 852 NewportWaitGFIFO(pNewport, 3); 853 pNewportRegs->set.xystarti = ((x & 0xFFFF) << 16) | (y & 0xFFFF); 854 pNewportRegs->set.xyendi = ((ex & 0xFFFF) << 16) | (ey & 0xFFFF); 855 pNewportRegs->set._setup = 1; 856 857 /* after return XAA will start blasting the image to go.hostrw0 register */ 858 /* we have to wait here for idle because if there is something in the pipeline that will take 859 long time to complete and if following cpu transfers will overflow the FIFO causing GIO bus 860 stall it will end up in bus error */ 861 NewportWaitIdle(pNewport, NEWPORT_GFIFO_ENTRIES); 862} 863 864static unsigned int 865repbyte(unsigned int b) 866{ 867 b &= 0xFF; 868 return b | (b << 8) | (b << 16) | (b << 24); 869} 870 871static void 872prerotatebyte(unsigned int b, unsigned int *p) 873{ 874 int i; 875 876 b &= 0xFF; 877 878 for (i = 0; i < 8; i++) 879 { 880 p[i] = repbyte(b); 881 if (b & 1) 882 b = (b >> 1) | 0x80; 883 else 884 b = b >> 1; 885 } 886} 887 888/******************************************************************************* 889 890*******************************************************************************/ 891static void 892NewportXAASetupForMono8x8PatternFill(ScrnInfoPtr pScrn, 893 int patx, 894 int paty, 895 int fg, 896 int bg, 897 int rop, 898 unsigned int planemask) 899{ 900 NewportRegsPtr pNewportRegs; 901 NewportPtr pNewport; 902 pNewport = NEWPORTPTR(pScrn); 903 pNewportRegs = NEWPORTREGSPTR(pScrn); 904 905#ifdef NEWPORT_PREROTATE 906 /* prerotate the pattern */ 907 prerotatebyte((unsigned int)patx >> 24, pNewport->pat8x8[0]); 908 prerotatebyte((unsigned int)patx >> 16, pNewport->pat8x8[1]); 909 prerotatebyte((unsigned int)patx >> 8, pNewport->pat8x8[2]); 910 prerotatebyte((unsigned int)patx, pNewport->pat8x8[3]); 911 prerotatebyte((unsigned int)paty >> 24, pNewport->pat8x8[4]); 912 prerotatebyte((unsigned int)paty >> 16, pNewport->pat8x8[5]); 913 prerotatebyte((unsigned int)paty >> 8, pNewport->pat8x8[6]); 914 prerotatebyte((unsigned int)paty, pNewport->pat8x8[7]); 915#endif 916 NewportUpdateDRAWMODE1(pNewport, pNewport->setup_drawmode1 | Rop2LogicOp(rop)); 917 NewportUpdateWRMASK(pNewport, pNewport->Color2Planes(planemask)); 918 if (bg != -1) 919 NewportUpdateCOLORBACK(pNewport, NewportColor2HOSTRW(bg)); 920 NewportUpdateCOLORI(pNewport, NewportColor2HOSTRW(fg)); 921 pNewport->skipleft = 0; 922 NewportUpdateClipping(pNewport); 923 NewportUpdateDRAWMODE0(pNewport, 924 0 925 | NPORT_DMODE0_DRAW 926 | NPORT_DMODE0_BLOCK 927 | NPORT_DMODE0_DOSETUP 928 | NPORT_DMODE0_STOPX 929 | NPORT_DMODE0_ZPENAB 930 | ((bg == -1) ? 0 : NPORT_DMODE0_ZOPQ) 931 | NPORT_DMODE0_L32 932 ); 933} 934 935 936 937/******************************************************************************* 938 939*******************************************************************************/ 940static void 941NewportXAASubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, 942 int patx, 943 int paty, 944 int x, 945 int y, 946 int w, 947 int h) 948{ 949 int ex, ey; 950 unsigned int d; 951#ifndef NEWPORT_PREROTATE 952 unsigned int p; 953 unsigned int epat[8]; 954#endif 955 956 NewportRegsPtr pNewportRegs; 957 NewportPtr pNewport; 958 pNewport = NEWPORTPTR(pScrn); 959 pNewportRegs = NEWPORTREGSPTR(pScrn); 960 961 if (w == 0) w = 1; 962 if (h == 0) h = 1; 963 ex = x + w - 1; 964 ey = y + h - 1; 965 966 NewportWaitGFIFO(pNewport, 3); 967 pNewportRegs->set.xystarti = ((x & 0xFFFF) << 16) | (y & 0xFFFF); 968 pNewportRegs->set.xyendi = ((ex & 0xFFFF) << 16) | (ey & 0xFFFF); 969 pNewportRegs->set._setup = 1; 970 971#ifdef NEWPORT_PREROTATE 972 patx &= 7; 973 paty &= 7; 974 while (h--) 975 { 976 for (d = (w + 31) >> 5; d; d--) 977 { 978 NewportWaitGFIFO(pNewport, 1); 979 pNewportRegs->go.zpattern = pNewport->pat8x8[paty][patx]; 980 } 981 paty = (paty + 1) & 7; 982 } 983#else 984 epat[0] = repbyte(patx >> 24); 985 epat[1] = repbyte(patx >> 16); 986 epat[2] = repbyte(patx >> 8); 987 epat[3] = repbyte(patx); 988 epat[4] = repbyte(paty >> 24); 989 epat[5] = repbyte(paty >> 16); 990 epat[6] = repbyte(paty >> 8); 991 epat[7] = repbyte(paty); 992 993 p = 0; 994 while (h--) 995 { 996 for (d = (w + 31) >> 5; d; d--) 997 { 998 NewportWaitGFIFO(pNewport, 1); 999 pNewportRegs->go.zpattern = epat[p]; 1000 } 1001 p = (p + 1) ^ 7; 1002 } 1003#endif 1004} 1005 1006/******************************************************************************* 1007 1008*******************************************************************************/ 1009static void 1010NewportXAAReadPixmap(ScrnInfoPtr pScrn, 1011 int x, 1012 int y, 1013 int w, 1014 int h, 1015 unsigned char *dst, 1016 int dstwidth, 1017 int bpp, 1018 int depth) 1019{ 1020 int ex, ey; 1021 NewportRegsPtr pNewportRegs; 1022 NewportPtr pNewport; 1023 pNewport = NEWPORTPTR(pScrn); 1024 pNewportRegs = NEWPORTREGSPTR(pScrn); 1025 1026 if (w == 0) w = 1; 1027 if (h == 0) h = 1; 1028 ex = x + w - 1; 1029 ey = y + h - 1; 1030 1031 NewportWaitIdle(pNewport, 0); 1032 NewportUpdateDRAWMODE1(pNewport, pNewport->setup_drawmode1 | Rop2LogicOp(GXcopy) | NPORT_DMODE1_PFENAB); 1033 NewportUpdateWRMASK(pNewport, pNewport->Color2Planes(0xFFFFFFFF)); 1034 NewportUpdateDRAWMODE0(pNewport, 1035 0 1036 | NPORT_DMODE0_RD 1037 | NPORT_DMODE0_BLOCK 1038 | NPORT_DMODE0_CHOST 1039 | NPORT_DMODE0_DOSETUP 1040 ); 1041 1042 NewportWaitGFIFO(pNewport, 3); 1043 pNewportRegs->set.xystarti = ((x & 0xFFFF) << 16) | (y & 0xFFFF); 1044 pNewportRegs->set.xyendi = ((ex & 0xFFFF) << 16) | (ey & 0xFFFF); 1045 /* with prefetch enabled go has to be issued before we start reading */ 1046 pNewportRegs->go._setup = 1; 1047 1048 1049 if (pScrn->bitsPerPixel == 8) 1050 { 1051 unsigned int d; 1052 while (h--) 1053 { 1054 unsigned char *p; 1055 p = (unsigned char *)dst; 1056 for (x = 0; x < w; x += 4) 1057 { 1058 if (!h && x+4 >= w) 1059 { /* the last dword does not need go */ 1060 d = pNewportRegs->set.hostrw0; 1061 } 1062 else 1063 { 1064 d = pNewportRegs->go.hostrw0; 1065 } 1066 1067 *p++ = (d & 0xFF000000) >> 24; 1068 if (x+1 < w) 1069 { 1070 *p++ = (d & 0x00FF0000) >> 16; 1071 } 1072 if (x+2 < w) 1073 { 1074 *p++ = (d & 0x0000FF00) >> 8; 1075 } 1076 if (x+3 < w) 1077 { 1078 *p++ = d & 0x000000FF; 1079 } 1080 } 1081 dst += dstwidth; 1082 } 1083 } 1084 else 1085 { 1086 while (h--) 1087 { 1088 unsigned int *p; 1089 p = (unsigned int *)dst; 1090 for (x = 0; x < w; x++) 1091 { 1092 if (!h && x+1 == w) 1093 { /* the last dword does not need go */ 1094 *p++ = pNewportRegs->set.hostrw0; 1095 } 1096 else 1097 { 1098 *p++ = pNewportRegs->go.hostrw0; 1099 } 1100 } 1101 dst += dstwidth; 1102 } 1103 } 1104} 1105 1106/******************************************************************************* 1107 1108*******************************************************************************/ 1109static void 1110NewportXAASetClippingRectangle(ScrnInfoPtr pScrn, 1111 int left, 1112 int top, 1113 int right, 1114 int bottom) 1115{ 1116 NewportPtr pNewport; 1117 pNewport = NEWPORTPTR(pScrn); 1118 1119 if (left < 0) left = 0; 1120 if (right > pScrn->virtualX-1) right = pScrn->virtualX-1; 1121 1122 if (top < 0) top = 0; 1123 if (bottom > pScrn->virtualY-1) bottom = pScrn->virtualY-1; 1124 1125 pNewport->clipsx = left; 1126 pNewport->clipex = right; 1127 pNewport->clipsy = top; 1128 pNewport->clipey = bottom; 1129 1130 NewportUpdateClipping(pNewport); 1131} 1132 1133/******************************************************************************* 1134 1135*******************************************************************************/ 1136static void 1137NewportXAADisableClipping(ScrnInfoPtr pScrn) 1138{ 1139 NewportPtr pNewport; 1140 pNewport = NEWPORTPTR(pScrn); 1141 1142 pNewport->clipsx = 0; 1143 pNewport->clipex = pScrn->virtualX-1; 1144 pNewport->clipsy = 0; 1145 pNewport->clipey = pScrn->virtualY-1; 1146 NewportUpdateClipping(pNewport); 1147} 1148 1149/******************************************************************************* 1150 1151*******************************************************************************/ 1152static void 1153NewportPolyPoint(DrawablePtr pDraw, 1154 GCPtr pGC, 1155 int mode, 1156 int npt, 1157 xPoint *ppt) 1158{ 1159 ScrnInfoPtr pScrn; 1160 int numRects = REGION_NUM_RECTS(pGC->pCompositeClip); 1161 int rect; 1162 XAAInfoRecPtr infoRec; 1163 BoxPtr pbox; 1164 int x, y; 1165 int rop; 1166 1167 NewportRegsPtr pNewportRegs; 1168 NewportPtr pNewport; 1169 1170 infoRec = GET_XAAINFORECPTR_FROM_GC(pGC); 1171 pScrn = infoRec->pScrn; 1172 1173 if (!numRects) 1174 return; 1175 1176 pNewport = NEWPORTPTR(pScrn); 1177 pNewportRegs = NEWPORTREGSPTR(pScrn); 1178 1179 x = pDraw->x; 1180 y = pDraw->y; 1181 1182 rop = pGC->alu; 1183 1184 NewportUpdateWRMASK(pNewport, pNewport->Color2Planes(pGC->planemask)); 1185 if (rop == GXcopy 1186 || rop == GXclear 1187 || rop == GXset) 1188 { 1189 /* if possible try to set up a fast clear which is 4x faster */ 1190 NewportUpdateDRAWMODE1(pNewport, pNewport->setup_drawmode1 | NPORT_DMODE1_FCLR | Rop2LogicOp(GXcopy)); 1191 if (rop == GXclear) 1192 NewportUpdateCOLORVRAM(pNewport, 0); 1193 else 1194 if (rop == GXset) 1195 NewportUpdateCOLORVRAM(pNewport, 0xFFFFFF); 1196 else 1197 NewportUpdateCOLORVRAM(pNewport, pNewport->Color2Planes((unsigned int)(pGC->fgPixel))); 1198 } 1199 else 1200 { 1201 NewportUpdateDRAWMODE1(pNewport, pNewport->setup_drawmode1 | Rop2LogicOp(rop)); 1202 NewportUpdateCOLORI(pNewport, NewportColor2HOSTRW(pGC->fgPixel)); 1203 } 1204 1205 pNewport->skipleft = 0; 1206 NewportUpdateClipping(pNewport); 1207 NewportUpdateDRAWMODE0(pNewport, 1208 0 1209 | NPORT_DMODE0_DRAW 1210 | NPORT_DMODE0_BLOCK 1211 | NPORT_DMODE0_DOSETUP 1212 ); 1213 1214 pbox = REGION_RECTS(pGC->pCompositeClip); 1215 1216 while (npt--) { 1217 if (mode == CoordModePrevious) 1218 { 1219 x += ppt->x; 1220 y += ppt->y; 1221 } 1222 else 1223 { 1224 x = pDraw->x + ppt->x; 1225 y = pDraw->y + ppt->y; 1226 } 1227 for (rect = 0; rect < numRects; rect++) 1228 if (x >= pbox[rect].x1 && x < pbox[rect].x2 1229 && y >= pbox[rect].y1 && y < pbox[rect].y2) 1230 { /* draw point */ 1231 unsigned int xy; 1232 xy = ((x & 0xFFFF) << 16) | (y & 0xFFFF); 1233 NewportWaitGFIFO(pNewport, 2); 1234 pNewportRegs->set.xystarti = xy; 1235 pNewportRegs->go.xyendi = xy; 1236 break; 1237 } 1238 ppt++; 1239 } 1240} 1241 1242/******************************************************************************* 1243 1244*******************************************************************************/ 1245static void 1246NewportValidatePolyPoint(GCPtr pGC, 1247 unsigned long changes, 1248 DrawablePtr pDraw) 1249{ 1250 1251 if (pDraw->type == DRAWABLE_WINDOW) 1252 { 1253 pGC->ops->PolyPoint = NewportPolyPoint; 1254 } 1255 else 1256 { 1257 pGC->ops->PolyPoint = XAAGetFallbackOps()->PolyPoint; 1258 } 1259} 1260 1261#if 1 1262/******************************************************************************* 1263 1264*******************************************************************************/ 1265static void 1266NewportPolyArc(DrawablePtr pDraw, 1267 GCPtr pGC, 1268 int narcs, 1269 xArc *parcs) 1270{ 1271 xArc *arc; 1272 BoxRec box; 1273 int i, x2, y2; 1274 RegionPtr cclip; 1275 1276 cclip = pGC->pCompositeClip; 1277 1278 if(!REGION_NUM_RECTS(cclip)) 1279 return; 1280 1281 for (arc = parcs, i = narcs; --i >= 0; arc++) { 1282 if (miCanZeroArc(arc)) { 1283 box.x1 = arc->x + pDraw->x; 1284 box.y1 = arc->y + pDraw->y; 1285 x2 = box.x1 + (int)arc->width + 1; 1286 box.x2 = x2; 1287 y2 = box.y1 + (int)arc->height + 1; 1288 box.y2 = y2; 1289 if ( (x2 <= SHRT_MAX) && (y2 <= SHRT_MAX) && 1290 (RECT_IN_REGION(pDraw->pScreen, cclip, &box) == rgnIN) ) 1291 miZeroPolyArc(pDraw, pGC, 1, arc); 1292 } 1293 else 1294 miPolyArc(pDraw, pGC, 1, arc); 1295 } 1296} 1297#endif 1298 1299/******************************************************************************* 1300 1301*******************************************************************************/ 1302static void 1303NewportValidatePolyArc(GCPtr pGC, 1304 unsigned long changes, 1305 DrawablePtr pDraw) 1306{ 1307 if (pDraw->type == DRAWABLE_WINDOW) 1308 { 1309 pGC->ops->PolyPoint = NewportPolyPoint; 1310 /*pGC->ops->PolyArc = miPolyArc;*/ 1311 pGC->ops->PolyArc = NewportPolyArc; 1312 1313 } 1314 else 1315 { 1316 pGC->ops->PolyPoint = XAAGetFallbackOps()->PolyPoint; 1317 pGC->ops->PolyArc = XAAGetFallbackOps()->PolyArc; 1318 } 1319} 1320 1321 1322#ifdef RENDER 1323/******************************************************************************* 1324 1325*******************************************************************************/ 1326static Bool 1327NewportXAASetupForCPUToScreenAlphaTexture( 1328 ScrnInfoPtr pScrn, 1329 int op, 1330 CARD16 red, 1331 CARD16 green, 1332 CARD16 blue, 1333 CARD16 alpha, 1334 CARD32 maskFormat, 1335 CARD32 dstFormat, 1336 CARD8 *alphaPtr, 1337 int alphaPitch, 1338 int width, 1339 int height, 1340 int flags) 1341{ 1342 unsigned int col, a; 1343 unsigned char *pSrc; 1344 unsigned int *pDst; 1345 unsigned int w; 1346 NewportRegsPtr pNewportRegs; 1347 NewportPtr pNewport; 1348 pNewport = NEWPORTPTR(pScrn); 1349 pNewportRegs = NEWPORTREGSPTR(pScrn); 1350 1351 if (width * height * sizeof(unsigned int) > pNewport->uTextureSize) 1352 { 1353 free(pNewport->pTexture); 1354 pNewport->pTexture = xnfalloc(pNewport->uTextureSize = width * height * sizeof(unsigned int)); 1355 } 1356 col = (((unsigned int)red & 0xFF00) << 8) 1357 | ((unsigned int)green & 0xFF00) 1358 | ((unsigned int)blue >> 8); 1359 1360 pNewport->uTextureWidth = width; 1361 pNewport->uTextureHeight = height; 1362 pNewport->uTextureFlags = flags; 1363 1364 /* copy texture */ 1365 pDst = pNewport->pTexture; 1366 while (height--) { 1367 pSrc = (unsigned char *)alphaPtr; 1368 1369 for (w = width; w; w--) 1370 { 1371 /* premultiply alpha */ 1372 a = *pSrc++; 1373 a *= alpha; 1374 a /= 0xFFFF; 1375 a <<= 24; 1376 *pDst++ = col | a; 1377 } 1378 alphaPtr += alphaPitch; 1379 } 1380#define SFACTOR (4 << 19) 1381#define DFACTOR (5 << 22) 1382 NewportUpdateDRAWMODE1(pNewport, pNewport->setup_drawmode1 | Rop2LogicOp(GXcopy) | NPORT_DMODE1_BENAB | SFACTOR | DFACTOR ); 1383#undef SFACTOR 1384#undef DFACTOR 1385 NewportUpdateWRMASK(pNewport, pNewport->Color2Planes(0xFFFFFFFF)); 1386 1387 pNewport->skipleft = 0; 1388 NewportUpdateClipping(pNewport); 1389 NewportUpdateDRAWMODE0(pNewport, 1390 0 1391 | NPORT_DMODE0_DRAW 1392 | NPORT_DMODE0_BLOCK 1393 | NPORT_DMODE0_CHOST 1394 | NPORT_DMODE0_AHOST 1395 | NPORT_DMODE0_DOSETUP 1396 ); 1397 return TRUE; 1398} 1399 1400/******************************************************************************* 1401 1402*******************************************************************************/ 1403static Bool 1404NewportXAASetupForCPUToScreenTexture( 1405 ScrnInfoPtr pScrn, 1406 int op, 1407 CARD32 srcFormat, 1408 CARD32 dstFormat, 1409 CARD8 *texPtr, 1410 int texPitch, 1411 int width, 1412 int height, 1413 int flags) 1414{ 1415 unsigned int *pSrc, *pDst; 1416 unsigned int w; 1417 NewportRegsPtr pNewportRegs; 1418 NewportPtr pNewport; 1419 pNewport = NEWPORTPTR(pScrn); 1420 pNewportRegs = NEWPORTREGSPTR(pScrn); 1421 1422 if (width * height * sizeof(unsigned int) > pNewport->uTextureSize) 1423 { 1424 free(pNewport->pTexture); 1425 pNewport->pTexture = xnfalloc(pNewport->uTextureSize = width * height * sizeof(unsigned int)); 1426 } 1427 1428 pNewport->uTextureWidth = width; 1429 pNewport->uTextureHeight = height; 1430 pNewport->uTextureFlags = flags; 1431 1432 /* copy texture */ 1433 pDst = pNewport->pTexture; 1434 1435 if (srcFormat == PICT_a8r8g8b8) 1436 { 1437 while (height--) { 1438 pSrc = (unsigned int *)texPtr; 1439 1440 for (w = width; w; w--) 1441 { 1442 unsigned int v; 1443 v = *pSrc++; 1444 *pDst++ = (v & 0xFF00FF00) | ((v & 0x00FF0000) >> 16) | ((v & 0x000000FF) << 16); 1445 } 1446 texPtr += texPitch; 1447 } 1448 } 1449 else 1450 if (srcFormat == PICT_a8b8g8r8) 1451 { 1452 while (height--) { 1453 pSrc = (unsigned int *)texPtr; 1454 1455 for (w = width; w; w--) 1456 *pDst++ = *pSrc++; 1457 texPtr += texPitch; 1458 } 1459 } 1460 else 1461 { 1462 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Unknown texture format\n"); 1463 } 1464 1465#define SFACTOR (4 << 19) 1466#define DFACTOR (5 << 22) 1467 NewportUpdateDRAWMODE1(pNewport, pNewport->setup_drawmode1 | Rop2LogicOp(GXcopy) | NPORT_DMODE1_BENAB | SFACTOR | DFACTOR ); 1468#undef SFACTOR 1469#undef DFACTOR 1470 NewportUpdateWRMASK(pNewport, pNewport->Color2Planes(0xFFFFFFFF)); 1471 1472 pNewport->skipleft = 0; 1473 NewportUpdateClipping(pNewport); 1474 NewportUpdateDRAWMODE0(pNewport, 1475 0 1476 | NPORT_DMODE0_DRAW 1477 | NPORT_DMODE0_BLOCK 1478 | NPORT_DMODE0_CHOST 1479 | NPORT_DMODE0_AHOST 1480 | NPORT_DMODE0_DOSETUP 1481 ); 1482 1483 return TRUE; 1484} 1485 1486/******************************************************************************* 1487 1488*******************************************************************************/ 1489static void 1490NewportRenderTexture1to1(NewportPtr pNewport, int srcx, int srcy, int w, int h) 1491{ 1492 unsigned int *p; 1493 unsigned int add, d; 1494 NewportRegsPtr pNewportRegs; 1495 pNewportRegs = pNewport->pNewportRegs; 1496 1497 p = pNewport->pTexture + srcx + (srcy * pNewport->uTextureWidth); 1498 add = pNewport->uTextureWidth - w + srcx; 1499 while (h--) 1500 { 1501 for (d = w; d; d--) 1502 { 1503 /*NewportWaitGFIFO(pNewport, 1);*/ 1504 /* hopefully we cannot write faster than XL24 can blend */ 1505 pNewportRegs->go.hostrw0 = *p++; 1506 } 1507 p += add; 1508 } 1509} 1510 1511/******************************************************************************* 1512 1513*******************************************************************************/ 1514static void 1515NewportRenderTextureScale(NewportPtr pNewport, int srcx, int srcy, int w, int h) 1516{ 1517 int d; 1518 int dx, dy; 1519 int curx, cury; 1520 unsigned int *pLine; 1521 int l, p; 1522 NewportRegsPtr pNewportRegs; 1523 pNewportRegs = pNewport->pNewportRegs; 1524 1525 dx = ((pNewport->uTextureWidth - srcx) << 16) / w; 1526 dy = ((pNewport->uTextureHeight - srcy) << 16) / h; 1527 1528 cury = srcy << 16; 1529 while (h--) 1530 { 1531 l = (cury + 0x7FFF) >> 16; 1532 if (l >= pNewport->uTextureHeight) 1533 l = pNewport->uTextureHeight-1; 1534 pLine = pNewport->pTexture + l * pNewport->uTextureWidth; 1535 1536 curx = srcx << 16; 1537 for (d = w; d; d--) 1538 { 1539 p = (curx + 0x7FFF) >> 16; 1540 if (p >= pNewport->uTextureWidth) 1541 p = pNewport->uTextureWidth-1; 1542 pNewportRegs->go.hostrw0 = pLine[p]; 1543 curx += dx; 1544 } 1545 cury += dy; 1546 } 1547} 1548 1549/******************************************************************************* 1550 1551*******************************************************************************/ 1552static void 1553NewportRenderTextureRepeat(NewportPtr pNewport, int srcx, int srcy, int w, int h) 1554{ 1555 int d; 1556 unsigned int *pLine; 1557 NewportRegsPtr pNewportRegs; 1558 pNewportRegs = pNewport->pNewportRegs; 1559 1560 srcx %= pNewport->uTextureWidth; 1561 srcy %= pNewport->uTextureHeight; 1562 1563 while (h--) 1564 { 1565 pLine = pNewport->pTexture + pNewport->uTextureWidth * srcy; 1566 for (d = w; d; d--) 1567 { 1568 pNewportRegs->go.hostrw0 = pLine[srcx]; 1569 srcx++; 1570 if (srcx >= pNewport->uTextureWidth) 1571 srcx = 0; 1572 } 1573 srcy++; 1574 if (srcy >= pNewport->uTextureHeight) 1575 srcy = 0; 1576 } 1577 1578} 1579 1580 1581/******************************************************************************* 1582 1583*******************************************************************************/ 1584static void 1585NewportXAASubsequentCPUToScreenTexture( 1586 ScrnInfoPtr pScrn, 1587 int x, 1588 int y, 1589 int srcx, 1590 int srcy, 1591 int w, 1592 int h) 1593{ 1594 int ex, ey; 1595 NewportRegsPtr pNewportRegs; 1596 NewportPtr pNewport; 1597 pNewport = NEWPORTPTR(pScrn); 1598 pNewportRegs = NEWPORTREGSPTR(pScrn); 1599 1600 if (w == 0) w = 1; 1601 if (h == 0) h = 1; 1602 ex = x + w - 1; 1603 ey = y + h - 1; 1604 1605 NewportWaitGFIFO(pNewport, 3); 1606 pNewportRegs->set.xystarti = ((x & 0xFFFF) << 16) | (y & 0xFFFF); 1607 pNewportRegs->set.xyendi = ((ex & 0xFFFF) << 16) | (ey & 0xFFFF); 1608 pNewportRegs->set._setup = 1; 1609 1610 NewportWaitIdle(pNewport, NEWPORT_GFIFO_ENTRIES); 1611 1612 if (srcx + w == pNewport->uTextureWidth 1613 && srcy + h == pNewport->uTextureHeight) 1614 NewportRenderTexture1to1(pNewport, srcx, srcy, w, h); 1615 else 1616 if (pNewport->uTextureFlags & XAA_RENDER_REPEAT) 1617 NewportRenderTextureRepeat(pNewport, srcx, srcy, w, h); 1618 else 1619 NewportRenderTextureScale(pNewport, srcx, srcy, w, h); 1620 1621 NewportWaitIdle(pNewport, NEWPORT_GFIFO_ENTRIES); 1622 1623} 1624 1625CARD32 NewportAlphaTextureFormats[2] = {PICT_a8, 0}; 1626CARD32 NewportTextureFormats[3] = {PICT_a8r8g8b8, PICT_a8b8g8r8, 0}; 1627/*CARD32 NewportTextureFormats[2] = {PICT_a8r8g8b8, 0};*/ 1628CARD32 NewportDstFormats[7] = {PICT_a8r8g8b8, PICT_a8b8g8r8, PICT_x8r8g8b8, PICT_x8b8g8r8, PICT_r8g8b8, PICT_b8g8r8, 0}; 1629 1630#endif 1631 1632/******************************************************************************* 1633 1634*******************************************************************************/ 1635Bool 1636NewportXAAScreenInit(ScreenPtr pScreen) 1637{ 1638 ScrnInfoPtr pScrn; 1639 NewportPtr pNewport; 1640 NewportRegsPtr pNewportRegs; 1641 XAAInfoRecPtr pXAAInfoRec; 1642 1643 /* First get a pointer to our private info */ 1644 pScrn = xf86Screens[pScreen->myNum]; 1645 pNewport = NEWPORTPTR(pScrn); 1646 pNewportRegs = NEWPORTREGSPTR(pScrn); 1647 1648 pXAAInfoRec = 1649 pNewport->pXAAInfoRec = XAACreateInfoRec(); 1650 /* initialize accelerated functions */ 1651 pXAAInfoRec->Sync = NewportXAASync; 1652 1653 pXAAInfoRec->Flags = 0 1654 /*| LINEAR_FRAMEBUFFER*/ 1655 ; 1656 /* screen to screen copy */ 1657 pXAAInfoRec->ScreenToScreenCopyFlags = 0 1658 | NO_TRANSPARENCY 1659 ; 1660 pXAAInfoRec->SetupForScreenToScreenCopy = NewportXAASetupForScreenToScreenCopy; 1661 pXAAInfoRec->SubsequentScreenToScreenCopy = NewportXAASubsequentScreenToScreenCopy; 1662 1663 /* solid fills */ 1664 pXAAInfoRec->SolidFillFlags = 0 1665 ; 1666 pXAAInfoRec->SetupForSolidFill = NewportXAASetupForSolidFill; 1667 pXAAInfoRec->SubsequentSolidFillRect = NewportXAASubsequentSolidFillRect; 1668 1669 /* solid lines */ 1670 pXAAInfoRec->SolidLineFlags = 0 1671 ; 1672 pXAAInfoRec->SetupForSolidLine = NewportXAASetupForSolidLine; 1673 pXAAInfoRec->SubsequentSolidTwoPointLine = NewportXAASubsequentSolidTwoPointLine; 1674 1675 /* dashed lines */ 1676 pXAAInfoRec->DashedLineFlags = 0 1677 | LINE_PATTERN_MSBFIRST_MSBJUSTIFIED 1678 ; 1679 pXAAInfoRec->DashPatternMaxLength = 2048; 1680 pXAAInfoRec->SetupForDashedLine = NewportXAASetupForDashedLine; 1681 pXAAInfoRec->SubsequentDashedTwoPointLine = NewportXAASubsequentDashedTwoPointLine; 1682 1683 /* cpu to screen expand color fill */ 1684 pXAAInfoRec->CPUToScreenColorExpandFillFlags = 0 1685 | BIT_ORDER_IN_BYTE_LSBFIRST 1686 | SCANLINE_PAD_DWORD 1687 | CPU_TRANSFER_PAD_DWORD 1688 | CPU_TRANSFER_BASE_FIXED 1689 | LEFT_EDGE_CLIPPING 1690 | LEFT_EDGE_CLIPPING_NEGATIVE_X 1691 /*| SYNC_AFTER_COLOR_EXPAND*/ 1692 ; 1693 1694 pXAAInfoRec->SetupForCPUToScreenColorExpandFill = NewportXAASetupForCPUToScreenColorExpandFill; 1695 pXAAInfoRec->SubsequentCPUToScreenColorExpandFill = NewportXAASubsequentCPUToScreenColorExpandFill; 1696 pXAAInfoRec->ColorExpandRange = 4; 1697 pXAAInfoRec->ColorExpandBase = (unsigned char *)&(pNewportRegs->go.zpattern); 1698 1699 1700 /* mono 8x8 pattern fill */ 1701 pXAAInfoRec->Mono8x8PatternFillFlags = 0 1702 | BIT_ORDER_IN_BYTE_LSBFIRST 1703 | HARDWARE_PATTERN_PROGRAMMED_BITS 1704#ifdef NEWPORT_PREROTATE 1705 | HARDWARE_PATTERN_PROGRAMMED_ORIGIN 1706#endif 1707 ; 1708 1709 pXAAInfoRec->SetupForMono8x8PatternFill = NewportXAASetupForMono8x8PatternFill; 1710 pXAAInfoRec->SubsequentMono8x8PatternFillRect = NewportXAASubsequentMono8x8PatternFillRect; 1711 1712 /* Image write */ 1713 pXAAInfoRec->ImageWriteFlags = 0 1714 | NO_TRANSPARENCY 1715 | CPU_TRANSFER_BASE_FIXED 1716 | CPU_TRANSFER_PAD_DWORD 1717 | SCANLINE_PAD_DWORD 1718 | LEFT_EDGE_CLIPPING 1719 | LEFT_EDGE_CLIPPING_NEGATIVE_X 1720 /*| SYNC_AFTER_IMAGE_WRITE*/ 1721 ; 1722 pXAAInfoRec->SetupForImageWrite = NewportXAASetupForImageWrite; 1723 pXAAInfoRec->SubsequentImageWriteRect = NewportXAASubsequentImageWriteRect; 1724 pXAAInfoRec->ImageWriteRange = 4; 1725 pXAAInfoRec->ImageWriteBase = (unsigned char *)&(pNewportRegs->go.hostrw0); 1726 1727 /* read pixmap */ 1728 pXAAInfoRec->ReadPixmapFlags = 0 1729 | CPU_TRANSFER_PAD_DWORD 1730 ; 1731 pXAAInfoRec->ReadPixmap = NewportXAAReadPixmap; 1732 1733 /* clipping */ 1734 pXAAInfoRec->ClippingFlags = 0 1735 /*| HARDWARE_CLIP_SCREEN_TO_SCREEN_COLOR_EXPAND*/ 1736 | HARDWARE_CLIP_SCREEN_TO_SCREEN_COPY 1737 | HARDWARE_CLIP_MONO_8x8_FILL 1738 /*| HARDWARE_CLIP_COLOR_8x8_FILL*/ 1739 | HARDWARE_CLIP_SOLID_FILL 1740 | HARDWARE_CLIP_DASHED_LINE 1741 | HARDWARE_CLIP_SOLID_LINE 1742 ; 1743 pXAAInfoRec->SetClippingRectangle = NewportXAASetClippingRectangle; 1744 pXAAInfoRec->DisableClipping = NewportXAADisableClipping; 1745 1746 /* make it draw points using our function */ 1747 pXAAInfoRec->ValidatePolyPoint = NewportValidatePolyPoint; 1748 pXAAInfoRec->PolyPointMask = GCFunction | GCPlaneMask; 1749 /*pXAAInfoRec->PolyPointMask = 0xFFFFFFFF;*/ 1750 1751 pXAAInfoRec->ValidatePolyArc = NewportValidatePolyArc; 1752 pXAAInfoRec->PolyArcMask = GCFunction | GCLineWidth; 1753#ifdef RENDER 1754 if (pScrn->bitsPerPixel > 8) 1755 { 1756 pXAAInfoRec->CPUToScreenTextureFlags = 0 1757 ; 1758 pXAAInfoRec->CPUToScreenTextureFormats = NewportTextureFormats; 1759 pXAAInfoRec->CPUToScreenTextureDstFormats = NewportDstFormats; 1760 pXAAInfoRec->SetupForCPUToScreenTexture2 = NewportXAASetupForCPUToScreenTexture; 1761 pXAAInfoRec->SubsequentCPUToScreenTexture = NewportXAASubsequentCPUToScreenTexture; 1762 1763 pXAAInfoRec->CPUToScreenAlphaTextureFlags = 0 1764 ; 1765 pXAAInfoRec->CPUToScreenAlphaTextureFormats = NewportAlphaTextureFormats; 1766 pXAAInfoRec->CPUToScreenAlphaTextureDstFormats = NewportDstFormats; 1767 pXAAInfoRec->SetupForCPUToScreenAlphaTexture2 = NewportXAASetupForCPUToScreenAlphaTexture; 1768 pXAAInfoRec->SubsequentCPUToScreenAlphaTexture = NewportXAASubsequentCPUToScreenTexture; /* this is the same for both */ 1769 pNewport->pTexture = (unsigned int *)xnfalloc(pNewport->uTextureSize = 16*16*sizeof(unsigned int)); 1770 } 1771#endif 1772 1773 pNewport->Color2Planes = NewportColor2Planes24; 1774 if (pScrn->bitsPerPixel == 8) 1775 { 1776 pNewport->Color2Planes = NewportColor2Planes8; 1777 } 1778 1779 if (!XAAInit(pScreen, pXAAInfoRec)) 1780 { 1781 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "XAAInit Failed!\n"); 1782 return FALSE; 1783 } 1784 1785 pNewport->fifoleft = 0; 1786 /* init bunch of registers */ 1787 1788 pNewport->shadow_drawmode0 = pNewportRegs->set.drawmode0; 1789 pNewport->shadow_colori = pNewportRegs->set.colori; 1790 pNewport->shadow_smask0x = pNewportRegs->set.smask0x; 1791 pNewport->shadow_smask0y = pNewportRegs->set.smask0y; 1792 1793 pNewport->shadow_drawmode1 = pNewport->drawmode1; 1794 pNewportRegs->set.drawmode1 = pNewport->drawmode1; 1795 pNewport->setup_drawmode1 = pNewport->drawmode1 & ~NPORT_DMODE1_LOMASK; 1796 1797 pNewport->shadow_xymove = 0; 1798 pNewportRegs->set.xymove = 0; 1799 1800 pNewport->shadow_wrmask = 0xFFFFFF; 1801 pNewportRegs->set.wrmask = 0xFFFFFF; 1802 1803 pNewport->shadow_colorvram = 0; 1804 pNewportRegs->set.colorvram = 0; 1805 1806 pNewport->shadow_colorback = 0; 1807 pNewportRegs->set.colorback = 0; 1808 1809 pNewport->clipsx = 0; 1810 pNewport->clipex = pScrn->virtualX-1; 1811 pNewport->clipsy = 0; 1812 pNewport->clipey = pScrn->virtualY-1; 1813 pNewport->skipleft = 0; 1814 1815 BARF1("CLIPMODE %08X\n", pNewportRegs->cset.clipmode); 1816 BARF1("XYWIN %08X\n", pNewportRegs->cset.xywin); 1817 BARF1("CONFIG %08X\n", pNewportRegs->cset.config); 1818 BARF1("SMASK0X %08X\n", pNewportRegs->set.smask0x); 1819 BARF1("SMASK0Y %08X\n", pNewportRegs->set.smask0y); 1820 1821/* 1822 set GIO bus timeout to highest possible value 4.32us 1823 this will allow for longer bus stalls without bus error 1824*/ 1825 { 1826 unsigned int conf; 1827 conf = pNewportRegs->cset.config; 1828 conf &= ~NPORT_CFG_TOMSK; 1829 conf |= NPORT_CFG_TOMSK; 1830 1831 conf &= ~NPORT_CFG_GDMSK; 1832 conf |= NPORT_CFG_GDMSK; 1833 1834 pNewportRegs->cset.config = conf; 1835 } 1836 1837 BARF1("CONFIG %08X\n", pNewportRegs->cset.config); 1838 1839 pNewport->shadow_clipmode = pNewportRegs->cset.clipmode; 1840 pNewportRegs->cset.clipmode |= 1; /* enable clipping mask 0 */ 1841 NewportUpdateClipping(pNewport); 1842 1843 return TRUE; 1844} 1845 1846#endif 1847/* NEWPORT_ACCEL */ 1848