sis310_accel.c revision 72b676d7
1/* $XFree86$ */ 2/* $XdotOrg: driver/xf86-video-sis/src/sis310_accel.c,v 1.31 2006-03-09 06:06:25 anholt Exp $ */ 3/* 4 * 2D Acceleration for SiS 315, 330 and 340 series 5 * 6 * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1) Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2) Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3) The name of the author may not be used to endorse or promote products 17 * derived from this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 * 30 * 31 * Author: Thomas Winischhofer <thomas@winischhofer.net> 32 * 33 * 2003/08/18: Rewritten for using VRAM command queue 34 * 35 */ 36 37#ifdef HAVE_CONFIG_H 38#include "config.h" 39#endif 40 41#include "sis.h" 42#define SIS_NEED_MYMMIO 43#define SIS_NEED_ACCELBUF 44#include "sis_regs.h" 45#include "sis310_accel.h" 46 47#if 0 48#define ACCELDEBUG 49#endif 50 51#define FBOFFSET (pSiS->dhmOffset) 52 53#define DEV_HEIGHT 0xfff /* "Device height of destination bitmap" */ 54 55#undef SIS_NEED_ARRAY 56 57/* For XAA */ 58 59#ifdef SIS_USE_XAA 60 61#undef TRAP /* Use/Don't use Trapezoid Fills 62 * DOES NOT WORK. XAA sometimes provides illegal 63 * trapezoid data (left and right edges cross each 64 * other) which causes drawing errors. Since 65 * checking the trapezoid for such a case is very 66 * time-intensive, it is faster to let it be done 67 * by the generic polygon functions. 68 * Does not work on 330 series at all, hangs the engine. 69 * Even with correct trapezoids, this is slower than 70 * doing it by the CPU. 71 */ 72 73#undef CTSCE /* Use/Don't use CPUToScreenColorExpand. Disabled 74 * because it is slower than doing it by the CPU. 75 * Indirect mode does not work in VRAM queue mode. 76 * Does not work on 330 series (even in MMIO mode). 77 */ 78#undef CTSCE_DIRECT /* Use direct method - This works (on both 315 and 330 at 79 * least in VRAM queue mode) but we don't use this either, 80 * because it's slower than doing it by the CPU. (Using it 81 * would require defining CTSCE) 82 */ 83 84#undef STSCE /* Use/Don't use ScreenToScreenColorExpand - does not work, 85 * see comments below. 86 */ 87 88#define INCL_RENDER /* Use/Don't use RENDER extension acceleration */ 89 90#ifdef INCL_RENDER 91# ifdef RENDER 92# include "mipict.h" 93# include "dixstruct.h" 94# define SIS_NEED_ARRAY 95# undef SISNEWRENDER 96# ifdef XORG_VERSION_CURRENT 97# if XORG_VERSION_CURRENT > XORG_VERSION_NUMERIC(6,7,0,0,0) 98# define SISNEWRENDER 99# endif 100# endif 101# endif 102#endif 103 104#endif /* XAA */ 105 106/* For EXA */ 107 108#ifdef SIS_USE_EXA 109#if 0 110#define SIS_HAVE_COMPOSITE /* Have our own EXA composite */ 111#endif 112#ifdef SIS_HAVE_COMPOSITE 113#ifndef SIS_NEED_ARRAY 114#define SIS_NEED_ARRAY 115#endif 116#endif 117#endif 118 119#ifdef SIS_USE_XAA /* XAA */ 120#ifdef INCL_RENDER 121#ifdef RENDER 122static CARD32 SiSAlphaTextureFormats[2] = { PICT_a8 , 0 }; 123static CARD32 SiSTextureFormats[2] = { PICT_a8r8g8b8, 0 }; 124#ifdef SISNEWRENDER 125static CARD32 SiSDstTextureFormats16[2] = { PICT_r5g6b5 , 0 }; 126static CARD32 SiSDstTextureFormats32[3] = { PICT_x8r8g8b8, PICT_a8r8g8b8, 0 }; 127#endif 128#endif /* RENDER */ 129#endif /* INCL_RENDER */ 130#endif /* XAA */ 131 132#ifdef SIS_USE_EXA /* EXA */ 133void SiSScratchSave(ScreenPtr pScreen, ExaOffscreenArea *area); 134Bool SiSUploadToScreen(PixmapPtr pDst, int x, int y, int w, int h, char *src, int src_pitch); 135Bool SiSUploadToScratch(PixmapPtr pSrc, PixmapPtr pDst); 136Bool SiSDownloadFromScreen(PixmapPtr pSrc, int x, int y, int w, int h, char *dst, int dst_pitch); 137#endif /* EXA */ 138 139#ifdef INCL_YUV_BLIT_ADAPTOR 140void SISWriteBlitPacket(SISPtr pSiS, CARD32 *packet); 141#endif 142 143extern unsigned char SiSGetCopyROP(int rop); 144extern unsigned char SiSGetPatternROP(int rop); 145 146CARD32 dummybuf; 147 148#ifdef SIS_NEED_ARRAY 149#if XF86_VERSION_CURRENT >= XF86_VERSION_NUMERIC(4,2,0,0,0) 150#define SiSRenderOpsMAX 0x2b 151#else 152#define SiSRenderOpsMAX 0x0f 153#endif 154static const CARD8 SiSRenderOps[] = { /* PictOpXXX 1 = supported, 0 = unsupported */ 155 1, 1, 1, 1, 156 0, 0, 0, 0, 157 0, 0, 0, 0, 158 0, 0, 0, 0, 159 1, 1, 1, 0, 160 0, 0, 0, 0, 161 0, 0, 0, 0, 162 0, 0, 0, 0, 163 1, 1, 1, 0, 164 0, 0, 0, 0, 165 0, 0, 0, 0, 166 0, 0, 0, 0 167}; 168#endif /* NEED ARRAY */ 169 170#ifdef SIS_NEED_ARRAY 171static void 172SiSCalcRenderAccelArray(ScrnInfoPtr pScrn) 173{ 174 SISPtr pSiS = SISPTR(pScrn); 175#ifdef SISDUALHEAD 176 SISEntPtr pSiSEnt = pSiS->entityPrivate;; 177#endif 178 179 if(((pScrn->bitsPerPixel == 16) || (pScrn->bitsPerPixel == 32)) && pSiS->doRender) { 180 int i, j; 181#ifdef SISDUALHEAD 182 if(pSiSEnt) pSiS->RenderAccelArray = pSiSEnt->RenderAccelArray; 183#endif 184 if(!pSiS->RenderAccelArray) { 185 if((pSiS->RenderAccelArray = xnfcalloc(65536, 1))) { 186#ifdef SISDUALHEAD 187 if(pSiSEnt) pSiSEnt->RenderAccelArray = pSiS->RenderAccelArray; 188#endif 189 for(i = 0; i < 256; i++) { 190 for(j = 0; j < 256; j++) { 191 pSiS->RenderAccelArray[(i << 8) + j] = (i * j) / 255; 192 } 193 } 194 } 195 } 196 } 197} 198#endif 199 200#ifdef SIS_USE_EXA 201void 202SiSScratchSave(ScreenPtr pScreen, ExaOffscreenArea *area) 203{ 204 SISPtr pSiS = SISPTR(xf86Screens[pScreen->myNum]); 205 206 pSiS->exa_scratch = NULL; 207} 208#endif 209 210static void 211SiSSync(ScrnInfoPtr pScrn) 212{ 213 SISPtr pSiS = SISPTR(pScrn); 214 215#ifdef SIS_USE_XAA 216 if(!pSiS->useEXA) { 217#ifdef CTSCE 218#ifdef CTSCE_DIRECT 219 if(pSiS->DoColorExpand) { 220 SiSDoCMD 221 pSiS->ColorExpandBusy = TRUE; 222 } 223#endif 224#endif 225 pSiS->DoColorExpand = FALSE; 226 } 227#endif 228 229 pSiS->alphaBlitBusy = FALSE; 230 231 SiSIdle 232} 233 234static void 235SiSSyncAccel(ScrnInfoPtr pScrn) 236{ 237 SISPtr pSiS = SISPTR(pScrn); 238 239 if(!pSiS->NoAccel) SiSSync(pScrn); 240} 241 242static void 243SiSInitializeAccelerator(ScrnInfoPtr pScrn) 244{ 245 SISPtr pSiS = SISPTR(pScrn); 246 247#ifdef SIS_USE_XAA 248 pSiS->DoColorExpand = FALSE; 249#endif 250 pSiS->alphaBlitBusy = FALSE; 251 252 if(!pSiS->NoAccel) { 253 254#ifndef SISVRAMQ 255 if(pSiS->ChipFlags & SiSCF_Integrated) { 256 CmdQueLen = 0; 257 } else { 258 CmdQueLen = ((128 * 1024) / 4) - 64; 259 } 260#endif 261 262#ifdef SISVRAMQ 263 if(pSiS->ChipType == XGI_40) { 264 SiSSync(pScrn); 265 SiSDualPipe(1); /* 1 = disable, 0 = enable */ 266 SiSSync(pScrn); 267 } 268#endif 269 270 } 271} 272 273static void 274SiSSetupForScreenToScreenCopy(ScrnInfoPtr pScrn, 275 int xdir, int ydir, int rop, 276 unsigned int planemask, int trans_color) 277{ 278 SISPtr pSiS = SISPTR(pScrn); 279 280#ifdef SISVRAMQ 281 SiSSetupDSTColorDepth(pSiS->SiS310_AccelDepth); 282 SiSCheckQueue(16 * 2); 283 SiSSetupSRCPitchDSTRect(pSiS->scrnOffset, pSiS->scrnOffset, DEV_HEIGHT) 284#else 285 SiSSetupDSTColorDepth(pSiS->DstColor); 286 SiSSetupSRCPitch(pSiS->scrnOffset) 287 SiSSetupDSTRect(pSiS->scrnOffset, DEV_HEIGHT) 288#endif 289 290 if(trans_color != -1) { 291 SiSSetupROP(0x0A) 292 SiSSetupSRCTrans(trans_color) 293 SiSSetupCMDFlag(TRANSPARENT_BITBLT) 294 } else { 295 SiSSetupROP(SiSGetCopyROP(rop)) 296 /* Set command - not needed, both 0 */ 297 /* SiSSetupCMDFlag(BITBLT | SRCVIDEO) */ 298 } 299 300#ifndef SISVRAMQ 301 SiSSetupCMDFlag(pSiS->SiS310_AccelDepth) 302#endif 303 304#ifdef SISVRAMQ 305 SiSSyncWP 306#endif 307 308 /* The chip is smart enough to know the direction */ 309} 310 311static void 312SiSSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, 313 int src_x, int src_y, int dst_x, int dst_y, 314 int width, int height) 315{ 316 SISPtr pSiS = SISPTR(pScrn); 317 CARD32 srcbase, dstbase; 318 int mymin, mymax; 319 320 srcbase = dstbase = 0; 321 mymin = min(src_y, dst_y); 322 mymax = max(src_y, dst_y); 323 324 /* Libxaa.a has a bug: The tilecache cannot operate 325 * correctly if there are 512x512 slots, but no 256x256 326 * slots. This leads to catastrophic data fed to us. 327 * Filter this out here and warn the user. 328 * Fixed in 4.3.99.10 (?) and Debian's 4.3.0.1 329 */ 330#if (XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,3,99,10,0)) && (XF86_VERSION_CURRENT != XF86_VERSION_NUMERIC(4,3,0,1,0)) 331 if((src_x < 0) || 332 (dst_x < 0) || 333 (src_y < 0) || 334 (dst_y < 0) || 335 (width <= 0) || 336 (height <= 0)) { 337 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 338 "BitBlit fatal error: Illegal coordinates:\n"); 339 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 340 "Source x %d y %d, dest x %d y %d, width %d height %d\n", 341 src_x, src_y, dst_x, dst_y, width, height); 342 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 343 "This is very probably caused by a known bug in libxaa.a.\n"); 344 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 345 "Please update libxaa.a to avoid this error.\n"); 346 return; 347 } 348#endif 349 350 /* Although the chip knows the direction to use 351 * if the source and destination areas overlap, 352 * that logic fails if we fiddle with the bitmap 353 * addresses. Therefore, we check if the source 354 * and destination blitting areas overlap and 355 * adapt the bitmap addresses synchronously 356 * if the coordinates exceed the valid range. 357 * The the areas do not overlap, we do our 358 * normal check. 359 */ 360 if((mymax - mymin) < height) { 361 if((src_y >= 2048) || (dst_y >= 2048)) { 362 srcbase = pSiS->scrnOffset * mymin; 363 dstbase = pSiS->scrnOffset * mymin; 364 src_y -= mymin; 365 dst_y -= mymin; 366 } 367 } else { 368 if(src_y >= 2048) { 369 srcbase = pSiS->scrnOffset * src_y; 370 src_y = 0; 371 } 372 if((dst_y >= pScrn->virtualY) || (dst_y >= 2048)) { 373 dstbase = pSiS->scrnOffset * dst_y; 374 dst_y = 0; 375 } 376 } 377 378 srcbase += FBOFFSET; 379 dstbase += FBOFFSET; 380 381#ifdef SISVRAMQ 382 SiSCheckQueue(16 * 3); 383 SiSSetupSRCDSTBase(srcbase, dstbase) 384 SiSSetupSRCDSTXY(src_x, src_y, dst_x, dst_y) 385 SiSSetRectDoCMD(width,height) 386#else 387 SiSSetupSRCBase(srcbase); 388 SiSSetupDSTBase(dstbase); 389 SiSSetupRect(width, height) 390 SiSSetupSRCXY(src_x, src_y) 391 SiSSetupDSTXY(dst_x, dst_y) 392 SiSDoCMD 393#endif 394} 395 396static void 397SiSSetupForSolidFill(ScrnInfoPtr pScrn, int color, 398 int rop, unsigned int planemask) 399{ 400 SISPtr pSiS = SISPTR(pScrn); 401 402 if(pSiS->disablecolorkeycurrent) { 403 if((CARD32)color == pSiS->colorKey) { 404 rop = 5; /* NOOP */ 405 } 406 } 407 408#ifdef SISVRAMQ 409 SiSSetupDSTColorDepth(pSiS->SiS310_AccelDepth); 410 SiSCheckQueue(16 * 1); 411 SiSSetupPATFGDSTRect(color, pSiS->scrnOffset, DEV_HEIGHT) 412 SiSSetupROP(SiSGetPatternROP(rop)) 413 SiSSetupCMDFlag(PATFG) 414 SiSSyncWP 415#else 416 SiSSetupPATFG(color) 417 SiSSetupDSTRect(pSiS->scrnOffset, DEV_HEIGHT) 418 SiSSetupDSTColorDepth(pSiS->DstColor); 419 SiSSetupROP(SiSGetPatternROP(rop)) 420 SiSSetupCMDFlag(PATFG | pSiS->SiS310_AccelDepth) 421#endif 422} 423 424static void 425SiSSubsequentSolidFillRect(ScrnInfoPtr pScrn, 426 int x, int y, int w, int h) 427{ 428 SISPtr pSiS = SISPTR(pScrn); 429 CARD32 dstbase = 0; 430 431 if(y >= 2048) { 432 dstbase = pSiS->scrnOffset * y; 433 y = 0; 434 } 435 436 dstbase += FBOFFSET; 437 438 pSiS->CommandReg &= ~(T_XISMAJORL | T_XISMAJORR | 439 T_L_X_INC | T_L_Y_INC | 440 T_R_X_INC | T_R_Y_INC | 441 TRAPAZOID_FILL); 442 443 /* SiSSetupCMDFlag(BITBLT) - BITBLT = 0 */ 444 445#ifdef SISVRAMQ 446 SiSCheckQueue(16 * 2) 447 SiSSetupDSTXYRect(x, y, w, h) 448 SiSSetupDSTBaseDoCMD(dstbase) 449#else 450 SiSSetupDSTBase(dstbase) 451 SiSSetupDSTXY(x, y) 452 SiSSetupRect(w, h) 453 SiSDoCMD 454#endif 455} 456 457#ifdef SIS_USE_XAA /* ---------------------------- XAA -------------------------- */ 458 459/* Trapezoid */ 460/* This would work better if XAA would provide us with valid trapezoids. 461 * In fact, with small trapezoids the left and the right edge often cross 462 * each other which causes drawing errors (filling over whole scanline). 463 * DOES NOT WORK ON 330 SERIES, HANGS THE ENGINE. 464 */ 465#ifdef TRAP 466static void 467SiSSubsequentSolidFillTrap(ScrnInfoPtr pScrn, int y, int h, 468 int left, int dxL, int dyL, int eL, 469 int right, int dxR, int dyR, int eR ) 470{ 471 SISPtr pSiS = SISPTR(pScrn); 472 CARD32 dstbase = 0; 473 474 if(y >= 2048) { 475 dstbase = pSiS->scrnOffset * y; 476 y = 0; 477 } 478 479 dstbase += FBOFFSET; 480 481#ifdef SISVRAMQ /* Not optimized yet */ 482 SiSCheckQueue(16 * 10) 483#else 484 SiSSetupDSTBase(dstbase) 485#endif 486 487#if 1 488 SiSSetupPATFG(0xff0000) /* FOR TESTING */ 489#endif 490 491 /* Clear CommandReg because SetUp can be used for Rect and Trap */ 492 pSiS->CommandReg &= ~(T_L_X_INC | T_L_Y_INC | 493 T_R_X_INC | T_R_Y_INC | 494 T_XISMAJORL | T_XISMAJORR | 495 BITBLT); 496 497 xf86DrvMsg(0, X_INFO, "Trap (%d %d %d %d) dxL %d dyL %d eL %d dxR %d dyR %d eR %d\n", 498 left, right, y, h, dxL, dyL, eL, dxR, dyR, eR); 499 500 /* Determine egde angles */ 501 if(dxL < 0) { dxL = -dxL; } 502 else { SiSSetupCMDFlag(T_L_X_INC) } 503 if(dxR < 0) { dxR = -dxR; } 504 else { SiSSetupCMDFlag(T_R_X_INC) } 505 506 /* (Y direction always positive - do this anyway) */ 507 if(dyL < 0) { dyL = -dyL; } 508 else { SiSSetupCMDFlag(T_L_Y_INC) } 509 if(dyR < 0) { dyR = -dyR; } 510 else { SiSSetupCMDFlag(T_R_Y_INC) } 511 512 /* Determine major axis */ 513 if(dxL >= dyL) { SiSSetupCMDFlag(T_XISMAJORL) } 514 if(dxR >= dyR) { SiSSetupCMDFlag(T_XISMAJORR) } 515 516 SiSSetupCMDFlag(TRAPAZOID_FILL); 517 518#ifdef SISVRAMQ 519 SiSSetupYHLR(y, h, left, right) 520 SiSSetupdLdR(dxL, dyL, dxR, dyR) 521 SiSSetupELER(eL, eR) 522 SiSSetupDSTBaseDoCMD(dstbase) 523#else 524 /* Set up deltas */ 525 SiSSetupdL(dxL, dyL) 526 SiSSetupdR(dxR, dyR) 527 /* Set up y, h, left, right */ 528 SiSSetupYH(y, h) 529 SiSSetupLR(left, right) 530 /* Set up initial error term */ 531 SiSSetupEL(eL) 532 SiSSetupER(eR) 533 SiSDoCMD 534#endif 535} 536#endif 537 538static void 539SiSSetupForSolidLine(ScrnInfoPtr pScrn, int color, int rop, 540 unsigned int planemask) 541{ 542 SISPtr pSiS = SISPTR(pScrn); 543 544#ifdef SISVRAMQ 545 SiSSetupDSTColorDepth(pSiS->SiS310_AccelDepth); 546 SiSCheckQueue(16 * 3); 547 SiSSetupLineCountPeriod(1, 1) 548 SiSSetupPATFGDSTRect(color, pSiS->scrnOffset, DEV_HEIGHT) 549 SiSSetupROP(SiSGetPatternROP(rop)) 550 SiSSetupCMDFlag(PATFG | LINE) 551 SiSSyncWP 552#else 553 SiSSetupLineCount(1) 554 SiSSetupPATFG(color) 555 SiSSetupDSTRect(pSiS->scrnOffset, DEV_HEIGHT) 556 SiSSetupDSTColorDepth(pSiS->DstColor) 557 SiSSetupROP(SiSGetPatternROP(rop)) 558 SiSSetupCMDFlag(PATFG | LINE | pSiS->SiS310_AccelDepth) 559#endif 560} 561 562static void 563SiSSubsequentSolidTwoPointLine(ScrnInfoPtr pScrn, 564 int x1, int y1, int x2, int y2, int flags) 565{ 566 SISPtr pSiS = SISPTR(pScrn); 567 int miny, maxy; 568 CARD32 dstbase = 0; 569 570 miny = (y1 > y2) ? y2 : y1; 571 maxy = (y1 > y2) ? y1 : y2; 572 if(maxy >= 2048) { 573 dstbase = pSiS->scrnOffset*miny; 574 y1 -= miny; 575 y2 -= miny; 576 } 577 578 dstbase += FBOFFSET; 579 580 if(flags & OMIT_LAST) { 581 SiSSetupCMDFlag(NO_LAST_PIXEL) 582 } else { 583 pSiS->CommandReg &= ~(NO_LAST_PIXEL); 584 } 585 586#ifdef SISVRAMQ 587 SiSCheckQueue(16 * 2); 588 SiSSetupX0Y0X1Y1(x1, y1, x2, y2) 589 SiSSetupDSTBaseDoCMD(dstbase) 590#else 591 SiSSetupDSTBase(dstbase) 592 SiSSetupX0Y0(x1, y1) 593 SiSSetupX1Y1(x2, y2) 594 SiSDoCMD 595#endif 596} 597 598static void 599SiSSubsequentSolidHorzVertLine(ScrnInfoPtr pScrn, 600 int x, int y, int len, int dir) 601{ 602 SISPtr pSiS = SISPTR(pScrn); 603 CARD32 dstbase = 0; 604 605 len--; /* starting point is included! */ 606 607 if((y >= 2048) || ((y + len) >= 2048)) { 608 dstbase = pSiS->scrnOffset * y; 609 y = 0; 610 } 611 612 dstbase += FBOFFSET; 613 614#ifdef SISVRAMQ 615 SiSCheckQueue(16 * 2); 616 if(dir == DEGREES_0) { 617 SiSSetupX0Y0X1Y1(x, y, (x + len), y) 618 } else { 619 SiSSetupX0Y0X1Y1(x, y, x, (y + len)) 620 } 621 SiSSetupDSTBaseDoCMD(dstbase) 622#else 623 SiSSetupDSTBase(dstbase) 624 SiSSetupX0Y0(x,y) 625 if(dir == DEGREES_0) { 626 SiSSetupX1Y1(x + len, y); 627 } else { 628 SiSSetupX1Y1(x, y + len); 629 } 630 SiSDoCMD 631#endif 632} 633 634static void 635SiSSetupForDashedLine(ScrnInfoPtr pScrn, 636 int fg, int bg, int rop, unsigned int planemask, 637 int length, unsigned char *pattern) 638{ 639 SISPtr pSiS = SISPTR(pScrn); 640 641#ifdef SISVRAMQ 642 SiSSetupDSTColorDepth(pSiS->SiS310_AccelDepth); 643 SiSCheckQueue(16 * 3); 644 SiSSetupLineCountPeriod(1, (length - 1)) 645 SiSSetupStyle(*pattern,*(pattern + 4)) 646 SiSSetupPATFGDSTRect(fg, pSiS->scrnOffset, DEV_HEIGHT) 647#else 648 SiSSetupLineCount(1) 649 SiSSetupDSTRect(pSiS->scrnOffset, DEV_HEIGHT) 650 SiSSetupDSTColorDepth(pSiS->DstColor); 651 SiSSetupStyleLow(*pattern) 652 SiSSetupStyleHigh(*(pattern + 4)) 653 SiSSetupStylePeriod(length - 1); 654 SiSSetupPATFG(fg) 655#endif 656 657 SiSSetupROP(SiSGetPatternROP(rop)) 658 659 SiSSetupCMDFlag(LINE | LINE_STYLE) 660 661 if(bg != -1) { 662 SiSSetupPATBG(bg) 663 } else { 664 SiSSetupCMDFlag(TRANSPARENT) 665 } 666#ifndef SISVRAMQ 667 SiSSetupCMDFlag(pSiS->SiS310_AccelDepth) 668#endif 669 670#ifdef SISVRAMQ 671 SiSSyncWP 672#endif 673} 674 675static void 676SiSSubsequentDashedTwoPointLine(ScrnInfoPtr pScrn, 677 int x1, int y1, int x2, int y2, 678 int flags, int phase) 679{ 680 SISPtr pSiS = SISPTR(pScrn); 681 CARD32 dstbase, miny, maxy; 682 683 dstbase = 0; 684 miny = (y1 > y2) ? y2 : y1; 685 maxy = (y1 > y2) ? y1 : y2; 686 if(maxy >= 2048) { 687 dstbase = pSiS->scrnOffset * miny; 688 y1 -= miny; 689 y2 -= miny; 690 } 691 692 dstbase += FBOFFSET; 693 694 if(flags & OMIT_LAST) { 695 SiSSetupCMDFlag(NO_LAST_PIXEL) 696 } else { 697 pSiS->CommandReg &= ~(NO_LAST_PIXEL); 698 } 699 700#ifdef SISVRAMQ 701 SiSCheckQueue(16 * 2); 702 SiSSetupX0Y0X1Y1(x1, y1, x2, y2) 703 SiSSetupDSTBaseDoCMD(dstbase) 704#else 705 SiSSetupDSTBase(dstbase) 706 SiSSetupX0Y0(x1, y1) 707 SiSSetupX1Y1(x2, y2) 708 SiSDoCMD 709#endif 710} 711 712static void 713SiSSetupForMonoPatternFill(ScrnInfoPtr pScrn, 714 int patx, int paty, int fg, int bg, 715 int rop, unsigned int planemask) 716{ 717 SISPtr pSiS = SISPTR(pScrn); 718 719#ifdef SISVRAMQ 720 SiSSetupDSTColorDepth(pSiS->SiS310_AccelDepth); 721 SiSCheckQueue(16 * 3); 722 SiSSetupPATFGDSTRect(fg, pSiS->scrnOffset, DEV_HEIGHT) 723#else 724 SiSSetupDSTRect(pSiS->scrnOffset, DEV_HEIGHT) 725 SiSSetupDSTColorDepth(pSiS->DstColor); 726#endif 727 728 SiSSetupMONOPAT(patx,paty) 729 730 SiSSetupROP(SiSGetPatternROP(rop)) 731 732#ifdef SISVRAMQ 733 SiSSetupCMDFlag(PATMONO) 734#else 735 SiSSetupPATFG(fg) 736 SiSSetupCMDFlag(PATMONO | pSiS->SiS310_AccelDepth) 737#endif 738 739 if(bg != -1) { 740 SiSSetupPATBG(bg) 741 } else { 742 SiSSetupCMDFlag(TRANSPARENT) 743 } 744 745#ifdef SISVRAMQ 746 SiSSyncWP 747#endif 748} 749 750static void 751SiSSubsequentMonoPatternFill(ScrnInfoPtr pScrn, 752 int patx, int paty, 753 int x, int y, int w, int h) 754{ 755 SISPtr pSiS = SISPTR(pScrn); 756 CARD32 dstbase = 0; 757 758 if(y >= 2048) { 759 dstbase = pSiS->scrnOffset * y; 760 y = 0; 761 } 762 763 dstbase += FBOFFSET; 764 765 /* Clear commandReg because Setup can be used for Rect and Trap */ 766 pSiS->CommandReg &= ~(T_XISMAJORL | T_XISMAJORR | 767 T_L_X_INC | T_L_Y_INC | 768 T_R_X_INC | T_R_Y_INC | 769 TRAPAZOID_FILL); 770 771#ifdef SISVRAMQ 772 SiSCheckQueue(16 * 2); 773 SiSSetupDSTXYRect(x,y,w,h) 774 SiSSetupDSTBaseDoCMD(dstbase) 775#else 776 SiSSetupDSTBase(dstbase) 777 SiSSetupDSTXY(x,y) 778 SiSSetupRect(w,h) 779 SiSDoCMD 780#endif 781} 782 783/* --- Trapezoid --- */ 784 785/* Does not work at all on 330 series */ 786 787#ifdef TRAP 788static void 789SiSSubsequentMonoPatternFillTrap(ScrnInfoPtr pScrn, 790 int patx, int paty, 791 int y, int h, 792 int left, int dxL, int dyL, int eL, 793 int right, int dxR, int dyR, int eR) 794{ 795 SISPtr pSiS = SISPTR(pScrn); 796 CARD32 dstbase = 0; 797 798 if(y >= 2048) { 799 dstbase=pSiS->scrnOffset*y; 800 y = 0; 801 } 802 803 dstbase += FBOFFSET; 804 805#ifdef SISVRAMQ 806 SiSCheckQueue(16 * 4); 807#else 808 SiSSetupDSTBase(dstbase) 809#endif 810 811 /* Clear CommandReg because SetUp can be used for Rect and Trap */ 812 pSiS->CommandReg &= ~(T_XISMAJORL | T_XISMAJORR | 813 T_L_X_INC | T_L_Y_INC | 814 T_R_X_INC | T_R_Y_INC | 815 BITBLT); 816 817 if(dxL < 0) { dxL = -dxL; } 818 else { SiSSetupCMDFlag(T_L_X_INC) } 819 if(dxR < 0) { dxR = -dxR; } 820 else { SiSSetupCMDFlag(T_R_X_INC) } 821 822 if(dyL < 0) { dyL = -dyL; } 823 else { SiSSetupCMDFlag(T_L_Y_INC) } 824 if(dyR < 0) { dyR = -dyR; } 825 else { SiSSetupCMDFlag(T_R_Y_INC) } 826 827 /* Determine major axis */ 828 if(dxL >= dyL) { SiSSetupCMDFlag(T_XISMAJORL) } 829 if(dxR >= dyR) { SiSSetupCMDFlag(T_XISMAJORR) } 830 831 SiSSetupCMDFlag(TRAPAZOID_FILL); 832 833#ifdef SISVRAMQ 834 SiSSetupYHLR(y, h, left, right) 835 SiSSetupdLdR(dxL, dyL, dxR, dyR) 836 SiSSetupELER(eL, eR) 837 SiSSetupDSTBaseDoCMD(dstbase) 838#else 839 SiSSetupYH(y, h) 840 SiSSetupLR(left, right) 841 SiSSetupdL(dxL, dyL) 842 SiSSetupdR(dxR, dyR) 843 SiSSetupEL(eL) 844 SiSSetupER(eR) 845 SiSDoCMD 846#endif 847} 848#endif 849 850/* Color 8x8 pattern */ 851 852#ifdef SISVRAMQ 853static void 854SiSSetupForColor8x8PatternFill(ScrnInfoPtr pScrn, int patternx, int patterny, 855 int rop, unsigned int planemask, int trans_col) 856{ 857 SISPtr pSiS = SISPTR(pScrn); 858 int j = pScrn->bitsPerPixel >> 3; 859 CARD32 *patadr = (CARD32 *)(pSiS->FbBase + (patterny * pSiS->scrnOffset) + 860 (patternx * j)); 861 862 SiSSetupDSTColorDepth(pSiS->SiS310_AccelDepth); 863 SiSCheckQueue(16 * 3); 864 865 SiSSetupDSTRectBurstHeader(pSiS->scrnOffset, DEV_HEIGHT, PATTERN_REG, (pScrn->bitsPerPixel << 1)) 866 867 while(j--) { 868 SiSSetupPatternRegBurst(patadr[0], patadr[1], patadr[2], patadr[3]); 869 SiSSetupPatternRegBurst(patadr[4], patadr[5], patadr[6], patadr[7]); 870 SiSSetupPatternRegBurst(patadr[8], patadr[9], patadr[10], patadr[11]); 871 SiSSetupPatternRegBurst(patadr[12], patadr[13], patadr[14], patadr[15]); 872 patadr += 16; /* = 64 due to (CARD32 *) */ 873 } 874 875 SiSSetupROP(SiSGetPatternROP(rop)) 876 877 SiSSetupCMDFlag(PATPATREG) 878 879 SiSSyncWP 880} 881 882static void 883SiSSubsequentColor8x8PatternFillRect(ScrnInfoPtr pScrn, int patternx, 884 int patterny, int x, int y, int w, int h) 885{ 886 SISPtr pSiS = SISPTR(pScrn); 887 CARD32 dstbase = 0; 888 889 if(y >= 2048) { 890 dstbase = pSiS->scrnOffset * y; 891 y = 0; 892 } 893 894 dstbase += FBOFFSET; 895 896 /* SiSSetupCMDFlag(BITBLT) - BITBLT = 0 */ 897 898 SiSCheckQueue(16 * 2) 899 SiSSetupDSTXYRect(x, y, w, h) 900 SiSSetupDSTBaseDoCMD(dstbase) 901} 902#endif 903 904/* ---- CPUToScreen Color Expand --- */ 905 906#ifdef CTSCE 907 908#ifdef CTSCE_DIRECT 909 910/* Direct method */ 911 912/* This is somewhat a fake. We let XAA copy its data not to an 913 * aperture, but to video RAM, and then do a ScreenToScreen 914 * color expansion. 915 * Since the data is sent AFTER the call to Subsequent, we 916 * don't execute the command here, but set a flag and do 917 * that in the (subsequent) call to Sync() 918 */ 919 920static void 921SiSSetupForCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, 922 int fg, int bg, int rop, unsigned int planemask) 923{ 924 SISPtr pSiS=SISPTR(pScrn); 925 926#ifdef SISVRAMQ 927 SiSSetupDSTColorDepth(pSiS->SiS310_AccelDepth); 928 SiSSetupROP(SiSGetCopyROP(rop)); 929 SiSSetupSRCFGDSTRect(fg, pSiS->scrnOffset, DEV_HEIGHT) 930 if(bg == -1) { 931 SiSSetupCMDFlag(TRANSPARENT | ENCOLOREXP | SRCVIDEO); 932 } else { 933 SiSSetupSRCBG(bg); 934 SiSSetupCMDFlag(ENCOLOREXP | SRCVIDEO); 935 } 936 SiSSyncWP 937#else 938 SiSSetupSRCXY(0,0); 939 SiSSetupROP(SiSGetCopyROP(rop)); 940 SiSSetupSRCFG(fg); 941 SiSSetupDSTRect(pSiS->scrnOffset, DEV_HEIGHT); 942 SiSSetupDSTColorDepth(pSiS->DstColor); 943 if(bg == -1) { 944 SiSSetupCMDFlag(TRANSPARENT | ENCOLOREXP | SRCVIDEO 945 | pSiS->SiS310_AccelDepth); 946 } else { 947 SiSSetupSRCBG(bg); 948 SiSSetupCMDFlag(ENCOLOREXP | SRCVIDEO | pSiS->SiS310_AccelDepth); 949 } 950#endif 951} 952 953static void 954SiSSubsequentCPUToScreenColorExpandFill( 955 ScrnInfoPtr pScrn, int x, int y, int w, 956 int h, int skipleft) 957{ 958 SISPtr pSiS = SISPTR(pScrn); 959 int _x0, _y0, _x1, _y1; 960 CARD32 srcbase, dstbase; 961 962 srcbase = pSiS->ColorExpandBase; 963 964 dstbase = 0; 965 if(y >= 2048) { 966 dstbase = pSiS->scrnOffset*y; 967 y = 0; 968 } 969 970 srcbase += FBOFFSET; 971 dstbase += FBOFFSET; 972 973#ifdef SISVRAMQ 974 SiSSetupSRCDSTBase(srcbase,dstbase); 975#else 976 SiSSetupSRCBase(srcbase); 977 SiSSetupDSTBase(dstbase) 978#endif 979 980 if(skipleft > 0) { 981 _x0 = x + skipleft; 982 _y0 = y; 983 _x1 = x + w; 984 _y1 = y + h; 985#ifdef SISVRAMQ 986 SiSSetupClip(_x0, _y0, _x1, _y1); 987#else 988 SiSSetupClipLT(_x0, _y0); 989 SiSSetupClipRB(_x1, _y1); 990#endif 991 SiSSetupCMDFlag(CLIPENABLE); 992 } else { 993 pSiS->CommandReg &= (~CLIPENABLE); 994 } 995 996#ifdef SISVRAMQ 997 SiSSetupRectSRCPitch(w, h, ((((w + 7) >> 3) + 3) >> 2) << 2); 998 SiSSetupSRCDSTXY(0, 0, x, y); 999#else 1000 SiSSetupRect(w, h); 1001 SiSSetupSRCPitch(((((w+7)/8)+3) >> 2) * 4); 1002 SiSSetupDSTXY(x, y); 1003#endif 1004 1005 if(pSiS->ColorExpandBusy) { 1006 pSiS->ColorExpandBusy = FALSE; 1007 SiSIdle 1008 } 1009 1010 pSiS->DoColorExpand = TRUE; 1011} 1012 1013#else 1014 1015/* Indirect method */ 1016 1017/* This is SLOW, slower than the CPU on most chipsets */ 1018/* Does not work in VRAM queue mode. */ 1019 1020static void 1021SiSSetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, 1022 int fg, int bg, int rop, unsigned int planemask) 1023{ 1024 SISPtr pSiS=SISPTR(pScrn); 1025 1026#ifdef SISVRAMQ 1027 SiSSetupDSTColorDepth(pSiS->SiS310_AccelDepth); 1028#endif 1029 1030 /* !!! DOES NOT WORK IN VRAM QUEUE MODE !!! */ 1031 1032 /* (hence this is not optimized for VRAM mode) */ 1033#ifndef SISVRAMQ 1034 SiSIdle 1035#endif 1036 SiSSetupSRCXY(0,0); 1037 1038 SiSSetupROP(SiSGetCopyROP(rop)); 1039 SiSSetupSRCFG(fg); 1040 SiSSetupDSTRect(pSiS->scrnOffset, DEV_HEIGHT); 1041#ifndef SISVRAMQ 1042 SiSSetupDSTColorDepth(pSiS->DstColor); 1043#endif 1044 if(bg == -1) { 1045#ifdef SISVRAMQ 1046 SiSSetupCMDFlag(TRANSPARENT | ENCOLOREXP | SRCVIDEO); 1047#else 1048 SiSSetupCMDFlag(TRANSPARENT | ENCOLOREXP | SRCCPUBLITBUF 1049 | pSiS->SiS310_AccelDepth); 1050#endif 1051 } else { 1052 SiSSetupSRCBG(bg); 1053#ifdef SISVRAMQ 1054 SiSSetupCMDFlag(ENCOLOREXP | SRCCPUBLITBUF); 1055#else 1056 SiSSetupCMDFlag(ENCOLOREXP | SRCCPUBLITBUF | pSiS->SiS310_AccelDepth); 1057#endif 1058 }; 1059 1060} 1061 1062static void 1063SiSSubsequentScanlineCPUToScreenColorExpandFill( 1064 ScrnInfoPtr pScrn, int x, int y, int w, 1065 int h, int skipleft) 1066{ 1067 SISPtr pSiS = SISPTR(pScrn); 1068 int _x0, _y0, _x1, _y1; 1069 CARD32 dstbase = 0; 1070 1071 if(y >= 2048) { 1072 dstbase = pSiS->scrnOffset*y; 1073 y = 0; 1074 } 1075 1076 dstbase += FBOFFSET; 1077 1078#ifndef SISVRAMQ 1079 if((SIS_MMIO_IN16(pSiS->IOBase, Q_STATUS+2) & 0x8000) != 0x8000) { 1080 SiSIdle; 1081 } 1082#endif 1083 1084 SiSSetupDSTBase(dstbase) 1085 1086 if(skipleft > 0) { 1087 _x0 = x+skipleft; 1088 _y0 = y; 1089 _x1 = x+w; 1090 _y1 = y+h; 1091#ifdef SISVRAMQ 1092 SiSSetupClip(_x0, _y0, _x1, _y1); 1093#else 1094 SiSSetupClipLT(_x0, _y0); 1095 SiSSetupClipRB(_x1, _y1); 1096#endif 1097 SiSSetupCMDFlag(CLIPENABLE); 1098 } else { 1099 pSiS->CommandReg &= (~CLIPENABLE); 1100 } 1101 SiSSetupRect(w, 1); 1102 SiSSetupSRCPitch(((((w+7)/8)+3) >> 2) * 4); 1103 pSiS->ycurrent = y; 1104 pSiS->xcurrent = x; 1105 1106} 1107 1108static void 1109SiSSubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno) 1110{ 1111 SISPtr pSiS = SISPTR(pScrn); 1112 CARD32 cbo; 1113 1114 cbo = pSiS->ColorExpandBufferScreenOffset[bufno]; 1115 cbo += FBOFFSET; 1116 1117#ifndef SISVRAMQ 1118 if((SIS_MMIO_IN16(pSiS->IOBase, Q_STATUS+2) & 0x8000) != 0x8000) { 1119 SiSIdle; 1120 } 1121#endif 1122 1123 SiSSetupSRCBase(cbo); 1124 1125 SiSSetupDSTXY(pSiS->xcurrent, pSiS->ycurrent); 1126 1127 SiSDoCMD 1128 1129 pSiS->ycurrent++; 1130#ifndef SISVRAMQ 1131 SiSIdle 1132#endif 1133} 1134#endif 1135#endif 1136 1137/* --- Screen To Screen Color Expand --- */ 1138 1139/* This method blits in a single task; this does not work because 1140 * the hardware does not use the source pitch as scanline offset 1141 * but to calculate pattern address from source X and Y and to 1142 * limit the drawing width (similar to width set by SetupRect). 1143 * XAA provides the pattern bitmap with scrnOffset (displayWidth * bpp/8) 1144 * offset, but this is not supported by the hardware. 1145 * DOES NOT WORK ON 330 SERIES, HANGS ENGINE. 1146 */ 1147 1148#ifdef STSCE 1149static void 1150SiSSetupForScreenToScreenColorExpand(ScrnInfoPtr pScrn, 1151 int fg, int bg, 1152 int rop, unsigned int planemask) 1153{ 1154 SISPtr pSiS = SISPTR(pScrn); 1155 1156#ifdef SISVRAMQ 1157 SiSSetupDSTColorDepth(pSiS->SiS310_AccelDepth); 1158#else 1159 SiSSetupDSTColorDepth(pSiS->DstColor) 1160#endif 1161 SiSSetupDSTRect(pSiS->scrnOffset, DEV_HEIGHT) 1162 SiSSetupROP(SiSGetCopyROP(rop)) 1163 SiSSetupSRCFG(fg) 1164 /* SiSSetupSRCXY(0,0) */ 1165 1166 if(bg == -1) { 1167 SiSSetupCMDFlag(TRANSPARENT | ENCOLOREXP | SRCVIDEO); 1168 } else { 1169 SiSSetupSRCBG(bg); 1170 SiSSetupCMDFlag(ENCOLOREXP | SRCVIDEO); 1171 }; 1172 1173#ifdef SISVRAMQ 1174 SiSSyncWP 1175#endif 1176} 1177 1178/* For testing, these are the methods: (use only one at a time!) */ 1179 1180#undef npitch /* Normal: Use srcx/y as srcx/y, use scrnOffset as source pitch 1181 * Does not work on 315 series, because the hardware does not 1182 * regard the src x and y. Apart from this problem: 1183 * This would work if the hareware used the source pitch for 1184 * incrementing the source address after each scanline - but 1185 * it doesn't do this! The first line of the area is correctly 1186 * color expanded, but since the source pitch is ignored and 1187 * the source address not incremented correctly, the following 1188 * lines are color expanded with any bit pattern that is left 1189 * in the unused space of the source bitmap (which is organized 1190 * with the depth of the screen framebuffer hence with a pitch 1191 * of scrnOffset). 1192 */ 1193 1194#undef pitchdw /* Use source pitch "displayWidth / 8" instead 1195 * of scrnOffset (=displayWidth * bpp / 8) 1196 * This can't work, because the pitch of the source 1197 * bitmap is scrnoffset! 1198 */ 1199 1200#define nopitch /* Calculate srcbase with srcx and srcy, set the 1201 * pitch to scrnOffset (which IS the correct pitch 1202 * for the source bitmap) and set srcx and srcy both 1203 * to 0. 1204 * This would work if the hareware used the source pitch for 1205 * incrementing the source address after each scanline - but 1206 * it doesn't do this! Again: The first line of the area is 1207 * correctly color expanded, but since the source pitch is 1208 * ignored for scanline address incremention, the following 1209 * lines are not correctly color expanded. 1210 * This is the only way it works (apart from the problem 1211 * described above). The hardware does not regard the src 1212 * x and y values in any way. 1213 */ 1214 1215static void 1216SiSSubsequentScreenToScreenColorExpand(ScrnInfoPtr pScrn, 1217 int x, int y, int w, int h, 1218 int srcx, int srcy, int skipleft) 1219{ 1220 SISPtr pSiS = SISPTR(pScrn); 1221 CARD32 srcbase, dstbase; 1222#if 0 1223 int _x0, _y0, _x1, _y1; 1224#endif 1225#ifdef pitchdw 1226 int newsrcx, newsrcy; 1227 1228 /* srcx and srcy are provided based on a scrnOffset pitch ( = displayWidth * bpp / 8 ) 1229 * We recalulate srcx and srcy based on pitch = displayWidth / 8 1230 */ 1231 newsrcy = ((pSiS->scrnOffset * srcy) + (srcx * ((pScrn->bitsPerPixel+7)/8))) / 1232 (pScrn->displayWidth/8); 1233 newsrcx = ((pSiS->scrnOffset * srcy) + (srcx * ((pScrn->bitsPerPixel+7)/8))) % 1234 (pScrn->displayWidth/8); 1235#endif 1236 xf86DrvMsg(0, X_INFO, "Sub ScreenToScreen ColorExp(%d,%d, %d,%d, %d,%d, %d)\n", 1237 x, y, w, h, srcx, srcy, skipleft); 1238 1239 srcbase = dstbase = 0; 1240 1241#ifdef pitchdw 1242 if(newsrcy >= 2048) { 1243 srcbase = (pScrn->displayWidth / 8) * newsrcy; 1244 newsrcy = 0; 1245 } 1246#endif 1247#ifdef nopitch 1248 srcbase = (pSiS->scrnOffset * srcy) + (srcx * ((pScrn->bitsPerPixel+7)/8)); 1249#endif 1250#ifdef npitch 1251 if(srcy >= 2048) { 1252 srcbase = pSiS->scrnOffset * srcy; 1253 srcy = 0; 1254 } 1255#endif 1256 if(y >= 2048) { 1257 dstbase = pSiS->scrnOffset * y; 1258 y = 0; 1259 } 1260 1261 srcbase += FBOFFSET; 1262 dstbase += FBOFFSET; 1263 1264 SiSSetupSRCBase(srcbase) 1265 SiSSetupDSTBase(dstbase) 1266 1267 /* 315 series seem to treat the src pitch as 1268 * a "drawing limit", but still (as 300 series) 1269 * does not use it for incrementing the 1270 * address pointer for the next scanline. ARGH! 1271 */ 1272 1273#ifdef pitchdw 1274 SiSSetupSRCPitch(pScrn->displayWidth/8) 1275#endif 1276#ifdef nopitch 1277 SiSSetupSRCPitch(pScrn->displayWidth/8) 1278 /* SiSSetupSRCPitch(1024/8) */ /* For test */ 1279#endif 1280#ifdef npitch 1281 SiSSetupSRCPitch(pScrn->displayWidth/8) 1282 /* SiSSetupSRCPitch(pSiS->scrnOffset) */ 1283#endif 1284 1285 SiSSetupRect(w,h) 1286 1287#if 0 /* How do I implement the offset? Not this way, that's for sure.. */ 1288 if (skipleft > 0) { 1289 _x0 = x+skipleft; 1290 _y0 = y; 1291 _x1 = x+w; 1292 _y1 = y+h; 1293 SiSSetupClipLT(_x0, _y0); 1294 SiSSetupClipRB(_x1, _y1); 1295 SiSSetupCMDFlag(CLIPENABLE); 1296 } 1297#endif 1298#ifdef pitchdw 1299 SiSSetupSRCXY(newsrcx, newsrcy) 1300#endif 1301#ifdef nopitch 1302 SiSSetupSRCXY(0,0) 1303#endif 1304#ifdef npitch 1305 SiSSetupSRCXY(srcx, srcy) 1306#endif 1307 1308 SiSSetupDSTXY(x,y) 1309 1310 SiSDoCMD 1311#ifdef SISVRAMQ 1312 /* We MUST sync here, there must not be 2 or more color expansion commands in the queue */ 1313 SiSIdle 1314#endif 1315} 1316#endif 1317 1318#ifdef SISDUALHEAD 1319static void 1320SiSRestoreAccelState(ScrnInfoPtr pScrn) 1321{ 1322 SISPtr pSiS = SISPTR(pScrn); 1323 1324 pSiS->ColorExpandBusy = FALSE; 1325 pSiS->alphaBlitBusy = FALSE; 1326 SiSIdle 1327} 1328#endif 1329 1330/* ---- RENDER ---- */ 1331 1332#ifdef INCL_RENDER 1333#ifdef RENDER 1334static void 1335SiSRenderCallback(ScrnInfoPtr pScrn) 1336{ 1337 SISPtr pSiS = SISPTR(pScrn); 1338 1339 if((currentTime.milliseconds > pSiS->RenderTime) && pSiS->AccelLinearScratch) { 1340 xf86FreeOffscreenLinear(pSiS->AccelLinearScratch); 1341 pSiS->AccelLinearScratch = NULL; 1342 } 1343 1344 if(!pSiS->AccelLinearScratch) { 1345 pSiS->RenderCallback = NULL; 1346 } 1347} 1348 1349#define RENDER_DELAY 15000 1350 1351static Bool 1352SiSAllocateLinear(ScrnInfoPtr pScrn, int sizeNeeded) 1353{ 1354 SISPtr pSiS = SISPTR(pScrn); 1355 1356 pSiS->RenderTime = currentTime.milliseconds + RENDER_DELAY; 1357 pSiS->RenderCallback = SiSRenderCallback; 1358 1359 if(pSiS->AccelLinearScratch) { 1360 if(pSiS->AccelLinearScratch->size >= sizeNeeded) { 1361 return TRUE; 1362 } else { 1363 if(pSiS->alphaBlitBusy) { 1364 pSiS->alphaBlitBusy = FALSE; 1365 SiSIdle 1366 } 1367 if(xf86ResizeOffscreenLinear(pSiS->AccelLinearScratch, sizeNeeded)) { 1368 return TRUE; 1369 } 1370 xf86FreeOffscreenLinear(pSiS->AccelLinearScratch); 1371 pSiS->AccelLinearScratch = NULL; 1372 } 1373 } 1374 1375 pSiS->AccelLinearScratch = xf86AllocateOffscreenLinear( 1376 pScrn->pScreen, sizeNeeded, 32, 1377 NULL, NULL, NULL); 1378 1379 return(pSiS->AccelLinearScratch != NULL); 1380} 1381 1382static Bool 1383SiSSetupForCPUToScreenAlphaTexture(ScrnInfoPtr pScrn, 1384 int op, CARD16 red, CARD16 green, 1385 CARD16 blue, CARD16 alpha, 1386#ifdef SISNEWRENDER 1387 CARD32 alphaType, CARD32 dstType, 1388#else 1389 int alphaType, 1390#endif 1391 CARD8 *alphaPtr, 1392 int alphaPitch, int width, 1393 int height, int flags) 1394{ 1395 SISPtr pSiS = SISPTR(pScrn); 1396 unsigned char *renderaccelarray; 1397 CARD32 *dstPtr; 1398 int x, pitch, sizeNeeded; 1399 int sbpp = pSiS->CurrentLayout.bitsPerPixel >> 3; 1400 int sbppshift = sbpp >> 1; /* 8->0, 16->1, 32->2 */ 1401 CARD8 myalpha; 1402 Bool docopy = TRUE; 1403 1404#ifdef ACCELDEBUG 1405 xf86DrvMsg(0, X_INFO, "AT(1): op %d t %x ARGB %x %x %x %x, w %d h %d pch %d\n", 1406 op, alphaType, /*dstType, */alpha, red, green, blue, width, height, alphaPitch); 1407#endif 1408 1409 if((width > 2048) || (height > 2048)) return FALSE; 1410 1411#ifdef SISVRAMQ 1412 if(op > SiSRenderOpsMAX) return FALSE; 1413 if(!SiSRenderOps[op]) return FALSE; 1414#else 1415 if(op != PictOpOver) return FALSE; 1416#endif 1417 1418 if(!((renderaccelarray = pSiS->RenderAccelArray))) 1419 return FALSE; 1420 1421#ifdef ACCELDEBUG 1422 xf86DrvMsg(0, X_INFO, "AT(2): op %d t %x ARGB %x %x %x %x, w %d h %d pch %d\n", 1423 op, alphaType, alpha, red, green, blue, width, height, alphaPitch); 1424#endif 1425 1426 pitch = (width + 31) & ~31; 1427 sizeNeeded = (pitch << 2) * height; /* Source a8 (=8bit), expand to A8R8G8B8 (=32bit) */ 1428 1429 if(!SiSAllocateLinear(pScrn, (sizeNeeded + sbpp - 1) >> sbppshift)) 1430 return FALSE; 1431 1432 red &= 0xff00; 1433 green &= 0xff00; 1434 blue &= 0xff00; 1435 1436#ifdef SISVRAMQ 1437 SiSSetupDSTColorDepth(pSiS->SiS310_AccelDepth); 1438 switch(op) { 1439 case PictOpClear: 1440#if XF86_VERSION_CURRENT >= XF86_VERSION_NUMERIC(4,2,0,0,0) 1441 case PictOpDisjointClear: 1442 case PictOpConjointClear: 1443#endif 1444 SiSSetupPATFGDSTRect(0, pSiS->scrnOffset, DEV_HEIGHT) 1445 /* SiSSetupROP(0x00) - is already 0 */ 1446 SiSSetupCMDFlag(PATFG) 1447 docopy = FALSE; 1448 break; 1449 case PictOpSrc: 1450#if XF86_VERSION_CURRENT >= XF86_VERSION_NUMERIC(4,2,0,0,0) 1451 case PictOpDisjointSrc: 1452 case PictOpConjointSrc: 1453#endif 1454 SiSSetupSRCPitchDSTRect((pitch << 2), pSiS->scrnOffset, DEV_HEIGHT); 1455 SiSSetupAlpha(0xff) 1456 SiSSetupCMDFlag(ALPHA_BLEND | SRCVIDEO | A_NODESTALPHA) 1457 break; 1458 case PictOpDst: 1459#if XF86_VERSION_CURRENT >= XF86_VERSION_NUMERIC(4,2,0,0,0) 1460 case PictOpDisjointDst: 1461 case PictOpConjointDst: 1462#endif 1463 SiSSetupSRCPitchDSTRect((pitch << 2), pSiS->scrnOffset, DEV_HEIGHT); 1464 SiSSetupAlpha(0x00) 1465 SiSSetupCMDFlag(ALPHA_BLEND | SRCVIDEO | A_CONSTANTALPHA) 1466 docopy = FALSE; 1467 break; 1468 case PictOpOver: 1469 SiSSetupSRCPitchDSTRect((pitch << 2), pSiS->scrnOffset, DEV_HEIGHT); 1470 SiSSetupCMDFlag(ALPHA_BLEND | SRCVIDEO | A_PERPIXELALPHA) 1471 break; 1472 } 1473 SiSSyncWP 1474#else 1475 SiSSetupDSTColorDepth(pSiS->DstColor); 1476 SiSSetupSRCPitch((pitch << 2)); 1477 SiSSetupDSTRect(pSiS->scrnOffset, DEV_HEIGHT) 1478 SiSSetupROP(0) 1479 SiSSetupCMDFlag(ALPHA_BLEND | SRCVIDEO | A_PERPIXELALPHA | pSiS->SiS310_AccelDepth) 1480#endif 1481 1482 /* Don't need source for clear and dest */ 1483 if(!docopy) return TRUE; 1484 1485 dstPtr = (CARD32*)(pSiS->FbBase + (pSiS->AccelLinearScratch->offset << sbppshift)); 1486 1487 if(pSiS->alphaBlitBusy) { 1488 pSiS->alphaBlitBusy = FALSE; 1489 SiSIdle 1490 } 1491 1492 if(alpha == 0xffff) { 1493 1494 while(height--) { 1495 for(x = 0; x < width; x++) { 1496 myalpha = alphaPtr[x]; 1497 dstPtr[x] = (renderaccelarray[red + myalpha] << 16) | 1498 (renderaccelarray[green + myalpha] << 8) | 1499 renderaccelarray[blue + myalpha] | 1500 myalpha << 24; 1501 } 1502 dstPtr += pitch; 1503 alphaPtr += alphaPitch; 1504 } 1505 1506 } else { 1507 1508 alpha &= 0xff00; 1509 1510 while(height--) { 1511 for(x = 0; x < width; x++) { 1512 myalpha = alphaPtr[x]; 1513 dstPtr[x] = (renderaccelarray[alpha + myalpha] << 24) | 1514 (renderaccelarray[red + myalpha] << 16) | 1515 (renderaccelarray[green + myalpha] << 8) | 1516 renderaccelarray[blue + myalpha]; 1517 } 1518 dstPtr += pitch; 1519 alphaPtr += alphaPitch; 1520 } 1521 1522 } 1523 1524 return TRUE; 1525} 1526 1527static Bool 1528SiSSetupForCPUToScreenTexture(ScrnInfoPtr pScrn, 1529 int op, 1530#ifdef SISNEWRENDER 1531 CARD32 texType, CARD32 dstType, 1532#else 1533 int texType, 1534#endif 1535 CARD8 *texPtr, 1536 int texPitch, int width, 1537 int height, int flags) 1538{ 1539 SISPtr pSiS = SISPTR(pScrn); 1540 CARD8 *dst; 1541 int pitch, sizeNeeded; 1542 int sbpp = pSiS->CurrentLayout.bitsPerPixel >> 3; 1543 int sbppshift = sbpp >> 1; /* 8->0, 16->1, 32->2 */ 1544 int bppshift = PICT_FORMAT_BPP(texType) >> 4; /* 8->0, 16->1, 32->2 */ 1545 Bool docopy = TRUE; 1546 1547#ifdef ACCELDEBUG 1548 xf86DrvMsg(0, X_INFO, "T: type %x op %d w %d h %d T-pitch %d\n", 1549 texType, op, width, height, texPitch); 1550#endif 1551 1552#ifdef SISVRAMQ 1553 if(op > SiSRenderOpsMAX) return FALSE; 1554 if(!SiSRenderOps[op]) return FALSE; 1555#else 1556 if(op != PictOpOver) return FALSE; 1557#endif 1558 1559 if((width > 2048) || (height > 2048)) return FALSE; 1560 1561 pitch = (width + 31) & ~31; 1562 sizeNeeded = (pitch << bppshift) * height; 1563 1564#ifdef ACCELDEBUG 1565 xf86DrvMsg(0, X_INFO, "T: %x op %x w %d h %d T-pitch %d size %d (%d %d %d)\n", 1566 texType, op, width, height, texPitch, sizeNeeded, sbpp, sbppshift, bppshift); 1567#endif 1568 1569 if(!SiSAllocateLinear(pScrn, (sizeNeeded + sbpp - 1) >> sbppshift)) 1570 return FALSE; 1571 1572 width <<= bppshift; /* -> bytes (for engine and memcpy) */ 1573 pitch <<= bppshift; /* -> bytes */ 1574 1575#ifdef SISVRAMQ 1576 SiSSetupDSTColorDepth(pSiS->SiS310_AccelDepth); 1577 switch(op) { 1578 case PictOpClear: 1579#if XF86_VERSION_CURRENT >= XF86_VERSION_NUMERIC(4,2,0,0,0) 1580 case PictOpDisjointClear: 1581 case PictOpConjointClear: 1582#endif 1583 SiSSetupPATFGDSTRect(0, pSiS->scrnOffset, DEV_HEIGHT) 1584 /* SiSSetupROP(0x00) - is already zero */ 1585 SiSSetupCMDFlag(PATFG) 1586 docopy = FALSE; 1587 break; 1588 case PictOpSrc: 1589#if XF86_VERSION_CURRENT >= XF86_VERSION_NUMERIC(4,2,0,0,0) 1590 case PictOpDisjointSrc: 1591 case PictOpConjointSrc: 1592#endif 1593 SiSSetupSRCPitchDSTRect(pitch, pSiS->scrnOffset, DEV_HEIGHT); 1594 SiSSetupAlpha(0xff) 1595 SiSSetupCMDFlag(ALPHA_BLEND | SRCVIDEO | A_NODESTALPHA) 1596 break; 1597 case PictOpDst: 1598#if XF86_VERSION_CURRENT >= XF86_VERSION_NUMERIC(4,2,0,0,0) 1599 case PictOpDisjointDst: 1600 case PictOpConjointDst: 1601#endif 1602 SiSSetupSRCPitchDSTRect(pitch, pSiS->scrnOffset, DEV_HEIGHT); 1603 SiSSetupAlpha(0x00) 1604 SiSSetupCMDFlag(ALPHA_BLEND | SRCVIDEO | A_CONSTANTALPHA) 1605 docopy = FALSE; 1606 break; 1607 case PictOpOver: 1608 SiSSetupSRCPitchDSTRect(pitch, pSiS->scrnOffset, DEV_HEIGHT); 1609 SiSSetupAlpha(0x00) 1610 SiSSetupCMDFlag(ALPHA_BLEND | SRCVIDEO | A_PERPIXELALPHA) 1611 break; 1612 default: 1613 return FALSE; 1614 } 1615 SiSSyncWP 1616#else 1617 SiSSetupDSTColorDepth(pSiS->DstColor); 1618 SiSSetupSRCPitch(pitch); 1619 SiSSetupDSTRect(pSiS->scrnOffset, DEV_HEIGHT) 1620 SiSSetupAlpha(0x00) 1621 SiSSetupCMDFlag(ALPHA_BLEND | SRCVIDEO | A_PERPIXELALPHA | pSiS->SiS310_AccelDepth) 1622#endif 1623 1624 /* Don't need source for clear and dest */ 1625 if(!docopy) return TRUE; 1626 1627 dst = (CARD8*)(pSiS->FbBase + (pSiS->AccelLinearScratch->offset << sbppshift)); 1628 1629 if(pSiS->alphaBlitBusy) { 1630 pSiS->alphaBlitBusy = FALSE; 1631 SiSIdle 1632 } 1633 1634 while(height--) { 1635 memcpy(dst, texPtr, width); 1636 texPtr += texPitch; 1637 dst += pitch; 1638 } 1639 1640 return TRUE; 1641} 1642 1643static void 1644SiSSubsequentCPUToScreenTexture(ScrnInfoPtr pScrn, 1645 int dst_x, int dst_y, 1646 int src_x, int src_y, 1647 int width, int height) 1648{ 1649 SISPtr pSiS = SISPTR(pScrn); 1650 CARD32 srcbase, dstbase; 1651 1652 srcbase = pSiS->AccelLinearScratch->offset << 1; 1653 if(pScrn->bitsPerPixel == 32) srcbase <<= 1; 1654 1655#ifdef ACCELDEBUG 1656 xf86DrvMsg(0, X_INFO, "FIRE: scrbase %x dx %d dy %d w %d h %d\n", 1657 srcbase, dst_x, dst_y, width, height); 1658#endif 1659 1660 dstbase = 0; 1661 if((dst_y >= pScrn->virtualY) || (dst_y >= 2048)) { 1662 dstbase = pSiS->scrnOffset * dst_y; 1663 dst_y = 0; 1664 } 1665 1666 srcbase += FBOFFSET; 1667 dstbase += FBOFFSET; 1668 1669#ifdef SISVRAMQ 1670 SiSCheckQueue(16 * 3) 1671 SiSSetupSRCDSTBase(srcbase,dstbase); 1672 SiSSetupSRCDSTXY(src_x, src_y, dst_x, dst_y) 1673 SiSSetRectDoCMD(width,height) 1674#else 1675 SiSSetupSRCBase(srcbase); 1676 SiSSetupDSTBase(dstbase); 1677 SiSSetupRect(width, height) 1678 SiSSetupSRCXY(src_x, src_y) 1679 SiSSetupDSTXY(dst_x, dst_y) 1680 SiSDoCMD 1681#endif 1682 pSiS->alphaBlitBusy = TRUE; 1683} 1684#endif 1685#endif 1686 1687#endif /* XAA */ 1688 1689#ifdef SIS_USE_EXA /* ---------------------------- EXA -------------------------- */ 1690 1691static void 1692SiSEXASync(ScreenPtr pScreen, int marker) 1693{ 1694 SISPtr pSiS = SISPTR(xf86Screens[pScreen->myNum]); 1695 1696 SiSIdle 1697} 1698 1699static Bool 1700SiSPrepareSolid(PixmapPtr pPixmap, int alu, Pixel planemask, Pixel fg) 1701{ 1702 ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum]; 1703 SISPtr pSiS = SISPTR(pScrn); 1704 1705 /* Planemask not supported */ 1706 if((planemask & ((1 << pPixmap->drawable.depth) - 1)) != 1707 (1 << pPixmap->drawable.depth) - 1) { 1708 return FALSE; 1709 } 1710 1711 if((pPixmap->drawable.bitsPerPixel != 8) && 1712 (pPixmap->drawable.bitsPerPixel != 16) && 1713 (pPixmap->drawable.bitsPerPixel != 32)) 1714 return FALSE; 1715 1716 if(pSiS->disablecolorkeycurrent) { 1717 if((CARD32)fg == pSiS->colorKey) { 1718 alu = 5; /* NOOP */ 1719 } 1720 } 1721 1722 /* Check that the pitch matches the hardware's requirements. Should 1723 * never be a problem due to pixmapPitchAlign and fbScreenInit. 1724 */ 1725 if(exaGetPixmapPitch(pPixmap) & 3) 1726 return FALSE; 1727 1728 SiSSetupDSTColorDepth((pPixmap->drawable.bitsPerPixel >> 4) << 16); 1729 SiSCheckQueue(16 * 1); 1730 SiSSetupPATFGDSTRect(fg, exaGetPixmapPitch(pPixmap), DEV_HEIGHT) 1731 SiSSetupROP(SiSGetPatternROP(alu)) 1732 SiSSetupCMDFlag(PATFG) 1733 SiSSyncWP 1734 1735 pSiS->fillDstBase = (CARD32)exaGetPixmapOffset(pPixmap) + FBOFFSET; 1736 1737 return TRUE; 1738} 1739 1740static void 1741SiSSolid(PixmapPtr pPixmap, int x1, int y1, int x2, int y2) 1742{ 1743 ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum]; 1744 SISPtr pSiS = SISPTR(pScrn); 1745 1746 /* SiSSetupCMDFlag(BITBLT) - BITBLT = 0 */ 1747 1748 SiSCheckQueue(16 * 2) 1749 SiSSetupDSTXYRect(x1, y1, x2-x1, y2-y1) 1750 SiSSetupDSTBaseDoCMD(pSiS->fillDstBase) 1751} 1752 1753static void 1754SiSDoneSolid(PixmapPtr pPixmap) 1755{ 1756} 1757 1758static Bool 1759SiSPrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, int xdir, int ydir, 1760 int alu, Pixel planemask) 1761{ 1762 ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum]; 1763 SISPtr pSiS = SISPTR(pScrn); 1764 CARD32 srcbase, dstbase; 1765 1766 /* Planemask not supported */ 1767 if((planemask & ((1 << pSrcPixmap->drawable.depth) - 1)) != 1768 (1 << pSrcPixmap->drawable.depth) - 1) { 1769 return FALSE; 1770 } 1771 1772 if((pDstPixmap->drawable.bitsPerPixel != 8) && 1773 (pDstPixmap->drawable.bitsPerPixel != 16) && 1774 (pDstPixmap->drawable.bitsPerPixel != 32)) 1775 return FALSE; 1776 1777 /* Check that the pitch matches the hardware's requirements. Should 1778 * never be a problem due to pixmapPitchAlign and fbScreenInit. 1779 */ 1780 if(exaGetPixmapPitch(pSrcPixmap) & 3) 1781 return FALSE; 1782 if(exaGetPixmapPitch(pDstPixmap) & 3) 1783 return FALSE; 1784 1785 srcbase = (CARD32)exaGetPixmapOffset(pSrcPixmap) + FBOFFSET; 1786 1787 dstbase = (CARD32)exaGetPixmapOffset(pDstPixmap) + FBOFFSET; 1788 1789 /* TODO: Will there eventually be overlapping blits? 1790 * If so, good night. Then we must calculate new base addresses 1791 * which are identical for source and dest, otherwise 1792 * the chips direction-logic will fail. Certainly funny 1793 * to re-calculate x and y then... 1794 */ 1795 1796 SiSSetupDSTColorDepth((pDstPixmap->drawable.bitsPerPixel >> 4) << 16); 1797 SiSCheckQueue(16 * 3); 1798 SiSSetupSRCPitchDSTRect(exaGetPixmapPitch(pSrcPixmap), 1799 exaGetPixmapPitch(pDstPixmap), DEV_HEIGHT) 1800 SiSSetupROP(SiSGetCopyROP(alu)) 1801 SiSSetupSRCDSTBase(srcbase, dstbase) 1802 SiSSyncWP 1803 1804 return TRUE; 1805} 1806 1807static void 1808SiSCopy(PixmapPtr pDstPixmap, int srcX, int srcY, int dstX, int dstY, int width, int height) 1809{ 1810 ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum]; 1811 SISPtr pSiS = SISPTR(pScrn); 1812 1813 SiSCheckQueue(16 * 2); 1814 SiSSetupSRCDSTXY(srcX, srcY, dstX, dstY) 1815 SiSSetRectDoCMD(width, height) 1816} 1817 1818static void 1819SiSDoneCopy(PixmapPtr pDstPixmap) 1820{ 1821} 1822 1823#ifdef SIS_HAVE_COMPOSITE 1824static Bool 1825SiSCheckComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture, 1826 PicturePtr pDstPicture) 1827{ 1828 ScrnInfoPtr pScrn = xf86Screens[pDstPicture->pDrawable->pScreen->myNum]; 1829 SISPtr pSiS = SISPTR(pScrn); 1830 1831 xf86DrvMsg(0, 0, "CC: %d Src %x (fi %d ca %d) Msk %x (%d %d) Dst %x (%d %d)\n", 1832 op, pSrcPicture->format, pSrcPicture->filter, pSrcPicture->componentAlpha, 1833 pMaskPicture ? pMaskPicture->format : 0x2011, pMaskPicture ? pMaskPicture->filter : -1, 1834 pMaskPicture ? pMaskPicture->componentAlpha : -1, 1835 pDstPicture->format, pDstPicture->filter, pDstPicture->componentAlpha); 1836 1837 if(pSrcPicture->transform || (pMaskPicture && pMaskPicture->transform) || pDstPicture->transform) { 1838 xf86DrvMsg(0, 0, "CC: src tr %p msk %p dst %p !!!!!!!!!!!!!!!\n", 1839 pSrcPicture->transform, 1840 pMaskPicture ? pMaskPicture->transform : 0, 1841 pDstPicture->transform); 1842 } 1843 1844 return FALSE; 1845} 1846 1847static Bool 1848SiSPrepareComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture, 1849 PicturePtr pDstPicture, PixmapPtr pSrc, PixmapPtr pMask, PixmapPtr pDst) 1850{ 1851#if 0 1852 ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum]; 1853 SISPtr pSiS = SISPTR(pScrn); 1854#endif 1855 return FALSE; 1856} 1857 1858static void 1859SiSComposite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY, int dstX, int dstY, 1860 int width, int height) 1861{ 1862#if 0 1863 ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum]; 1864 SISPtr pSiS = SISPTR(pScrn); 1865#endif 1866} 1867 1868static void 1869SiSDoneComposite(PixmapPtr pDst) 1870{ 1871} 1872#endif 1873 1874Bool 1875SiSUploadToScreen(PixmapPtr pDst, int x, int y, int w, int h, char *src, int src_pitch) 1876{ 1877 ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum]; 1878 SISPtr pSiS = SISPTR(pScrn); 1879 unsigned char *dst = pDst->devPrivate.ptr; 1880 int dst_pitch = exaGetPixmapPitch(pDst); 1881 1882 (pSiS->SyncAccel)(pScrn); 1883 1884 if(pDst->drawable.bitsPerPixel < 8) 1885 return FALSE; 1886 1887 dst += (x * pDst->drawable.bitsPerPixel / 8) + (y * src_pitch); 1888 while(h--) { 1889 SiSMemCopyToVideoRam(pSiS, dst, (unsigned char *)src, 1890 (w * pDst->drawable.bitsPerPixel / 8)); 1891 src += src_pitch; 1892 dst += dst_pitch; 1893 } 1894 1895 return TRUE; 1896} 1897 1898Bool 1899SiSUploadToScratch(PixmapPtr pSrc, PixmapPtr pDst) 1900{ 1901 ScrnInfoPtr pScrn = xf86Screens[pSrc->drawable.pScreen->myNum]; 1902 SISPtr pSiS = SISPTR(pScrn); 1903 unsigned char *src, *dst; 1904 int src_pitch = exaGetPixmapPitch(pSrc); 1905 int dst_pitch, size, w, h, bytes; 1906 1907 w = pSrc->drawable.width; 1908 1909 dst_pitch = ((w * (pSrc->drawable.bitsPerPixel >> 3)) + 1910 pSiS->EXADriverPtr->pixmapPitchAlign - 1) & 1911 ~(pSiS->EXADriverPtr->pixmapPitchAlign - 1); 1912 1913 size = dst_pitch * pSrc->drawable.height; 1914 1915 if(size > pSiS->exa_scratch->size) 1916 return FALSE; 1917 1918 pSiS->exa_scratch_next = (pSiS->exa_scratch_next + 1919 pSiS->EXADriverPtr->pixmapOffsetAlign - 1) & 1920 ~(pSiS->EXADriverPtr->pixmapOffsetAlign - 1); 1921 1922 if(pSiS->exa_scratch_next + size > 1923 pSiS->exa_scratch->offset + pSiS->exa_scratch->size) { 1924 (pSiS->EXADriverPtr->WaitMarker)(pSrc->drawable.pScreen, 0); 1925 pSiS->exa_scratch_next = pSiS->exa_scratch->offset; 1926 } 1927 1928 memcpy(pDst, pSrc, sizeof(*pDst)); 1929 pDst->devKind = dst_pitch; 1930 pDst->devPrivate.ptr = pSiS->EXADriverPtr->memoryBase + pSiS->exa_scratch_next; 1931 1932 pSiS->exa_scratch_next += size; 1933 1934 src = pSrc->devPrivate.ptr; 1935 src_pitch = exaGetPixmapPitch(pSrc); 1936 dst = pDst->devPrivate.ptr; 1937 1938 bytes = (src_pitch < dst_pitch) ? src_pitch : dst_pitch; 1939 1940 h = pSrc->drawable.height; 1941 1942 (pSiS->SyncAccel)(pScrn); 1943 1944 while(h--) { 1945 SiSMemCopyToVideoRam(pSiS, dst, src, size); 1946 src += src_pitch; 1947 dst += dst_pitch; 1948 } 1949 1950 return TRUE; 1951} 1952 1953Bool 1954SiSDownloadFromScreen(PixmapPtr pSrc, int x, int y, int w, int h, char *dst, int dst_pitch) 1955{ 1956 ScrnInfoPtr pScrn = xf86Screens[pSrc->drawable.pScreen->myNum]; 1957 SISPtr pSiS = SISPTR(pScrn); 1958 unsigned char *src = pSrc->devPrivate.ptr; 1959 int src_pitch = exaGetPixmapPitch(pSrc); 1960 int size = src_pitch < dst_pitch ? src_pitch : dst_pitch; 1961 1962 (pSiS->SyncAccel)(pScrn); 1963 1964 if(pSrc->drawable.bitsPerPixel < 8) 1965 return FALSE; 1966 1967 src += (x * pSrc->drawable.bitsPerPixel / 8) + (y * src_pitch); 1968 while(h--) { 1969 SiSMemCopyFromVideoRam(pSiS, (unsigned char *)dst, src, size); 1970 src += src_pitch; 1971 dst += dst_pitch; 1972 } 1973 1974 return TRUE; 1975} 1976#endif /* EXA */ 1977 1978/* Helper for xv video blitter */ 1979 1980#ifdef INCL_YUV_BLIT_ADAPTOR 1981void 1982SISWriteBlitPacket(SISPtr pSiS, CARD32 *packet) 1983{ 1984 CARD32 dummybuf; 1985 1986 SiSWritePacketPart(packet[0], packet[1], packet[2], packet[3]); 1987 SiSWritePacketPart(packet[4], packet[5], packet[6], packet[7]); 1988 SiSWritePacketPart(packet[8], packet[9], packet[10], packet[11]); 1989 SiSWritePacketPart(packet[12], packet[13], packet[14], packet[15]); 1990 SiSWritePacketPart(packet[16], packet[17], packet[18], packet[19]); 1991 SiSSyncWP; 1992 (void)dummybuf; /* Suppress compiler warning */ 1993} 1994#endif 1995 1996/* For DGA usage */ 1997 1998static void 1999SiSDGAFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h, int color) 2000{ 2001 SiSSetupForSolidFill(pScrn, color, GXcopy, ~0); 2002 SiSSubsequentSolidFillRect(pScrn, x, y, w, h); 2003} 2004 2005static void 2006SiSDGABlitRect(ScrnInfoPtr pScrn, int srcx, int srcy, int dstx, int dsty, int w, int h, int color) 2007{ 2008 /* Don't need xdir, ydir */ 2009 SiSSetupForScreenToScreenCopy(pScrn, 0, 0, GXcopy, (CARD32)~0, color); 2010 SiSSubsequentScreenToScreenCopy(pScrn, srcx, srcy, dstx, dsty, w, h); 2011} 2012 2013/* Initialisation */ 2014 2015Bool 2016SiS315AccelInit(ScreenPtr pScreen) 2017{ 2018 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 2019 SISPtr pSiS = SISPTR(pScrn); 2020#ifdef SIS_USE_XAA 2021 XAAInfoRecPtr infoPtr = NULL; 2022 int topFB, reservedFbSize, usableFbSize; 2023 BoxRec Avail; 2024#ifdef CTSCE 2025 unsigned char *AvailBufBase; 2026#ifndef CTSCE_DIRECT 2027 int i; 2028#endif 2029#endif 2030#endif /* XAA */ 2031 2032 pSiS->ColorExpandBufferNumber = 0; 2033 pSiS->PerColorExpandBufferSize = 0; 2034 pSiS->RenderAccelArray = NULL; 2035#ifdef SIS_USE_XAA 2036 pSiS->AccelInfoPtr = NULL; 2037#endif 2038#ifdef SIS_USE_EXA 2039 pSiS->EXADriverPtr = NULL; 2040 pSiS->exa_scratch = NULL; 2041#endif 2042 2043 if((pScrn->bitsPerPixel != 8) && 2044 (pScrn->bitsPerPixel != 16) && 2045 (pScrn->bitsPerPixel != 32)) { 2046 pSiS->NoAccel = TRUE; 2047 } 2048 2049 if(!pSiS->NoAccel) { 2050#ifdef SIS_USE_XAA 2051 if(!pSiS->useEXA) { 2052 pSiS->AccelInfoPtr = infoPtr = XAACreateInfoRec(); 2053 if(!infoPtr) pSiS->NoAccel = TRUE; 2054 } 2055#endif 2056#ifdef SIS_USE_EXA 2057 if(pSiS->useEXA) { 2058 if(!(pSiS->EXADriverPtr = exaDriverAlloc())) { 2059 pSiS->NoAccel = TRUE; 2060 pSiS->NoXvideo = TRUE; /* No fbmem manager -> no xv */ 2061 } 2062 } 2063#endif 2064 } 2065 2066 if(!pSiS->NoAccel) { 2067 2068 SiSInitializeAccelerator(pScrn); 2069 2070 pSiS->InitAccel = SiSInitializeAccelerator; 2071 pSiS->SyncAccel = SiSSyncAccel; 2072 pSiS->FillRect = SiSDGAFillRect; 2073 pSiS->BlitRect = SiSDGABlitRect; 2074 2075#ifdef SIS_USE_XAA /* ----------------------- XAA ----------------------- */ 2076 if(!pSiS->useEXA) { 2077 2078 infoPtr->Flags = LINEAR_FRAMEBUFFER | 2079 OFFSCREEN_PIXMAPS | 2080 PIXMAP_CACHE; 2081 2082 /* sync */ 2083 infoPtr->Sync = SiSSync; 2084 2085 /* BitBlt */ 2086 infoPtr->SetupForScreenToScreenCopy = SiSSetupForScreenToScreenCopy; 2087 infoPtr->SubsequentScreenToScreenCopy = SiSSubsequentScreenToScreenCopy; 2088 infoPtr->ScreenToScreenCopyFlags = NO_PLANEMASK | TRANSPARENCY_GXCOPY_ONLY; 2089 2090 /* solid fills */ 2091 infoPtr->SetupForSolidFill = SiSSetupForSolidFill; 2092 infoPtr->SubsequentSolidFillRect = SiSSubsequentSolidFillRect; 2093#ifdef TRAP 2094 if((pSiS->Chipset != PCI_CHIP_SIS660) && 2095 (pSiS->Chipset != PCI_CHIP_SIS330) && 2096 (pSiS->Chipset != PCI_CHIP_SIS340) && 2097 (pSiS->Chipset != PCI_CHIP_XGIXG20) && 2098 (pSiS->Chipset != PCI_CHIP_XGIXG40)) { 2099 infoPtr->SubsequentSolidFillTrap = SiSSubsequentSolidFillTrap; 2100 } 2101#endif 2102 infoPtr->SolidFillFlags = NO_PLANEMASK; 2103 2104 /* solid line */ 2105 infoPtr->SetupForSolidLine = SiSSetupForSolidLine; 2106 infoPtr->SubsequentSolidTwoPointLine = SiSSubsequentSolidTwoPointLine; 2107 infoPtr->SubsequentSolidHorVertLine = SiSSubsequentSolidHorzVertLine; 2108 infoPtr->SolidLineFlags = NO_PLANEMASK; 2109 2110 /* dashed line */ 2111 infoPtr->SetupForDashedLine = SiSSetupForDashedLine; 2112 infoPtr->SubsequentDashedTwoPointLine = SiSSubsequentDashedTwoPointLine; 2113 infoPtr->DashPatternMaxLength = 64; 2114 infoPtr->DashedLineFlags = NO_PLANEMASK | 2115 LINE_PATTERN_MSBFIRST_LSBJUSTIFIED; 2116 2117 /* 8x8 mono pattern fill */ 2118 infoPtr->SetupForMono8x8PatternFill = SiSSetupForMonoPatternFill; 2119 infoPtr->SubsequentMono8x8PatternFillRect = SiSSubsequentMonoPatternFill; 2120#ifdef TRAP 2121 if((pSiS->Chipset != PCI_CHIP_SIS660) && 2122 (pSiS->Chipset != PCI_CHIP_SIS330) && 2123 (pSiS->Chipset != PCI_CHIP_SIS340) && 2124 (pSiS->Chipset != PCI_CHIP_XGIXG20) && 2125 (pSiS->Chipset != PCI_CHIP_XGIXG40)) { 2126 infoPtr->SubsequentMono8x8PatternFillTrap = SiSSubsequentMonoPatternFillTrap; 2127 } 2128#endif 2129 infoPtr->Mono8x8PatternFillFlags = NO_PLANEMASK | 2130 HARDWARE_PATTERN_SCREEN_ORIGIN | 2131 HARDWARE_PATTERN_PROGRAMMED_BITS | 2132 BIT_ORDER_IN_BYTE_MSBFIRST; 2133 2134#ifdef SISVRAMQ 2135 /* 8x8 color pattern fill (MMIO support not implemented) */ 2136 infoPtr->SetupForColor8x8PatternFill = SiSSetupForColor8x8PatternFill; 2137 infoPtr->SubsequentColor8x8PatternFillRect = SiSSubsequentColor8x8PatternFillRect; 2138 infoPtr->Color8x8PatternFillFlags = NO_PLANEMASK | 2139 HARDWARE_PATTERN_SCREEN_ORIGIN | 2140 NO_TRANSPARENCY; 2141#endif 2142 2143#ifdef STSCE 2144 /* Screen To Screen Color Expand */ 2145 /* The hardware does not support this the way we need it, because 2146 * the mono-bitmap is not provided with a pitch of (width), but 2147 * with a pitch of scrnOffset (= width * bpp / 8). 2148 */ 2149 infoPtr->SetupForScreenToScreenColorExpandFill = 2150 SiSSetupForScreenToScreenColorExpand; 2151 infoPtr->SubsequentScreenToScreenColorExpandFill = 2152 SiSSubsequentScreenToScreenColorExpand; 2153 infoPtr->ScreenToScreenColorExpandFillFlags = NO_PLANEMASK | 2154 BIT_ORDER_IN_BYTE_MSBFIRST ; 2155#endif 2156 2157#ifdef CTSCE 2158#ifdef CTSCE_DIRECT 2159 /* CPU color expansion - direct method 2160 * 2161 * We somewhat fake this function here in the following way: 2162 * XAA copies its mono-bitmap data not into an aperture, but 2163 * into our video RAM buffer. We then do a ScreenToScreen 2164 * color expand. 2165 * Unfortunately, XAA sends the data to the aperture AFTER 2166 * the call to Subsequent(), therefore we do not execute the 2167 * command in Subsequent, but in the following call to Sync(). 2168 * (Hence, the SYNC_AFTER_COLOR_EXPAND flag MUST BE SET) 2169 * 2170 * This is slower than doing it by the CPU. 2171 */ 2172 2173 pSiS->ColorExpandBufferNumber = 48; 2174 pSiS->PerColorExpandBufferSize = ((pScrn->virtualX + 31)/32) * 4; 2175 infoPtr->SetupForCPUToScreenColorExpandFill = SiSSetupForCPUToScreenColorExpandFill; 2176 infoPtr->SubsequentCPUToScreenColorExpandFill = SiSSubsequentCPUToScreenColorExpandFill; 2177 infoPtr->ColorExpandRange = pSiS->ColorExpandBufferNumber * pSiS->PerColorExpandBufferSize; 2178 infoPtr->CPUToScreenColorExpandFillFlags = 2179 NO_PLANEMASK | 2180 CPU_TRANSFER_PAD_DWORD | 2181 SCANLINE_PAD_DWORD | 2182 BIT_ORDER_IN_BYTE_MSBFIRST | 2183 LEFT_EDGE_CLIPPING | 2184 SYNC_AFTER_COLOR_EXPAND; 2185#else 2186 /* CPU color expansion - per-scanline / indirect method 2187 * 2188 * SLOW! SLOWER! SLOWEST! 2189 * 2190 * Does not work on 330 series, hangs the engine (both VRAM and MMIO). 2191 * Does not work in VRAM queue mode. 2192 */ 2193#ifndef SISVRAMQ 2194 if((pSiS->Chipset != PCI_CHIP_SIS650) && 2195 (pSiS->Chipset != PCI_CHIP_SIS660) && 2196 (pSiS->Chipset != PCI_CHIP_SIS330) && 2197 (pSiS->Chipset != PCI_CHIP_SIS340) && 2198 (pSiS->Chipset != PCI_CHIP_XGIXG20) && 2199 (pSiS->Chipset != PCI_CHIP_XGIXG40)) { 2200 pSiS->ColorExpandBufferNumber = 16; 2201 pSiS->ColorExpandBufferCountMask = 0x0F; 2202 pSiS->PerColorExpandBufferSize = ((pScrn->virtualX + 31)/32) * 4; 2203 infoPtr->NumScanlineColorExpandBuffers = pSiS->ColorExpandBufferNumber; 2204 infoPtr->ScanlineColorExpandBuffers = (unsigned char **)&pSiS->ColorExpandBufferAddr[0]; 2205 infoPtr->SetupForScanlineCPUToScreenColorExpandFill = SiSSetupForScanlineCPUToScreenColorExpandFill; 2206 infoPtr->SubsequentScanlineCPUToScreenColorExpandFill = SiSSubsequentScanlineCPUToScreenColorExpandFill; 2207 infoPtr->SubsequentColorExpandScanline = SiSSubsequentColorExpandScanline; 2208 infoPtr->ScanlineCPUToScreenColorExpandFillFlags = 2209 NO_PLANEMASK | 2210 CPU_TRANSFER_PAD_DWORD | 2211 SCANLINE_PAD_DWORD | 2212 BIT_ORDER_IN_BYTE_MSBFIRST | 2213 LEFT_EDGE_CLIPPING; 2214 } 2215#endif 2216#endif 2217#endif 2218 2219#ifdef INCL_RENDER 2220#ifdef RENDER 2221 /* Render */ 2222 SiSCalcRenderAccelArray(pScrn); 2223 2224 if(pSiS->RenderAccelArray) { 2225 pSiS->AccelLinearScratch = NULL; 2226 2227#ifdef SISNEWRENDER 2228 infoPtr->SetupForCPUToScreenAlphaTexture2 = SiSSetupForCPUToScreenAlphaTexture; 2229 infoPtr->CPUToScreenAlphaTextureDstFormats = (pScrn->bitsPerPixel == 16) ? 2230 SiSDstTextureFormats16 : SiSDstTextureFormats32; 2231#else 2232 infoPtr->SetupForCPUToScreenAlphaTexture = SiSSetupForCPUToScreenAlphaTexture; 2233#endif 2234 infoPtr->SubsequentCPUToScreenAlphaTexture = SiSSubsequentCPUToScreenTexture; 2235 infoPtr->CPUToScreenAlphaTextureFormats = SiSAlphaTextureFormats; 2236 infoPtr->CPUToScreenAlphaTextureFlags = XAA_RENDER_NO_TILE; 2237 2238#ifdef SISNEWRENDER 2239 infoPtr->SetupForCPUToScreenTexture2 = SiSSetupForCPUToScreenTexture; 2240 infoPtr->CPUToScreenTextureDstFormats = (pScrn->bitsPerPixel == 16) ? 2241 SiSDstTextureFormats16 : SiSDstTextureFormats32; 2242#else 2243 infoPtr->SetupForCPUToScreenTexture = SiSSetupForCPUToScreenTexture; 2244#endif 2245 infoPtr->SubsequentCPUToScreenTexture = SiSSubsequentCPUToScreenTexture; 2246 infoPtr->CPUToScreenTextureFormats = SiSTextureFormats; 2247 infoPtr->CPUToScreenTextureFlags = XAA_RENDER_NO_TILE; 2248 2249 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "RENDER acceleration enabled\n"); 2250 } 2251#endif 2252#endif 2253 2254#ifdef SISDUALHEAD 2255 if(pSiS->DualHeadMode) { 2256 infoPtr->RestoreAccelState = SiSRestoreAccelState; 2257 } 2258#endif 2259 } /* !EXA */ 2260#endif /* XAA */ 2261 2262#ifdef SIS_USE_EXA /* ----------------------- EXA ----------------------- */ 2263 if(pSiS->useEXA) { 2264 pSiS->EXADriverPtr->exa_major = 2; 2265 pSiS->EXADriverPtr->exa_minor = 0; 2266 2267 /* data */ 2268 pSiS->EXADriverPtr->memoryBase = pSiS->FbBase; 2269 pSiS->EXADriverPtr->memorySize = pSiS->maxxfbmem; 2270 pSiS->EXADriverPtr->offScreenBase = pScrn->virtualX * pScrn->virtualY 2271 * ((pScrn->bitsPerPixel + 7) / 8); 2272 if(pSiS->EXADriverPtr->memorySize > pSiS->EXADriverPtr->offScreenBase) { 2273 pSiS->EXADriverPtr->flags = EXA_OFFSCREEN_PIXMAPS; 2274 } else { 2275 pSiS->NoXvideo = TRUE; 2276 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 2277 "Not enough video RAM for offscreen memory manager. Xv disabled\n"); 2278 } 2279 pSiS->EXADriverPtr->pixmapOffsetAlign = 16; /* src/dst: double quad word boundary */ 2280 pSiS->EXADriverPtr->pixmapPitchAlign = 4; /* pitch: double word boundary */ 2281 pSiS->EXADriverPtr->maxX = 4095; 2282 pSiS->EXADriverPtr->maxY = 4095; 2283 2284 /* Sync */ 2285 pSiS->EXADriverPtr->WaitMarker = SiSEXASync; 2286 2287 /* Solid fill */ 2288 pSiS->EXADriverPtr->PrepareSolid = SiSPrepareSolid; 2289 pSiS->EXADriverPtr->Solid = SiSSolid; 2290 pSiS->EXADriverPtr->DoneSolid = SiSDoneSolid; 2291 2292 /* Copy */ 2293 pSiS->EXADriverPtr->PrepareCopy = SiSPrepareCopy; 2294 pSiS->EXADriverPtr->Copy = SiSCopy; 2295 pSiS->EXADriverPtr->DoneCopy = SiSDoneCopy; 2296 2297 /* Composite */ 2298#ifdef SIS_HAVE_COMPOSITE 2299 SiSCalcRenderAccelArray(pScrn); 2300 if(pSiS->RenderAccelArray) { 2301 pSiS->EXADriverPtr->CheckComposite = SiSCheckComposite; 2302 pSiS->EXADriverPtr->PrepareComposite = SiSPrepareComposite; 2303 pSiS->EXADriverPtr->Composite = SiSComposite; 2304 pSiS->EXADriverPtr->DoneComposite = SiSDoneComposite; 2305 } 2306#endif 2307 2308 /* Upload, download to/from Screen */ 2309 pSiS->EXADriverPtr->UploadToScreen = SiSUploadToScreen; 2310 pSiS->EXADriverPtr->DownloadFromScreen = SiSDownloadFromScreen; 2311 2312 } 2313#endif 2314 2315 } /* NoAccel */ 2316 2317 /* Init framebuffer memory manager */ 2318 2319 /* Traditional layout: 2320 * |-----------------++++++++++++++++++++^************==========~~~~~~~~~~~~| 2321 * | UsableFbSize ColorExpandBuffers | DRI-Heap HWCursor CommandQueue 2322 * FbBase topFB 2323 * +-------------maxxfbmem---------------+ 2324 * 2325 * On SiS76x with UMA+LFB: 2326 * |UUUUUUUUUUUUUUU--------------++++++++++++++++++++^==========~~~~~~~~~~~~| 2327 * DRI heap |UsableFbSize ColorExpandBuffers | HWCursor CommandQueue 2328 * (in UMA and FbBase topFB 2329 * eventually +---------- maxxfbmem ------------+ 2330 * beginning of 2331 * LFB) 2332 */ 2333 2334#ifdef SIS_USE_XAA 2335 if(!pSiS->useEXA) { 2336 2337 topFB = pSiS->maxxfbmem; /* relative to FbBase */ 2338 2339 reservedFbSize = pSiS->ColorExpandBufferNumber * pSiS->PerColorExpandBufferSize; 2340 2341 usableFbSize = topFB - reservedFbSize; 2342 2343#ifdef CTSCE 2344 AvailBufBase = pSiS->FbBase + usableFbSize; 2345 if(pSiS->ColorExpandBufferNumber) { 2346#ifdef CTSCE_DIRECT 2347 infoPtr->ColorExpandBase = (unsigned char *)AvailBufBase; 2348 pSiS->ColorExpandBase = usableFbSize; 2349#else 2350 for(i = 0; i < pSiS->ColorExpandBufferNumber; i++) { 2351 pSiS->ColorExpandBufferAddr[i] = AvailBufBase + 2352 i * pSiS->PerColorExpandBufferSize; 2353 pSiS->ColorExpandBufferScreenOffset[i] = usableFbSize + 2354 i * pSiS->PerColorExpandBufferSize; 2355 } 2356#endif 2357 } 2358#endif 2359 2360 Avail.x1 = 0; 2361 Avail.y1 = 0; 2362 Avail.x2 = pScrn->displayWidth; 2363 Avail.y2 = (usableFbSize / (pScrn->displayWidth * pScrn->bitsPerPixel/8)) - 1; 2364 2365 if(Avail.y2 < 0) Avail.y2 = 32767; 2366 2367 if(Avail.y2 < pScrn->currentMode->VDisplay) { 2368 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 2369 "Not enough video RAM for accelerator. At least " 2370 "%dKB needed, %dKB available\n", 2371 ((((pScrn->displayWidth * pScrn->bitsPerPixel/8) /* +8 for make it sure */ 2372 * pScrn->currentMode->VDisplay) + reservedFbSize) / 1024) + 8, 2373 pSiS->maxxfbmem/1024); 2374 pSiS->NoAccel = TRUE; 2375 pSiS->NoXvideo = TRUE; 2376 XAADestroyInfoRec(pSiS->AccelInfoPtr); 2377 pSiS->AccelInfoPtr = NULL; 2378 return FALSE; /* Don't even init fb manager */ 2379 } 2380 2381 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2382 "Framebuffer from (%d,%d) to (%d,%d)\n", 2383 Avail.x1, Avail.y1, Avail.x2 - 1, Avail.y2 - 1); 2384 2385 xf86InitFBManager(pScreen, &Avail); 2386 2387 if(!pSiS->NoAccel) { 2388 return XAAInit(pScreen, infoPtr); 2389 } 2390 } /* !EXA */ 2391#endif /* XAA */ 2392 2393#ifdef SIS_USE_EXA 2394 if(pSiS->useEXA) { 2395 2396 if(!pSiS->NoAccel) { 2397 2398 if(!exaDriverInit(pScreen, pSiS->EXADriverPtr)) { 2399 pSiS->NoAccel = TRUE; 2400 pSiS->NoXvideo = TRUE; /* No fbmem manager -> no xv */ 2401 return FALSE; 2402 } 2403 2404 /* Reserve locked offscreen scratch area of 128K for glyph data */ 2405 pSiS->exa_scratch = exaOffscreenAlloc(pScreen, 128 * 1024, 16, TRUE, 2406 SiSScratchSave, pSiS); 2407 if(pSiS->exa_scratch) { 2408 pSiS->exa_scratch_next = pSiS->exa_scratch->offset; 2409 pSiS->EXADriverPtr->UploadToScratch = SiSUploadToScratch; 2410 } 2411 2412 } else { 2413 2414 pSiS->NoXvideo = TRUE; /* No fbmem manager -> no xv */ 2415 2416 } 2417 2418 } 2419#endif /* EXA */ 2420 2421 return TRUE; 2422} 2423 2424 2425 2426 2427