172b676d7Smrg/* 272b676d7Smrg * 2D Acceleration for SiS 530, 620, 300, 540, 630, 730. 372b676d7Smrg * 472b676d7Smrg * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria 572b676d7Smrg * 672b676d7Smrg * Redistribution and use in source and binary forms, with or without 772b676d7Smrg * modification, are permitted provided that the following conditions 872b676d7Smrg * are met: 972b676d7Smrg * 1) Redistributions of source code must retain the above copyright 1072b676d7Smrg * notice, this list of conditions and the following disclaimer. 1172b676d7Smrg * 2) Redistributions in binary form must reproduce the above copyright 1272b676d7Smrg * notice, this list of conditions and the following disclaimer in the 1372b676d7Smrg * documentation and/or other materials provided with the distribution. 1472b676d7Smrg * 3) The name of the author may not be used to endorse or promote products 1572b676d7Smrg * derived from this software without specific prior written permission. 1672b676d7Smrg * 1772b676d7Smrg * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 1872b676d7Smrg * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 1972b676d7Smrg * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 2072b676d7Smrg * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 2172b676d7Smrg * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 2272b676d7Smrg * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2372b676d7Smrg * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2472b676d7Smrg * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2572b676d7Smrg * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 2672b676d7Smrg * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2772b676d7Smrg * 2872b676d7Smrg * Authors: Thomas Winischhofer <thomas@winischhofer.net> 2972b676d7Smrg * Can-Ru Yeou, SiS Inc. 3072b676d7Smrg * 3172b676d7Smrg */ 3272b676d7Smrg 3372b676d7Smrg#ifdef HAVE_CONFIG_H 3472b676d7Smrg#include "config.h" 3572b676d7Smrg#endif 3672b676d7Smrg 3772b676d7Smrg#if 0 3872b676d7Smrg#define DEBUG 3972b676d7Smrg#endif 4072b676d7Smrg 4172b676d7Smrg#include "sis.h" 4272b676d7Smrg#include "sis_regs.h" 4372b676d7Smrg 4472b676d7Smrg#include "sis300_accel.h" 4572b676d7Smrg 4672b676d7Smrg/* This is the offset to the memory for each head */ 4772b676d7Smrg#define HEADOFFSET (pSiS->dhmOffset) 4872b676d7Smrg 4972b676d7Smrg#ifdef SIS_USE_XAA 5072b676d7Smrg 5172b676d7Smrg#undef STSCE /* Use/Don't use ScreenToScreenColorExpand - does not work */ 5272b676d7Smrg 5372b676d7Smrg#undef TRAP /* Use/Don't use Trapezoid Fills - does not work - XAA provides 5472b676d7Smrg * illegal trapezoid data (left and right edges cross each other 5572b676d7Smrg * sometimes) which causes drawing errors. Further, I have not found 5672b676d7Smrg * out how to draw polygones with a height greater than 127... 5772b676d7Smrg */ 5872b676d7Smrg#endif /* XAA */ 5972b676d7Smrg 6072b676d7Smrg#ifdef SIS_USE_EXA 6172b676d7Smrgextern void SiSScratchSave(ScreenPtr pScreen, ExaOffscreenArea *area); 6272b676d7Smrgextern Bool SiSUploadToScratch(PixmapPtr pSrc, PixmapPtr pDst); 6372b676d7Smrg#endif /* EXA */ 6472b676d7Smrg 6572b676d7Smrgextern UChar SiSGetCopyROP(int rop); 6672b676d7Smrgextern UChar SiSGetPatternROP(int rop); 6772b676d7Smrg 6872b676d7Smrgstatic void 6972b676d7SmrgSiSInitializeAccelerator(ScrnInfoPtr pScrn) 7072b676d7Smrg{ 7172b676d7Smrg#ifdef SIS_USE_XAA 7272b676d7Smrg SISPtr pSiS = SISPTR(pScrn); 7372b676d7Smrg 7472b676d7Smrg pSiS->DoColorExpand = FALSE; 7572b676d7Smrg#endif 7672b676d7Smrg} 7772b676d7Smrg 7872b676d7Smrgstatic void 7972b676d7SmrgSiSSync(ScrnInfoPtr pScrn) 8072b676d7Smrg{ 8172b676d7Smrg SISPtr pSiS = SISPTR(pScrn); 8272b676d7Smrg 8372b676d7Smrg SiSIdle 8472b676d7Smrg} 8572b676d7Smrg 8672b676d7Smrgstatic void 8772b676d7SmrgSiSSyncAccel(ScrnInfoPtr pScrn) 8872b676d7Smrg{ 8972b676d7Smrg SISPtr pSiS = SISPTR(pScrn); 9072b676d7Smrg 9172b676d7Smrg if(!pSiS->NoAccel) SiSSync(pScrn); 9272b676d7Smrg} 9372b676d7Smrg 9472b676d7Smrgstatic void 9572b676d7SmrgSiSSetupForScreenToScreenCopy(ScrnInfoPtr pScrn, 9672b676d7Smrg int xdir, int ydir, int rop, 9772b676d7Smrg unsigned int planemask, int trans_color) 9872b676d7Smrg{ 9972b676d7Smrg SISPtr pSiS = SISPTR(pScrn); 10072b676d7Smrg 10172b676d7Smrg SiSSetupDSTColorDepth(pSiS->DstColor); 10272b676d7Smrg SiSSetupSRCPitch(pSiS->scrnOffset) 10372b676d7Smrg SiSSetupDSTRect(pSiS->scrnOffset, -1) 10472b676d7Smrg 10572b676d7Smrg if(trans_color != -1) { 10672b676d7Smrg SiSSetupROP(0x0A) 10772b676d7Smrg SiSSetupSRCTrans(trans_color) 10872b676d7Smrg SiSSetupCMDFlag(TRANSPARENT_BITBLT) 10972b676d7Smrg } else { 11072b676d7Smrg SiSSetupROP(SiSGetCopyROP(rop)) 11172b676d7Smrg } 11272b676d7Smrg if(xdir > 0) { 11372b676d7Smrg SiSSetupCMDFlag(X_INC) 11472b676d7Smrg } 11572b676d7Smrg if(ydir > 0) { 11672b676d7Smrg SiSSetupCMDFlag(Y_INC) 11772b676d7Smrg } 11872b676d7Smrg} 11972b676d7Smrg 12072b676d7Smrgstatic void 12172b676d7SmrgSiSSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, 12272b676d7Smrg int src_x, int src_y, int dst_x, int dst_y, 12372b676d7Smrg int width, int height) 12472b676d7Smrg{ 12572b676d7Smrg SISPtr pSiS = SISPTR(pScrn); 12672b676d7Smrg CARD32 srcbase, dstbase; 12772b676d7Smrg 12872b676d7Smrg srcbase = dstbase = 0; 12972b676d7Smrg if(src_y >= 2048) { 13072b676d7Smrg srcbase = pSiS->scrnOffset * src_y; 13172b676d7Smrg src_y = 0; 13272b676d7Smrg } 13372b676d7Smrg if((dst_y >= pScrn->virtualY) || (dst_y >= 2048)) { 13472b676d7Smrg dstbase = pSiS->scrnOffset * dst_y; 13572b676d7Smrg dst_y = 0; 13672b676d7Smrg } 13772b676d7Smrg#ifdef SISDUALHEAD 13872b676d7Smrg if(pSiS->VGAEngine != SIS_530_VGA) { 13972b676d7Smrg srcbase += HEADOFFSET; 14072b676d7Smrg dstbase += HEADOFFSET; 14172b676d7Smrg } 14272b676d7Smrg#endif 14372b676d7Smrg SiSSetupSRCBase(srcbase); 14472b676d7Smrg SiSSetupDSTBase(dstbase); 14572b676d7Smrg 14672b676d7Smrg if(!(pSiS->CommandReg & X_INC)) { 14772b676d7Smrg src_x += width-1; 14872b676d7Smrg dst_x += width-1; 14972b676d7Smrg } 15072b676d7Smrg if(!(pSiS->CommandReg & Y_INC)) { 15172b676d7Smrg src_y += height-1; 15272b676d7Smrg dst_y += height-1; 15372b676d7Smrg } 15472b676d7Smrg SiSSetupRect(width, height) 15572b676d7Smrg SiSSetupSRCXY(src_x, src_y) 15672b676d7Smrg SiSSetupDSTXY(dst_x, dst_y) 15772b676d7Smrg 15872b676d7Smrg SiSDoCMD 15972b676d7Smrg} 16072b676d7Smrg 16172b676d7Smrgstatic void 16272b676d7SmrgSiSSetupForSolidFill(ScrnInfoPtr pScrn, 16372b676d7Smrg int color, int rop, unsigned int planemask) 16472b676d7Smrg{ 16572b676d7Smrg SISPtr pSiS = SISPTR(pScrn); 16672b676d7Smrg 16772b676d7Smrg if(pSiS->disablecolorkeycurrent) { 16872b676d7Smrg if((CARD32)color == pSiS->colorKey) { 16972b676d7Smrg rop = 5; /* NOOP */ 17072b676d7Smrg } 17172b676d7Smrg } 17272b676d7Smrg SiSSetupPATFG(color) 17372b676d7Smrg SiSSetupDSTRect(pSiS->scrnOffset, -1) 17472b676d7Smrg SiSSetupDSTColorDepth(pSiS->DstColor); 17572b676d7Smrg SiSSetupROP(SiSGetPatternROP(rop)) 17672b676d7Smrg /* SiSSetupCMDFlag(PATFG) - is zero */ 17772b676d7Smrg} 17872b676d7Smrg 17972b676d7Smrgstatic void 18072b676d7SmrgSiSSubsequentSolidFillRect(ScrnInfoPtr pScrn, 18172b676d7Smrg int x, int y, int w, int h) 18272b676d7Smrg{ 18372b676d7Smrg SISPtr pSiS = SISPTR(pScrn); 18472b676d7Smrg CARD32 dstbase = 0; 18572b676d7Smrg 18672b676d7Smrg if(y >= 2048) { 18772b676d7Smrg dstbase = pSiS->scrnOffset * y; 18872b676d7Smrg y = 0; 18972b676d7Smrg } 19072b676d7Smrg#ifdef SISDUALHEAD 19172b676d7Smrg if(pSiS->VGAEngine != SIS_530_VGA) { 19272b676d7Smrg dstbase += HEADOFFSET; 19372b676d7Smrg } 19472b676d7Smrg#endif 19572b676d7Smrg SiSSetupDSTBase(dstbase) 19672b676d7Smrg SiSSetupDSTXY(x,y) 19772b676d7Smrg SiSSetupRect(w,h) 19872b676d7Smrg /* Clear commandReg because Setup can be used for Rect and Trap */ 19972b676d7Smrg pSiS->CommandReg &= ~(T_XISMAJORL | T_XISMAJORR | 20072b676d7Smrg T_L_X_INC | T_L_Y_INC | 20172b676d7Smrg T_R_X_INC | T_R_Y_INC | 20272b676d7Smrg TRAPAZOID_FILL); 20372b676d7Smrg SiSSetupCMDFlag(X_INC | Y_INC | BITBLT) 20472b676d7Smrg 20572b676d7Smrg SiSDoCMD 20672b676d7Smrg} 20772b676d7Smrg 20872b676d7Smrg#ifdef SIS_USE_XAA /* ---------------------------- XAA -------------------------- */ 20972b676d7Smrg 21072b676d7Smrg#ifdef SISDUALHEAD 21172b676d7Smrgstatic void 21272b676d7SmrgSiSRestoreAccelState(ScrnInfoPtr pScrn) 21372b676d7Smrg{ 21472b676d7Smrg SISPtr pSiS = SISPTR(pScrn); 21572b676d7Smrg 21672b676d7Smrg /* We don't need to do anything special here; forcing the 21772b676d7Smrg * other head to re-read the CmdQueLen is not necessary: 21872b676d7Smrg * After the Sync in RestoreAccelState(), the real queue 21972b676d7Smrg * length is always larger than (or at least equal to) 22072b676d7Smrg * the amount stored in CmdQueueLen of the other head, 22172b676d7Smrg * so the only thing that might happen is one unnecessary 22272b676d7Smrg * Sync on the other head. I think we can live with that. 22372b676d7Smrg */ 22472b676d7Smrg pSiS->DoColorExpand = FALSE; 22572b676d7Smrg SiSIdle 22672b676d7Smrg} 22772b676d7Smrg#endif 22872b676d7Smrg 22972b676d7Smrg/* Trapezoid */ 23072b676d7Smrg/* This would work better if XAA would provide us with valid trapezoids. 23172b676d7Smrg * In fact, with small trapezoids the left and the right edge often cross 23272b676d7Smrg * each other or result in a line length of 0 which causes drawing errors 23372b676d7Smrg * (filling over whole scanline). 23472b676d7Smrg * Furthermore, I have not found out how to draw trapezoids with a height 23572b676d7Smrg * greater than 127. 23672b676d7Smrg */ 23772b676d7Smrg#ifdef TRAP 23872b676d7Smrgstatic void 23972b676d7SmrgSiSSubsequentSolidFillTrap(ScrnInfoPtr pScrn, int y, int h, 24072b676d7Smrg int left, int dxL, int dyL, int eL, 24172b676d7Smrg int right, int dxR, int dyR, int eR ) 24272b676d7Smrg{ 24372b676d7Smrg SISPtr pSiS = SISPTR(pScrn); 24472b676d7Smrg CARD32 dstbase; 24572b676d7Smrg#if 0 24672b676d7Smrg float kL, kR; 24772b676d7Smrg#endif 24872b676d7Smrg 24972b676d7Smrg dstbase = 0; 25072b676d7Smrg if(y >= 2048) { 25172b676d7Smrg dstbase=pSiS->scrnOffset*y; 25272b676d7Smrg y = 0; 25372b676d7Smrg } 25472b676d7Smrg#ifdef SISDUALHEAD 25572b676d7Smrg if(pSiS->VGAEngine != SIS_530_VGA) { 25672b676d7Smrg dstbase += HEADOFFSET; 25772b676d7Smrg } 25872b676d7Smrg#endif 25972b676d7Smrg SiSSetupDSTBase(dstbase) 26072b676d7Smrg /* SiSSetupRect(w,h) */ 26172b676d7Smrg 26272b676d7Smrg#if 1 26372b676d7Smrg SiSSetupPATFG(0xff0000) /* FOR TESTING */ 26472b676d7Smrg#endif 26572b676d7Smrg 26672b676d7Smrg /* Clear CommandReg because SetUp can be used for Rect and Trap */ 26772b676d7Smrg pSiS->CommandReg &= ~(T_L_X_INC | T_L_Y_INC | 26872b676d7Smrg T_R_X_INC | T_R_Y_INC | 26972b676d7Smrg T_XISMAJORL | T_XISMAJORR | 27072b676d7Smrg BITBLT); 27172b676d7Smrg 27272b676d7Smrg xf86DrvMsg(0, X_INFO, "Trap (%d %d %d %d) dxL %d dyL %d eL %d dxR %d dyR %d eR %d\n", 27372b676d7Smrg left, right, y, h, dxL, dyL, eL, dxR, dyR, eR); 27472b676d7Smrg 27572b676d7Smrg /* Unfortunately, we must check if the right and the left edge 27672b676d7Smrg * cross each other... INCOMPLETE (line equation wrong) 27772b676d7Smrg */ 27872b676d7Smrg#if 0 27972b676d7Smrg if (dxL == 0) kL = 0; 28072b676d7Smrg else kL = (float)dyL / (float)dxL; 28172b676d7Smrg if (dxR == 0) kR = 0; 28272b676d7Smrg else kR = (float)dyR / (float)dxR; 28372b676d7Smrg xf86DrvMsg(0, X_INFO, "kL %f kR %f!\n", kL, kR); 28472b676d7Smrg if ( (kR != kL) && 28572b676d7Smrg (!(kR == 0 && kL == 0)) && 28672b676d7Smrg (!(kR < 0 && kL > 0)) ) { 28772b676d7Smrg xf86DrvMsg(0, X_INFO, "Inside if (%f - %d)\n", ( kL * ( ( ((float)right - (float)left) / (kL - kR) ) - left) + y), h+y); 28872b676d7Smrg if ( ( ( kL * ( ( ((float)right - (float)left) / (kL - kR) ) - (float)left) + (float)y) < (h + y) ) ) { 28972b676d7Smrg xf86DrvMsg(0, X_INFO, "Cross detected!\n"); 29072b676d7Smrg } 29172b676d7Smrg } 29272b676d7Smrg#endif 29372b676d7Smrg 29472b676d7Smrg /* Determine egde angles */ 29572b676d7Smrg if(dxL < 0) { dxL = -dxL; } 29672b676d7Smrg else { SiSSetupCMDFlag(T_L_X_INC) } 29772b676d7Smrg if(dxR < 0) { dxR = -dxR; } 29872b676d7Smrg else { SiSSetupCMDFlag(T_R_X_INC) } 29972b676d7Smrg 30072b676d7Smrg /* (Y direction always positive - do this anyway) */ 30172b676d7Smrg if(dyL < 0) { dyL = -dyL; } 30272b676d7Smrg else { SiSSetupCMDFlag(T_L_Y_INC) } 30372b676d7Smrg if(dyR < 0) { dyR = -dyR; } 30472b676d7Smrg else { SiSSetupCMDFlag(T_R_Y_INC) } 30572b676d7Smrg 30672b676d7Smrg /* Determine major axis */ 30772b676d7Smrg if(dxL >= dyL) { /* X is major axis */ 30872b676d7Smrg SiSSetupCMDFlag(T_XISMAJORL) 30972b676d7Smrg } 31072b676d7Smrg if(dxR >= dyR) { /* X is major axis */ 31172b676d7Smrg SiSSetupCMDFlag(T_XISMAJORR) 31272b676d7Smrg } 31372b676d7Smrg 31472b676d7Smrg /* Set up deltas */ 31572b676d7Smrg SiSSetupdL(dxL, dyL) 31672b676d7Smrg SiSSetupdR(dxR, dyR) 31772b676d7Smrg 31872b676d7Smrg#if 0 /* Could it be that this crappy engine can only draw trapezoids up to 127 pixels high? */ 31972b676d7Smrg h &= 0x7F; 32072b676d7Smrg if (h == 0) h = 10; 32172b676d7Smrg#endif 32272b676d7Smrg 32372b676d7Smrg /* Set up y, h, left, right */ 32472b676d7Smrg SiSSetupYH(y,h) 32572b676d7Smrg SiSSetupLR(left,right) 32672b676d7Smrg 32772b676d7Smrg /* Set up initial error term */ 32872b676d7Smrg SiSSetupEL(eL) 32972b676d7Smrg SiSSetupER(eR) 33072b676d7Smrg 33172b676d7Smrg SiSSetupCMDFlag(TRAPAZOID_FILL); 33272b676d7Smrg 33372b676d7Smrg SiSDoCMD 33472b676d7Smrg} 33572b676d7Smrg#endif 33672b676d7Smrg 33772b676d7Smrgstatic void 33872b676d7SmrgSiSSetupForSolidLine(ScrnInfoPtr pScrn, 33972b676d7Smrg int color, int rop, unsigned int planemask) 34072b676d7Smrg{ 34172b676d7Smrg SISPtr pSiS = SISPTR(pScrn); 34272b676d7Smrg 34372b676d7Smrg SiSSetupLineCount(1) 34472b676d7Smrg SiSSetupPATFG(color) 34572b676d7Smrg SiSSetupDSTRect(pSiS->scrnOffset, -1) 34672b676d7Smrg SiSSetupDSTColorDepth(pSiS->DstColor); 34772b676d7Smrg SiSSetupROP(SiSGetPatternROP(rop)) 34872b676d7Smrg SiSSetupCMDFlag(PATFG | LINE) 34972b676d7Smrg} 35072b676d7Smrg 35172b676d7Smrgstatic void 35272b676d7SmrgSiSSubsequentSolidTwoPointLine(ScrnInfoPtr pScrn, 35372b676d7Smrg int x1, int y1, int x2, int y2, int flags) 35472b676d7Smrg{ 35572b676d7Smrg SISPtr pSiS = SISPTR(pScrn); 35672b676d7Smrg int miny, maxy; 35772b676d7Smrg CARD32 dstbase = 0; 35872b676d7Smrg 35972b676d7Smrg miny = (y1 > y2) ? y2 : y1; 36072b676d7Smrg maxy = (y1 > y2) ? y1 : y2; 36172b676d7Smrg if(maxy >= 2048) { 36272b676d7Smrg dstbase = pSiS->scrnOffset * miny; 36372b676d7Smrg y1 -= miny; 36472b676d7Smrg y2 -= miny; 36572b676d7Smrg } 36672b676d7Smrg#ifdef SISDUALHEAD 36772b676d7Smrg if(pSiS->VGAEngine != SIS_530_VGA) { 36872b676d7Smrg dstbase += HEADOFFSET; 36972b676d7Smrg } 37072b676d7Smrg#endif 37172b676d7Smrg SiSSetupDSTBase(dstbase) 37272b676d7Smrg 37372b676d7Smrg SiSSetupX0Y0(x1,y1) 37472b676d7Smrg SiSSetupX1Y1(x2,y2) 37572b676d7Smrg if(flags & OMIT_LAST) { 37672b676d7Smrg SiSSetupCMDFlag(NO_LAST_PIXEL) 37772b676d7Smrg } else { 37872b676d7Smrg pSiS->CommandReg &= ~(NO_LAST_PIXEL); 37972b676d7Smrg } 38072b676d7Smrg 38172b676d7Smrg SiSDoCMD 38272b676d7Smrg} 38372b676d7Smrg 38472b676d7Smrgstatic void 38572b676d7SmrgSiSSubsequentSolidHorzVertLine(ScrnInfoPtr pScrn, 38672b676d7Smrg int x, int y, int len, int dir) 38772b676d7Smrg{ 38872b676d7Smrg SISPtr pSiS = SISPTR(pScrn); 38972b676d7Smrg CARD32 dstbase = 0; 39072b676d7Smrg 39172b676d7Smrg len--; /* starting point is included! */ 39272b676d7Smrg 39372b676d7Smrg if((y >= 2048) || ((dir != DEGREES_0) && ((y + len) >= 2048))) { 39472b676d7Smrg dstbase = pSiS->scrnOffset * y; 39572b676d7Smrg y = 0; 39672b676d7Smrg } 39772b676d7Smrg#ifdef SISDUALHEAD 39872b676d7Smrg if(pSiS->VGAEngine != SIS_530_VGA) { 39972b676d7Smrg dstbase += HEADOFFSET; 40072b676d7Smrg } 40172b676d7Smrg#endif 40272b676d7Smrg SiSSetupDSTBase(dstbase) 40372b676d7Smrg 40472b676d7Smrg SiSSetupX0Y0(x,y) 40572b676d7Smrg if(dir == DEGREES_0) { 40672b676d7Smrg SiSSetupX1Y1(x + len, y); 40772b676d7Smrg } else { 40872b676d7Smrg SiSSetupX1Y1(x, y + len); 40972b676d7Smrg } 41072b676d7Smrg 41172b676d7Smrg SiSDoCMD 41272b676d7Smrg} 41372b676d7Smrg 41472b676d7Smrgstatic void 41572b676d7SmrgSiSSetupForDashedLine(ScrnInfoPtr pScrn, 41672b676d7Smrg int fg, int bg, int rop, unsigned int planemask, 41772b676d7Smrg int length, UChar *pattern) 41872b676d7Smrg{ 41972b676d7Smrg SISPtr pSiS = SISPTR(pScrn); 42072b676d7Smrg 42172b676d7Smrg SiSSetupLineCount(1) 42272b676d7Smrg SiSSetupDSTRect(pSiS->scrnOffset, -1) 42372b676d7Smrg SiSSetupDSTColorDepth(pSiS->DstColor); 42472b676d7Smrg SiSSetupStyleLow(*pattern) 42572b676d7Smrg SiSSetupStyleHigh(*(pattern+4)) 42672b676d7Smrg SiSSetupStylePeriod(length-1); 42772b676d7Smrg SiSSetupROP(SiSGetPatternROP(rop)) 42872b676d7Smrg SiSSetupPATFG(fg) 42972b676d7Smrg SiSSetupCMDFlag(LINE | LINE_STYLE) 43072b676d7Smrg if(bg != -1) { 43172b676d7Smrg SiSSetupPATBG(bg) 43272b676d7Smrg } else { 43372b676d7Smrg SiSSetupCMDFlag(TRANSPARENT); 43472b676d7Smrg } 43572b676d7Smrg} 43672b676d7Smrg 43772b676d7Smrgstatic void 43872b676d7SmrgSiSSubsequentDashedTwoPointLine(ScrnInfoPtr pScrn, 43972b676d7Smrg int x1, int y1, int x2, int y2, 44072b676d7Smrg int flags, int phase) 44172b676d7Smrg{ 44272b676d7Smrg SISPtr pSiS = SISPTR(pScrn); 44372b676d7Smrg int miny, maxy; 44472b676d7Smrg CARD32 dstbase = 0; 44572b676d7Smrg 44672b676d7Smrg miny = (y1 > y2) ? y2 : y1; 44772b676d7Smrg maxy = (y1 > y2) ? y1 : y2; 44872b676d7Smrg if(maxy >= 2048) { 44972b676d7Smrg dstbase = pSiS->scrnOffset * miny; 45072b676d7Smrg y1 -= miny; 45172b676d7Smrg y2 -= miny; 45272b676d7Smrg } 45372b676d7Smrg#ifdef SISDUALHEAD 45472b676d7Smrg if(pSiS->VGAEngine != SIS_530_VGA) { 45572b676d7Smrg dstbase += HEADOFFSET; 45672b676d7Smrg } 45772b676d7Smrg#endif 45872b676d7Smrg SiSSetupDSTBase(dstbase) 45972b676d7Smrg 46072b676d7Smrg SiSSetupX0Y0(x1,y1) 46172b676d7Smrg SiSSetupX1Y1(x2,y2) 46272b676d7Smrg if(flags & OMIT_LAST) { 46372b676d7Smrg SiSSetupCMDFlag(NO_LAST_PIXEL) 46472b676d7Smrg } else { 46572b676d7Smrg pSiS->CommandReg &= ~(NO_LAST_PIXEL); 46672b676d7Smrg } 46772b676d7Smrg 46872b676d7Smrg SiSDoCMD 46972b676d7Smrg} 47072b676d7Smrg 47172b676d7Smrgstatic void 47272b676d7SmrgSiSSetupForMonoPatternFill(ScrnInfoPtr pScrn, 47372b676d7Smrg int patx, int paty, int fg, int bg, 47472b676d7Smrg int rop, unsigned int planemask) 47572b676d7Smrg{ 47672b676d7Smrg SISPtr pSiS = SISPTR(pScrn); 47772b676d7Smrg 47872b676d7Smrg SiSSetupDSTRect(pSiS->scrnOffset, -1) 47972b676d7Smrg SiSSetupDSTColorDepth(pSiS->DstColor); 48072b676d7Smrg SiSSetupMONOPAT(patx,paty) 48172b676d7Smrg SiSSetupPATFG(fg) 48272b676d7Smrg SiSSetupROP(SiSGetPatternROP(rop)) 48372b676d7Smrg SiSSetupCMDFlag(PATMONO) 48472b676d7Smrg if(bg != -1) { 48572b676d7Smrg SiSSetupPATBG(bg) 48672b676d7Smrg } else { 48772b676d7Smrg SiSSetupCMDFlag(TRANSPARENT) 48872b676d7Smrg } 48972b676d7Smrg} 49072b676d7Smrg 49172b676d7Smrgstatic void 49272b676d7SmrgSiSSubsequentMonoPatternFill(ScrnInfoPtr pScrn, 49372b676d7Smrg int patx, int paty, 49472b676d7Smrg int x, int y, int w, int h) 49572b676d7Smrg{ 49672b676d7Smrg SISPtr pSiS = SISPTR(pScrn); 49772b676d7Smrg CARD32 dstbase = 0; 49872b676d7Smrg 49972b676d7Smrg if(y >= 2048) { 50072b676d7Smrg dstbase = pSiS->scrnOffset * y; 50172b676d7Smrg y = 0; 50272b676d7Smrg } 50372b676d7Smrg#ifdef SISDUALHEAD 50472b676d7Smrg if(pSiS->VGAEngine != SIS_530_VGA) { 50572b676d7Smrg dstbase += HEADOFFSET; 50672b676d7Smrg } 50772b676d7Smrg#endif 50872b676d7Smrg SiSSetupDSTBase(dstbase) 50972b676d7Smrg SiSSetupDSTXY(x, y) 51072b676d7Smrg SiSSetupRect(w, h) 51172b676d7Smrg /* Clear commandReg because Setup can be used for Rect and Trap */ 51272b676d7Smrg pSiS->CommandReg &= ~(T_XISMAJORL | T_XISMAJORR | 51372b676d7Smrg T_L_X_INC | T_L_Y_INC | 51472b676d7Smrg T_R_X_INC | T_R_Y_INC | 51572b676d7Smrg TRAPAZOID_FILL); 51672b676d7Smrg SiSSetupCMDFlag(X_INC | Y_INC) 51772b676d7Smrg 51872b676d7Smrg SiSDoCMD 51972b676d7Smrg} 52072b676d7Smrg 52172b676d7Smrg/* Trapezoid */ 52272b676d7Smrg#ifdef TRAP 52372b676d7Smrgstatic void 52472b676d7SmrgSiSSubsequentMonoPatternFillTrap(ScrnInfoPtr pScrn, 52572b676d7Smrg int patx, int paty, 52672b676d7Smrg int y, int h, 52772b676d7Smrg int left, int dxL, int dyL, int eL, 52872b676d7Smrg int right, int dxR, int dyR, int eR ) 52972b676d7Smrg{ 53072b676d7Smrg SISPtr pSiS = SISPTR(pScrn); 53172b676d7Smrg CARD32 dstbase = 0; 53272b676d7Smrg 53372b676d7Smrg if(y >= 2048) { 53472b676d7Smrg dstbase = pSiS->scrnOffset * y; 53572b676d7Smrg y = 0; 53672b676d7Smrg } 53772b676d7Smrg#ifdef SISDUALHEAD 53872b676d7Smrg if(pSiS->VGAEngine != SIS_530_VGA) { 53972b676d7Smrg dstbase += HEADOFFSET; 54072b676d7Smrg } 54172b676d7Smrg#endif 54272b676d7Smrg SiSSetupDSTBase(dstbase) 54372b676d7Smrg 54472b676d7Smrg /* Clear CommandReg because SetUp can be used for Rect and Trap */ 54572b676d7Smrg pSiS->CommandReg &= ~(T_XISMAJORL | T_XISMAJORR | 54672b676d7Smrg T_L_X_INC | T_L_Y_INC | 54772b676d7Smrg T_R_X_INC | T_R_Y_INC | 54872b676d7Smrg BITBLT); 54972b676d7Smrg 55072b676d7Smrg if(dxL < 0) { dxL = -dxL; } 55172b676d7Smrg else { SiSSetupCMDFlag(T_L_X_INC) } 55272b676d7Smrg if(dxR < 0) { dxR = -dxR; } 55372b676d7Smrg else { SiSSetupCMDFlag(T_R_X_INC) } 55472b676d7Smrg 55572b676d7Smrg if(dyL < 0) { dyL = -dyL; } 55672b676d7Smrg else { SiSSetupCMDFlag(T_L_Y_INC) } 55772b676d7Smrg if(dyR < 0) { dyR = -dyR; } 55872b676d7Smrg else { SiSSetupCMDFlag(T_R_Y_INC) } 55972b676d7Smrg 56072b676d7Smrg /* Determine major axis */ 56172b676d7Smrg if(dxL >= dyL) { /* X is major axis */ 56272b676d7Smrg SiSSetupCMDFlag(T_XISMAJORL) 56372b676d7Smrg } 56472b676d7Smrg if(dxR >= dyR) { /* X is major axis */ 56572b676d7Smrg SiSSetupCMDFlag(T_XISMAJORR) 56672b676d7Smrg } 56772b676d7Smrg 56872b676d7Smrg SiSSetupYH(y,h) 56972b676d7Smrg SiSSetupLR(left,right) 57072b676d7Smrg 57172b676d7Smrg SiSSetupdL(dxL, dyL) 57272b676d7Smrg SiSSetupdR(dxR, dyR) 57372b676d7Smrg 57472b676d7Smrg SiSSetupEL(eL) 57572b676d7Smrg SiSSetupER(eR) 57672b676d7Smrg 57772b676d7Smrg SiSSetupCMDFlag(TRAPAZOID_FILL); 57872b676d7Smrg 57972b676d7Smrg SiSDoCMD 58072b676d7Smrg} 58172b676d7Smrg#endif 58272b676d7Smrg 58372b676d7Smrg/* ------ Screen To Screen Color Expand ------------------------------- */ 58472b676d7Smrg 58572b676d7Smrg/* The hareware does not seem to support this the way we need it */ 58672b676d7Smrg 58772b676d7Smrg#ifdef STSCE 58872b676d7Smrgstatic void 58972b676d7SmrgSiSSetupForScreenToScreenColorExpand(ScrnInfoPtr pScrn, 59072b676d7Smrg int fg, int bg, 59172b676d7Smrg int rop, unsigned int planemask) 59272b676d7Smrg{ 59372b676d7Smrg SISPtr pSiS = SISPTR(pScrn); 59472b676d7Smrg 59572b676d7Smrg SiSSetupDSTColorDepth(pSiS->DstColor) 59672b676d7Smrg SiSSetupDSTRect(pSiS->scrnOffset, -1) 59772b676d7Smrg SiSSetupROP(SiSGetCopyROP(rop)) 59872b676d7Smrg SiSSetupSRCFG(fg) 59972b676d7Smrg /* SiSSetupSRCXY(0,0) */ 60072b676d7Smrg 60172b676d7Smrg if(bg == -1) { 60272b676d7Smrg SiSSetupCMDFlag(TRANSPARENT | ENCOLOREXP | X_INC | 60372b676d7Smrg Y_INC | SRCVIDEO); 60472b676d7Smrg } else { 60572b676d7Smrg SiSSetupSRCBG(bg); 60672b676d7Smrg SiSSetupCMDFlag(ENCOLOREXP | X_INC | Y_INC | 60772b676d7Smrg SRCVIDEO); 60872b676d7Smrg }; 60972b676d7Smrg} 61072b676d7Smrg#endif 61172b676d7Smrg 61272b676d7Smrg/* This method blits in a single task; this does not seem to work 61372b676d7Smrg * because the hardware does not use the source pitch as scanline 61472b676d7Smrg * offset but only to calculate pattern address from source X and Y. 61572b676d7Smrg * XAA provides the pattern bitmap with scrnOffset (displayWidth * bpp/8) 61672b676d7Smrg * offset, but this does not seem to be supported by the hardware. 61772b676d7Smrg */ 61872b676d7Smrg#ifdef STSCE 61972b676d7Smrg 62072b676d7Smrg/* For testing, these are the methods: (use only one at a time!) */ 62172b676d7Smrg 62272b676d7Smrg#undef npitch /* Normal: Use srcx/y as srcx/y, use scrnOffset as source pitch 62372b676d7Smrg * This would work if the hareware used the source pitch for 62472b676d7Smrg * incrementing the source address after each scanline - but 62572b676d7Smrg * it doesn't do this! The first line of the area is correctly 62672b676d7Smrg * color expanded, but since the source pitch is ignored and 62772b676d7Smrg * the source address not incremented correctly, the following 62872b676d7Smrg * lines are color expanded with any bit pattern that is left 62972b676d7Smrg * in the unused space of the source bitmap (which is organized 63072b676d7Smrg * with the depth of the screen framebuffer hence with a pitch 63172b676d7Smrg * of scrnOffset). 63272b676d7Smrg */ 63372b676d7Smrg 63472b676d7Smrg#undef pitchdw /* Use source pitch "displayWidth / 8" instead 63572b676d7Smrg * of scrnOffset (=displayWidth * bpp / 8) 63672b676d7Smrg * This can't work, because the pitch of the source 63772b676d7Smrg * bitmap is scrnoffset! 63872b676d7Smrg */ 63972b676d7Smrg 64072b676d7Smrg#define nopitch /* Calculate srcbase with srcx and srcy, set the 64172b676d7Smrg * pitch to scrnOffset (which IS the correct pitch 64272b676d7Smrg * for the source bitmap) and set srcx and srcy both 64372b676d7Smrg * to 0. 64472b676d7Smrg * This would work if the hareware used the source pitch for 64572b676d7Smrg * incrementing the source address after each scanline - but 64672b676d7Smrg * it doesn't do this! Again: The first line of the area is 64772b676d7Smrg * correctly color expanded, but since the source pitch is 64872b676d7Smrg * ignored for scanline address incremention, the following 64972b676d7Smrg * lines are not correctly color expanded. 65072b676d7Smrg * WHATEVER I write to source pitch is ignored! 65172b676d7Smrg */ 65272b676d7Smrg 65372b676d7Smrgstatic void 65472b676d7SmrgSiSSubsequentScreenToScreenColorExpand(ScrnInfoPtr pScrn, 65572b676d7Smrg int x, int y, int w, int h, 65672b676d7Smrg int srcx, int srcy, int skipleft) 65772b676d7Smrg{ 65872b676d7Smrg SISPtr pSiS = SISPTR(pScrn); 65972b676d7Smrg CARD32 srcbase, dstbase; 66072b676d7Smrg#if 0 66172b676d7Smrg int _x0, _y0, _x1, _y1; 66272b676d7Smrg#endif 66372b676d7Smrg#ifdef pitchdw 66472b676d7Smrg int newsrcx, newsrcy; 66572b676d7Smrg 66672b676d7Smrg /* srcx and srcy are provided based on a scrnOffset pitch ( = displayWidth * bpp / 8 ) 66772b676d7Smrg * We recalulate srcx and srcy based on pitch = displayWidth / 8 66872b676d7Smrg */ 66972b676d7Smrg newsrcy = ((pSiS->scrnOffset * srcy) + (srcx * ((pScrn->bitsPerPixel+7)/8))) / 67072b676d7Smrg (pScrn->displayWidth/8); 67172b676d7Smrg newsrcx = ((pSiS->scrnOffset * srcy) + (srcx * ((pScrn->bitsPerPixel+7)/8))) % 67272b676d7Smrg (pScrn->displayWidth/8); 67372b676d7Smrg#endif 67472b676d7Smrg xf86DrvMsg(0, X_INFO, "Sub ScreenToScreen ColorExp(%d,%d, %d,%d, %d,%d, %d)\n", 67572b676d7Smrg x, y, w, h, srcx, srcy, skipleft); 67672b676d7Smrg 67772b676d7Smrg srcbase = dstbase = 0; 67872b676d7Smrg 67972b676d7Smrg#ifdef pitchdw 68072b676d7Smrg if(newsrcy >= 2048) { 68172b676d7Smrg srcbase = (pScrn->displayWidth / 8) * newsrcy; 68272b676d7Smrg newsrcy = 0; 68372b676d7Smrg } 68472b676d7Smrg#endif 68572b676d7Smrg#ifdef nopitch 68672b676d7Smrg srcbase = (pSiS->scrnOffset * srcy) + (srcx * ((pScrn->bitsPerPixel+7)/8)); 68772b676d7Smrg#endif 68872b676d7Smrg#ifdef npitch 68972b676d7Smrg if(srcy >= 2048) { 69072b676d7Smrg srcbase = pSiS->scrnOffset * srcy; 69172b676d7Smrg srcy = 0; 69272b676d7Smrg } 69372b676d7Smrg#endif 69472b676d7Smrg if(y >= 2048) { 69572b676d7Smrg dstbase = pSiS->scrnOffset * y; 69672b676d7Smrg y = 0; 69772b676d7Smrg } 69872b676d7Smrg#ifdef SISDUALHEAD 69972b676d7Smrg if(pSiS->VGAEngine != SIS_530_VGA) { 70072b676d7Smrg srcbase += HEADOFFSET; 70172b676d7Smrg dstbase += HEADOFFSET; 70272b676d7Smrg } 70372b676d7Smrg#endif 70472b676d7Smrg SiSSetupSRCBase(srcbase) 70572b676d7Smrg SiSSetupDSTBase(dstbase) 70672b676d7Smrg 70772b676d7Smrg#ifdef pitchdw 70872b676d7Smrg SiSSetupSRCPitch(pScrn->displayWidth/8) 70972b676d7Smrg#endif 71072b676d7Smrg#ifdef nopitch 71172b676d7Smrg SiSSetupSRCPitch(pSiS->scrnOffset) 71272b676d7Smrg /* SiSSetupSRCPitch(100) */ /* For test - has NO effect WHATSOEVER */ 71372b676d7Smrg#endif 71472b676d7Smrg#ifdef npitch 71572b676d7Smrg SiSSetupSRCPitch(pSiS->scrnOffset) 71672b676d7Smrg#endif 71772b676d7Smrg 71872b676d7Smrg SiSSetupRect(w,h) 71972b676d7Smrg 72072b676d7Smrg#if 0 /* How do I implement the offset? Not this way, that's for sure.. */ 72172b676d7Smrg if (skipleft > 0) { 72272b676d7Smrg _x0 = x+skipleft; 72372b676d7Smrg _y0 = y; 72472b676d7Smrg _x1 = x+w; 72572b676d7Smrg _y1 = y+h; 72672b676d7Smrg SiSSetupClipLT(_x0, _y0); 72772b676d7Smrg SiSSetupClipRB(_x1, _y1); 72872b676d7Smrg SiSSetupCMDFlag(CLIPENABLE); 72972b676d7Smrg } 73072b676d7Smrg#endif 73172b676d7Smrg#ifdef pitchdw 73272b676d7Smrg SiSSetupSRCXY(newsrcx, newsrcy) 73372b676d7Smrg#endif 73472b676d7Smrg#ifdef nopitch 73572b676d7Smrg SiSSetupSRCXY(0,0) 73672b676d7Smrg#endif 73772b676d7Smrg#ifdef npitch 73872b676d7Smrg SiSSetupSRCXY(srcx, srcy) 73972b676d7Smrg#endif 74072b676d7Smrg 74172b676d7Smrg SiSSetupDSTXY(x,y) 74272b676d7Smrg 74372b676d7Smrg SiSDoCMD 74472b676d7Smrg} 74572b676d7Smrg#endif 74672b676d7Smrg 74772b676d7Smrg/* ----- CPU To Screen Color Expand (scanline-wise) ----------------- */ 74872b676d7Smrg 74972b676d7Smrg/* We do it using the indirect method */ 75072b676d7Smrg 75172b676d7Smrgstatic void 75272b676d7SmrgSiSSetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, 75372b676d7Smrg int fg, int bg, int rop, unsigned int planemask) 75472b676d7Smrg{ 75572b676d7Smrg SISPtr pSiS=SISPTR(pScrn); 75672b676d7Smrg 75772b676d7Smrg /* Make sure that current CPU-driven BitBlt buffer stage is 0 75872b676d7Smrg * This is required!!! (Otherwise -> drawing errors) 75972b676d7Smrg */ 76072b676d7Smrg while((SIS_MMIO_IN16(pSiS->IOBase, 0x8242) & 0x1F00) != 0) {} /* WDR: == 0x10 */ 76172b676d7Smrg 76272b676d7Smrg SiSSetupSRCXY(0,0); 76372b676d7Smrg SiSSetupROP(SiSGetCopyROP(rop)); 76472b676d7Smrg SiSSetupSRCFG(fg); 76572b676d7Smrg SiSSetupDSTRect(pSiS->scrnOffset, -1); 76672b676d7Smrg SiSSetupDSTColorDepth(pSiS->DstColor); 76772b676d7Smrg if(bg == -1) { 76872b676d7Smrg SiSSetupCMDFlag(TRANSPARENT | 76972b676d7Smrg ENCOLOREXP | 77072b676d7Smrg X_INC | Y_INC | 77172b676d7Smrg SRCCPUBLITBUF); 77272b676d7Smrg } else { 77372b676d7Smrg SiSSetupSRCBG(bg); 77472b676d7Smrg SiSSetupCMDFlag(ENCOLOREXP | 77572b676d7Smrg X_INC | Y_INC | 77672b676d7Smrg SRCCPUBLITBUF); 77772b676d7Smrg } 77872b676d7Smrg} 77972b676d7Smrg 78072b676d7Smrg 78172b676d7Smrgstatic void 78272b676d7SmrgSiSSubsequentScanlineCPUToScreenColorExpandFill( 78372b676d7Smrg ScrnInfoPtr pScrn, int x, int y, int w, 78472b676d7Smrg int h, int skipleft) 78572b676d7Smrg{ 78672b676d7Smrg SISPtr pSiS = SISPTR(pScrn); 78772b676d7Smrg int _x0, _y0, _x1, _y1; 78872b676d7Smrg CARD32 dstbase = 0; 78972b676d7Smrg 79072b676d7Smrg if((y >= 2048) || ((y + h) >= 2048)) { 79172b676d7Smrg dstbase = pSiS->scrnOffset * y; 79272b676d7Smrg y = 0; 79372b676d7Smrg } 79472b676d7Smrg#ifdef SISDUALHEAD 79572b676d7Smrg if(pSiS->VGAEngine != SIS_530_VGA) { 79672b676d7Smrg dstbase += HEADOFFSET; 79772b676d7Smrg } 79872b676d7Smrg#endif 79972b676d7Smrg 80072b676d7Smrg /* Wait until there is no color expansion command in queue 80172b676d7Smrg * (This solves the OpenOffice.org window-move bug) 80272b676d7Smrg * Added Idle-check - bit 23 is set sometimes, although 80372b676d7Smrg * engine is actually idle! 80472b676d7Smrg * Update: Bit 23 is not reliable. After heavy 3D engine 80572b676d7Smrg * action, this bit never gets cleared again. So do 80672b676d7Smrg * SiSIdle instead. 80772b676d7Smrg */ 80872b676d7Smrg if((SIS_MMIO_IN16(pSiS->IOBase, 0x8242) & 0xe000) != 0xe000) { 80972b676d7Smrg /* while ((SIS_MMIO_IN16(pSiS->IOBase, 0x8242) & 0x0080) != 0) {} */ 81072b676d7Smrg SiSIdle 81172b676d7Smrg } 81272b676d7Smrg 81372b676d7Smrg SiSSetupDSTBase(dstbase) 81472b676d7Smrg 81572b676d7Smrg if(skipleft > 0) { 81672b676d7Smrg _x0 = x + skipleft; 81772b676d7Smrg _y0 = y; 81872b676d7Smrg _x1 = x + w; 81972b676d7Smrg _y1 = y + h; 82072b676d7Smrg SiSSetupClipLT(_x0, _y0); 82172b676d7Smrg SiSSetupClipRB(_x1, _y1); 82272b676d7Smrg SiSSetupCMDFlag(CLIPENABLE); 82372b676d7Smrg } else { 82472b676d7Smrg pSiS->CommandReg &= (~CLIPENABLE); 82572b676d7Smrg } 82672b676d7Smrg 82772b676d7Smrg SiSSetupRect(w, 1); 82872b676d7Smrg SiSSetupSRCPitch(((((w + 7) / 8) + 3) >> 2) * 4); 82972b676d7Smrg pSiS->xcurrent = x; 83072b676d7Smrg pSiS->ycurrent = y; 83172b676d7Smrg} 83272b676d7Smrg 83372b676d7Smrgstatic void 83472b676d7SmrgSiSSubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno) 83572b676d7Smrg{ 83672b676d7Smrg SISPtr pSiS=SISPTR(pScrn); 83772b676d7Smrg#if 0 83872b676d7Smrg int newhead,bltbufstage,newtail; 83972b676d7Smrg#endif 84072b676d7Smrg CARD32 cbo; 84172b676d7Smrg 84272b676d7Smrg cbo = pSiS->ColorExpandBufferScreenOffset[bufno]; 84372b676d7Smrg#ifdef SISDUALHEAD 84472b676d7Smrg if(pSiS->VGAEngine != SIS_530_VGA) { 84572b676d7Smrg cbo += HEADOFFSET; 84672b676d7Smrg } 84772b676d7Smrg#endif 84872b676d7Smrg 84972b676d7Smrg /* Wait until there is no color expansion command in queue 85072b676d7Smrg * (This solves the GTK-big-font bug) 85172b676d7Smrg * Added Idle-check - bit 23 is set sometimes, although 85272b676d7Smrg * engine is actually idle! 85372b676d7Smrg * Update: Bit 23 is not reliable. After heavy 3D engine 85472b676d7Smrg * action, this bit never gets cleared again. So do 85572b676d7Smrg * SiSIdle instead. 85672b676d7Smrg */ 85772b676d7Smrg if((SIS_MMIO_IN16(pSiS->IOBase, 0x8242) & 0xe000) != 0xe000) { 85872b676d7Smrg /* while ((SIS_MMIO_IN16(pSiS->IOBase, 0x8242) & 0x0080) != 0) {} */ 85972b676d7Smrg SiSIdle 86072b676d7Smrg } 86172b676d7Smrg 86272b676d7Smrg SiSSetupSRCBase(cbo); 86372b676d7Smrg 86472b676d7Smrg SiSSetupDSTXY(pSiS->xcurrent, pSiS->ycurrent); 86572b676d7Smrg 86672b676d7Smrg SiSDoCMD 86772b676d7Smrg 86872b676d7Smrg pSiS->ycurrent++; 86972b676d7Smrg 87072b676d7Smrg if(pSiS->VGAEngine == SIS_530_VGA) { 87172b676d7Smrg while(SIS_MMIO_IN8(pSiS->IOBase, 0x8242) & 0x80) {} 87272b676d7Smrg } 87372b676d7Smrg} 87472b676d7Smrg 87572b676d7Smrg#endif /* XAA */ 87672b676d7Smrg 87772b676d7Smrg#ifdef SIS_USE_EXA /* ---------------------------- EXA -------------------------- */ 87872b676d7Smrg 87972b676d7Smrgstatic const unsigned short dstcol[] = { 0x0000, 0x8000, 0xc000 }; 88072b676d7Smrg 88172b676d7Smrgstatic void 88272b676d7SmrgSiSEXASync(ScreenPtr pScreen, int marker) 88372b676d7Smrg{ 88474c14cd6Smrg SISPtr pSiS = SISPTR(xf86ScreenToScrn(pScreen)); 88572b676d7Smrg 88672b676d7Smrg SiSIdle 88772b676d7Smrg} 88872b676d7Smrg 88972b676d7Smrgstatic Bool 89072b676d7SmrgSiSPrepareSolid(PixmapPtr pPixmap, int alu, Pixel planemask, Pixel fg) 89172b676d7Smrg{ 89274c14cd6Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pPixmap->drawable.pScreen); 89372b676d7Smrg SISPtr pSiS = SISPTR(pScrn); 89472b676d7Smrg CARD32 dstbase; 89572b676d7Smrg 89672b676d7Smrg /* Planemask not supported */ 89772b676d7Smrg if((planemask & ((1 << pPixmap->drawable.depth) - 1)) != 89872b676d7Smrg (1 << pPixmap->drawable.depth) - 1) { 89972b676d7Smrg return FALSE; 90072b676d7Smrg } 90172b676d7Smrg 90272b676d7Smrg /* Since the 530/620 have no "dest color depth" register, I 90372b676d7Smrg * assume that the 2D engine reads the current color depth 90472b676d7Smrg * from the DAC.... FIXME ? */ 90572b676d7Smrg if(pSiS->VGAEngine == SIS_530_VGA) { 90672b676d7Smrg if(pPixmap->drawable.bitsPerPixel != pSiS->CurrentLayout.bitsPerPixel) 90772b676d7Smrg return FALSE; 90872b676d7Smrg } else if((pPixmap->drawable.bitsPerPixel != 8) && 90972b676d7Smrg (pPixmap->drawable.bitsPerPixel != 16) && 91072b676d7Smrg (pPixmap->drawable.bitsPerPixel != 32)) 91172b676d7Smrg return FALSE; 91272b676d7Smrg 91372b676d7Smrg if(pSiS->disablecolorkeycurrent) { 91472b676d7Smrg if((CARD32)fg == pSiS->colorKey) { 91572b676d7Smrg alu = 5; /* NOOP */ 91672b676d7Smrg } 91772b676d7Smrg } 91872b676d7Smrg 91972b676d7Smrg /* Check that the pitch matches the hardware's requirements. Should 92072b676d7Smrg * never be a problem due to pixmapPitchAlign and fbScreenInit. 92172b676d7Smrg */ 92272b676d7Smrg if(exaGetPixmapPitch(pPixmap) & 3) 92372b676d7Smrg return FALSE; 92472b676d7Smrg 92572b676d7Smrg dstbase = (CARD32)exaGetPixmapOffset(pPixmap) + HEADOFFSET; 92672b676d7Smrg 92772b676d7Smrg SiSSetupPATFG(fg) 92872b676d7Smrg SiSSetupDSTRect(exaGetPixmapPitch(pPixmap), -1) 92972b676d7Smrg SiSSetupDSTColorDepth(dstcol[pPixmap->drawable.bitsPerPixel >> 4]); 93072b676d7Smrg SiSSetupROP(SiSGetPatternROP(alu)) 93172b676d7Smrg SiSSetupDSTBase(dstbase) 93272b676d7Smrg /* SiSSetupCMDFlag(PATFG) - is zero */ 93372b676d7Smrg 93472b676d7Smrg return TRUE; 93572b676d7Smrg} 93672b676d7Smrg 93772b676d7Smrgstatic void 93872b676d7SmrgSiSSolid(PixmapPtr pPixmap, int x1, int y1, int x2, int y2) 93972b676d7Smrg{ 94074c14cd6Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pPixmap->drawable.pScreen); 94172b676d7Smrg SISPtr pSiS = SISPTR(pScrn); 94272b676d7Smrg 94372b676d7Smrg SiSSetupDSTXY(x1, y1) 94472b676d7Smrg SiSSetupRect(x2-x1, y2-y1) 94572b676d7Smrg 94672b676d7Smrg SiSSetupCMDFlag(X_INC | Y_INC | BITBLT) 94772b676d7Smrg 94872b676d7Smrg SiSDoCMD 94972b676d7Smrg} 95072b676d7Smrg 95172b676d7Smrgstatic void 95272b676d7SmrgSiSDoneSolid(PixmapPtr pPixmap) 95372b676d7Smrg{ 95472b676d7Smrg} 95572b676d7Smrg 95672b676d7Smrgstatic Bool 95772b676d7SmrgSiSPrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, int xdir, int ydir, 95872b676d7Smrg int alu, Pixel planemask) 95972b676d7Smrg{ 96074c14cd6Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pDstPixmap->drawable.pScreen); 96172b676d7Smrg SISPtr pSiS = SISPTR(pScrn); 96272b676d7Smrg CARD32 srcbase, dstbase; 96372b676d7Smrg 96472b676d7Smrg /* Planemask not supported */ 96572b676d7Smrg if((planemask & ((1 << pSrcPixmap->drawable.depth) - 1)) != 96672b676d7Smrg (1 << pSrcPixmap->drawable.depth) - 1) { 96772b676d7Smrg return FALSE; 96872b676d7Smrg } 96972b676d7Smrg 97072b676d7Smrg /* Since the 530/620 have no "dest color depth" register, I 97172b676d7Smrg * assume that the 2D engine reads the current color depth 97272b676d7Smrg * from the DAC.... FIXME ? */ 97372b676d7Smrg if(pSiS->VGAEngine == SIS_530_VGA) { 97472b676d7Smrg if(pDstPixmap->drawable.bitsPerPixel != pSiS->CurrentLayout.bitsPerPixel) 97572b676d7Smrg return FALSE; 97672b676d7Smrg } else if((pDstPixmap->drawable.bitsPerPixel != 8) && 97772b676d7Smrg (pDstPixmap->drawable.bitsPerPixel != 16) && 97872b676d7Smrg (pDstPixmap->drawable.bitsPerPixel != 32)) 97972b676d7Smrg return FALSE; 98072b676d7Smrg 98172b676d7Smrg /* Check that the pitch matches the hardware's requirements. Should 98272b676d7Smrg * never be a problem due to pixmapPitchAlign and fbScreenInit. 98372b676d7Smrg */ 98472b676d7Smrg if(exaGetPixmapPitch(pSrcPixmap) & 3) 98572b676d7Smrg return FALSE; 98672b676d7Smrg if(exaGetPixmapPitch(pDstPixmap) & 3) 98772b676d7Smrg return FALSE; 98872b676d7Smrg 98972b676d7Smrg SiSSetupDSTColorDepth(dstcol[pDstPixmap->drawable.bitsPerPixel >> 4]); 99072b676d7Smrg SiSSetupSRCPitch(exaGetPixmapPitch(pSrcPixmap)) 99172b676d7Smrg SiSSetupDSTRect(exaGetPixmapPitch(pDstPixmap), -1) 99272b676d7Smrg 99372b676d7Smrg SiSSetupROP(SiSGetCopyROP(alu)) 99472b676d7Smrg 99572b676d7Smrg if(xdir >= 0) { 99672b676d7Smrg SiSSetupCMDFlag(X_INC) 99772b676d7Smrg } 99872b676d7Smrg if(ydir >= 0) { 99972b676d7Smrg SiSSetupCMDFlag(Y_INC) 100072b676d7Smrg } 100172b676d7Smrg 100272b676d7Smrg srcbase = (CARD32)exaGetPixmapOffset(pSrcPixmap) + HEADOFFSET; 100372b676d7Smrg 100472b676d7Smrg dstbase = (CARD32)exaGetPixmapOffset(pDstPixmap) + HEADOFFSET; 100572b676d7Smrg 100672b676d7Smrg SiSSetupSRCBase(srcbase); 100772b676d7Smrg SiSSetupDSTBase(dstbase); 100872b676d7Smrg 100972b676d7Smrg return TRUE; 101072b676d7Smrg} 101172b676d7Smrg 101272b676d7Smrgstatic void 101372b676d7SmrgSiSCopy(PixmapPtr pDstPixmap, int srcX, int srcY, int dstX, int dstY, int width, int height) 101472b676d7Smrg{ 101574c14cd6Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pDstPixmap->drawable.pScreen); 101672b676d7Smrg SISPtr pSiS = SISPTR(pScrn); 101772b676d7Smrg 101872b676d7Smrg if(!(pSiS->CommandReg & X_INC)) { 101972b676d7Smrg srcX += width-1; 102072b676d7Smrg dstX += width-1; 102172b676d7Smrg } 102272b676d7Smrg if(!(pSiS->CommandReg & Y_INC)) { 102372b676d7Smrg srcY += height-1; 102472b676d7Smrg dstY += height-1; 102572b676d7Smrg } 102672b676d7Smrg SiSSetupRect(width, height) 102772b676d7Smrg SiSSetupSRCXY(srcX, srcY) 102872b676d7Smrg SiSSetupDSTXY(dstX, dstY) 102972b676d7Smrg 103072b676d7Smrg SiSDoCMD 103172b676d7Smrg} 103272b676d7Smrg 103372b676d7Smrgstatic void 103472b676d7SmrgSiSDoneCopy(PixmapPtr pDstPixmap) 103572b676d7Smrg{ 103672b676d7Smrg} 103772b676d7Smrg 103872b676d7Smrg#endif /* EXA */ 103972b676d7Smrg 104072b676d7Smrg/* For DGA usage */ 104172b676d7Smrg 104272b676d7Smrgstatic void 104372b676d7SmrgSiSDGAFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h, int color) 104472b676d7Smrg{ 104572b676d7Smrg SiSSetupForSolidFill(pScrn, color, GXcopy, ~0); 104672b676d7Smrg SiSSubsequentSolidFillRect(pScrn, x, y, w, h); 104772b676d7Smrg} 104872b676d7Smrg 104972b676d7Smrgstatic void 105072b676d7SmrgSiSDGABlitRect(ScrnInfoPtr pScrn, int srcx, int srcy, int dstx, int dsty, int w, int h, int color) 105172b676d7Smrg{ 105272b676d7Smrg int xdir = ((srcx < dstx) && (srcy == dsty)) ? -1 : 1; 105372b676d7Smrg int ydir = (srcy < dsty) ? -1 : 1; 105472b676d7Smrg 105572b676d7Smrg SiSSetupForScreenToScreenCopy(pScrn, xdir, ydir, GXcopy, (CARD32)~0, color); 105672b676d7Smrg SiSSubsequentScreenToScreenCopy(pScrn, srcx, srcy, dstx, dsty, w, h); 105772b676d7Smrg} 105872b676d7Smrg 105972b676d7Smrg/* Initialisation */ 106072b676d7Smrg 106172b676d7SmrgBool 106272b676d7SmrgSiS300AccelInit(ScreenPtr pScreen) 106372b676d7Smrg{ 106474c14cd6Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 106572b676d7Smrg SISPtr pSiS = SISPTR(pScrn); 106672b676d7Smrg#ifdef SIS_USE_XAA 106772b676d7Smrg XAAInfoRecPtr infoPtr = NULL; 106872b676d7Smrg UChar *AvailBufBase; 106972b676d7Smrg int topFB, reservedFbSize, usableFbSize, i; 107072b676d7Smrg BoxRec Avail; 107172b676d7Smrg#endif /* XAA */ 107272b676d7Smrg 107372b676d7Smrg pSiS->ColorExpandBufferNumber = 0; 107472b676d7Smrg pSiS->PerColorExpandBufferSize = 0; 107572b676d7Smrg pSiS->RenderAccelArray = NULL; 107672b676d7Smrg#ifdef SIS_USE_XAA 107772b676d7Smrg pSiS->AccelInfoPtr = NULL; 107872b676d7Smrg#endif 107972b676d7Smrg#ifdef SIS_USE_EXA 108072b676d7Smrg pSiS->EXADriverPtr = NULL; 108172b676d7Smrg pSiS->exa_scratch = NULL; 108272b676d7Smrg#endif 108372b676d7Smrg 108472b676d7Smrg if((pScrn->bitsPerPixel != 8) && 108572b676d7Smrg (pScrn->bitsPerPixel != 16) && 108672b676d7Smrg (pScrn->bitsPerPixel != 32)) { 108772b676d7Smrg pSiS->NoAccel = TRUE; 108872b676d7Smrg } 108972b676d7Smrg 109072b676d7Smrg if(!pSiS->NoAccel) { 109172b676d7Smrg#ifdef SIS_USE_XAA 109272b676d7Smrg if(!pSiS->useEXA) { 109372b676d7Smrg pSiS->AccelInfoPtr = infoPtr = XAACreateInfoRec(); 109472b676d7Smrg if(!infoPtr) pSiS->NoAccel = TRUE; 109572b676d7Smrg } 109672b676d7Smrg#endif 109772b676d7Smrg#ifdef SIS_USE_EXA 109872b676d7Smrg if(pSiS->useEXA) { 109972b676d7Smrg if(!(pSiS->EXADriverPtr = exaDriverAlloc())) { 110072b676d7Smrg pSiS->NoAccel = TRUE; 110172b676d7Smrg pSiS->NoXvideo = TRUE; /* No fbmem manager -> no xv */ 110272b676d7Smrg } 110372b676d7Smrg } 110472b676d7Smrg#endif 110572b676d7Smrg } 110672b676d7Smrg 110772b676d7Smrg if(!pSiS->NoAccel) { 110872b676d7Smrg 110972b676d7Smrg SiSInitializeAccelerator(pScrn); 111072b676d7Smrg 111172b676d7Smrg pSiS->InitAccel = SiSInitializeAccelerator; 111272b676d7Smrg pSiS->SyncAccel = SiSSyncAccel; 111372b676d7Smrg pSiS->FillRect = SiSDGAFillRect; 111472b676d7Smrg pSiS->BlitRect = SiSDGABlitRect; 111572b676d7Smrg 111672b676d7Smrg#ifdef SIS_USE_XAA /* ----------------------- XAA ----------------------- */ 111772b676d7Smrg if(!pSiS->useEXA) { 111872b676d7Smrg 111972b676d7Smrg infoPtr->Flags = LINEAR_FRAMEBUFFER | 112072b676d7Smrg OFFSCREEN_PIXMAPS | 112172b676d7Smrg PIXMAP_CACHE; 112272b676d7Smrg 112372b676d7Smrg /* sync */ 112472b676d7Smrg infoPtr->Sync = SiSSync; 112572b676d7Smrg 112672b676d7Smrg /* Although SiS states that the 300 series supports a 112772b676d7Smrg * virtual screen of 4096x4096, the 2D accelerator 112872b676d7Smrg * does not seem to know that. If the destination bitmap 112972b676d7Smrg * pitch is > 8192 (which easily happens in 32bpp mode), 113072b676d7Smrg * the accelerator engine collapses. 113172b676d7Smrg * TODO: Find out about the 530 and 620 113272b676d7Smrg */ 113372b676d7Smrg 113472b676d7Smrg if(pSiS->scrnOffset < 8192) { 113572b676d7Smrg 113672b676d7Smrg /* screen to screen copy */ 113772b676d7Smrg infoPtr->SetupForScreenToScreenCopy = SiSSetupForScreenToScreenCopy; 113872b676d7Smrg infoPtr->SubsequentScreenToScreenCopy = SiSSubsequentScreenToScreenCopy; 113972b676d7Smrg infoPtr->ScreenToScreenCopyFlags = NO_PLANEMASK | 114072b676d7Smrg TRANSPARENCY_GXCOPY_ONLY; 114172b676d7Smrg 114272b676d7Smrg /* solid fills */ 114372b676d7Smrg infoPtr->SetupForSolidFill = SiSSetupForSolidFill; 114472b676d7Smrg infoPtr->SubsequentSolidFillRect = SiSSubsequentSolidFillRect; 114572b676d7Smrg#ifdef TRAP 114672b676d7Smrg infoPtr->SubsequentSolidFillTrap = SiSSubsequentSolidFillTrap; 114772b676d7Smrg#endif 114872b676d7Smrg infoPtr->SolidFillFlags = NO_PLANEMASK; 114972b676d7Smrg 115072b676d7Smrg /* solid line */ 115172b676d7Smrg infoPtr->SetupForSolidLine = SiSSetupForSolidLine; 115272b676d7Smrg infoPtr->SubsequentSolidTwoPointLine = SiSSubsequentSolidTwoPointLine; 115372b676d7Smrg infoPtr->SubsequentSolidHorVertLine = SiSSubsequentSolidHorzVertLine; 115472b676d7Smrg infoPtr->SolidLineFlags = NO_PLANEMASK; 115572b676d7Smrg 115672b676d7Smrg /* dashed line */ 115772b676d7Smrg infoPtr->SetupForDashedLine = SiSSetupForDashedLine; 115872b676d7Smrg infoPtr->SubsequentDashedTwoPointLine = SiSSubsequentDashedTwoPointLine; 115972b676d7Smrg infoPtr->DashPatternMaxLength = 64; 116072b676d7Smrg infoPtr->DashedLineFlags = NO_PLANEMASK | 116172b676d7Smrg LINE_PATTERN_MSBFIRST_LSBJUSTIFIED; 116272b676d7Smrg 116372b676d7Smrg /* 8x8 mono pattern fill */ 116472b676d7Smrg infoPtr->SetupForMono8x8PatternFill = SiSSetupForMonoPatternFill; 116572b676d7Smrg infoPtr->SubsequentMono8x8PatternFillRect = SiSSubsequentMonoPatternFill; 116672b676d7Smrg#ifdef TRAP 116772b676d7Smrg infoPtr->SubsequentMono8x8PatternFillTrap = SiSSubsequentMonoPatternFillTrap; 116872b676d7Smrg#endif 116972b676d7Smrg infoPtr->Mono8x8PatternFillFlags = NO_PLANEMASK | 117072b676d7Smrg HARDWARE_PATTERN_SCREEN_ORIGIN | 117172b676d7Smrg HARDWARE_PATTERN_PROGRAMMED_BITS | 117272b676d7Smrg /* NO_TRANSPARENCY | */ 117372b676d7Smrg BIT_ORDER_IN_BYTE_MSBFIRST ; 117472b676d7Smrg 117572b676d7Smrg#ifdef STSCE 117672b676d7Smrg /* Screen To Screen Color Expand */ 117772b676d7Smrg /* The hardware does support this the way we need it */ 117872b676d7Smrg infoPtr->SetupForScreenToScreenColorExpandFill = 117972b676d7Smrg SiSSetupForScreenToScreenColorExpand; 118072b676d7Smrg infoPtr->SubsequentScreenToScreenColorExpandFill = 118172b676d7Smrg SiSSubsequentScreenToScreenColorExpand; 118272b676d7Smrg infoPtr->ScreenToScreenColorExpandFillFlags = NO_PLANEMASK | 118372b676d7Smrg BIT_ORDER_IN_BYTE_MSBFIRST ; 118472b676d7Smrg#endif 118572b676d7Smrg 118672b676d7Smrg /* per-scanline color expansion (using indirect method) */ 118772b676d7Smrg if(pSiS->VGAEngine == SIS_530_VGA) { 118872b676d7Smrg pSiS->ColorExpandBufferNumber = 4; 118972b676d7Smrg pSiS->ColorExpandBufferCountMask = 0x03; 119072b676d7Smrg } else { 119172b676d7Smrg pSiS->ColorExpandBufferNumber = 16; 119272b676d7Smrg pSiS->ColorExpandBufferCountMask = 0x0F; 119372b676d7Smrg } 119472b676d7Smrg 119572b676d7Smrg pSiS->PerColorExpandBufferSize = ((pScrn->virtualX + 31)/32) * 4; 119672b676d7Smrg infoPtr->NumScanlineColorExpandBuffers = pSiS->ColorExpandBufferNumber; 119772b676d7Smrg infoPtr->ScanlineColorExpandBuffers = (UChar **)&pSiS->ColorExpandBufferAddr[0]; 119872b676d7Smrg 119972b676d7Smrg infoPtr->SetupForScanlineCPUToScreenColorExpandFill = 120072b676d7Smrg SiSSetupForScanlineCPUToScreenColorExpandFill; 120172b676d7Smrg infoPtr->SubsequentScanlineCPUToScreenColorExpandFill = 120272b676d7Smrg SiSSubsequentScanlineCPUToScreenColorExpandFill; 120372b676d7Smrg infoPtr->SubsequentColorExpandScanline = 120472b676d7Smrg SiSSubsequentColorExpandScanline; 120572b676d7Smrg infoPtr->ScanlineCPUToScreenColorExpandFillFlags = NO_PLANEMASK | 120672b676d7Smrg CPU_TRANSFER_PAD_DWORD | 120772b676d7Smrg SCANLINE_PAD_DWORD | 120872b676d7Smrg BIT_ORDER_IN_BYTE_MSBFIRST | 120972b676d7Smrg LEFT_EDGE_CLIPPING; 121072b676d7Smrg } else { 121172b676d7Smrg 121272b676d7Smrg xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 121372b676d7Smrg "Virtual screen width too large for accelerator engine\n"); 121472b676d7Smrg xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 121572b676d7Smrg "\t2D acceleration and Xv disabled\n"); 121672b676d7Smrg pSiS->NoXvideo = TRUE; 121772b676d7Smrg 121872b676d7Smrg } 121972b676d7Smrg 122072b676d7Smrg#ifdef SISDUALHEAD 122172b676d7Smrg if(pSiS->DualHeadMode) { 122272b676d7Smrg infoPtr->RestoreAccelState = SiSRestoreAccelState; 122372b676d7Smrg } 122472b676d7Smrg#endif 122572b676d7Smrg } /* !exa */ 122672b676d7Smrg#endif /* XAA */ 122772b676d7Smrg 122872b676d7Smrg#ifdef SIS_USE_EXA /* ----------------------- EXA ----------------------- */ 122972b676d7Smrg if(pSiS->useEXA) { 123072b676d7Smrg 123172b676d7Smrg pSiS->EXADriverPtr->exa_major = 2; 123272b676d7Smrg pSiS->EXADriverPtr->exa_minor = 0; 123372b676d7Smrg 123472b676d7Smrg if(pSiS->scrnOffset < 8192) { 123572b676d7Smrg 123672b676d7Smrg /* data */ 123772b676d7Smrg pSiS->EXADriverPtr->memoryBase = pSiS->FbBase; 123872b676d7Smrg pSiS->EXADriverPtr->memorySize = pSiS->maxxfbmem; 123972b676d7Smrg pSiS->EXADriverPtr->offScreenBase = pScrn->virtualX * pScrn->virtualY 124072b676d7Smrg * ((pScrn->bitsPerPixel + 7) / 8); 124172b676d7Smrg if(pSiS->EXADriverPtr->memorySize > pSiS->EXADriverPtr->offScreenBase) { 124272b676d7Smrg pSiS->EXADriverPtr->flags = EXA_OFFSCREEN_PIXMAPS; 124372b676d7Smrg } else { 124472b676d7Smrg pSiS->NoXvideo = TRUE; 124572b676d7Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 124672b676d7Smrg "Not enough video RAM for offscreen memory manager. Xv disabled\n"); 124772b676d7Smrg } 124872b676d7Smrg pSiS->EXADriverPtr->pixmapOffsetAlign = 16; /* src/dst: double quad word boundary */ 124972b676d7Smrg pSiS->EXADriverPtr->pixmapPitchAlign = 4; /* pitch: double word boundary */ 125072b676d7Smrg if(pSiS->VGAEngine == SIS_300_VGA) { 125172b676d7Smrg pSiS->EXADriverPtr->maxX = 4095; 125272b676d7Smrg pSiS->EXADriverPtr->maxY = 4095; 125372b676d7Smrg } else { 125472b676d7Smrg pSiS->EXADriverPtr->maxX = 2047; 125572b676d7Smrg pSiS->EXADriverPtr->maxY = 2047; 125672b676d7Smrg } 125772b676d7Smrg 125872b676d7Smrg /* Sync */ 125972b676d7Smrg pSiS->EXADriverPtr->WaitMarker = SiSEXASync; 126072b676d7Smrg 126172b676d7Smrg /* Solid fill */ 126272b676d7Smrg pSiS->EXADriverPtr->PrepareSolid = SiSPrepareSolid; 126372b676d7Smrg pSiS->EXADriverPtr->Solid = SiSSolid; 126472b676d7Smrg pSiS->EXADriverPtr->DoneSolid = SiSDoneSolid; 126572b676d7Smrg 126672b676d7Smrg /* Copy */ 126772b676d7Smrg pSiS->EXADriverPtr->PrepareCopy = SiSPrepareCopy; 126872b676d7Smrg pSiS->EXADriverPtr->Copy = SiSCopy; 126972b676d7Smrg pSiS->EXADriverPtr->DoneCopy = SiSDoneCopy; 127072b676d7Smrg 127172b676d7Smrg /* Composite not supported */ 127272b676d7Smrg 127372b676d7Smrg } else { 127472b676d7Smrg 127572b676d7Smrg xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 127672b676d7Smrg "Virtual screen width too large for accelerator engine\n"); 127772b676d7Smrg xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 127872b676d7Smrg "\t2D acceleration and Xv disabled\n"); 127972b676d7Smrg pSiS->NoAccel = TRUE; 128072b676d7Smrg pSiS->NoXvideo = TRUE; /* No fbmem manager -> no xv */ 128172b676d7Smrg 128272b676d7Smrg } 128372b676d7Smrg 128472b676d7Smrg } 128572b676d7Smrg#endif /* EXA */ 128672b676d7Smrg 128772b676d7Smrg 128872b676d7Smrg } /* NoAccel */ 128972b676d7Smrg 129072b676d7Smrg /* Init framebuffer memory manager */ 129172b676d7Smrg 129272b676d7Smrg /* Layout: (Sizes do not reflect correct proportions) 129372b676d7Smrg * |--------------++++++++++++++++++++^************==========~~~~~~~~~~~~| 129472b676d7Smrg * UsableFbSize ColorExpandBuffers | DRI-Heap | HWCursor TurboQueue 300/310/325 series 129572b676d7Smrg * |--------------++++++++++++++++++++| ====================~~~~~~~~~~~~| 129672b676d7Smrg * UsableFbSize ColorExpandBuffers | TurboQueue HWCursor 530/620 129772b676d7Smrg * topFB 129872b676d7Smrg */ 129972b676d7Smrg 130072b676d7Smrg#ifdef SIS_USE_XAA 130172b676d7Smrg if(!pSiS->useEXA) { 130272b676d7Smrg 130372b676d7Smrg topFB = pSiS->maxxfbmem; 130472b676d7Smrg 130572b676d7Smrg reservedFbSize = pSiS->ColorExpandBufferNumber * pSiS->PerColorExpandBufferSize; 130672b676d7Smrg 130772b676d7Smrg usableFbSize = topFB - reservedFbSize; 130872b676d7Smrg 130972b676d7Smrg AvailBufBase = pSiS->FbBase + usableFbSize; 131072b676d7Smrg for(i = 0; i < pSiS->ColorExpandBufferNumber; i++) { 131172b676d7Smrg pSiS->ColorExpandBufferAddr[i] = AvailBufBase + 131272b676d7Smrg i * pSiS->PerColorExpandBufferSize; 131372b676d7Smrg pSiS->ColorExpandBufferScreenOffset[i] = usableFbSize + 131472b676d7Smrg i * pSiS->PerColorExpandBufferSize; 131572b676d7Smrg } 131672b676d7Smrg 131772b676d7Smrg Avail.x1 = 0; 131872b676d7Smrg Avail.y1 = 0; 131972b676d7Smrg Avail.x2 = pScrn->displayWidth; 132072b676d7Smrg Avail.y2 = (usableFbSize / (pScrn->displayWidth * pScrn->bitsPerPixel/8)) - 1; 132172b676d7Smrg 132272b676d7Smrg if(Avail.y2 < 0) Avail.y2 = 32767; 132372b676d7Smrg 132472b676d7Smrg if(Avail.y2 < pScrn->currentMode->VDisplay) { 132572b676d7Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 132672b676d7Smrg "Not enough video RAM for accelerator. At least " 132772b676d7Smrg "%dKB needed, %dKB available\n", 132872b676d7Smrg ((((pScrn->displayWidth * pScrn->bitsPerPixel/8) /* +8 for make it sure */ 132972b676d7Smrg * pScrn->currentMode->VDisplay) + reservedFbSize) / 1024) + 8, 133072b676d7Smrg pSiS->maxxfbmem/1024); 133172b676d7Smrg pSiS->NoAccel = TRUE; 133272b676d7Smrg pSiS->NoXvideo = TRUE; 133372b676d7Smrg XAADestroyInfoRec(pSiS->AccelInfoPtr); 133472b676d7Smrg pSiS->AccelInfoPtr = NULL; 133572b676d7Smrg return FALSE; 133672b676d7Smrg } 133772b676d7Smrg 133872b676d7Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 133972b676d7Smrg "Framebuffer from (%d,%d) to (%d,%d)\n", 134072b676d7Smrg Avail.x1, Avail.y1, Avail.x2 - 1, Avail.y2 - 1); 134172b676d7Smrg 134272b676d7Smrg xf86InitFBManager(pScreen, &Avail); 134372b676d7Smrg 134472b676d7Smrg if(!pSiS->NoAccel) { 134572b676d7Smrg return XAAInit(pScreen, infoPtr); 134672b676d7Smrg } 134772b676d7Smrg } /* !exa */ 134872b676d7Smrg#endif /* XAA */ 134972b676d7Smrg 135072b676d7Smrg#ifdef SIS_USE_EXA 135172b676d7Smrg if(pSiS->useEXA) { 135272b676d7Smrg 135372b676d7Smrg if(!pSiS->NoAccel) { 135472b676d7Smrg 135572b676d7Smrg if(!exaDriverInit(pScreen, pSiS->EXADriverPtr)) { 135672b676d7Smrg pSiS->NoAccel = TRUE; 135772b676d7Smrg pSiS->NoXvideo = TRUE; /* No fbmem manager -> no xv */ 135872b676d7Smrg return FALSE; 135972b676d7Smrg } 136072b676d7Smrg 136172b676d7Smrg /* Reserve locked offscreen scratch area of 128K for glyph data */ 136272b676d7Smrg pSiS->exa_scratch = exaOffscreenAlloc(pScreen, 128 * 1024, 16, TRUE, 136372b676d7Smrg SiSScratchSave, pSiS); 136472b676d7Smrg if(pSiS->exa_scratch) { 136572b676d7Smrg pSiS->exa_scratch_next = pSiS->exa_scratch->offset; 136672b676d7Smrg pSiS->EXADriverPtr->UploadToScratch = SiSUploadToScratch; 136772b676d7Smrg } 136872b676d7Smrg 136972b676d7Smrg } else { 137072b676d7Smrg 137172b676d7Smrg pSiS->NoXvideo = TRUE; /* No fbmem manager -> no xv */ 137272b676d7Smrg 137372b676d7Smrg } 137472b676d7Smrg 137572b676d7Smrg } 137672b676d7Smrg#endif /* EXA */ 137772b676d7Smrg 137872b676d7Smrg return TRUE; 137972b676d7Smrg} 138072b676d7Smrg 138172b676d7Smrg 138272b676d7Smrg 138372b676d7Smrg 138472b676d7Smrg 138572b676d7Smrg 138672b676d7Smrg 1387