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