1/* 2 * 2D acceleration for SiS5597/5598 and 6326 3 * 4 * Copyright (C) 1998, 1999 by Alan Hourihane, Wigan, England. 5 * Parts Copyright (C) 2001-2005 Thomas Winischhofer, Vienna, Austria. 6 * 7 * Licensed under the following terms: 8 * 9 * Permission to use, copy, modify, distribute, and sell this software and its 10 * documentation for any purpose is hereby granted without fee, provided that 11 * the above copyright notice appears in all copies and that both that copyright 12 * notice and this permission notice appear in supporting documentation, and 13 * and that the name of the copyright holder not be used in advertising 14 * or publicity pertaining to distribution of the software without specific, 15 * written prior permission. The copyright holder makes no representations 16 * about the suitability of this software for any purpose. It is provided 17 * "as is" without expressed or implied warranty. 18 * 19 * THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 20 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO 21 * EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR 22 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 23 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 24 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 25 * PERFORMANCE OF THIS SOFTWARE. 26 * 27 * Authors: Alan Hourihane <alanh@fairlite.demon.co.uk>, 28 * Mike Chapman <mike@paranoia.com>, 29 * Juanjo Santamarta <santamarta@ctv.es>, 30 * Mitani Hiroshi <hmitani@drl.mei.co.jp>, 31 * David Thomas <davtom@dream.org.uk>, 32 * Thomas Winischhofer <thomas@winischhofer.net>. 33 */ 34 35#ifdef HAVE_CONFIG_H 36#include "config.h" 37#endif 38 39#include "sis.h" 40#include "sis_regs.h" 41#ifdef SIS_USE_XAA 42#include "xaarop.h" 43#endif 44#include "sis_accel.h" 45 46#ifdef SIS_USE_XAA 47 48#if 0 49#define CTSCE /* Include enhanced color expansion code */ 50#endif /* This produces drawing errors sometimes */ 51 52#endif /* XAA */ 53 54#ifdef SIS_USE_EXA 55extern void SiSScratchSave(ScreenPtr pScreen, ExaOffscreenArea *area); 56extern Bool SiSUploadToScratch(PixmapPtr pSrc, PixmapPtr pDst); 57#endif /* EXA */ 58 59extern UChar SiSGetCopyROP(int rop); 60extern UChar SiSGetPatternROP(int rop); 61 62static void 63SiSInitializeAccelerator(ScrnInfoPtr pScrn) 64{ 65 /* Nothing here yet */ 66} 67 68/* sync */ 69static void 70SiSSync(ScrnInfoPtr pScrn) 71{ 72 SISPtr pSiS = SISPTR(pScrn); 73 74 sisBLTSync; 75} 76 77static void 78SiSSyncAccel(ScrnInfoPtr pScrn) 79{ 80 SISPtr pSiS = SISPTR(pScrn); 81 82 if(!pSiS->NoAccel) SiSSync(pScrn); 83} 84 85/* Screen to screen copy */ 86static void 87SiSSetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir, 88 int rop, unsigned int planemask, 89 int transparency_color) 90{ 91 SISPtr pSiS = SISPTR(pScrn); 92 93 sisBLTSync; 94 sisSETPITCH(pSiS->scrnOffset, pSiS->scrnOffset); 95 96 sisSETROP(SiSGetCopyROP(rop)); 97 pSiS->Xdirection = xdir; 98 pSiS->Ydirection = ydir; 99} 100 101static void 102SiSSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, int y1, int x2, 103 int y2, int w, int h) 104{ 105 SISPtr pSiS = SISPTR(pScrn); 106 int srcaddr, destaddr, op; 107 108 op = sisCMDBLT | sisSRCVIDEO; 109 110 if(pSiS->Ydirection == -1) { 111 op |= sisBOTTOM2TOP; 112 srcaddr = (y1 + h - 1) * pSiS->CurrentLayout.displayWidth; 113 destaddr = (y2 + h - 1) * pSiS->CurrentLayout.displayWidth; 114 } else { 115 op |= sisTOP2BOTTOM; 116 srcaddr = y1 * pSiS->CurrentLayout.displayWidth; 117 destaddr = y2 * pSiS->CurrentLayout.displayWidth; 118 } 119 120 if(pSiS->Xdirection == -1) { 121 op |= sisRIGHT2LEFT; 122 srcaddr += x1 + w - 1; 123 destaddr += x2 + w - 1; 124 } else { 125 op |= sisLEFT2RIGHT; 126 srcaddr += x1; 127 destaddr += x2; 128 } 129 130 if(pSiS->ClipEnabled) 131 op |= sisCLIPINTRN | sisCLIPENABL; 132 133 srcaddr *= (pSiS->CurrentLayout.bitsPerPixel/8); 134 destaddr *= (pSiS->CurrentLayout.bitsPerPixel/8); 135 if(((pSiS->CurrentLayout.bitsPerPixel / 8) > 1) && (pSiS->Xdirection == -1)) { 136 srcaddr += (pSiS->CurrentLayout.bitsPerPixel/8)-1; 137 destaddr += (pSiS->CurrentLayout.bitsPerPixel/8)-1; 138 } 139 140 sisBLTSync; 141 sisSETSRCADDR(srcaddr); 142 sisSETDSTADDR(destaddr); 143 sisSETHEIGHTWIDTH(h-1, w * (pSiS->CurrentLayout.bitsPerPixel/8)-1); 144 sisSETCMD(op); 145} 146 147/* solid fill */ 148static void 149SiSSetupForFillRectSolid(ScrnInfoPtr pScrn, int color, int rop, 150 unsigned int planemask) 151{ 152 SISPtr pSiS = SISPTR(pScrn); 153 154 sisBLTSync; 155 sisSETBGROPCOL(SiSGetCopyROP(rop), color); 156 sisSETFGROPCOL(SiSGetCopyROP(rop), color); 157 sisSETPITCH(pSiS->scrnOffset, pSiS->scrnOffset); 158} 159 160static void 161SiSSubsequentFillRectSolid(ScrnInfoPtr pScrn, int x, int y, int w, int h) 162{ 163 SISPtr pSiS = SISPTR(pScrn); 164 int destaddr, op; 165 166 destaddr = y * pSiS->CurrentLayout.displayWidth + x; 167 168 op = sisCMDBLT | sisSRCBG | sisTOP2BOTTOM | sisLEFT2RIGHT; 169 170 if(pSiS->ClipEnabled) 171 op |= sisCLIPINTRN | sisCLIPENABL; 172 173 destaddr *= (pSiS->CurrentLayout.bitsPerPixel / 8); 174 175 sisBLTSync; 176 sisSETHEIGHTWIDTH(h-1, w * (pSiS->CurrentLayout.bitsPerPixel/8)-1); 177 sisSETDSTADDR(destaddr); 178 sisSETCMD(op); 179} 180 181#ifdef SIS_USE_XAA /* ---------------------------- XAA -------------------------- */ 182 183/* Clipping */ 184static void 185SiSSetClippingRectangle(ScrnInfoPtr pScrn, 186 int left, int top, int right, int bottom) 187{ 188 SISPtr pSiS = SISPTR(pScrn); 189 190 sisBLTSync; 191 sisSETCLIPTOP(left,top); 192 sisSETCLIPBOTTOM(right,bottom); 193 pSiS->ClipEnabled = TRUE; 194} 195 196static void 197SiSDisableClipping(ScrnInfoPtr pScrn) 198{ 199 SISPtr pSiS = SISPTR(pScrn); 200 pSiS->ClipEnabled = FALSE; 201} 202 203/* 8x8 mono */ 204static void 205SiSSetupForMono8x8PatternFill(ScrnInfoPtr pScrn, int patternx, int patterny, 206 int fg, int bg, int rop, unsigned int planemask) 207{ 208 SISPtr pSiS = SISPTR(pScrn); 209 unsigned int *patternRegPtr; 210 int i; 211 212 (void)XAAHelpPatternROP(pScrn, &fg, &bg, planemask, &rop); 213 214 sisBLTSync; 215 if(bg != -1) { 216 sisSETBGROPCOL(0xcc, bg); /* copy */ 217 } else { 218 sisSETBGROPCOL(0xAA, bg); /* noop */ 219 } 220 sisSETFGROPCOL(rop, fg); 221 sisSETPITCH(0, pSiS->scrnOffset); 222 sisSETSRCADDR(0); 223 patternRegPtr = (unsigned int *)sisSETPATREG(); 224 pSiS->sisPatternReg[0] = pSiS->sisPatternReg[2] = patternx ; 225 pSiS->sisPatternReg[1] = pSiS->sisPatternReg[3] = patterny ; 226 for(i = 0 ; i < 16 /* sisPatternHeight */ ; ) { 227 patternRegPtr[i++] = patternx ; 228 patternRegPtr[i++] = patterny ; 229 } 230} 231 232static void 233SiSSubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, int patternx, 234 int patterny, int x, int y, int w, int h) 235{ 236 SISPtr pSiS = SISPTR(pScrn); 237 register UChar *patternRegPtr; 238 register UChar *srcPatternRegPtr; 239 register unsigned int *patternRegPtrL; 240 UShort tmp; 241 int dstaddr, i, k, shift; 242 int op = sisCMDCOLEXP | 243 sisTOP2BOTTOM | 244 sisLEFT2RIGHT | 245 sisPATFG | 246 sisSRCBG; 247 248 if(pSiS->ClipEnabled) 249 op |= sisCLIPINTRN | sisCLIPENABL; 250 251 dstaddr = ( y * pSiS->CurrentLayout.displayWidth + x ) * 252 pSiS->CurrentLayout.bitsPerPixel / 8; 253 254 sisBLTSync; 255 256 patternRegPtr = sisSETPATREG(); 257 srcPatternRegPtr = (UChar *)pSiS->sisPatternReg ; 258 shift = 8 - patternx ; 259 for(i = 0, k = patterny ; i < 8 ; i++, k++ ) { 260 tmp = srcPatternRegPtr[k]<<8 | srcPatternRegPtr[k] ; 261 tmp >>= shift ; 262 patternRegPtr[i] = tmp & 0xff; 263 } 264 patternRegPtrL = (unsigned int *)sisSETPATREG(); 265 for(i = 2 ; i < 16 /* sisPatternHeight */; ) { 266 patternRegPtrL[i++] = patternRegPtrL[0]; 267 patternRegPtrL[i++] = patternRegPtrL[1]; 268 } 269 270 sisSETDSTADDR(dstaddr); 271 sisSETHEIGHTWIDTH(h-1, w*(pSiS->CurrentLayout.bitsPerPixel/8)-1); 272 sisSETCMD(op); 273} 274 275/* Line */ 276static void 277SiSSetupForSolidLine(ScrnInfoPtr pScrn, 278 int color, int rop, unsigned int planemask) 279{ 280 SISPtr pSiS = SISPTR(pScrn); 281 282 sisBLTSync; 283 sisSETBGROPCOL(SiSGetCopyROP(rop), 0); 284 sisSETFGROPCOL(SiSGetCopyROP(rop), color); 285} 286 287static void 288SiSSubsequentSolidTwoPointLine(ScrnInfoPtr pScrn, 289 int x1, int y1, int x2, int y2, int flags) 290 291{ 292 SISPtr pSiS = SISPTR(pScrn); 293 int op, major, minor, err, K1, K2, tmp; 294 295 op = sisCMDLINE | sisSRCFG; 296 297 if((flags & OMIT_LAST)) 298 op |= sisLASTPIX; 299 300 if(pSiS->ClipEnabled) 301 op |= sisCLIPINTRN | sisCLIPENABL; 302 303 if((major = x2 - x1) <= 0) 304 major = -major; 305 else 306 op |= sisXINCREASE; 307 308 if((minor = y2 - y1) <= 0) 309 minor = -minor; 310 else 311 op |= sisYINCREASE; 312 313 if(minor >= major) { 314 tmp = minor; 315 minor = major; 316 major = tmp; 317 } else 318 op |= sisXMAJOR; 319 320 K1 = (minor - major) << 1; 321 K2 = minor << 1; 322 err = (minor << 1) - major; 323 324 sisBLTSync; 325 sisSETXStart(x1); 326 sisSETYStart(y1); 327 sisSETLineSteps((short)K1,(short)K2); 328 sisSETLineErrorTerm((short)err); 329 sisSETLineMajorCount((short)major); 330 sisSETCMD(op); 331} 332 333static void 334SiSSubsequentSolidHorVertLine(ScrnInfoPtr pScrn, 335 int x, int y, int len, int dir) 336{ 337 SISPtr pSiS = SISPTR(pScrn); 338 int destaddr, op; 339 340 destaddr = y * pSiS->CurrentLayout.displayWidth + x; 341 342 op = sisCMDBLT | sisSRCFG | sisTOP2BOTTOM | sisLEFT2RIGHT; 343 344 if(pSiS->ClipEnabled) 345 op |= sisCLIPINTRN | sisCLIPENABL; 346 347 destaddr *= (pSiS->CurrentLayout.bitsPerPixel / 8); 348 349 sisBLTSync; 350 351 sisSETPITCH(pSiS->scrnOffset, pSiS->scrnOffset); 352 353 if(dir == DEGREES_0) { 354 sisSETHEIGHTWIDTH(0, len * (pSiS->CurrentLayout.bitsPerPixel >> 3) - 1); 355 } else { 356 sisSETHEIGHTWIDTH(len - 1, (pSiS->CurrentLayout.bitsPerPixel >> 3) - 1); 357 } 358 359 sisSETDSTADDR(destaddr); 360 sisSETCMD(op); 361} 362 363#ifdef CTSCE 364/* ----- CPU To Screen Color Expand (scanline-wise) ------ */ 365static void 366SiSSetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, 367 int fg, int bg, int rop, unsigned int planemask) 368{ 369 SISPtr pSiS=SISPTR(pScrn); 370 371 pSiS->CommandReg = 0; 372 373 pSiS->CommandReg |= (sisCMDECOLEXP | 374 sisLEFT2RIGHT | 375 sisTOP2BOTTOM); 376 377 sisBLTSync; 378 379 /* The combination of flags in the following 380 * is not understandable. However, this is the 381 * only combination that seems to work. 382 */ 383 if(bg == -1) { 384 sisSETROPBG(0xAA); /* dst = dst (=noop) */ 385 pSiS->CommandReg |= sisSRCFG; 386 } else { 387 sisSETBGROPCOL(SiSGetPatternROP(rop), bg); 388 pSiS->CommandReg |= sisSRCFG | sisPATBG; 389 } 390 391 sisSETFGROPCOL(SiSGetCopyROP(rop), fg); 392 393 sisSETDSTPITCH(pSiS->scrnOffset); 394} 395 396 397static void 398SiSSubsequentScanlineCPUToScreenColorExpandFill( 399 ScrnInfoPtr pScrn, int x, int y, int w, 400 int h, int skipleft) 401{ 402 SISPtr pSiS = SISPTR(pScrn); 403 int _x0, _y0, _x1, _y1; 404 int op = pSiS->CommandReg; 405 406 if(skipleft > 0) { 407 _x0 = x + skipleft; 408 _y0 = y; 409 _x1 = x + w; 410 _y1 = y + h; 411 sisSETCLIPTOP(_x0, _y0); 412 sisSETCLIPBOTTOM(_x1, _y1); 413 op |= sisCLIPENABL; 414 } else { 415 op &= (~(sisCLIPINTRN | sisCLIPENABL)); 416 } 417 418 sisSETSRCPITCH(((((w + 7) / 8) + 3) >> 2) * 4); 419 420 sisSETHEIGHTWIDTH(1-1, (w * (pSiS->CurrentLayout.bitsPerPixel/8)) - 1); 421 422 pSiS->xcurrent = x; 423 pSiS->ycurrent = y; 424 425 pSiS->CommandReg = op; 426} 427 428static void 429SiSSubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno) 430{ 431 SISPtr pSiS = SISPTR(pScrn); 432 unsigned long cbo = pSiS->ColorExpandBufferScreenOffset[bufno]; 433 int op = pSiS->CommandReg; 434 int destaddr; 435 436 destaddr = (pSiS->ycurrent * pSiS->CurrentLayout.displayWidth) + pSiS->xcurrent; 437 destaddr *= (pSiS->CurrentLayout.bitsPerPixel / 8); 438 439 /* Wait until there is no color expansion command in queue */ 440 /* sisBLTSync; */ 441 442 sisSETSRCADDR(cbo); 443 444 sisSETDSTADDR(destaddr); 445 446 sisSETCMD(op); 447 448 pSiS->ycurrent++; 449 450 /* Wait for eventual color expand commands to finish */ 451 /* (needs to be done, otherwise the data in the buffer may 452 * be overwritten while accessed by the hardware) 453 */ 454 while((SIS_MMIO_IN32(pSiS->IOBase, 0x8284) & 0x80000000)) {} 455 456 sisBLTSync; 457} 458#endif /* CTSCE */ 459 460#endif /* XAA */ 461 462#ifdef SIS_USE_EXA /* ---------------------------- EXA -------------------------- */ 463 464static void 465SiSEXASync(ScreenPtr pScreen, int marker) 466{ 467 SISPtr pSiS = SISPTR(xf86ScreenToScrn(pScreen)); 468 469 sisBLTSync; 470} 471 472static Bool 473SiSPrepareSolid(PixmapPtr pPixmap, int alu, Pixel planemask, Pixel fg) 474{ 475 ScrnInfoPtr pScrn = xf86ScreenToScrn(pPixmap->drawable.pScreen); 476 SISPtr pSiS = SISPTR(pScrn); 477 478 /* Planemask not supported */ 479 if((planemask & ((1 << pPixmap->drawable.depth) - 1)) != 480 (1 << pPixmap->drawable.depth) - 1) { 481 return FALSE; 482 } 483 484 /* Since these old engines have no "dest color depth" register, I assume 485 * the 2D engine takes the bpp from the DAC... FIXME ? */ 486 if(pPixmap->drawable.bitsPerPixel != pSiS->CurrentLayout.bitsPerPixel) 487 return FALSE; 488 489 /* Check that the pitch matches the hardware's requirements. Should 490 * never be a problem due to pixmapPitchAlign and fbScreenInit. 491 */ 492 if(exaGetPixmapPitch(pPixmap) & 7) 493 return FALSE; 494 495 pSiS->fillPitch = exaGetPixmapPitch(pPixmap); 496 pSiS->fillBpp = pPixmap->drawable.bitsPerPixel >> 3; 497 pSiS->fillDstBase = (CARD32)exaGetPixmapOffset(pPixmap); 498 499 sisBLTSync; 500 sisSETBGROPCOL(SiSGetCopyROP(alu), fg); 501 sisSETFGROPCOL(SiSGetCopyROP(alu), fg); 502 sisSETPITCH(pSiS->fillPitch, pSiS->fillPitch); 503 504 return TRUE; 505} 506 507static void 508SiSSolid(PixmapPtr pPixmap, int x1, int y1, int x2, int y2) 509{ 510 ScrnInfoPtr pScrn = xf86ScreenToScrn(pPixmap->drawable.pScreen); 511 SISPtr pSiS = SISPTR(pScrn); 512 513 sisBLTSync; 514 sisSETHEIGHTWIDTH((y2 - y1) - 1, (x2 - x1) * pSiS->fillBpp - 1); 515 sisSETDSTADDR((pSiS->fillDstBase + ((y1 * (pSiS->fillPitch / pSiS->fillBpp) + x1) * pSiS->fillBpp))); 516 sisSETCMD((sisCMDBLT | sisSRCBG | sisTOP2BOTTOM | sisLEFT2RIGHT)); 517} 518 519static void 520SiSDoneSolid(PixmapPtr pPixmap) 521{ 522} 523 524static Bool 525SiSPrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, int xdir, int ydir, 526 int alu, Pixel planemask) 527{ 528 ScrnInfoPtr pScrn = xf86ScreenToScrn(pSrcPixmap->drawable.pScreen); 529 SISPtr pSiS = SISPTR(pScrn); 530 531 /* Planemask not supported */ 532 if((planemask & ((1 << pSrcPixmap->drawable.depth) - 1)) != 533 (1 << pSrcPixmap->drawable.depth) - 1) { 534 return FALSE; 535 } 536 537 /* Since these old engines have no "dest color depth" register, I assume 538 * the 2D engine takes the bpp from the DAC... FIXME ? */ 539 if(pDstPixmap->drawable.bitsPerPixel != pSiS->CurrentLayout.bitsPerPixel) 540 return FALSE; 541 542 /* Check that the pitch matches the hardware's requirements. Should 543 * never be a problem due to pixmapPitchAlign and fbScreenInit. 544 */ 545 if(exaGetPixmapPitch(pSrcPixmap) & 3) 546 return FALSE; 547 if(exaGetPixmapPitch(pDstPixmap) & 7) 548 return FALSE; 549 550 pSiS->copyXdir = xdir; 551 pSiS->copyYdir = ydir; 552 pSiS->copyBpp = pSrcPixmap->drawable.bitsPerPixel >> 3; 553 pSiS->copySPitch = exaGetPixmapPitch(pSrcPixmap); 554 pSiS->copyDPitch = exaGetPixmapPitch(pDstPixmap); 555 pSiS->copySrcBase = (CARD32)exaGetPixmapOffset(pSrcPixmap); 556 pSiS->copyDstBase = (CARD32)exaGetPixmapOffset(pDstPixmap); 557 558 sisBLTSync; 559 sisSETPITCH(pSiS->copySPitch, pSiS->copyDPitch); 560 sisSETROP(SiSGetCopyROP(alu)); 561 562 return TRUE; 563} 564 565static void 566SiSCopy(PixmapPtr pDstPixmap, int srcX, int srcY, int dstX, int dstY, int width, int height) 567{ 568 ScrnInfoPtr pScrn = xf86ScreenToScrn(pDstPixmap->drawable.pScreen); 569 SISPtr pSiS = SISPTR(pScrn); 570 CARD32 srcbase, dstbase, cmd; 571 int bpp = pSiS->copyBpp; 572 int srcPixelPitch = pSiS->copySPitch / bpp; 573 int dstPixelPitch = pSiS->copyDPitch / bpp; 574 575 cmd = sisCMDBLT | sisSRCVIDEO; 576 577 if(pSiS->copyYdir < 0) { 578 cmd |= sisBOTTOM2TOP; 579 srcbase = (srcY + height - 1) * srcPixelPitch; 580 dstbase = (dstY + height - 1) * dstPixelPitch; 581 } else { 582 cmd |= sisTOP2BOTTOM; 583 srcbase = srcY * srcPixelPitch; 584 dstbase = dstY * dstPixelPitch; 585 } 586 587 if(pSiS->copyXdir < 0) { 588 cmd |= sisRIGHT2LEFT; 589 srcbase += srcX + width - 1; 590 dstbase += dstX + width - 1; 591 } else { 592 cmd |= sisLEFT2RIGHT; 593 srcbase += srcX; 594 dstbase += dstX; 595 } 596 597 srcbase *= bpp; 598 dstbase *= bpp; 599 if(pSiS->copyXdir < 0) { 600 srcbase += bpp - 1; 601 dstbase += bpp - 1; 602 } 603 604 srcbase += pSiS->copySrcBase; 605 dstbase += pSiS->copyDstBase; 606 607 sisBLTSync; 608 sisSETSRCADDR(srcbase); 609 sisSETDSTADDR(dstbase); 610 sisSETHEIGHTWIDTH(height - 1, width * bpp - 1); 611 sisSETCMD(cmd); 612} 613 614static void 615SiSDoneCopy(PixmapPtr pDstPixmap) 616{ 617} 618 619#endif /* EXA */ 620 621/* For DGA usage */ 622 623static void 624SiSDGAFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h, int color) 625{ 626 SiSSetupForFillRectSolid(pScrn, color, GXcopy, ~0); 627 SiSSubsequentFillRectSolid(pScrn, x, y, w, h); 628} 629 630static void 631SiSDGABlitRect(ScrnInfoPtr pScrn, int srcx, int srcy, int dstx, int dsty, int w, int h, int color) 632{ 633 int xdir = ((srcx < dstx) && (srcy == dsty)) ? -1 : 1; 634 int ydir = (srcy < dsty) ? -1 : 1; 635 636 SiSSetupForScreenToScreenCopy(pScrn, xdir, ydir, GXcopy, (CARD32)~0, color); 637 SiSSubsequentScreenToScreenCopy(pScrn, srcx, srcy, dstx, dsty, w, h); 638} 639 640/* Initialisation */ 641 642Bool 643SiSAccelInit(ScreenPtr pScreen) 644{ 645 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 646 SISPtr pSiS = SISPTR(pScrn); 647#ifdef SIS_USE_XAA 648 XAAInfoRecPtr infoPtr = NULL; 649 int topFB, reservedFbSize, usableFbSize, i; 650 UChar *AvailBufBase; 651 BoxRec Avail; 652#endif 653 654 pSiS->ColorExpandBufferNumber = 0; 655 pSiS->PerColorExpandBufferSize = 0; 656 pSiS->RenderAccelArray = NULL; 657#ifdef SIS_USE_XAA 658 pSiS->AccelInfoPtr = NULL; 659#endif 660#ifdef SIS_USE_EXA 661 pSiS->EXADriverPtr = NULL; 662 pSiS->exa_scratch = NULL; 663#endif 664 665 if(!pSiS->NoAccel) { 666#ifdef SIS_USE_XAA 667 if(!pSiS->useEXA) { 668 pSiS->AccelInfoPtr = infoPtr = XAACreateInfoRec(); 669 if(!infoPtr) pSiS->NoAccel = TRUE; 670 } 671#endif 672#ifdef SIS_USE_EXA 673 if(pSiS->useEXA) { 674 if(!(pSiS->EXADriverPtr = exaDriverAlloc())) { 675 pSiS->NoAccel = TRUE; 676 pSiS->NoXvideo = TRUE; /* No fbmem manager -> no xv */ 677 } 678 } 679#endif 680 } 681 682 if(!pSiS->NoAccel) { 683 684 SiSInitializeAccelerator(pScrn); 685 686 pSiS->InitAccel = SiSInitializeAccelerator; 687 pSiS->SyncAccel = SiSSyncAccel; 688 pSiS->FillRect = SiSDGAFillRect; 689 pSiS->BlitRect = SiSDGABlitRect; 690 691#ifdef SIS_USE_XAA /* ----------------------- XAA ----------------------- */ 692 if(!pSiS->useEXA) { 693 694 infoPtr->Flags = LINEAR_FRAMEBUFFER | 695 OFFSCREEN_PIXMAPS | 696 PIXMAP_CACHE; 697 698 /* Sync */ 699 infoPtr->Sync = SiSSync; 700 701 /* Screen To Screen copy */ 702 infoPtr->SetupForScreenToScreenCopy = SiSSetupForScreenToScreenCopy; 703 infoPtr->SubsequentScreenToScreenCopy = SiSSubsequentScreenToScreenCopy; 704 infoPtr->ScreenToScreenCopyFlags = NO_TRANSPARENCY | NO_PLANEMASK; 705 706 /* Solid fill */ 707 infoPtr->SetupForSolidFill = SiSSetupForFillRectSolid; 708 infoPtr->SubsequentSolidFillRect = SiSSubsequentFillRectSolid; 709 infoPtr->SolidFillFlags = NO_PLANEMASK; 710 711 /* On 5597/5598 and 6326, clipping and lines only work 712 for 1024, 2048, 4096 logical width */ 713 if(pSiS->ValidWidth) { 714 /* Clipping */ 715 infoPtr->SetClippingRectangle = SiSSetClippingRectangle; 716 infoPtr->DisableClipping = SiSDisableClipping; 717 infoPtr->ClippingFlags = HARDWARE_CLIP_SOLID_LINE | 718 HARDWARE_CLIP_SCREEN_TO_SCREEN_COPY | 719 HARDWARE_CLIP_MONO_8x8_FILL | 720 HARDWARE_CLIP_SOLID_FILL ; 721 722 /* Solid Lines */ 723 infoPtr->SetupForSolidLine = SiSSetupForSolidLine; 724 infoPtr->SubsequentSolidTwoPointLine = SiSSubsequentSolidTwoPointLine; 725 infoPtr->SubsequentSolidHorVertLine = SiSSubsequentSolidHorVertLine; 726 infoPtr->SolidLineFlags = NO_PLANEMASK; 727 } 728 729 if(pScrn->bitsPerPixel != 24) { 730 /* 8x8 mono pattern */ 731 infoPtr->SetupForMono8x8PatternFill = SiSSetupForMono8x8PatternFill; 732 infoPtr->SubsequentMono8x8PatternFillRect = SiSSubsequentMono8x8PatternFillRect; 733 infoPtr->Mono8x8PatternFillFlags = NO_PLANEMASK | 734 HARDWARE_PATTERN_PROGRAMMED_BITS | 735 HARDWARE_PATTERN_PROGRAMMED_ORIGIN | 736 BIT_ORDER_IN_BYTE_MSBFIRST; 737 } 738 739#ifdef CTSCE 740 if(pScrn->bitsPerPixel != 24) { 741 /* per-scanline color expansion (using indirect method) */ 742 pSiS->ColorExpandBufferNumber = 4; 743 pSiS->ColorExpandBufferCountMask = 0x03; 744 pSiS->PerColorExpandBufferSize = ((pScrn->virtualX + 31) / 32) * 4; 745 746 infoPtr->NumScanlineColorExpandBuffers = pSiS->ColorExpandBufferNumber; 747 infoPtr->ScanlineColorExpandBuffers = (UChar **)&pSiS->ColorExpandBufferAddr[0]; 748 749 infoPtr->SetupForScanlineCPUToScreenColorExpandFill = 750 SiSSetupForScanlineCPUToScreenColorExpandFill; 751 infoPtr->SubsequentScanlineCPUToScreenColorExpandFill = 752 SiSSubsequentScanlineCPUToScreenColorExpandFill; 753 infoPtr->SubsequentColorExpandScanline = 754 SiSSubsequentColorExpandScanline; 755 infoPtr->ScanlineCPUToScreenColorExpandFillFlags = NO_PLANEMASK | 756 CPU_TRANSFER_PAD_DWORD | 757 SCANLINE_PAD_DWORD | 758 BIT_ORDER_IN_BYTE_MSBFIRST | 759 LEFT_EDGE_CLIPPING; 760 } 761#endif 762 } /* !exa */ 763#endif /* XAA */ 764 765#ifdef SIS_USE_EXA /* ----------------------- EXA ----------------------- */ 766 if(pSiS->useEXA) { 767 pSiS->EXADriverPtr->exa_major = 2; 768 pSiS->EXADriverPtr->exa_minor = 0; 769 770 /* data */ 771 pSiS->EXADriverPtr->memoryBase = pSiS->FbBase; 772 pSiS->EXADriverPtr->memorySize = pSiS->maxxfbmem; 773 pSiS->EXADriverPtr->offScreenBase = pScrn->virtualX * pScrn->virtualY 774 * (pScrn->bitsPerPixel >> 3); 775 if(pSiS->EXADriverPtr->memorySize > pSiS->EXADriverPtr->offScreenBase) { 776 pSiS->EXADriverPtr->flags = EXA_OFFSCREEN_PIXMAPS; 777 } else { 778 pSiS->NoXvideo = TRUE; 779 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 780 "Not enough video RAM for offscreen memory manager. Xv disabled\n"); 781 } 782 pSiS->EXADriverPtr->pixmapOffsetAlign = 8; /* src/dst: double quad word boundary */ 783 pSiS->EXADriverPtr->pixmapPitchAlign = 8; /* could possibly be 1, but who knows for sure */ 784 pSiS->EXADriverPtr->maxX = 2047; 785 pSiS->EXADriverPtr->maxY = 2047; 786 787 /* Sync */ 788 pSiS->EXADriverPtr->WaitMarker = SiSEXASync; 789 790 /* Solid fill */ 791 pSiS->EXADriverPtr->PrepareSolid = SiSPrepareSolid; 792 pSiS->EXADriverPtr->Solid = SiSSolid; 793 pSiS->EXADriverPtr->DoneSolid = SiSDoneSolid; 794 795 /* Copy */ 796 pSiS->EXADriverPtr->PrepareCopy = SiSPrepareCopy; 797 pSiS->EXADriverPtr->Copy = SiSCopy; 798 pSiS->EXADriverPtr->DoneCopy = SiSDoneCopy; 799 800 /* Composite not supported */ 801 802 } 803#endif /* EXA */ 804 805 } /* NoAccel */ 806 807 /* Offscreen memory manager 808 * 809 * Layout: (Sizes here do not reflect correct proportions) 810 * |--------------++++++++++++++++++++| ====================~~~~~~~~~~~~| 811 * UsableFbSize ColorExpandBuffers | TurboQueue HWCursor 812 * topFB 813 */ 814 815#ifdef SIS_USE_XAA 816 if(!pSiS->useEXA) { 817 818 topFB = pSiS->maxxfbmem; 819 820 reservedFbSize = pSiS->ColorExpandBufferNumber * pSiS->PerColorExpandBufferSize; 821 822 usableFbSize = topFB - reservedFbSize; 823 824 if(pSiS->ColorExpandBufferNumber) { 825 AvailBufBase = pSiS->FbBase + usableFbSize; 826 for(i = 0; i < pSiS->ColorExpandBufferNumber; i++) { 827 pSiS->ColorExpandBufferAddr[i] = AvailBufBase + 828 i * pSiS->PerColorExpandBufferSize; 829 pSiS->ColorExpandBufferScreenOffset[i] = usableFbSize + 830 i * pSiS->PerColorExpandBufferSize; 831 } 832 } 833 834 Avail.x1 = 0; 835 Avail.y1 = 0; 836 Avail.x2 = pScrn->displayWidth; 837 Avail.y2 = usableFbSize / (pScrn->displayWidth * pScrn->bitsPerPixel / 8) - 1; 838 839 if(Avail.y2 < 0) Avail.y2 = 32767; 840 841 if(Avail.y2 < pScrn->currentMode->VDisplay) { 842 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 843 "Not enough video RAM for accelerator: %dKB needed, %dKB available\n", 844 ((((pScrn->displayWidth * pScrn->bitsPerPixel/8) /* +8 for make it sure */ 845 * pScrn->currentMode->VDisplay) + reservedFbSize) / 1024) + 8, 846 pSiS->maxxfbmem/1024); 847 pSiS->NoAccel = TRUE; 848 pSiS->NoXvideo = TRUE; 849 XAADestroyInfoRec(pSiS->AccelInfoPtr); 850 pSiS->AccelInfoPtr = NULL; 851 return FALSE; 852 } 853 854 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 855 "Framebuffer from (%d,%d) to (%d,%d)\n", 856 Avail.x1, Avail.y1, Avail.x2 - 1, Avail.y2 - 1); 857 858 xf86InitFBManager(pScreen, &Avail); 859 860 if(!pSiS->NoAccel) { 861 return XAAInit(pScreen, infoPtr); 862 } 863 } /* !exa */ 864#endif 865 866#ifdef SIS_USE_EXA 867 if(pSiS->useEXA) { 868 869 if(!pSiS->NoAccel) { 870 871 if(!exaDriverInit(pScreen, pSiS->EXADriverPtr)) { 872 pSiS->NoAccel = TRUE; 873 pSiS->NoXvideo = TRUE; /* No fbmem manager -> no xv */ 874 return FALSE; 875 } 876 877 /* Reserve locked offscreen scratch area of 64K for glyph data */ 878 pSiS->exa_scratch = exaOffscreenAlloc(pScreen, 64 * 1024, 16, TRUE, 879 SiSScratchSave, pSiS); 880 if(pSiS->exa_scratch) { 881 pSiS->exa_scratch_next = pSiS->exa_scratch->offset; 882 pSiS->EXADriverPtr->UploadToScratch = SiSUploadToScratch; 883 } 884 885 } else { 886 887 pSiS->NoXvideo = TRUE; /* No fbmem manager -> no xv */ 888 889 } 890 891 } 892#endif /* EXA */ 893 894 return TRUE; 895} 896 897 898 899 900 901 902 903