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