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