sis310_accel.c revision 72b676d7
172b676d7Smrg/* $XFree86$ */
272b676d7Smrg/* $XdotOrg: driver/xf86-video-sis/src/sis310_accel.c,v 1.31 2006-03-09 06:06:25 anholt Exp $ */
372b676d7Smrg/*
472b676d7Smrg * 2D Acceleration for SiS 315, 330 and 340 series
572b676d7Smrg *
672b676d7Smrg * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria
772b676d7Smrg *
872b676d7Smrg * Redistribution and use in source and binary forms, with or without
972b676d7Smrg * modification, are permitted provided that the following conditions
1072b676d7Smrg * are met:
1172b676d7Smrg * 1) Redistributions of source code must retain the above copyright
1272b676d7Smrg *    notice, this list of conditions and the following disclaimer.
1372b676d7Smrg * 2) Redistributions in binary form must reproduce the above copyright
1472b676d7Smrg *    notice, this list of conditions and the following disclaimer in the
1572b676d7Smrg *    documentation and/or other materials provided with the distribution.
1672b676d7Smrg * 3) The name of the author may not be used to endorse or promote products
1772b676d7Smrg *    derived from this software without specific prior written permission.
1872b676d7Smrg *
1972b676d7Smrg * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
2072b676d7Smrg * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
2172b676d7Smrg * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2272b676d7Smrg * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
2372b676d7Smrg * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
2472b676d7Smrg * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2572b676d7Smrg * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2672b676d7Smrg * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2772b676d7Smrg * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2872b676d7Smrg * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2972b676d7Smrg *
3072b676d7Smrg *
3172b676d7Smrg * Author:  	Thomas Winischhofer <thomas@winischhofer.net>
3272b676d7Smrg *
3372b676d7Smrg * 2003/08/18: Rewritten for using VRAM command queue
3472b676d7Smrg *
3572b676d7Smrg */
3672b676d7Smrg
3772b676d7Smrg#ifdef HAVE_CONFIG_H
3872b676d7Smrg#include "config.h"
3972b676d7Smrg#endif
4072b676d7Smrg
4172b676d7Smrg#include "sis.h"
4272b676d7Smrg#define SIS_NEED_MYMMIO
4372b676d7Smrg#define SIS_NEED_ACCELBUF
4472b676d7Smrg#include "sis_regs.h"
4572b676d7Smrg#include "sis310_accel.h"
4672b676d7Smrg
4772b676d7Smrg#if 0
4872b676d7Smrg#define ACCELDEBUG
4972b676d7Smrg#endif
5072b676d7Smrg
5172b676d7Smrg#define FBOFFSET 	(pSiS->dhmOffset)
5272b676d7Smrg
5372b676d7Smrg#define DEV_HEIGHT	0xfff	/* "Device height of destination bitmap" */
5472b676d7Smrg
5572b676d7Smrg#undef SIS_NEED_ARRAY
5672b676d7Smrg
5772b676d7Smrg/* For XAA */
5872b676d7Smrg
5972b676d7Smrg#ifdef SIS_USE_XAA
6072b676d7Smrg
6172b676d7Smrg#undef TRAP		/* Use/Don't use Trapezoid Fills
6272b676d7Smrg			 * DOES NOT WORK. XAA sometimes provides illegal
6372b676d7Smrg			 * trapezoid data (left and right edges cross each
6472b676d7Smrg			 * other) which causes drawing errors. Since
6572b676d7Smrg			 * checking the trapezoid for such a case is very
6672b676d7Smrg			 * time-intensive, it is faster to let it be done
6772b676d7Smrg			 * by the generic polygon functions.
6872b676d7Smrg			 * Does not work on 330 series at all, hangs the engine.
6972b676d7Smrg			 * Even with correct trapezoids, this is slower than
7072b676d7Smrg			 * doing it by the CPU.
7172b676d7Smrg                         */
7272b676d7Smrg
7372b676d7Smrg#undef CTSCE		/* Use/Don't use CPUToScreenColorExpand. Disabled
7472b676d7Smrg			 * because it is slower than doing it by the CPU.
7572b676d7Smrg			 * Indirect mode does not work in VRAM queue mode.
7672b676d7Smrg			 * Does not work on 330 series (even in MMIO mode).
7772b676d7Smrg			 */
7872b676d7Smrg#undef CTSCE_DIRECT	/* Use direct method - This works (on both 315 and 330 at
7972b676d7Smrg			 * least in VRAM queue mode) but we don't use this either,
8072b676d7Smrg			 * because it's slower than doing it by the CPU. (Using it
8172b676d7Smrg			 * would require defining CTSCE)
8272b676d7Smrg			 */
8372b676d7Smrg
8472b676d7Smrg#undef STSCE		/* Use/Don't use ScreenToScreenColorExpand - does not work,
8572b676d7Smrg			 * see comments below.
8672b676d7Smrg			 */
8772b676d7Smrg
8872b676d7Smrg#define INCL_RENDER	/* Use/Don't use RENDER extension acceleration */
8972b676d7Smrg
9072b676d7Smrg#ifdef INCL_RENDER
9172b676d7Smrg# ifdef RENDER
9272b676d7Smrg#  include "mipict.h"
9372b676d7Smrg#  include "dixstruct.h"
9472b676d7Smrg#  define SIS_NEED_ARRAY
9572b676d7Smrg#  undef SISNEWRENDER
9672b676d7Smrg#  ifdef XORG_VERSION_CURRENT
9772b676d7Smrg#   if XORG_VERSION_CURRENT > XORG_VERSION_NUMERIC(6,7,0,0,0)
9872b676d7Smrg#    define SISNEWRENDER
9972b676d7Smrg#   endif
10072b676d7Smrg#  endif
10172b676d7Smrg# endif
10272b676d7Smrg#endif
10372b676d7Smrg
10472b676d7Smrg#endif /* XAA */
10572b676d7Smrg
10672b676d7Smrg/* For EXA */
10772b676d7Smrg
10872b676d7Smrg#ifdef SIS_USE_EXA
10972b676d7Smrg#if 0
11072b676d7Smrg#define SIS_HAVE_COMPOSITE		/* Have our own EXA composite */
11172b676d7Smrg#endif
11272b676d7Smrg#ifdef SIS_HAVE_COMPOSITE
11372b676d7Smrg#ifndef SIS_NEED_ARRAY
11472b676d7Smrg#define SIS_NEED_ARRAY
11572b676d7Smrg#endif
11672b676d7Smrg#endif
11772b676d7Smrg#endif
11872b676d7Smrg
11972b676d7Smrg#ifdef SIS_USE_XAA		/* XAA */
12072b676d7Smrg#ifdef INCL_RENDER
12172b676d7Smrg#ifdef RENDER
12272b676d7Smrgstatic CARD32 SiSAlphaTextureFormats[2] = { PICT_a8      , 0 };
12372b676d7Smrgstatic CARD32 SiSTextureFormats[2]      = { PICT_a8r8g8b8, 0 };
12472b676d7Smrg#ifdef SISNEWRENDER
12572b676d7Smrgstatic CARD32 SiSDstTextureFormats16[2] = { PICT_r5g6b5  , 0 };
12672b676d7Smrgstatic CARD32 SiSDstTextureFormats32[3] = { PICT_x8r8g8b8, PICT_a8r8g8b8, 0 };
12772b676d7Smrg#endif
12872b676d7Smrg#endif /* RENDER */
12972b676d7Smrg#endif /* INCL_RENDER */
13072b676d7Smrg#endif /* XAA */
13172b676d7Smrg
13272b676d7Smrg#ifdef SIS_USE_EXA		/* EXA */
13372b676d7Smrgvoid SiSScratchSave(ScreenPtr pScreen, ExaOffscreenArea *area);
13472b676d7SmrgBool SiSUploadToScreen(PixmapPtr pDst, int x, int y, int w, int h, char *src, int src_pitch);
13572b676d7SmrgBool SiSUploadToScratch(PixmapPtr pSrc, PixmapPtr pDst);
13672b676d7SmrgBool SiSDownloadFromScreen(PixmapPtr pSrc, int x, int y, int w, int h, char *dst, int dst_pitch);
13772b676d7Smrg#endif /* EXA */
13872b676d7Smrg
13972b676d7Smrg#ifdef INCL_YUV_BLIT_ADAPTOR
14072b676d7Smrgvoid SISWriteBlitPacket(SISPtr pSiS, CARD32 *packet);
14172b676d7Smrg#endif
14272b676d7Smrg
14372b676d7Smrgextern unsigned char SiSGetCopyROP(int rop);
14472b676d7Smrgextern unsigned char SiSGetPatternROP(int rop);
14572b676d7Smrg
14672b676d7SmrgCARD32 dummybuf;
14772b676d7Smrg
14872b676d7Smrg#ifdef SIS_NEED_ARRAY
14972b676d7Smrg#if XF86_VERSION_CURRENT >= XF86_VERSION_NUMERIC(4,2,0,0,0)
15072b676d7Smrg#define SiSRenderOpsMAX 0x2b
15172b676d7Smrg#else
15272b676d7Smrg#define SiSRenderOpsMAX 0x0f
15372b676d7Smrg#endif
15472b676d7Smrgstatic const CARD8 SiSRenderOps[] = {	/* PictOpXXX 1 = supported, 0 = unsupported */
15572b676d7Smrg     1, 1, 1, 1,
15672b676d7Smrg     0, 0, 0, 0,
15772b676d7Smrg     0, 0, 0, 0,
15872b676d7Smrg     0, 0, 0, 0,
15972b676d7Smrg     1, 1, 1, 0,
16072b676d7Smrg     0, 0, 0, 0,
16172b676d7Smrg     0, 0, 0, 0,
16272b676d7Smrg     0, 0, 0, 0,
16372b676d7Smrg     1, 1, 1, 0,
16472b676d7Smrg     0, 0, 0, 0,
16572b676d7Smrg     0, 0, 0, 0,
16672b676d7Smrg     0, 0, 0, 0
16772b676d7Smrg};
16872b676d7Smrg#endif /* NEED ARRAY */
16972b676d7Smrg
17072b676d7Smrg#ifdef SIS_NEED_ARRAY
17172b676d7Smrgstatic void
17272b676d7SmrgSiSCalcRenderAccelArray(ScrnInfoPtr pScrn)
17372b676d7Smrg{
17472b676d7Smrg	SISPtr  pSiS = SISPTR(pScrn);
17572b676d7Smrg#ifdef SISDUALHEAD
17672b676d7Smrg	SISEntPtr pSiSEnt = pSiS->entityPrivate;;
17772b676d7Smrg#endif
17872b676d7Smrg
17972b676d7Smrg	if(((pScrn->bitsPerPixel == 16) || (pScrn->bitsPerPixel == 32)) && pSiS->doRender) {
18072b676d7Smrg	   int i, j;
18172b676d7Smrg#ifdef SISDUALHEAD
18272b676d7Smrg	   if(pSiSEnt) pSiS->RenderAccelArray = pSiSEnt->RenderAccelArray;
18372b676d7Smrg#endif
18472b676d7Smrg	   if(!pSiS->RenderAccelArray) {
18572b676d7Smrg	      if((pSiS->RenderAccelArray = xnfcalloc(65536, 1))) {
18672b676d7Smrg#ifdef SISDUALHEAD
18772b676d7Smrg	         if(pSiSEnt) pSiSEnt->RenderAccelArray = pSiS->RenderAccelArray;
18872b676d7Smrg#endif
18972b676d7Smrg		 for(i = 0; i < 256; i++) {
19072b676d7Smrg		    for(j = 0; j < 256; j++) {
19172b676d7Smrg		       pSiS->RenderAccelArray[(i << 8) + j] = (i * j) / 255;
19272b676d7Smrg		    }
19372b676d7Smrg		 }
19472b676d7Smrg	      }
19572b676d7Smrg	   }
19672b676d7Smrg	}
19772b676d7Smrg}
19872b676d7Smrg#endif
19972b676d7Smrg
20072b676d7Smrg#ifdef SIS_USE_EXA
20172b676d7Smrgvoid
20272b676d7SmrgSiSScratchSave(ScreenPtr pScreen, ExaOffscreenArea *area)
20372b676d7Smrg{
20472b676d7Smrg	SISPtr pSiS = SISPTR(xf86Screens[pScreen->myNum]);
20572b676d7Smrg
20672b676d7Smrg	pSiS->exa_scratch = NULL;
20772b676d7Smrg}
20872b676d7Smrg#endif
20972b676d7Smrg
21072b676d7Smrgstatic void
21172b676d7SmrgSiSSync(ScrnInfoPtr pScrn)
21272b676d7Smrg{
21372b676d7Smrg	SISPtr pSiS = SISPTR(pScrn);
21472b676d7Smrg
21572b676d7Smrg#ifdef SIS_USE_XAA
21672b676d7Smrg	if(!pSiS->useEXA) {
21772b676d7Smrg#ifdef CTSCE
21872b676d7Smrg#ifdef CTSCE_DIRECT
21972b676d7Smrg	   if(pSiS->DoColorExpand) {
22072b676d7Smrg	      SiSDoCMD
22172b676d7Smrg	      pSiS->ColorExpandBusy = TRUE;
22272b676d7Smrg	   }
22372b676d7Smrg#endif
22472b676d7Smrg#endif
22572b676d7Smrg	   pSiS->DoColorExpand = FALSE;
22672b676d7Smrg	}
22772b676d7Smrg#endif
22872b676d7Smrg
22972b676d7Smrg	pSiS->alphaBlitBusy = FALSE;
23072b676d7Smrg
23172b676d7Smrg	SiSIdle
23272b676d7Smrg}
23372b676d7Smrg
23472b676d7Smrgstatic void
23572b676d7SmrgSiSSyncAccel(ScrnInfoPtr pScrn)
23672b676d7Smrg{
23772b676d7Smrg	SISPtr pSiS = SISPTR(pScrn);
23872b676d7Smrg
23972b676d7Smrg	if(!pSiS->NoAccel) SiSSync(pScrn);
24072b676d7Smrg}
24172b676d7Smrg
24272b676d7Smrgstatic void
24372b676d7SmrgSiSInitializeAccelerator(ScrnInfoPtr pScrn)
24472b676d7Smrg{
24572b676d7Smrg	SISPtr  pSiS = SISPTR(pScrn);
24672b676d7Smrg
24772b676d7Smrg#ifdef SIS_USE_XAA
24872b676d7Smrg	pSiS->DoColorExpand = FALSE;
24972b676d7Smrg#endif
25072b676d7Smrg	pSiS->alphaBlitBusy = FALSE;
25172b676d7Smrg
25272b676d7Smrg	if(!pSiS->NoAccel) {
25372b676d7Smrg
25472b676d7Smrg#ifndef SISVRAMQ
25572b676d7Smrg	   if(pSiS->ChipFlags & SiSCF_Integrated) {
25672b676d7Smrg	      CmdQueLen = 0;
25772b676d7Smrg	   } else {
25872b676d7Smrg	      CmdQueLen = ((128 * 1024) / 4) - 64;
25972b676d7Smrg	   }
26072b676d7Smrg#endif
26172b676d7Smrg
26272b676d7Smrg#ifdef SISVRAMQ
26372b676d7Smrg	   if(pSiS->ChipType == XGI_40) {
26472b676d7Smrg	      SiSSync(pScrn);
26572b676d7Smrg	      SiSDualPipe(1);	/* 1 = disable, 0 = enable */
26672b676d7Smrg	      SiSSync(pScrn);
26772b676d7Smrg	   }
26872b676d7Smrg#endif
26972b676d7Smrg
27072b676d7Smrg	}
27172b676d7Smrg}
27272b676d7Smrg
27372b676d7Smrgstatic void
27472b676d7SmrgSiSSetupForScreenToScreenCopy(ScrnInfoPtr pScrn,
27572b676d7Smrg			int xdir, int ydir, int rop,
27672b676d7Smrg			unsigned int planemask, int trans_color)
27772b676d7Smrg{
27872b676d7Smrg	SISPtr  pSiS = SISPTR(pScrn);
27972b676d7Smrg
28072b676d7Smrg#ifdef SISVRAMQ
28172b676d7Smrg	SiSSetupDSTColorDepth(pSiS->SiS310_AccelDepth);
28272b676d7Smrg	SiSCheckQueue(16 * 2);
28372b676d7Smrg	SiSSetupSRCPitchDSTRect(pSiS->scrnOffset, pSiS->scrnOffset, DEV_HEIGHT)
28472b676d7Smrg#else
28572b676d7Smrg	SiSSetupDSTColorDepth(pSiS->DstColor);
28672b676d7Smrg	SiSSetupSRCPitch(pSiS->scrnOffset)
28772b676d7Smrg	SiSSetupDSTRect(pSiS->scrnOffset, DEV_HEIGHT)
28872b676d7Smrg#endif
28972b676d7Smrg
29072b676d7Smrg	if(trans_color != -1) {
29172b676d7Smrg	   SiSSetupROP(0x0A)
29272b676d7Smrg	   SiSSetupSRCTrans(trans_color)
29372b676d7Smrg	   SiSSetupCMDFlag(TRANSPARENT_BITBLT)
29472b676d7Smrg	} else {
29572b676d7Smrg	   SiSSetupROP(SiSGetCopyROP(rop))
29672b676d7Smrg	   /* Set command - not needed, both 0 */
29772b676d7Smrg	   /* SiSSetupCMDFlag(BITBLT | SRCVIDEO) */
29872b676d7Smrg	}
29972b676d7Smrg
30072b676d7Smrg#ifndef SISVRAMQ
30172b676d7Smrg	SiSSetupCMDFlag(pSiS->SiS310_AccelDepth)
30272b676d7Smrg#endif
30372b676d7Smrg
30472b676d7Smrg#ifdef SISVRAMQ
30572b676d7Smrg	SiSSyncWP
30672b676d7Smrg#endif
30772b676d7Smrg
30872b676d7Smrg	/* The chip is smart enough to know the direction */
30972b676d7Smrg}
31072b676d7Smrg
31172b676d7Smrgstatic void
31272b676d7SmrgSiSSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn,
31372b676d7Smrg			int src_x, int src_y, int dst_x, int dst_y,
31472b676d7Smrg			int width, int height)
31572b676d7Smrg{
31672b676d7Smrg	SISPtr pSiS = SISPTR(pScrn);
31772b676d7Smrg	CARD32 srcbase, dstbase;
31872b676d7Smrg	int    mymin, mymax;
31972b676d7Smrg
32072b676d7Smrg	srcbase = dstbase = 0;
32172b676d7Smrg	mymin = min(src_y, dst_y);
32272b676d7Smrg	mymax = max(src_y, dst_y);
32372b676d7Smrg
32472b676d7Smrg	/* Libxaa.a has a bug: The tilecache cannot operate
32572b676d7Smrg	 * correctly if there are 512x512 slots, but no 256x256
32672b676d7Smrg	 * slots. This leads to catastrophic data fed to us.
32772b676d7Smrg	 * Filter this out here and warn the user.
32872b676d7Smrg	 * Fixed in 4.3.99.10 (?) and Debian's 4.3.0.1
32972b676d7Smrg	 */
33072b676d7Smrg#if (XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,3,99,10,0)) && (XF86_VERSION_CURRENT != XF86_VERSION_NUMERIC(4,3,0,1,0))
33172b676d7Smrg	if((src_x < 0)  ||
33272b676d7Smrg	   (dst_x < 0)  ||
33372b676d7Smrg	   (src_y < 0)  ||
33472b676d7Smrg	   (dst_y < 0)  ||
33572b676d7Smrg	   (width <= 0) ||
33672b676d7Smrg	   (height <= 0)) {
33772b676d7Smrg	   xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
33872b676d7Smrg		"BitBlit fatal error: Illegal coordinates:\n");
33972b676d7Smrg	   xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
34072b676d7Smrg	        "Source x %d y %d, dest x %d y %d, width %d height %d\n",
34172b676d7Smrg			  src_x, src_y, dst_x, dst_y, width, height);
34272b676d7Smrg	   xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
34372b676d7Smrg		"This is very probably caused by a known bug in libxaa.a.\n");
34472b676d7Smrg	   xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
34572b676d7Smrg		"Please update libxaa.a to avoid this error.\n");
34672b676d7Smrg	   return;
34772b676d7Smrg	}
34872b676d7Smrg#endif
34972b676d7Smrg
35072b676d7Smrg	/* Although the chip knows the direction to use
35172b676d7Smrg	 * if the source and destination areas overlap,
35272b676d7Smrg	 * that logic fails if we fiddle with the bitmap
35372b676d7Smrg	 * addresses. Therefore, we check if the source
35472b676d7Smrg	 * and destination blitting areas overlap and
35572b676d7Smrg	 * adapt the bitmap addresses synchronously
35672b676d7Smrg	 * if the coordinates exceed the valid range.
35772b676d7Smrg	 * The the areas do not overlap, we do our
35872b676d7Smrg	 * normal check.
35972b676d7Smrg	 */
36072b676d7Smrg	if((mymax - mymin) < height) {
36172b676d7Smrg	   if((src_y >= 2048) || (dst_y >= 2048)) {
36272b676d7Smrg	      srcbase = pSiS->scrnOffset * mymin;
36372b676d7Smrg	      dstbase = pSiS->scrnOffset * mymin;
36472b676d7Smrg	      src_y -= mymin;
36572b676d7Smrg	      dst_y -= mymin;
36672b676d7Smrg	   }
36772b676d7Smrg	} else {
36872b676d7Smrg	   if(src_y >= 2048) {
36972b676d7Smrg	      srcbase = pSiS->scrnOffset * src_y;
37072b676d7Smrg	      src_y = 0;
37172b676d7Smrg	   }
37272b676d7Smrg	   if((dst_y >= pScrn->virtualY) || (dst_y >= 2048)) {
37372b676d7Smrg	      dstbase = pSiS->scrnOffset * dst_y;
37472b676d7Smrg	      dst_y = 0;
37572b676d7Smrg	   }
37672b676d7Smrg	}
37772b676d7Smrg
37872b676d7Smrg	srcbase += FBOFFSET;
37972b676d7Smrg	dstbase += FBOFFSET;
38072b676d7Smrg
38172b676d7Smrg#ifdef SISVRAMQ
38272b676d7Smrg	SiSCheckQueue(16 * 3);
38372b676d7Smrg	SiSSetupSRCDSTBase(srcbase, dstbase)
38472b676d7Smrg	SiSSetupSRCDSTXY(src_x, src_y, dst_x, dst_y)
38572b676d7Smrg	SiSSetRectDoCMD(width,height)
38672b676d7Smrg#else
38772b676d7Smrg	SiSSetupSRCBase(srcbase);
38872b676d7Smrg	SiSSetupDSTBase(dstbase);
38972b676d7Smrg	SiSSetupRect(width, height)
39072b676d7Smrg	SiSSetupSRCXY(src_x, src_y)
39172b676d7Smrg	SiSSetupDSTXY(dst_x, dst_y)
39272b676d7Smrg	SiSDoCMD
39372b676d7Smrg#endif
39472b676d7Smrg}
39572b676d7Smrg
39672b676d7Smrgstatic void
39772b676d7SmrgSiSSetupForSolidFill(ScrnInfoPtr pScrn, int color,
39872b676d7Smrg			int rop, unsigned int planemask)
39972b676d7Smrg{
40072b676d7Smrg	SISPtr  pSiS = SISPTR(pScrn);
40172b676d7Smrg
40272b676d7Smrg	if(pSiS->disablecolorkeycurrent) {
40372b676d7Smrg	   if((CARD32)color == pSiS->colorKey) {
40472b676d7Smrg	      rop = 5;  /* NOOP */
40572b676d7Smrg	   }
40672b676d7Smrg	}
40772b676d7Smrg
40872b676d7Smrg#ifdef SISVRAMQ
40972b676d7Smrg	SiSSetupDSTColorDepth(pSiS->SiS310_AccelDepth);
41072b676d7Smrg	SiSCheckQueue(16 * 1);
41172b676d7Smrg	SiSSetupPATFGDSTRect(color, pSiS->scrnOffset, DEV_HEIGHT)
41272b676d7Smrg	SiSSetupROP(SiSGetPatternROP(rop))
41372b676d7Smrg	SiSSetupCMDFlag(PATFG)
41472b676d7Smrg	SiSSyncWP
41572b676d7Smrg#else
41672b676d7Smrg	SiSSetupPATFG(color)
41772b676d7Smrg	SiSSetupDSTRect(pSiS->scrnOffset, DEV_HEIGHT)
41872b676d7Smrg	SiSSetupDSTColorDepth(pSiS->DstColor);
41972b676d7Smrg	SiSSetupROP(SiSGetPatternROP(rop))
42072b676d7Smrg	SiSSetupCMDFlag(PATFG | pSiS->SiS310_AccelDepth)
42172b676d7Smrg#endif
42272b676d7Smrg}
42372b676d7Smrg
42472b676d7Smrgstatic void
42572b676d7SmrgSiSSubsequentSolidFillRect(ScrnInfoPtr pScrn,
42672b676d7Smrg			int x, int y, int w, int h)
42772b676d7Smrg{
42872b676d7Smrg	SISPtr pSiS = SISPTR(pScrn);
42972b676d7Smrg	CARD32 dstbase = 0;
43072b676d7Smrg
43172b676d7Smrg	if(y >= 2048) {
43272b676d7Smrg	   dstbase = pSiS->scrnOffset * y;
43372b676d7Smrg	   y = 0;
43472b676d7Smrg	}
43572b676d7Smrg
43672b676d7Smrg	dstbase += FBOFFSET;
43772b676d7Smrg
43872b676d7Smrg	pSiS->CommandReg &= ~(T_XISMAJORL | T_XISMAJORR |
43972b676d7Smrg	                      T_L_X_INC | T_L_Y_INC |
44072b676d7Smrg	                      T_R_X_INC | T_R_Y_INC |
44172b676d7Smrg			      TRAPAZOID_FILL);
44272b676d7Smrg
44372b676d7Smrg	/* SiSSetupCMDFlag(BITBLT)  - BITBLT = 0 */
44472b676d7Smrg
44572b676d7Smrg#ifdef SISVRAMQ
44672b676d7Smrg	SiSCheckQueue(16 * 2)
44772b676d7Smrg	SiSSetupDSTXYRect(x, y, w, h)
44872b676d7Smrg	SiSSetupDSTBaseDoCMD(dstbase)
44972b676d7Smrg#else
45072b676d7Smrg	SiSSetupDSTBase(dstbase)
45172b676d7Smrg	SiSSetupDSTXY(x, y)
45272b676d7Smrg	SiSSetupRect(w, h)
45372b676d7Smrg	SiSDoCMD
45472b676d7Smrg#endif
45572b676d7Smrg}
45672b676d7Smrg
45772b676d7Smrg#ifdef SIS_USE_XAA  /* ---------------------------- XAA -------------------------- */
45872b676d7Smrg
45972b676d7Smrg/* Trapezoid */
46072b676d7Smrg/* This would work better if XAA would provide us with valid trapezoids.
46172b676d7Smrg * In fact, with small trapezoids the left and the right edge often cross
46272b676d7Smrg * each other which causes drawing errors (filling over whole scanline).
46372b676d7Smrg * DOES NOT WORK ON 330 SERIES, HANGS THE ENGINE.
46472b676d7Smrg */
46572b676d7Smrg#ifdef TRAP
46672b676d7Smrgstatic void
46772b676d7SmrgSiSSubsequentSolidFillTrap(ScrnInfoPtr pScrn, int y, int h,
46872b676d7Smrg			int left,  int dxL, int dyL, int eL,
46972b676d7Smrg			int right, int dxR, int dyR, int eR )
47072b676d7Smrg{
47172b676d7Smrg	SISPtr pSiS = SISPTR(pScrn);
47272b676d7Smrg	CARD32 dstbase = 0;
47372b676d7Smrg
47472b676d7Smrg	if(y >= 2048) {
47572b676d7Smrg	   dstbase = pSiS->scrnOffset * y;
47672b676d7Smrg	   y = 0;
47772b676d7Smrg	}
47872b676d7Smrg
47972b676d7Smrg	dstbase += FBOFFSET;
48072b676d7Smrg
48172b676d7Smrg#ifdef SISVRAMQ	/* Not optimized yet */
48272b676d7Smrg	SiSCheckQueue(16 * 10)
48372b676d7Smrg#else
48472b676d7Smrg	SiSSetupDSTBase(dstbase)
48572b676d7Smrg#endif
48672b676d7Smrg
48772b676d7Smrg#if 1
48872b676d7Smrg	SiSSetupPATFG(0xff0000) /* FOR TESTING */
48972b676d7Smrg#endif
49072b676d7Smrg
49172b676d7Smrg	/* Clear CommandReg because SetUp can be used for Rect and Trap */
49272b676d7Smrg	pSiS->CommandReg &= ~(T_L_X_INC | T_L_Y_INC |
49372b676d7Smrg	                      T_R_X_INC | T_R_Y_INC |
49472b676d7Smrg	                      T_XISMAJORL | T_XISMAJORR |
49572b676d7Smrg			      BITBLT);
49672b676d7Smrg
49772b676d7Smrg        xf86DrvMsg(0, X_INFO, "Trap (%d %d %d %d) dxL %d dyL %d eL %d   dxR %d dyR %d eR %d\n",
49872b676d7Smrg		left, right, y, h, dxL, dyL, eL, dxR, dyR, eR);
49972b676d7Smrg
50072b676d7Smrg	/* Determine egde angles */
50172b676d7Smrg	if(dxL < 0) 	{ dxL = -dxL; }
50272b676d7Smrg	else 		{ SiSSetupCMDFlag(T_L_X_INC) }
50372b676d7Smrg	if(dxR < 0) 	{ dxR = -dxR; }
50472b676d7Smrg	else 		{ SiSSetupCMDFlag(T_R_X_INC) }
50572b676d7Smrg
50672b676d7Smrg	/* (Y direction always positive - do this anyway) */
50772b676d7Smrg	if(dyL < 0) 	{ dyL = -dyL; }
50872b676d7Smrg	else 		{ SiSSetupCMDFlag(T_L_Y_INC) }
50972b676d7Smrg	if(dyR < 0) 	{ dyR = -dyR; }
51072b676d7Smrg	else 		{ SiSSetupCMDFlag(T_R_Y_INC) }
51172b676d7Smrg
51272b676d7Smrg	/* Determine major axis */
51372b676d7Smrg	if(dxL >= dyL) {  SiSSetupCMDFlag(T_XISMAJORL) }
51472b676d7Smrg	if(dxR >= dyR) {  SiSSetupCMDFlag(T_XISMAJORR) }
51572b676d7Smrg
51672b676d7Smrg	SiSSetupCMDFlag(TRAPAZOID_FILL);
51772b676d7Smrg
51872b676d7Smrg#ifdef SISVRAMQ
51972b676d7Smrg	SiSSetupYHLR(y, h, left, right)
52072b676d7Smrg	SiSSetupdLdR(dxL, dyL, dxR, dyR)
52172b676d7Smrg	SiSSetupELER(eL, eR)
52272b676d7Smrg	SiSSetupDSTBaseDoCMD(dstbase)
52372b676d7Smrg#else
52472b676d7Smrg	/* Set up deltas */
52572b676d7Smrg	SiSSetupdL(dxL, dyL)
52672b676d7Smrg	SiSSetupdR(dxR, dyR)
52772b676d7Smrg	/* Set up y, h, left, right */
52872b676d7Smrg	SiSSetupYH(y, h)
52972b676d7Smrg	SiSSetupLR(left, right)
53072b676d7Smrg	/* Set up initial error term */
53172b676d7Smrg	SiSSetupEL(eL)
53272b676d7Smrg	SiSSetupER(eR)
53372b676d7Smrg	SiSDoCMD
53472b676d7Smrg#endif
53572b676d7Smrg}
53672b676d7Smrg#endif
53772b676d7Smrg
53872b676d7Smrgstatic void
53972b676d7SmrgSiSSetupForSolidLine(ScrnInfoPtr pScrn, int color, int rop,
54072b676d7Smrg			unsigned int planemask)
54172b676d7Smrg{
54272b676d7Smrg	SISPtr pSiS = SISPTR(pScrn);
54372b676d7Smrg
54472b676d7Smrg#ifdef SISVRAMQ
54572b676d7Smrg	SiSSetupDSTColorDepth(pSiS->SiS310_AccelDepth);
54672b676d7Smrg	SiSCheckQueue(16 * 3);
54772b676d7Smrg	SiSSetupLineCountPeriod(1, 1)
54872b676d7Smrg	SiSSetupPATFGDSTRect(color, pSiS->scrnOffset, DEV_HEIGHT)
54972b676d7Smrg	SiSSetupROP(SiSGetPatternROP(rop))
55072b676d7Smrg	SiSSetupCMDFlag(PATFG | LINE)
55172b676d7Smrg	SiSSyncWP
55272b676d7Smrg#else
55372b676d7Smrg	SiSSetupLineCount(1)
55472b676d7Smrg	SiSSetupPATFG(color)
55572b676d7Smrg	SiSSetupDSTRect(pSiS->scrnOffset, DEV_HEIGHT)
55672b676d7Smrg	SiSSetupDSTColorDepth(pSiS->DstColor)
55772b676d7Smrg	SiSSetupROP(SiSGetPatternROP(rop))
55872b676d7Smrg	SiSSetupCMDFlag(PATFG | LINE | pSiS->SiS310_AccelDepth)
55972b676d7Smrg#endif
56072b676d7Smrg}
56172b676d7Smrg
56272b676d7Smrgstatic void
56372b676d7SmrgSiSSubsequentSolidTwoPointLine(ScrnInfoPtr pScrn,
56472b676d7Smrg			int x1, int y1, int x2, int y2, int flags)
56572b676d7Smrg{
56672b676d7Smrg	SISPtr pSiS = SISPTR(pScrn);
56772b676d7Smrg	int    miny, maxy;
56872b676d7Smrg	CARD32 dstbase = 0;
56972b676d7Smrg
57072b676d7Smrg	miny = (y1 > y2) ? y2 : y1;
57172b676d7Smrg	maxy = (y1 > y2) ? y1 : y2;
57272b676d7Smrg	if(maxy >= 2048) {
57372b676d7Smrg	   dstbase = pSiS->scrnOffset*miny;
57472b676d7Smrg	   y1 -= miny;
57572b676d7Smrg	   y2 -= miny;
57672b676d7Smrg	}
57772b676d7Smrg
57872b676d7Smrg	dstbase += FBOFFSET;
57972b676d7Smrg
58072b676d7Smrg	if(flags & OMIT_LAST) {
58172b676d7Smrg	   SiSSetupCMDFlag(NO_LAST_PIXEL)
58272b676d7Smrg	} else {
58372b676d7Smrg	   pSiS->CommandReg &= ~(NO_LAST_PIXEL);
58472b676d7Smrg	}
58572b676d7Smrg
58672b676d7Smrg#ifdef SISVRAMQ
58772b676d7Smrg	SiSCheckQueue(16 * 2);
58872b676d7Smrg	SiSSetupX0Y0X1Y1(x1, y1, x2, y2)
58972b676d7Smrg	SiSSetupDSTBaseDoCMD(dstbase)
59072b676d7Smrg#else
59172b676d7Smrg	SiSSetupDSTBase(dstbase)
59272b676d7Smrg	SiSSetupX0Y0(x1, y1)
59372b676d7Smrg	SiSSetupX1Y1(x2, y2)
59472b676d7Smrg	SiSDoCMD
59572b676d7Smrg#endif
59672b676d7Smrg}
59772b676d7Smrg
59872b676d7Smrgstatic void
59972b676d7SmrgSiSSubsequentSolidHorzVertLine(ScrnInfoPtr pScrn,
60072b676d7Smrg			int x, int y, int len, int dir)
60172b676d7Smrg{
60272b676d7Smrg	SISPtr pSiS = SISPTR(pScrn);
60372b676d7Smrg	CARD32 dstbase = 0;
60472b676d7Smrg
60572b676d7Smrg	len--; /* starting point is included! */
60672b676d7Smrg
60772b676d7Smrg	if((y >= 2048) || ((y + len) >= 2048)) {
60872b676d7Smrg	   dstbase = pSiS->scrnOffset * y;
60972b676d7Smrg	   y = 0;
61072b676d7Smrg	}
61172b676d7Smrg
61272b676d7Smrg	dstbase += FBOFFSET;
61372b676d7Smrg
61472b676d7Smrg#ifdef SISVRAMQ
61572b676d7Smrg	SiSCheckQueue(16 * 2);
61672b676d7Smrg	if(dir == DEGREES_0) {
61772b676d7Smrg	   SiSSetupX0Y0X1Y1(x, y, (x + len), y)
61872b676d7Smrg	} else {
61972b676d7Smrg	   SiSSetupX0Y0X1Y1(x, y, x, (y + len))
62072b676d7Smrg	}
62172b676d7Smrg	SiSSetupDSTBaseDoCMD(dstbase)
62272b676d7Smrg#else
62372b676d7Smrg	SiSSetupDSTBase(dstbase)
62472b676d7Smrg	SiSSetupX0Y0(x,y)
62572b676d7Smrg	if(dir == DEGREES_0) {
62672b676d7Smrg	   SiSSetupX1Y1(x + len, y);
62772b676d7Smrg	} else {
62872b676d7Smrg	   SiSSetupX1Y1(x, y + len);
62972b676d7Smrg	}
63072b676d7Smrg	SiSDoCMD
63172b676d7Smrg#endif
63272b676d7Smrg}
63372b676d7Smrg
63472b676d7Smrgstatic void
63572b676d7SmrgSiSSetupForDashedLine(ScrnInfoPtr pScrn,
63672b676d7Smrg			int fg, int bg, int rop, unsigned int planemask,
63772b676d7Smrg			int length, unsigned char *pattern)
63872b676d7Smrg{
63972b676d7Smrg	SISPtr pSiS = SISPTR(pScrn);
64072b676d7Smrg
64172b676d7Smrg#ifdef SISVRAMQ
64272b676d7Smrg	SiSSetupDSTColorDepth(pSiS->SiS310_AccelDepth);
64372b676d7Smrg	SiSCheckQueue(16 * 3);
64472b676d7Smrg	SiSSetupLineCountPeriod(1, (length - 1))
64572b676d7Smrg	SiSSetupStyle(*pattern,*(pattern + 4))
64672b676d7Smrg	SiSSetupPATFGDSTRect(fg, pSiS->scrnOffset, DEV_HEIGHT)
64772b676d7Smrg#else
64872b676d7Smrg	SiSSetupLineCount(1)
64972b676d7Smrg	SiSSetupDSTRect(pSiS->scrnOffset, DEV_HEIGHT)
65072b676d7Smrg	SiSSetupDSTColorDepth(pSiS->DstColor);
65172b676d7Smrg	SiSSetupStyleLow(*pattern)
65272b676d7Smrg	SiSSetupStyleHigh(*(pattern + 4))
65372b676d7Smrg	SiSSetupStylePeriod(length - 1);
65472b676d7Smrg	SiSSetupPATFG(fg)
65572b676d7Smrg#endif
65672b676d7Smrg
65772b676d7Smrg	SiSSetupROP(SiSGetPatternROP(rop))
65872b676d7Smrg
65972b676d7Smrg	SiSSetupCMDFlag(LINE | LINE_STYLE)
66072b676d7Smrg
66172b676d7Smrg	if(bg != -1) {
66272b676d7Smrg	   SiSSetupPATBG(bg)
66372b676d7Smrg	} else {
66472b676d7Smrg	   SiSSetupCMDFlag(TRANSPARENT)
66572b676d7Smrg	}
66672b676d7Smrg#ifndef SISVRAMQ
66772b676d7Smrg	SiSSetupCMDFlag(pSiS->SiS310_AccelDepth)
66872b676d7Smrg#endif
66972b676d7Smrg
67072b676d7Smrg#ifdef SISVRAMQ
67172b676d7Smrg        SiSSyncWP
67272b676d7Smrg#endif
67372b676d7Smrg}
67472b676d7Smrg
67572b676d7Smrgstatic void
67672b676d7SmrgSiSSubsequentDashedTwoPointLine(ScrnInfoPtr pScrn,
67772b676d7Smrg			int x1, int y1, int x2, int y2,
67872b676d7Smrg			int flags, int phase)
67972b676d7Smrg{
68072b676d7Smrg	SISPtr pSiS = SISPTR(pScrn);
68172b676d7Smrg	CARD32 dstbase, miny, maxy;
68272b676d7Smrg
68372b676d7Smrg	dstbase = 0;
68472b676d7Smrg	miny = (y1 > y2) ? y2 : y1;
68572b676d7Smrg	maxy = (y1 > y2) ? y1 : y2;
68672b676d7Smrg	if(maxy >= 2048) {
68772b676d7Smrg	   dstbase = pSiS->scrnOffset * miny;
68872b676d7Smrg	   y1 -= miny;
68972b676d7Smrg	   y2 -= miny;
69072b676d7Smrg	}
69172b676d7Smrg
69272b676d7Smrg	dstbase += FBOFFSET;
69372b676d7Smrg
69472b676d7Smrg	if(flags & OMIT_LAST) {
69572b676d7Smrg	   SiSSetupCMDFlag(NO_LAST_PIXEL)
69672b676d7Smrg	} else {
69772b676d7Smrg	   pSiS->CommandReg &= ~(NO_LAST_PIXEL);
69872b676d7Smrg	}
69972b676d7Smrg
70072b676d7Smrg#ifdef SISVRAMQ
70172b676d7Smrg	SiSCheckQueue(16 * 2);
70272b676d7Smrg	SiSSetupX0Y0X1Y1(x1, y1, x2, y2)
70372b676d7Smrg	SiSSetupDSTBaseDoCMD(dstbase)
70472b676d7Smrg#else
70572b676d7Smrg	SiSSetupDSTBase(dstbase)
70672b676d7Smrg	SiSSetupX0Y0(x1, y1)
70772b676d7Smrg	SiSSetupX1Y1(x2, y2)
70872b676d7Smrg	SiSDoCMD
70972b676d7Smrg#endif
71072b676d7Smrg}
71172b676d7Smrg
71272b676d7Smrgstatic void
71372b676d7SmrgSiSSetupForMonoPatternFill(ScrnInfoPtr pScrn,
71472b676d7Smrg			int patx, int paty, int fg, int bg,
71572b676d7Smrg			int rop, unsigned int planemask)
71672b676d7Smrg{
71772b676d7Smrg	SISPtr pSiS = SISPTR(pScrn);
71872b676d7Smrg
71972b676d7Smrg#ifdef SISVRAMQ
72072b676d7Smrg	SiSSetupDSTColorDepth(pSiS->SiS310_AccelDepth);
72172b676d7Smrg	SiSCheckQueue(16 * 3);
72272b676d7Smrg	SiSSetupPATFGDSTRect(fg, pSiS->scrnOffset, DEV_HEIGHT)
72372b676d7Smrg#else
72472b676d7Smrg	SiSSetupDSTRect(pSiS->scrnOffset, DEV_HEIGHT)
72572b676d7Smrg	SiSSetupDSTColorDepth(pSiS->DstColor);
72672b676d7Smrg#endif
72772b676d7Smrg
72872b676d7Smrg	SiSSetupMONOPAT(patx,paty)
72972b676d7Smrg
73072b676d7Smrg	SiSSetupROP(SiSGetPatternROP(rop))
73172b676d7Smrg
73272b676d7Smrg#ifdef SISVRAMQ
73372b676d7Smrg	SiSSetupCMDFlag(PATMONO)
73472b676d7Smrg#else
73572b676d7Smrg	SiSSetupPATFG(fg)
73672b676d7Smrg	SiSSetupCMDFlag(PATMONO | pSiS->SiS310_AccelDepth)
73772b676d7Smrg#endif
73872b676d7Smrg
73972b676d7Smrg	if(bg != -1) {
74072b676d7Smrg	   SiSSetupPATBG(bg)
74172b676d7Smrg	} else {
74272b676d7Smrg	   SiSSetupCMDFlag(TRANSPARENT)
74372b676d7Smrg	}
74472b676d7Smrg
74572b676d7Smrg#ifdef SISVRAMQ
74672b676d7Smrg	SiSSyncWP
74772b676d7Smrg#endif
74872b676d7Smrg}
74972b676d7Smrg
75072b676d7Smrgstatic void
75172b676d7SmrgSiSSubsequentMonoPatternFill(ScrnInfoPtr pScrn,
75272b676d7Smrg			int patx, int paty,
75372b676d7Smrg			int x, int y, int w, int h)
75472b676d7Smrg{
75572b676d7Smrg	SISPtr pSiS = SISPTR(pScrn);
75672b676d7Smrg	CARD32 dstbase = 0;
75772b676d7Smrg
75872b676d7Smrg	if(y >= 2048) {
75972b676d7Smrg	   dstbase = pSiS->scrnOffset * y;
76072b676d7Smrg	   y = 0;
76172b676d7Smrg	}
76272b676d7Smrg
76372b676d7Smrg	dstbase += FBOFFSET;
76472b676d7Smrg
76572b676d7Smrg	/* Clear commandReg because Setup can be used for Rect and Trap */
76672b676d7Smrg	pSiS->CommandReg &= ~(T_XISMAJORL | T_XISMAJORR |
76772b676d7Smrg			      T_L_X_INC | T_L_Y_INC |
76872b676d7Smrg			      T_R_X_INC | T_R_Y_INC |
76972b676d7Smrg			      TRAPAZOID_FILL);
77072b676d7Smrg
77172b676d7Smrg#ifdef SISVRAMQ
77272b676d7Smrg	SiSCheckQueue(16 * 2);
77372b676d7Smrg	SiSSetupDSTXYRect(x,y,w,h)
77472b676d7Smrg	SiSSetupDSTBaseDoCMD(dstbase)
77572b676d7Smrg#else
77672b676d7Smrg	SiSSetupDSTBase(dstbase)
77772b676d7Smrg	SiSSetupDSTXY(x,y)
77872b676d7Smrg	SiSSetupRect(w,h)
77972b676d7Smrg	SiSDoCMD
78072b676d7Smrg#endif
78172b676d7Smrg}
78272b676d7Smrg
78372b676d7Smrg/* --- Trapezoid --- */
78472b676d7Smrg
78572b676d7Smrg/* Does not work at all on 330 series */
78672b676d7Smrg
78772b676d7Smrg#ifdef TRAP
78872b676d7Smrgstatic void
78972b676d7SmrgSiSSubsequentMonoPatternFillTrap(ScrnInfoPtr pScrn,
79072b676d7Smrg			int patx, int paty,
79172b676d7Smrg			int y, int h,
79272b676d7Smrg			int left, int dxL, int dyL, int eL,
79372b676d7Smrg			int right, int dxR, int dyR, int eR)
79472b676d7Smrg{
79572b676d7Smrg	SISPtr pSiS = SISPTR(pScrn);
79672b676d7Smrg	CARD32 dstbase = 0;
79772b676d7Smrg
79872b676d7Smrg	if(y >= 2048) {
79972b676d7Smrg	   dstbase=pSiS->scrnOffset*y;
80072b676d7Smrg	   y = 0;
80172b676d7Smrg	}
80272b676d7Smrg
80372b676d7Smrg	dstbase += FBOFFSET;
80472b676d7Smrg
80572b676d7Smrg#ifdef SISVRAMQ
80672b676d7Smrg	SiSCheckQueue(16 * 4);
80772b676d7Smrg#else
80872b676d7Smrg	SiSSetupDSTBase(dstbase)
80972b676d7Smrg#endif
81072b676d7Smrg
81172b676d7Smrg	/* Clear CommandReg because SetUp can be used for Rect and Trap */
81272b676d7Smrg	pSiS->CommandReg &= ~(T_XISMAJORL | T_XISMAJORR |
81372b676d7Smrg			      T_L_X_INC | T_L_Y_INC |
81472b676d7Smrg			      T_R_X_INC | T_R_Y_INC |
81572b676d7Smrg			      BITBLT);
81672b676d7Smrg
81772b676d7Smrg	if(dxL < 0) 	{ dxL = -dxL;  }
81872b676d7Smrg	else 		{ SiSSetupCMDFlag(T_L_X_INC) }
81972b676d7Smrg	if(dxR < 0) 	{ dxR = -dxR; }
82072b676d7Smrg	else 		{ SiSSetupCMDFlag(T_R_X_INC) }
82172b676d7Smrg
82272b676d7Smrg	if(dyL < 0) 	{ dyL = -dyL; }
82372b676d7Smrg	else 		{ SiSSetupCMDFlag(T_L_Y_INC) }
82472b676d7Smrg	if(dyR < 0) 	{ dyR = -dyR; }
82572b676d7Smrg	else 		{ SiSSetupCMDFlag(T_R_Y_INC) }
82672b676d7Smrg
82772b676d7Smrg	/* Determine major axis */
82872b676d7Smrg	if(dxL >= dyL)  { SiSSetupCMDFlag(T_XISMAJORL) }
82972b676d7Smrg	if(dxR >= dyR)  { SiSSetupCMDFlag(T_XISMAJORR) }
83072b676d7Smrg
83172b676d7Smrg	SiSSetupCMDFlag(TRAPAZOID_FILL);
83272b676d7Smrg
83372b676d7Smrg#ifdef SISVRAMQ
83472b676d7Smrg	SiSSetupYHLR(y, h, left, right)
83572b676d7Smrg	SiSSetupdLdR(dxL, dyL, dxR, dyR)
83672b676d7Smrg	SiSSetupELER(eL, eR)
83772b676d7Smrg	SiSSetupDSTBaseDoCMD(dstbase)
83872b676d7Smrg#else
83972b676d7Smrg	SiSSetupYH(y, h)
84072b676d7Smrg	SiSSetupLR(left, right)
84172b676d7Smrg	SiSSetupdL(dxL, dyL)
84272b676d7Smrg	SiSSetupdR(dxR, dyR)
84372b676d7Smrg	SiSSetupEL(eL)
84472b676d7Smrg	SiSSetupER(eR)
84572b676d7Smrg	SiSDoCMD
84672b676d7Smrg#endif
84772b676d7Smrg}
84872b676d7Smrg#endif
84972b676d7Smrg
85072b676d7Smrg/* Color 8x8 pattern */
85172b676d7Smrg
85272b676d7Smrg#ifdef SISVRAMQ
85372b676d7Smrgstatic void
85472b676d7SmrgSiSSetupForColor8x8PatternFill(ScrnInfoPtr pScrn, int patternx, int patterny,
85572b676d7Smrg			int rop, unsigned int planemask, int trans_col)
85672b676d7Smrg{
85772b676d7Smrg	SISPtr pSiS = SISPTR(pScrn);
85872b676d7Smrg	int j = pScrn->bitsPerPixel >> 3;
85972b676d7Smrg	CARD32 *patadr = (CARD32 *)(pSiS->FbBase + (patterny * pSiS->scrnOffset) +
86072b676d7Smrg				(patternx * j));
86172b676d7Smrg
86272b676d7Smrg	SiSSetupDSTColorDepth(pSiS->SiS310_AccelDepth);
86372b676d7Smrg	SiSCheckQueue(16 * 3);
86472b676d7Smrg
86572b676d7Smrg	SiSSetupDSTRectBurstHeader(pSiS->scrnOffset, DEV_HEIGHT, PATTERN_REG, (pScrn->bitsPerPixel << 1))
86672b676d7Smrg
86772b676d7Smrg	while(j--) {
86872b676d7Smrg	   SiSSetupPatternRegBurst(patadr[0],  patadr[1],  patadr[2],  patadr[3]);
86972b676d7Smrg	   SiSSetupPatternRegBurst(patadr[4],  patadr[5],  patadr[6],  patadr[7]);
87072b676d7Smrg	   SiSSetupPatternRegBurst(patadr[8],  patadr[9],  patadr[10], patadr[11]);
87172b676d7Smrg	   SiSSetupPatternRegBurst(patadr[12], patadr[13], patadr[14], patadr[15]);
87272b676d7Smrg	   patadr += 16;  /* = 64 due to (CARD32 *) */
87372b676d7Smrg	}
87472b676d7Smrg
87572b676d7Smrg	SiSSetupROP(SiSGetPatternROP(rop))
87672b676d7Smrg
87772b676d7Smrg	SiSSetupCMDFlag(PATPATREG)
87872b676d7Smrg
87972b676d7Smrg	SiSSyncWP
88072b676d7Smrg}
88172b676d7Smrg
88272b676d7Smrgstatic void
88372b676d7SmrgSiSSubsequentColor8x8PatternFillRect(ScrnInfoPtr pScrn, int patternx,
88472b676d7Smrg			int patterny, int x, int y, int w, int h)
88572b676d7Smrg{
88672b676d7Smrg	SISPtr pSiS = SISPTR(pScrn);
88772b676d7Smrg	CARD32 dstbase = 0;
88872b676d7Smrg
88972b676d7Smrg	if(y >= 2048) {
89072b676d7Smrg	   dstbase = pSiS->scrnOffset * y;
89172b676d7Smrg	   y = 0;
89272b676d7Smrg	}
89372b676d7Smrg
89472b676d7Smrg	dstbase += FBOFFSET;
89572b676d7Smrg
89672b676d7Smrg	/* SiSSetupCMDFlag(BITBLT)  - BITBLT = 0 */
89772b676d7Smrg
89872b676d7Smrg	SiSCheckQueue(16 * 2)
89972b676d7Smrg	SiSSetupDSTXYRect(x, y, w, h)
90072b676d7Smrg	SiSSetupDSTBaseDoCMD(dstbase)
90172b676d7Smrg}
90272b676d7Smrg#endif
90372b676d7Smrg
90472b676d7Smrg/* ---- CPUToScreen Color Expand --- */
90572b676d7Smrg
90672b676d7Smrg#ifdef CTSCE
90772b676d7Smrg
90872b676d7Smrg#ifdef CTSCE_DIRECT
90972b676d7Smrg
91072b676d7Smrg/* Direct method */
91172b676d7Smrg
91272b676d7Smrg/* This is somewhat a fake. We let XAA copy its data not to an
91372b676d7Smrg * aperture, but to video RAM, and then do a ScreenToScreen
91472b676d7Smrg * color expansion.
91572b676d7Smrg * Since the data is sent AFTER the call to Subsequent, we
91672b676d7Smrg * don't execute the command here, but set a flag and do
91772b676d7Smrg * that in the (subsequent) call to Sync()
91872b676d7Smrg */
91972b676d7Smrg
92072b676d7Smrgstatic void
92172b676d7SmrgSiSSetupForCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
92272b676d7Smrg			int fg, int bg, int rop, unsigned int planemask)
92372b676d7Smrg{
92472b676d7Smrg	SISPtr pSiS=SISPTR(pScrn);
92572b676d7Smrg
92672b676d7Smrg#ifdef SISVRAMQ
92772b676d7Smrg	SiSSetupDSTColorDepth(pSiS->SiS310_AccelDepth);
92872b676d7Smrg	SiSSetupROP(SiSGetCopyROP(rop));
92972b676d7Smrg	SiSSetupSRCFGDSTRect(fg, pSiS->scrnOffset, DEV_HEIGHT)
93072b676d7Smrg	if(bg == -1) {
93172b676d7Smrg	   SiSSetupCMDFlag(TRANSPARENT | ENCOLOREXP | SRCVIDEO);
93272b676d7Smrg	} else {
93372b676d7Smrg	   SiSSetupSRCBG(bg);
93472b676d7Smrg	   SiSSetupCMDFlag(ENCOLOREXP | SRCVIDEO);
93572b676d7Smrg	}
93672b676d7Smrg	SiSSyncWP
93772b676d7Smrg#else
93872b676d7Smrg	SiSSetupSRCXY(0,0);
93972b676d7Smrg	SiSSetupROP(SiSGetCopyROP(rop));
94072b676d7Smrg	SiSSetupSRCFG(fg);
94172b676d7Smrg	SiSSetupDSTRect(pSiS->scrnOffset, DEV_HEIGHT);
94272b676d7Smrg	SiSSetupDSTColorDepth(pSiS->DstColor);
94372b676d7Smrg	if(bg == -1) {
94472b676d7Smrg	   SiSSetupCMDFlag(TRANSPARENT | ENCOLOREXP | SRCVIDEO
94572b676d7Smrg				       | pSiS->SiS310_AccelDepth);
94672b676d7Smrg	} else {
94772b676d7Smrg	   SiSSetupSRCBG(bg);
94872b676d7Smrg	   SiSSetupCMDFlag(ENCOLOREXP | SRCVIDEO | pSiS->SiS310_AccelDepth);
94972b676d7Smrg	}
95072b676d7Smrg#endif
95172b676d7Smrg}
95272b676d7Smrg
95372b676d7Smrgstatic void
95472b676d7SmrgSiSSubsequentCPUToScreenColorExpandFill(
95572b676d7Smrg			ScrnInfoPtr pScrn, int x, int y, int w,
95672b676d7Smrg			int h, int skipleft)
95772b676d7Smrg{
95872b676d7Smrg	SISPtr pSiS = SISPTR(pScrn);
95972b676d7Smrg	int _x0, _y0, _x1, _y1;
96072b676d7Smrg	CARD32 srcbase, dstbase;
96172b676d7Smrg
96272b676d7Smrg	srcbase = pSiS->ColorExpandBase;
96372b676d7Smrg
96472b676d7Smrg	dstbase = 0;
96572b676d7Smrg	if(y >= 2048) {
96672b676d7Smrg	   dstbase = pSiS->scrnOffset*y;
96772b676d7Smrg	   y = 0;
96872b676d7Smrg	}
96972b676d7Smrg
97072b676d7Smrg	srcbase += FBOFFSET;
97172b676d7Smrg	dstbase += FBOFFSET;
97272b676d7Smrg
97372b676d7Smrg#ifdef SISVRAMQ
97472b676d7Smrg	SiSSetupSRCDSTBase(srcbase,dstbase);
97572b676d7Smrg#else
97672b676d7Smrg	SiSSetupSRCBase(srcbase);
97772b676d7Smrg	SiSSetupDSTBase(dstbase)
97872b676d7Smrg#endif
97972b676d7Smrg
98072b676d7Smrg	if(skipleft > 0) {
98172b676d7Smrg	   _x0 = x + skipleft;
98272b676d7Smrg	   _y0 = y;
98372b676d7Smrg	   _x1 = x + w;
98472b676d7Smrg	   _y1 = y + h;
98572b676d7Smrg#ifdef SISVRAMQ
98672b676d7Smrg	   SiSSetupClip(_x0, _y0, _x1, _y1);
98772b676d7Smrg#else
98872b676d7Smrg	   SiSSetupClipLT(_x0, _y0);
98972b676d7Smrg	   SiSSetupClipRB(_x1, _y1);
99072b676d7Smrg#endif
99172b676d7Smrg	   SiSSetupCMDFlag(CLIPENABLE);
99272b676d7Smrg	} else {
99372b676d7Smrg	   pSiS->CommandReg &= (~CLIPENABLE);
99472b676d7Smrg	}
99572b676d7Smrg
99672b676d7Smrg#ifdef SISVRAMQ
99772b676d7Smrg	SiSSetupRectSRCPitch(w, h, ((((w + 7) >> 3) + 3) >> 2) << 2);
99872b676d7Smrg	SiSSetupSRCDSTXY(0, 0, x, y);
99972b676d7Smrg#else
100072b676d7Smrg	SiSSetupRect(w, h);
100172b676d7Smrg	SiSSetupSRCPitch(((((w+7)/8)+3) >> 2) * 4);
100272b676d7Smrg	SiSSetupDSTXY(x, y);
100372b676d7Smrg#endif
100472b676d7Smrg
100572b676d7Smrg	if(pSiS->ColorExpandBusy) {
100672b676d7Smrg	   pSiS->ColorExpandBusy = FALSE;
100772b676d7Smrg	   SiSIdle
100872b676d7Smrg	}
100972b676d7Smrg
101072b676d7Smrg	pSiS->DoColorExpand = TRUE;
101172b676d7Smrg}
101272b676d7Smrg
101372b676d7Smrg#else
101472b676d7Smrg
101572b676d7Smrg/* Indirect method */
101672b676d7Smrg
101772b676d7Smrg/* This is SLOW, slower than the CPU on most chipsets */
101872b676d7Smrg/* Does not work in VRAM queue mode. */
101972b676d7Smrg
102072b676d7Smrgstatic void
102172b676d7SmrgSiSSetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
102272b676d7Smrg			int fg, int bg, int rop, unsigned int planemask)
102372b676d7Smrg{
102472b676d7Smrg	SISPtr pSiS=SISPTR(pScrn);
102572b676d7Smrg
102672b676d7Smrg#ifdef SISVRAMQ
102772b676d7Smrg        SiSSetupDSTColorDepth(pSiS->SiS310_AccelDepth);
102872b676d7Smrg#endif
102972b676d7Smrg
103072b676d7Smrg	/* !!! DOES NOT WORK IN VRAM QUEUE MODE !!! */
103172b676d7Smrg
103272b676d7Smrg	/* (hence this is not optimized for VRAM mode) */
103372b676d7Smrg#ifndef SISVRAMQ
103472b676d7Smrg	SiSIdle
103572b676d7Smrg#endif
103672b676d7Smrg	SiSSetupSRCXY(0,0);
103772b676d7Smrg
103872b676d7Smrg	SiSSetupROP(SiSGetCopyROP(rop));
103972b676d7Smrg	SiSSetupSRCFG(fg);
104072b676d7Smrg	SiSSetupDSTRect(pSiS->scrnOffset, DEV_HEIGHT);
104172b676d7Smrg#ifndef SISVRAMQ
104272b676d7Smrg	SiSSetupDSTColorDepth(pSiS->DstColor);
104372b676d7Smrg#endif
104472b676d7Smrg	if(bg == -1) {
104572b676d7Smrg#ifdef SISVRAMQ
104672b676d7Smrg	   SiSSetupCMDFlag(TRANSPARENT | ENCOLOREXP | SRCVIDEO);
104772b676d7Smrg#else
104872b676d7Smrg	   SiSSetupCMDFlag(TRANSPARENT | ENCOLOREXP | SRCCPUBLITBUF
104972b676d7Smrg				       | pSiS->SiS310_AccelDepth);
105072b676d7Smrg#endif
105172b676d7Smrg	} else {
105272b676d7Smrg	   SiSSetupSRCBG(bg);
105372b676d7Smrg#ifdef SISVRAMQ
105472b676d7Smrg	   SiSSetupCMDFlag(ENCOLOREXP | SRCCPUBLITBUF);
105572b676d7Smrg#else
105672b676d7Smrg	   SiSSetupCMDFlag(ENCOLOREXP | SRCCPUBLITBUF | pSiS->SiS310_AccelDepth);
105772b676d7Smrg#endif
105872b676d7Smrg	};
105972b676d7Smrg
106072b676d7Smrg}
106172b676d7Smrg
106272b676d7Smrgstatic void
106372b676d7SmrgSiSSubsequentScanlineCPUToScreenColorExpandFill(
106472b676d7Smrg			ScrnInfoPtr pScrn, int x, int y, int w,
106572b676d7Smrg			int h, int skipleft)
106672b676d7Smrg{
106772b676d7Smrg	SISPtr pSiS = SISPTR(pScrn);
106872b676d7Smrg	int _x0, _y0, _x1, _y1;
106972b676d7Smrg	CARD32 dstbase = 0;
107072b676d7Smrg
107172b676d7Smrg	if(y >= 2048) {
107272b676d7Smrg	   dstbase = pSiS->scrnOffset*y;
107372b676d7Smrg	   y = 0;
107472b676d7Smrg	}
107572b676d7Smrg
107672b676d7Smrg	dstbase += FBOFFSET;
107772b676d7Smrg
107872b676d7Smrg#ifndef SISVRAMQ
107972b676d7Smrg        if((SIS_MMIO_IN16(pSiS->IOBase, Q_STATUS+2) & 0x8000) != 0x8000) {
108072b676d7Smrg	   SiSIdle;
108172b676d7Smrg        }
108272b676d7Smrg#endif
108372b676d7Smrg
108472b676d7Smrg	SiSSetupDSTBase(dstbase)
108572b676d7Smrg
108672b676d7Smrg	if(skipleft > 0) {
108772b676d7Smrg	   _x0 = x+skipleft;
108872b676d7Smrg	   _y0 = y;
108972b676d7Smrg	   _x1 = x+w;
109072b676d7Smrg	   _y1 = y+h;
109172b676d7Smrg#ifdef SISVRAMQ
109272b676d7Smrg           SiSSetupClip(_x0, _y0, _x1, _y1);
109372b676d7Smrg#else
109472b676d7Smrg	   SiSSetupClipLT(_x0, _y0);
109572b676d7Smrg	   SiSSetupClipRB(_x1, _y1);
109672b676d7Smrg#endif
109772b676d7Smrg	   SiSSetupCMDFlag(CLIPENABLE);
109872b676d7Smrg	} else {
109972b676d7Smrg	   pSiS->CommandReg &= (~CLIPENABLE);
110072b676d7Smrg	}
110172b676d7Smrg	SiSSetupRect(w, 1);
110272b676d7Smrg	SiSSetupSRCPitch(((((w+7)/8)+3) >> 2) * 4);
110372b676d7Smrg	pSiS->ycurrent = y;
110472b676d7Smrg	pSiS->xcurrent = x;
110572b676d7Smrg
110672b676d7Smrg}
110772b676d7Smrg
110872b676d7Smrgstatic void
110972b676d7SmrgSiSSubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno)
111072b676d7Smrg{
111172b676d7Smrg	SISPtr pSiS = SISPTR(pScrn);
111272b676d7Smrg	CARD32 cbo;
111372b676d7Smrg
111472b676d7Smrg	cbo = pSiS->ColorExpandBufferScreenOffset[bufno];
111572b676d7Smrg	cbo += FBOFFSET;
111672b676d7Smrg
111772b676d7Smrg#ifndef SISVRAMQ
111872b676d7Smrg	if((SIS_MMIO_IN16(pSiS->IOBase, Q_STATUS+2) & 0x8000) != 0x8000) {
111972b676d7Smrg	   SiSIdle;
112072b676d7Smrg        }
112172b676d7Smrg#endif
112272b676d7Smrg
112372b676d7Smrg	SiSSetupSRCBase(cbo);
112472b676d7Smrg
112572b676d7Smrg	SiSSetupDSTXY(pSiS->xcurrent, pSiS->ycurrent);
112672b676d7Smrg
112772b676d7Smrg	SiSDoCMD
112872b676d7Smrg
112972b676d7Smrg	pSiS->ycurrent++;
113072b676d7Smrg#ifndef SISVRAMQ
113172b676d7Smrg	SiSIdle
113272b676d7Smrg#endif
113372b676d7Smrg}
113472b676d7Smrg#endif
113572b676d7Smrg#endif
113672b676d7Smrg
113772b676d7Smrg/* --- Screen To Screen Color Expand --- */
113872b676d7Smrg
113972b676d7Smrg/* This method blits in a single task; this does not work because
114072b676d7Smrg * the hardware does not use the source pitch as scanline offset
114172b676d7Smrg * but to calculate pattern address from source X and Y and to
114272b676d7Smrg * limit the drawing width (similar to width set by SetupRect).
114372b676d7Smrg * XAA provides the pattern bitmap with scrnOffset (displayWidth * bpp/8)
114472b676d7Smrg * offset, but this is not supported by the hardware.
114572b676d7Smrg * DOES NOT WORK ON 330 SERIES, HANGS ENGINE.
114672b676d7Smrg */
114772b676d7Smrg
114872b676d7Smrg#ifdef STSCE
114972b676d7Smrgstatic void
115072b676d7SmrgSiSSetupForScreenToScreenColorExpand(ScrnInfoPtr pScrn,
115172b676d7Smrg			int fg, int bg,
115272b676d7Smrg			int rop, unsigned int planemask)
115372b676d7Smrg{
115472b676d7Smrg	SISPtr          pSiS = SISPTR(pScrn);
115572b676d7Smrg
115672b676d7Smrg#ifdef SISVRAMQ
115772b676d7Smrg        SiSSetupDSTColorDepth(pSiS->SiS310_AccelDepth);
115872b676d7Smrg#else
115972b676d7Smrg	SiSSetupDSTColorDepth(pSiS->DstColor)
116072b676d7Smrg#endif
116172b676d7Smrg	SiSSetupDSTRect(pSiS->scrnOffset, DEV_HEIGHT)
116272b676d7Smrg	SiSSetupROP(SiSGetCopyROP(rop))
116372b676d7Smrg	SiSSetupSRCFG(fg)
116472b676d7Smrg	/* SiSSetupSRCXY(0,0) */
116572b676d7Smrg
116672b676d7Smrg	if(bg == -1) {
116772b676d7Smrg	   SiSSetupCMDFlag(TRANSPARENT | ENCOLOREXP | SRCVIDEO);
116872b676d7Smrg	} else {
116972b676d7Smrg	   SiSSetupSRCBG(bg);
117072b676d7Smrg	   SiSSetupCMDFlag(ENCOLOREXP | SRCVIDEO);
117172b676d7Smrg	};
117272b676d7Smrg
117372b676d7Smrg#ifdef SISVRAMQ
117472b676d7Smrg        SiSSyncWP
117572b676d7Smrg#endif
117672b676d7Smrg}
117772b676d7Smrg
117872b676d7Smrg/* For testing, these are the methods: (use only one at a time!) */
117972b676d7Smrg
118072b676d7Smrg#undef npitch 		/* Normal: Use srcx/y as srcx/y, use scrnOffset as source pitch
118172b676d7Smrg			 * Does not work on 315 series, because the hardware does not
118272b676d7Smrg			 * regard the src x and y. Apart from this problem:
118372b676d7Smrg			 * This would work if the hareware used the source pitch for
118472b676d7Smrg			 * incrementing the source address after each scanline - but
118572b676d7Smrg			 * it doesn't do this! The first line of the area is correctly
118672b676d7Smrg			 * color expanded, but since the source pitch is ignored and
118772b676d7Smrg			 * the source address not incremented correctly, the following
118872b676d7Smrg			 * lines are color expanded with any bit pattern that is left
118972b676d7Smrg			 * in the unused space of the source bitmap (which is organized
119072b676d7Smrg			 * with the depth of the screen framebuffer hence with a pitch
119172b676d7Smrg			 * of scrnOffset).
119272b676d7Smrg			 */
119372b676d7Smrg
119472b676d7Smrg#undef pitchdw    	/* Use source pitch "displayWidth / 8" instead
119572b676d7Smrg			 * of scrnOffset (=displayWidth * bpp / 8)
119672b676d7Smrg			 * This can't work, because the pitch of the source
119772b676d7Smrg			 * bitmap is scrnoffset!
119872b676d7Smrg			 */
119972b676d7Smrg
120072b676d7Smrg#define nopitch 	/* Calculate srcbase with srcx and srcy, set the
120172b676d7Smrg			 * pitch to scrnOffset (which IS the correct pitch
120272b676d7Smrg			 * for the source bitmap) and set srcx and srcy both
120372b676d7Smrg			 * to 0.
120472b676d7Smrg			 * This would work if the hareware used the source pitch for
120572b676d7Smrg			 * incrementing the source address after each scanline - but
120672b676d7Smrg			 * it doesn't do this! Again: The first line of the area is
120772b676d7Smrg			 * correctly color expanded, but since the source pitch is
120872b676d7Smrg			 * ignored for scanline address incremention, the following
120972b676d7Smrg			 * lines are not correctly color expanded.
121072b676d7Smrg			 * This is the only way it works (apart from the problem
121172b676d7Smrg			 * described above). The hardware does not regard the src
121272b676d7Smrg			 * x and y values in any way.
121372b676d7Smrg			 */
121472b676d7Smrg
121572b676d7Smrgstatic void
121672b676d7SmrgSiSSubsequentScreenToScreenColorExpand(ScrnInfoPtr pScrn,
121772b676d7Smrg			int x, int y, int w, int h,
121872b676d7Smrg			int srcx, int srcy, int skipleft)
121972b676d7Smrg{
122072b676d7Smrg	SISPtr pSiS = SISPTR(pScrn);
122172b676d7Smrg        CARD32 srcbase, dstbase;
122272b676d7Smrg#if 0
122372b676d7Smrg	int _x0, _y0, _x1, _y1;
122472b676d7Smrg#endif
122572b676d7Smrg#ifdef pitchdw
122672b676d7Smrg	int newsrcx, newsrcy;
122772b676d7Smrg
122872b676d7Smrg	/* srcx and srcy are provided based on a scrnOffset pitch ( = displayWidth * bpp / 8 )
122972b676d7Smrg	 * We recalulate srcx and srcy based on pitch = displayWidth / 8
123072b676d7Smrg	 */
123172b676d7Smrg        newsrcy = ((pSiS->scrnOffset * srcy) + (srcx * ((pScrn->bitsPerPixel+7)/8))) /
123272b676d7Smrg					  (pScrn->displayWidth/8);
123372b676d7Smrg        newsrcx = ((pSiS->scrnOffset * srcy) + (srcx * ((pScrn->bitsPerPixel+7)/8))) %
123472b676d7Smrg					  (pScrn->displayWidth/8);
123572b676d7Smrg#endif
123672b676d7Smrg	xf86DrvMsg(0, X_INFO, "Sub ScreenToScreen ColorExp(%d,%d, %d,%d, %d,%d, %d)\n",
123772b676d7Smrg					x, y, w, h, srcx, srcy, skipleft);
123872b676d7Smrg
123972b676d7Smrg	srcbase = dstbase = 0;
124072b676d7Smrg
124172b676d7Smrg#ifdef pitchdw
124272b676d7Smrg	if(newsrcy >= 2048) {
124372b676d7Smrg	   srcbase = (pScrn->displayWidth / 8) * newsrcy;
124472b676d7Smrg	   newsrcy = 0;
124572b676d7Smrg	}
124672b676d7Smrg#endif
124772b676d7Smrg#ifdef nopitch
124872b676d7Smrg	srcbase = (pSiS->scrnOffset * srcy) + (srcx * ((pScrn->bitsPerPixel+7)/8));
124972b676d7Smrg#endif
125072b676d7Smrg#ifdef npitch
125172b676d7Smrg	if(srcy >= 2048) {
125272b676d7Smrg	   srcbase = pSiS->scrnOffset * srcy;
125372b676d7Smrg	   srcy = 0;
125472b676d7Smrg	}
125572b676d7Smrg#endif
125672b676d7Smrg	if(y >= 2048) {
125772b676d7Smrg	   dstbase = pSiS->scrnOffset * y;
125872b676d7Smrg	   y = 0;
125972b676d7Smrg	}
126072b676d7Smrg
126172b676d7Smrg	srcbase += FBOFFSET;
126272b676d7Smrg	dstbase += FBOFFSET;
126372b676d7Smrg
126472b676d7Smrg	SiSSetupSRCBase(srcbase)
126572b676d7Smrg	SiSSetupDSTBase(dstbase)
126672b676d7Smrg
126772b676d7Smrg	/* 315 series seem to treat the src pitch as
126872b676d7Smrg	 * a "drawing limit", but still (as 300 series)
126972b676d7Smrg	 * does not use it for incrementing the
127072b676d7Smrg	 * address pointer for the next scanline. ARGH!
127172b676d7Smrg	 */
127272b676d7Smrg
127372b676d7Smrg#ifdef pitchdw
127472b676d7Smrg	SiSSetupSRCPitch(pScrn->displayWidth/8)
127572b676d7Smrg#endif
127672b676d7Smrg#ifdef nopitch
127772b676d7Smrg	SiSSetupSRCPitch(pScrn->displayWidth/8)
127872b676d7Smrg	/* SiSSetupSRCPitch(1024/8) */ /* For test */
127972b676d7Smrg#endif
128072b676d7Smrg#ifdef npitch
128172b676d7Smrg	SiSSetupSRCPitch(pScrn->displayWidth/8)
128272b676d7Smrg	/* SiSSetupSRCPitch(pSiS->scrnOffset) */
128372b676d7Smrg#endif
128472b676d7Smrg
128572b676d7Smrg	SiSSetupRect(w,h)
128672b676d7Smrg
128772b676d7Smrg#if 0   /* How do I implement the offset? Not this way, that's for sure.. */
128872b676d7Smrg	if (skipleft > 0) {
128972b676d7Smrg		_x0 = x+skipleft;
129072b676d7Smrg		_y0 = y;
129172b676d7Smrg		_x1 = x+w;
129272b676d7Smrg		_y1 = y+h;
129372b676d7Smrg		SiSSetupClipLT(_x0, _y0);
129472b676d7Smrg		SiSSetupClipRB(_x1, _y1);
129572b676d7Smrg		SiSSetupCMDFlag(CLIPENABLE);
129672b676d7Smrg	}
129772b676d7Smrg#endif
129872b676d7Smrg#ifdef pitchdw
129972b676d7Smrg	SiSSetupSRCXY(newsrcx, newsrcy)
130072b676d7Smrg#endif
130172b676d7Smrg#ifdef nopitch
130272b676d7Smrg	SiSSetupSRCXY(0,0)
130372b676d7Smrg#endif
130472b676d7Smrg#ifdef npitch
130572b676d7Smrg	SiSSetupSRCXY(srcx, srcy)
130672b676d7Smrg#endif
130772b676d7Smrg
130872b676d7Smrg	SiSSetupDSTXY(x,y)
130972b676d7Smrg
131072b676d7Smrg	SiSDoCMD
131172b676d7Smrg#ifdef SISVRAMQ
131272b676d7Smrg	/* We MUST sync here, there must not be 2 or more color expansion commands in the queue */
131372b676d7Smrg	SiSIdle
131472b676d7Smrg#endif
131572b676d7Smrg}
131672b676d7Smrg#endif
131772b676d7Smrg
131872b676d7Smrg#ifdef SISDUALHEAD
131972b676d7Smrgstatic void
132072b676d7SmrgSiSRestoreAccelState(ScrnInfoPtr pScrn)
132172b676d7Smrg{
132272b676d7Smrg	SISPtr pSiS = SISPTR(pScrn);
132372b676d7Smrg
132472b676d7Smrg	pSiS->ColorExpandBusy = FALSE;
132572b676d7Smrg	pSiS->alphaBlitBusy = FALSE;
132672b676d7Smrg	SiSIdle
132772b676d7Smrg}
132872b676d7Smrg#endif
132972b676d7Smrg
133072b676d7Smrg/* ---- RENDER ---- */
133172b676d7Smrg
133272b676d7Smrg#ifdef INCL_RENDER
133372b676d7Smrg#ifdef RENDER
133472b676d7Smrgstatic void
133572b676d7SmrgSiSRenderCallback(ScrnInfoPtr pScrn)
133672b676d7Smrg{
133772b676d7Smrg	SISPtr pSiS = SISPTR(pScrn);
133872b676d7Smrg
133972b676d7Smrg	if((currentTime.milliseconds > pSiS->RenderTime) && pSiS->AccelLinearScratch) {
134072b676d7Smrg	   xf86FreeOffscreenLinear(pSiS->AccelLinearScratch);
134172b676d7Smrg	   pSiS->AccelLinearScratch = NULL;
134272b676d7Smrg	}
134372b676d7Smrg
134472b676d7Smrg	if(!pSiS->AccelLinearScratch) {
134572b676d7Smrg	   pSiS->RenderCallback = NULL;
134672b676d7Smrg	}
134772b676d7Smrg}
134872b676d7Smrg
134972b676d7Smrg#define RENDER_DELAY 15000
135072b676d7Smrg
135172b676d7Smrgstatic Bool
135272b676d7SmrgSiSAllocateLinear(ScrnInfoPtr pScrn, int sizeNeeded)
135372b676d7Smrg{
135472b676d7Smrg	SISPtr pSiS = SISPTR(pScrn);
135572b676d7Smrg
135672b676d7Smrg	pSiS->RenderTime = currentTime.milliseconds + RENDER_DELAY;
135772b676d7Smrg	pSiS->RenderCallback = SiSRenderCallback;
135872b676d7Smrg
135972b676d7Smrg	if(pSiS->AccelLinearScratch) {
136072b676d7Smrg	   if(pSiS->AccelLinearScratch->size >= sizeNeeded) {
136172b676d7Smrg	      return TRUE;
136272b676d7Smrg	   } else {
136372b676d7Smrg	      if(pSiS->alphaBlitBusy) {
136472b676d7Smrg	         pSiS->alphaBlitBusy = FALSE;
136572b676d7Smrg	         SiSIdle
136672b676d7Smrg	      }
136772b676d7Smrg	      if(xf86ResizeOffscreenLinear(pSiS->AccelLinearScratch, sizeNeeded)) {
136872b676d7Smrg		 return TRUE;
136972b676d7Smrg	      }
137072b676d7Smrg	      xf86FreeOffscreenLinear(pSiS->AccelLinearScratch);
137172b676d7Smrg	      pSiS->AccelLinearScratch = NULL;
137272b676d7Smrg	   }
137372b676d7Smrg	}
137472b676d7Smrg
137572b676d7Smrg	pSiS->AccelLinearScratch = xf86AllocateOffscreenLinear(
137672b676d7Smrg				 	pScrn->pScreen, sizeNeeded, 32,
137772b676d7Smrg				 	NULL, NULL, NULL);
137872b676d7Smrg
137972b676d7Smrg	return(pSiS->AccelLinearScratch != NULL);
138072b676d7Smrg}
138172b676d7Smrg
138272b676d7Smrgstatic Bool
138372b676d7SmrgSiSSetupForCPUToScreenAlphaTexture(ScrnInfoPtr pScrn,
138472b676d7Smrg			int op, CARD16 red, CARD16 green,
138572b676d7Smrg			CARD16 blue, CARD16 alpha,
138672b676d7Smrg#ifdef SISNEWRENDER
138772b676d7Smrg			CARD32 alphaType, CARD32 dstType,
138872b676d7Smrg#else
138972b676d7Smrg			int alphaType,
139072b676d7Smrg#endif
139172b676d7Smrg			CARD8 *alphaPtr,
139272b676d7Smrg			int alphaPitch, int width,
139372b676d7Smrg			int height, int	flags)
139472b676d7Smrg{
139572b676d7Smrg	SISPtr pSiS = SISPTR(pScrn);
139672b676d7Smrg	unsigned char *renderaccelarray;
139772b676d7Smrg	CARD32 *dstPtr;
139872b676d7Smrg	int    x, pitch, sizeNeeded;
139972b676d7Smrg	int    sbpp = pSiS->CurrentLayout.bitsPerPixel >> 3;
140072b676d7Smrg	int    sbppshift = sbpp >> 1;	/* 8->0, 16->1, 32->2 */
140172b676d7Smrg	CARD8  myalpha;
140272b676d7Smrg	Bool   docopy = TRUE;
140372b676d7Smrg
140472b676d7Smrg#ifdef ACCELDEBUG
140572b676d7Smrg	xf86DrvMsg(0, X_INFO, "AT(1): op %d t %x ARGB %x %x %x %x, w %d h %d pch %d\n",
140672b676d7Smrg		op, alphaType, /*dstType, */alpha, red, green, blue, width, height, alphaPitch);
140772b676d7Smrg#endif
140872b676d7Smrg
140972b676d7Smrg	if((width > 2048) || (height > 2048)) return FALSE;
141072b676d7Smrg
141172b676d7Smrg#ifdef SISVRAMQ
141272b676d7Smrg	if(op > SiSRenderOpsMAX) return FALSE;
141372b676d7Smrg	if(!SiSRenderOps[op])    return FALSE;
141472b676d7Smrg#else
141572b676d7Smrg	if(op != PictOpOver) return FALSE;
141672b676d7Smrg#endif
141772b676d7Smrg
141872b676d7Smrg	if(!((renderaccelarray = pSiS->RenderAccelArray)))
141972b676d7Smrg	   return FALSE;
142072b676d7Smrg
142172b676d7Smrg#ifdef ACCELDEBUG
142272b676d7Smrg	xf86DrvMsg(0, X_INFO, "AT(2): op %d t %x ARGB %x %x %x %x, w %d h %d pch %d\n",
142372b676d7Smrg		op, alphaType, alpha, red, green, blue, width, height, alphaPitch);
142472b676d7Smrg#endif
142572b676d7Smrg
142672b676d7Smrg	pitch = (width + 31) & ~31;
142772b676d7Smrg	sizeNeeded = (pitch << 2) * height; /* Source a8 (=8bit), expand to A8R8G8B8 (=32bit) */
142872b676d7Smrg
142972b676d7Smrg	if(!SiSAllocateLinear(pScrn, (sizeNeeded + sbpp - 1) >> sbppshift))
143072b676d7Smrg	   return FALSE;
143172b676d7Smrg
143272b676d7Smrg	red &= 0xff00;
143372b676d7Smrg	green &= 0xff00;
143472b676d7Smrg	blue &= 0xff00;
143572b676d7Smrg
143672b676d7Smrg#ifdef SISVRAMQ
143772b676d7Smrg	SiSSetupDSTColorDepth(pSiS->SiS310_AccelDepth);
143872b676d7Smrg	switch(op) {
143972b676d7Smrg	case PictOpClear:
144072b676d7Smrg#if XF86_VERSION_CURRENT >= XF86_VERSION_NUMERIC(4,2,0,0,0)
144172b676d7Smrg	case PictOpDisjointClear:
144272b676d7Smrg	case PictOpConjointClear:
144372b676d7Smrg#endif
144472b676d7Smrg	   SiSSetupPATFGDSTRect(0, pSiS->scrnOffset, DEV_HEIGHT)
144572b676d7Smrg	   /* SiSSetupROP(0x00) - is already 0 */
144672b676d7Smrg	   SiSSetupCMDFlag(PATFG)
144772b676d7Smrg	   docopy = FALSE;
144872b676d7Smrg	   break;
144972b676d7Smrg	case PictOpSrc:
145072b676d7Smrg#if XF86_VERSION_CURRENT >= XF86_VERSION_NUMERIC(4,2,0,0,0)
145172b676d7Smrg	case PictOpDisjointSrc:
145272b676d7Smrg	case PictOpConjointSrc:
145372b676d7Smrg#endif
145472b676d7Smrg	   SiSSetupSRCPitchDSTRect((pitch << 2), pSiS->scrnOffset, DEV_HEIGHT);
145572b676d7Smrg	   SiSSetupAlpha(0xff)
145672b676d7Smrg	   SiSSetupCMDFlag(ALPHA_BLEND | SRCVIDEO | A_NODESTALPHA)
145772b676d7Smrg	   break;
145872b676d7Smrg	case PictOpDst:
145972b676d7Smrg#if XF86_VERSION_CURRENT >= XF86_VERSION_NUMERIC(4,2,0,0,0)
146072b676d7Smrg	case PictOpDisjointDst:
146172b676d7Smrg	case PictOpConjointDst:
146272b676d7Smrg#endif
146372b676d7Smrg	   SiSSetupSRCPitchDSTRect((pitch << 2), pSiS->scrnOffset, DEV_HEIGHT);
146472b676d7Smrg	   SiSSetupAlpha(0x00)
146572b676d7Smrg	   SiSSetupCMDFlag(ALPHA_BLEND | SRCVIDEO | A_CONSTANTALPHA)
146672b676d7Smrg	   docopy = FALSE;
146772b676d7Smrg	   break;
146872b676d7Smrg	case PictOpOver:
146972b676d7Smrg	   SiSSetupSRCPitchDSTRect((pitch << 2), pSiS->scrnOffset, DEV_HEIGHT);
147072b676d7Smrg	   SiSSetupCMDFlag(ALPHA_BLEND | SRCVIDEO | A_PERPIXELALPHA)
147172b676d7Smrg	   break;
147272b676d7Smrg	}
147372b676d7Smrg        SiSSyncWP
147472b676d7Smrg#else
147572b676d7Smrg	SiSSetupDSTColorDepth(pSiS->DstColor);
147672b676d7Smrg	SiSSetupSRCPitch((pitch << 2));
147772b676d7Smrg	SiSSetupDSTRect(pSiS->scrnOffset, DEV_HEIGHT)
147872b676d7Smrg	SiSSetupROP(0)
147972b676d7Smrg	SiSSetupCMDFlag(ALPHA_BLEND | SRCVIDEO | A_PERPIXELALPHA | pSiS->SiS310_AccelDepth)
148072b676d7Smrg#endif
148172b676d7Smrg
148272b676d7Smrg	/* Don't need source for clear and dest */
148372b676d7Smrg	if(!docopy) return TRUE;
148472b676d7Smrg
148572b676d7Smrg	dstPtr = (CARD32*)(pSiS->FbBase + (pSiS->AccelLinearScratch->offset << sbppshift));
148672b676d7Smrg
148772b676d7Smrg	if(pSiS->alphaBlitBusy) {
148872b676d7Smrg	   pSiS->alphaBlitBusy = FALSE;
148972b676d7Smrg	   SiSIdle
149072b676d7Smrg	}
149172b676d7Smrg
149272b676d7Smrg	if(alpha == 0xffff) {
149372b676d7Smrg
149472b676d7Smrg	   while(height--) {
149572b676d7Smrg	      for(x = 0; x < width; x++) {
149672b676d7Smrg	         myalpha = alphaPtr[x];
149772b676d7Smrg	         dstPtr[x] = (renderaccelarray[red + myalpha] << 16)  |
149872b676d7Smrg			     (renderaccelarray[green + myalpha] << 8) |
149972b676d7Smrg			     renderaccelarray[blue + myalpha]         |
150072b676d7Smrg			     myalpha << 24;
150172b676d7Smrg	      }
150272b676d7Smrg	      dstPtr += pitch;
150372b676d7Smrg	      alphaPtr += alphaPitch;
150472b676d7Smrg	   }
150572b676d7Smrg
150672b676d7Smrg	} else {
150772b676d7Smrg
150872b676d7Smrg	   alpha &= 0xff00;
150972b676d7Smrg
151072b676d7Smrg	   while(height--) {
151172b676d7Smrg	      for(x = 0; x < width; x++) {
151272b676d7Smrg	         myalpha = alphaPtr[x];
151372b676d7Smrg	         dstPtr[x] = (renderaccelarray[alpha + myalpha] << 24) |
151472b676d7Smrg			     (renderaccelarray[red + myalpha] << 16)   |
151572b676d7Smrg			     (renderaccelarray[green + myalpha] << 8)  |
151672b676d7Smrg			     renderaccelarray[blue + myalpha];
151772b676d7Smrg	      }
151872b676d7Smrg	      dstPtr += pitch;
151972b676d7Smrg	      alphaPtr += alphaPitch;
152072b676d7Smrg	   }
152172b676d7Smrg
152272b676d7Smrg	}
152372b676d7Smrg
152472b676d7Smrg	return TRUE;
152572b676d7Smrg}
152672b676d7Smrg
152772b676d7Smrgstatic Bool
152872b676d7SmrgSiSSetupForCPUToScreenTexture(ScrnInfoPtr pScrn,
152972b676d7Smrg			int op,
153072b676d7Smrg#ifdef SISNEWRENDER
153172b676d7Smrg			CARD32 texType, CARD32 dstType,
153272b676d7Smrg#else
153372b676d7Smrg			int texType,
153472b676d7Smrg#endif
153572b676d7Smrg			CARD8 *texPtr,
153672b676d7Smrg			int texPitch, int width,
153772b676d7Smrg			int height, int	flags)
153872b676d7Smrg{
153972b676d7Smrg	SISPtr  pSiS = SISPTR(pScrn);
154072b676d7Smrg	CARD8   *dst;
154172b676d7Smrg	int     pitch, sizeNeeded;
154272b676d7Smrg	int     sbpp = pSiS->CurrentLayout.bitsPerPixel >> 3;
154372b676d7Smrg	int     sbppshift = sbpp >> 1;	          	  /* 8->0, 16->1, 32->2 */
154472b676d7Smrg	int     bppshift = PICT_FORMAT_BPP(texType) >> 4; /* 8->0, 16->1, 32->2 */
154572b676d7Smrg	Bool    docopy = TRUE;
154672b676d7Smrg
154772b676d7Smrg#ifdef ACCELDEBUG
154872b676d7Smrg	xf86DrvMsg(0, X_INFO, "T: type %x op %d w %d h %d T-pitch %d\n",
154972b676d7Smrg		texType, op, width, height, texPitch);
155072b676d7Smrg#endif
155172b676d7Smrg
155272b676d7Smrg#ifdef SISVRAMQ
155372b676d7Smrg	if(op > SiSRenderOpsMAX) return FALSE;
155472b676d7Smrg	if(!SiSRenderOps[op])    return FALSE;
155572b676d7Smrg#else
155672b676d7Smrg	if(op != PictOpOver) return FALSE;
155772b676d7Smrg#endif
155872b676d7Smrg
155972b676d7Smrg	if((width > 2048) || (height > 2048)) return FALSE;
156072b676d7Smrg
156172b676d7Smrg	pitch = (width + 31) & ~31;
156272b676d7Smrg	sizeNeeded = (pitch << bppshift) * height;
156372b676d7Smrg
156472b676d7Smrg#ifdef ACCELDEBUG
156572b676d7Smrg	xf86DrvMsg(0, X_INFO, "T: %x op %x w %d h %d T-pitch %d size %d (%d %d %d)\n",
156672b676d7Smrg		texType, op, width, height, texPitch, sizeNeeded, sbpp, sbppshift, bppshift);
156772b676d7Smrg#endif
156872b676d7Smrg
156972b676d7Smrg	if(!SiSAllocateLinear(pScrn, (sizeNeeded + sbpp - 1) >> sbppshift))
157072b676d7Smrg	   return FALSE;
157172b676d7Smrg
157272b676d7Smrg	width <<= bppshift;  /* -> bytes (for engine and memcpy) */
157372b676d7Smrg	pitch <<= bppshift;  /* -> bytes */
157472b676d7Smrg
157572b676d7Smrg#ifdef SISVRAMQ
157672b676d7Smrg	SiSSetupDSTColorDepth(pSiS->SiS310_AccelDepth);
157772b676d7Smrg	switch(op) {
157872b676d7Smrg	case PictOpClear:
157972b676d7Smrg#if XF86_VERSION_CURRENT >= XF86_VERSION_NUMERIC(4,2,0,0,0)
158072b676d7Smrg	case PictOpDisjointClear:
158172b676d7Smrg	case PictOpConjointClear:
158272b676d7Smrg#endif
158372b676d7Smrg	   SiSSetupPATFGDSTRect(0, pSiS->scrnOffset, DEV_HEIGHT)
158472b676d7Smrg	   /* SiSSetupROP(0x00) - is already zero */
158572b676d7Smrg	   SiSSetupCMDFlag(PATFG)
158672b676d7Smrg	   docopy = FALSE;
158772b676d7Smrg	   break;
158872b676d7Smrg	case PictOpSrc:
158972b676d7Smrg#if XF86_VERSION_CURRENT >= XF86_VERSION_NUMERIC(4,2,0,0,0)
159072b676d7Smrg	case PictOpDisjointSrc:
159172b676d7Smrg	case PictOpConjointSrc:
159272b676d7Smrg#endif
159372b676d7Smrg	   SiSSetupSRCPitchDSTRect(pitch, pSiS->scrnOffset, DEV_HEIGHT);
159472b676d7Smrg	   SiSSetupAlpha(0xff)
159572b676d7Smrg	   SiSSetupCMDFlag(ALPHA_BLEND | SRCVIDEO | A_NODESTALPHA)
159672b676d7Smrg	   break;
159772b676d7Smrg	case PictOpDst:
159872b676d7Smrg#if XF86_VERSION_CURRENT >= XF86_VERSION_NUMERIC(4,2,0,0,0)
159972b676d7Smrg	case PictOpDisjointDst:
160072b676d7Smrg	case PictOpConjointDst:
160172b676d7Smrg#endif
160272b676d7Smrg	   SiSSetupSRCPitchDSTRect(pitch, pSiS->scrnOffset, DEV_HEIGHT);
160372b676d7Smrg	   SiSSetupAlpha(0x00)
160472b676d7Smrg	   SiSSetupCMDFlag(ALPHA_BLEND | SRCVIDEO | A_CONSTANTALPHA)
160572b676d7Smrg	   docopy = FALSE;
160672b676d7Smrg	   break;
160772b676d7Smrg	case PictOpOver:
160872b676d7Smrg	   SiSSetupSRCPitchDSTRect(pitch, pSiS->scrnOffset, DEV_HEIGHT);
160972b676d7Smrg	   SiSSetupAlpha(0x00)
161072b676d7Smrg	   SiSSetupCMDFlag(ALPHA_BLEND | SRCVIDEO | A_PERPIXELALPHA)
161172b676d7Smrg	   break;
161272b676d7Smrg	default:
161372b676d7Smrg	   return FALSE;
161472b676d7Smrg 	}
161572b676d7Smrg        SiSSyncWP
161672b676d7Smrg#else
161772b676d7Smrg	SiSSetupDSTColorDepth(pSiS->DstColor);
161872b676d7Smrg	SiSSetupSRCPitch(pitch);
161972b676d7Smrg	SiSSetupDSTRect(pSiS->scrnOffset, DEV_HEIGHT)
162072b676d7Smrg	SiSSetupAlpha(0x00)
162172b676d7Smrg	SiSSetupCMDFlag(ALPHA_BLEND | SRCVIDEO | A_PERPIXELALPHA | pSiS->SiS310_AccelDepth)
162272b676d7Smrg#endif
162372b676d7Smrg
162472b676d7Smrg	/* Don't need source for clear and dest */
162572b676d7Smrg	if(!docopy) return TRUE;
162672b676d7Smrg
162772b676d7Smrg	dst = (CARD8*)(pSiS->FbBase + (pSiS->AccelLinearScratch->offset << sbppshift));
162872b676d7Smrg
162972b676d7Smrg	if(pSiS->alphaBlitBusy) {
163072b676d7Smrg	   pSiS->alphaBlitBusy = FALSE;
163172b676d7Smrg	   SiSIdle
163272b676d7Smrg	}
163372b676d7Smrg
163472b676d7Smrg	while(height--) {
163572b676d7Smrg	   memcpy(dst, texPtr, width);
163672b676d7Smrg	   texPtr += texPitch;
163772b676d7Smrg	   dst += pitch;
163872b676d7Smrg	}
163972b676d7Smrg
164072b676d7Smrg	return TRUE;
164172b676d7Smrg}
164272b676d7Smrg
164372b676d7Smrgstatic void
164472b676d7SmrgSiSSubsequentCPUToScreenTexture(ScrnInfoPtr pScrn,
164572b676d7Smrg			int dst_x, int dst_y,
164672b676d7Smrg			int src_x, int src_y,
164772b676d7Smrg			int width, int height)
164872b676d7Smrg{
164972b676d7Smrg	SISPtr pSiS = SISPTR(pScrn);
165072b676d7Smrg	CARD32 srcbase, dstbase;
165172b676d7Smrg
165272b676d7Smrg	srcbase = pSiS->AccelLinearScratch->offset << 1;
165372b676d7Smrg	if(pScrn->bitsPerPixel == 32) srcbase <<= 1;
165472b676d7Smrg
165572b676d7Smrg#ifdef ACCELDEBUG
165672b676d7Smrg	xf86DrvMsg(0, X_INFO, "FIRE: scrbase %x dx %d dy %d w %d h %d\n",
165772b676d7Smrg		srcbase, dst_x, dst_y, width, height);
165872b676d7Smrg#endif
165972b676d7Smrg
166072b676d7Smrg	dstbase = 0;
166172b676d7Smrg	if((dst_y >= pScrn->virtualY) || (dst_y >= 2048)) {
166272b676d7Smrg	   dstbase = pSiS->scrnOffset * dst_y;
166372b676d7Smrg	   dst_y = 0;
166472b676d7Smrg	}
166572b676d7Smrg
166672b676d7Smrg	srcbase += FBOFFSET;
166772b676d7Smrg	dstbase += FBOFFSET;
166872b676d7Smrg
166972b676d7Smrg#ifdef SISVRAMQ
167072b676d7Smrg	SiSCheckQueue(16 * 3)
167172b676d7Smrg	SiSSetupSRCDSTBase(srcbase,dstbase);
167272b676d7Smrg	SiSSetupSRCDSTXY(src_x, src_y, dst_x, dst_y)
167372b676d7Smrg	SiSSetRectDoCMD(width,height)
167472b676d7Smrg#else
167572b676d7Smrg	SiSSetupSRCBase(srcbase);
167672b676d7Smrg	SiSSetupDSTBase(dstbase);
167772b676d7Smrg	SiSSetupRect(width, height)
167872b676d7Smrg	SiSSetupSRCXY(src_x, src_y)
167972b676d7Smrg	SiSSetupDSTXY(dst_x, dst_y)
168072b676d7Smrg	SiSDoCMD
168172b676d7Smrg#endif
168272b676d7Smrg	pSiS->alphaBlitBusy = TRUE;
168372b676d7Smrg}
168472b676d7Smrg#endif
168572b676d7Smrg#endif
168672b676d7Smrg
168772b676d7Smrg#endif /* XAA */
168872b676d7Smrg
168972b676d7Smrg#ifdef SIS_USE_EXA  /* ---------------------------- EXA -------------------------- */
169072b676d7Smrg
169172b676d7Smrgstatic void
169272b676d7SmrgSiSEXASync(ScreenPtr pScreen, int marker)
169372b676d7Smrg{
169472b676d7Smrg	SISPtr pSiS = SISPTR(xf86Screens[pScreen->myNum]);
169572b676d7Smrg
169672b676d7Smrg	SiSIdle
169772b676d7Smrg}
169872b676d7Smrg
169972b676d7Smrgstatic Bool
170072b676d7SmrgSiSPrepareSolid(PixmapPtr pPixmap, int alu, Pixel planemask, Pixel fg)
170172b676d7Smrg{
170272b676d7Smrg	ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
170372b676d7Smrg	SISPtr pSiS = SISPTR(pScrn);
170472b676d7Smrg
170572b676d7Smrg	/* Planemask not supported */
170672b676d7Smrg	if((planemask & ((1 << pPixmap->drawable.depth) - 1)) !=
170772b676d7Smrg				(1 << pPixmap->drawable.depth) - 1) {
170872b676d7Smrg	   return FALSE;
170972b676d7Smrg	}
171072b676d7Smrg
171172b676d7Smrg	if((pPixmap->drawable.bitsPerPixel != 8) &&
171272b676d7Smrg	   (pPixmap->drawable.bitsPerPixel != 16) &&
171372b676d7Smrg	   (pPixmap->drawable.bitsPerPixel != 32))
171472b676d7Smrg	   return FALSE;
171572b676d7Smrg
171672b676d7Smrg	if(pSiS->disablecolorkeycurrent) {
171772b676d7Smrg	   if((CARD32)fg == pSiS->colorKey) {
171872b676d7Smrg	      alu = 5;  /* NOOP */
171972b676d7Smrg	   }
172072b676d7Smrg	}
172172b676d7Smrg
172272b676d7Smrg	/* Check that the pitch matches the hardware's requirements. Should
172372b676d7Smrg	 * never be a problem due to pixmapPitchAlign and fbScreenInit.
172472b676d7Smrg	 */
172572b676d7Smrg	if(exaGetPixmapPitch(pPixmap) & 3)
172672b676d7Smrg	   return FALSE;
172772b676d7Smrg
172872b676d7Smrg	SiSSetupDSTColorDepth((pPixmap->drawable.bitsPerPixel >> 4) << 16);
172972b676d7Smrg	SiSCheckQueue(16 * 1);
173072b676d7Smrg	SiSSetupPATFGDSTRect(fg, exaGetPixmapPitch(pPixmap), DEV_HEIGHT)
173172b676d7Smrg	SiSSetupROP(SiSGetPatternROP(alu))
173272b676d7Smrg	SiSSetupCMDFlag(PATFG)
173372b676d7Smrg	SiSSyncWP
173472b676d7Smrg
173572b676d7Smrg	pSiS->fillDstBase = (CARD32)exaGetPixmapOffset(pPixmap) + FBOFFSET;
173672b676d7Smrg
173772b676d7Smrg	return TRUE;
173872b676d7Smrg}
173972b676d7Smrg
174072b676d7Smrgstatic void
174172b676d7SmrgSiSSolid(PixmapPtr pPixmap, int x1, int y1, int x2, int y2)
174272b676d7Smrg{
174372b676d7Smrg	ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
174472b676d7Smrg	SISPtr pSiS = SISPTR(pScrn);
174572b676d7Smrg
174672b676d7Smrg	/* SiSSetupCMDFlag(BITBLT)  - BITBLT = 0 */
174772b676d7Smrg
174872b676d7Smrg	SiSCheckQueue(16 * 2)
174972b676d7Smrg	SiSSetupDSTXYRect(x1, y1, x2-x1, y2-y1)
175072b676d7Smrg	SiSSetupDSTBaseDoCMD(pSiS->fillDstBase)
175172b676d7Smrg}
175272b676d7Smrg
175372b676d7Smrgstatic void
175472b676d7SmrgSiSDoneSolid(PixmapPtr pPixmap)
175572b676d7Smrg{
175672b676d7Smrg}
175772b676d7Smrg
175872b676d7Smrgstatic Bool
175972b676d7SmrgSiSPrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, int xdir, int ydir,
176072b676d7Smrg					int alu, Pixel planemask)
176172b676d7Smrg{
176272b676d7Smrg	ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum];
176372b676d7Smrg	SISPtr pSiS = SISPTR(pScrn);
176472b676d7Smrg	CARD32 srcbase, dstbase;
176572b676d7Smrg
176672b676d7Smrg	/* Planemask not supported */
176772b676d7Smrg	if((planemask & ((1 << pSrcPixmap->drawable.depth) - 1)) !=
176872b676d7Smrg				(1 << pSrcPixmap->drawable.depth) - 1) {
176972b676d7Smrg	   return FALSE;
177072b676d7Smrg	}
177172b676d7Smrg
177272b676d7Smrg	if((pDstPixmap->drawable.bitsPerPixel != 8) &&
177372b676d7Smrg	   (pDstPixmap->drawable.bitsPerPixel != 16) &&
177472b676d7Smrg	   (pDstPixmap->drawable.bitsPerPixel != 32))
177572b676d7Smrg	   return FALSE;
177672b676d7Smrg
177772b676d7Smrg	/* Check that the pitch matches the hardware's requirements. Should
177872b676d7Smrg	 * never be a problem due to pixmapPitchAlign and fbScreenInit.
177972b676d7Smrg	 */
178072b676d7Smrg	if(exaGetPixmapPitch(pSrcPixmap) & 3)
178172b676d7Smrg	   return FALSE;
178272b676d7Smrg	if(exaGetPixmapPitch(pDstPixmap) & 3)
178372b676d7Smrg	   return FALSE;
178472b676d7Smrg
178572b676d7Smrg	srcbase = (CARD32)exaGetPixmapOffset(pSrcPixmap) + FBOFFSET;
178672b676d7Smrg
178772b676d7Smrg	dstbase = (CARD32)exaGetPixmapOffset(pDstPixmap) + FBOFFSET;
178872b676d7Smrg
178972b676d7Smrg	/* TODO: Will there eventually be overlapping blits?
179072b676d7Smrg	 * If so, good night. Then we must calculate new base addresses
179172b676d7Smrg	 * which are identical for source and dest, otherwise
179272b676d7Smrg	 * the chips direction-logic will fail. Certainly funny
179372b676d7Smrg	 * to re-calculate x and y then...
179472b676d7Smrg	 */
179572b676d7Smrg
179672b676d7Smrg	SiSSetupDSTColorDepth((pDstPixmap->drawable.bitsPerPixel >> 4) << 16);
179772b676d7Smrg	SiSCheckQueue(16 * 3);
179872b676d7Smrg	SiSSetupSRCPitchDSTRect(exaGetPixmapPitch(pSrcPixmap),
179972b676d7Smrg					exaGetPixmapPitch(pDstPixmap), DEV_HEIGHT)
180072b676d7Smrg	SiSSetupROP(SiSGetCopyROP(alu))
180172b676d7Smrg	SiSSetupSRCDSTBase(srcbase, dstbase)
180272b676d7Smrg	SiSSyncWP
180372b676d7Smrg
180472b676d7Smrg	return TRUE;
180572b676d7Smrg}
180672b676d7Smrg
180772b676d7Smrgstatic void
180872b676d7SmrgSiSCopy(PixmapPtr pDstPixmap, int srcX, int srcY, int dstX, int dstY, int width, int height)
180972b676d7Smrg{
181072b676d7Smrg	ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum];
181172b676d7Smrg	SISPtr pSiS = SISPTR(pScrn);
181272b676d7Smrg
181372b676d7Smrg	SiSCheckQueue(16 * 2);
181472b676d7Smrg	SiSSetupSRCDSTXY(srcX, srcY, dstX, dstY)
181572b676d7Smrg	SiSSetRectDoCMD(width, height)
181672b676d7Smrg}
181772b676d7Smrg
181872b676d7Smrgstatic void
181972b676d7SmrgSiSDoneCopy(PixmapPtr pDstPixmap)
182072b676d7Smrg{
182172b676d7Smrg}
182272b676d7Smrg
182372b676d7Smrg#ifdef SIS_HAVE_COMPOSITE
182472b676d7Smrgstatic Bool
182572b676d7SmrgSiSCheckComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture,
182672b676d7Smrg				PicturePtr pDstPicture)
182772b676d7Smrg{
182872b676d7Smrg	ScrnInfoPtr pScrn = xf86Screens[pDstPicture->pDrawable->pScreen->myNum];
182972b676d7Smrg	SISPtr pSiS = SISPTR(pScrn);
183072b676d7Smrg
183172b676d7Smrg	xf86DrvMsg(0, 0, "CC: %d Src %x (fi %d ca %d) Msk %x (%d %d) Dst %x (%d %d)\n",
183272b676d7Smrg		op, pSrcPicture->format, pSrcPicture->filter, pSrcPicture->componentAlpha,
183372b676d7Smrg		pMaskPicture ? pMaskPicture->format : 0x2011, pMaskPicture ? pMaskPicture->filter : -1,
183472b676d7Smrg			pMaskPicture ? pMaskPicture->componentAlpha : -1,
183572b676d7Smrg		pDstPicture->format, pDstPicture->filter, pDstPicture->componentAlpha);
183672b676d7Smrg
183772b676d7Smrg	if(pSrcPicture->transform || (pMaskPicture && pMaskPicture->transform) || pDstPicture->transform) {
183872b676d7Smrg		xf86DrvMsg(0, 0, "CC: src tr %p msk %p dst %p  !!!!!!!!!!!!!!!\n",
183972b676d7Smrg			pSrcPicture->transform,
184072b676d7Smrg			pMaskPicture ? pMaskPicture->transform : 0,
184172b676d7Smrg			pDstPicture->transform);
184272b676d7Smrg        }
184372b676d7Smrg
184472b676d7Smrg	return FALSE;
184572b676d7Smrg}
184672b676d7Smrg
184772b676d7Smrgstatic Bool
184872b676d7SmrgSiSPrepareComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture,
184972b676d7Smrg				PicturePtr pDstPicture, PixmapPtr pSrc, PixmapPtr pMask, PixmapPtr pDst)
185072b676d7Smrg{
185172b676d7Smrg#if 0
185272b676d7Smrg	ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum];
185372b676d7Smrg	SISPtr pSiS = SISPTR(pScrn);
185472b676d7Smrg#endif
185572b676d7Smrg	return FALSE;
185672b676d7Smrg}
185772b676d7Smrg
185872b676d7Smrgstatic void
185972b676d7SmrgSiSComposite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY, int dstX, int dstY,
186072b676d7Smrg				int width, int height)
186172b676d7Smrg{
186272b676d7Smrg#if 0
186372b676d7Smrg	ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum];
186472b676d7Smrg	SISPtr pSiS = SISPTR(pScrn);
186572b676d7Smrg#endif
186672b676d7Smrg}
186772b676d7Smrg
186872b676d7Smrgstatic void
186972b676d7SmrgSiSDoneComposite(PixmapPtr pDst)
187072b676d7Smrg{
187172b676d7Smrg}
187272b676d7Smrg#endif
187372b676d7Smrg
187472b676d7SmrgBool
187572b676d7SmrgSiSUploadToScreen(PixmapPtr pDst, int x, int y, int w, int h, char *src, int src_pitch)
187672b676d7Smrg{
187772b676d7Smrg	ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum];
187872b676d7Smrg	SISPtr pSiS = SISPTR(pScrn);
187972b676d7Smrg	unsigned char *dst = pDst->devPrivate.ptr;
188072b676d7Smrg	int dst_pitch = exaGetPixmapPitch(pDst);
188172b676d7Smrg
188272b676d7Smrg	(pSiS->SyncAccel)(pScrn);
188372b676d7Smrg
188472b676d7Smrg	if(pDst->drawable.bitsPerPixel < 8)
188572b676d7Smrg	   return FALSE;
188672b676d7Smrg
188772b676d7Smrg	dst += (x * pDst->drawable.bitsPerPixel / 8) + (y * src_pitch);
188872b676d7Smrg	while(h--) {
188972b676d7Smrg	   SiSMemCopyToVideoRam(pSiS, dst, (unsigned char *)src,
189072b676d7Smrg				(w * pDst->drawable.bitsPerPixel / 8));
189172b676d7Smrg	   src += src_pitch;
189272b676d7Smrg	   dst += dst_pitch;
189372b676d7Smrg	}
189472b676d7Smrg
189572b676d7Smrg	return TRUE;
189672b676d7Smrg}
189772b676d7Smrg
189872b676d7SmrgBool
189972b676d7SmrgSiSUploadToScratch(PixmapPtr pSrc, PixmapPtr pDst)
190072b676d7Smrg{
190172b676d7Smrg	ScrnInfoPtr pScrn = xf86Screens[pSrc->drawable.pScreen->myNum];
190272b676d7Smrg	SISPtr pSiS = SISPTR(pScrn);
190372b676d7Smrg	unsigned char *src, *dst;
190472b676d7Smrg	int src_pitch = exaGetPixmapPitch(pSrc);
190572b676d7Smrg	int dst_pitch, size, w, h, bytes;
190672b676d7Smrg
190772b676d7Smrg	w = pSrc->drawable.width;
190872b676d7Smrg
190972b676d7Smrg	dst_pitch = ((w * (pSrc->drawable.bitsPerPixel >> 3)) +
191072b676d7Smrg		     pSiS->EXADriverPtr->pixmapPitchAlign - 1) &
191172b676d7Smrg		    ~(pSiS->EXADriverPtr->pixmapPitchAlign - 1);
191272b676d7Smrg
191372b676d7Smrg	size = dst_pitch * pSrc->drawable.height;
191472b676d7Smrg
191572b676d7Smrg	if(size > pSiS->exa_scratch->size)
191672b676d7Smrg	   return FALSE;
191772b676d7Smrg
191872b676d7Smrg	pSiS->exa_scratch_next = (pSiS->exa_scratch_next +
191972b676d7Smrg				  pSiS->EXADriverPtr->pixmapOffsetAlign - 1) &
192072b676d7Smrg				  ~(pSiS->EXADriverPtr->pixmapOffsetAlign - 1);
192172b676d7Smrg
192272b676d7Smrg	if(pSiS->exa_scratch_next + size >
192372b676d7Smrg	   pSiS->exa_scratch->offset + pSiS->exa_scratch->size) {
192472b676d7Smrg	   (pSiS->EXADriverPtr->WaitMarker)(pSrc->drawable.pScreen, 0);
192572b676d7Smrg	   pSiS->exa_scratch_next = pSiS->exa_scratch->offset;
192672b676d7Smrg	}
192772b676d7Smrg
192872b676d7Smrg	memcpy(pDst, pSrc, sizeof(*pDst));
192972b676d7Smrg	pDst->devKind = dst_pitch;
193072b676d7Smrg	pDst->devPrivate.ptr = pSiS->EXADriverPtr->memoryBase + pSiS->exa_scratch_next;
193172b676d7Smrg
193272b676d7Smrg	pSiS->exa_scratch_next += size;
193372b676d7Smrg
193472b676d7Smrg	src = pSrc->devPrivate.ptr;
193572b676d7Smrg	src_pitch = exaGetPixmapPitch(pSrc);
193672b676d7Smrg	dst = pDst->devPrivate.ptr;
193772b676d7Smrg
193872b676d7Smrg	bytes = (src_pitch < dst_pitch) ? src_pitch : dst_pitch;
193972b676d7Smrg
194072b676d7Smrg	h = pSrc->drawable.height;
194172b676d7Smrg
194272b676d7Smrg	(pSiS->SyncAccel)(pScrn);
194372b676d7Smrg
194472b676d7Smrg	while(h--) {
194572b676d7Smrg	   SiSMemCopyToVideoRam(pSiS, dst, src, size);
194672b676d7Smrg	   src += src_pitch;
194772b676d7Smrg	   dst += dst_pitch;
194872b676d7Smrg	}
194972b676d7Smrg
195072b676d7Smrg	return TRUE;
195172b676d7Smrg}
195272b676d7Smrg
195372b676d7SmrgBool
195472b676d7SmrgSiSDownloadFromScreen(PixmapPtr pSrc, int x, int y, int w, int h, char *dst, int dst_pitch)
195572b676d7Smrg{
195672b676d7Smrg	ScrnInfoPtr pScrn = xf86Screens[pSrc->drawable.pScreen->myNum];
195772b676d7Smrg	SISPtr pSiS = SISPTR(pScrn);
195872b676d7Smrg	unsigned char *src = pSrc->devPrivate.ptr;
195972b676d7Smrg	int src_pitch = exaGetPixmapPitch(pSrc);
196072b676d7Smrg	int size = src_pitch < dst_pitch ? src_pitch : dst_pitch;
196172b676d7Smrg
196272b676d7Smrg	(pSiS->SyncAccel)(pScrn);
196372b676d7Smrg
196472b676d7Smrg	if(pSrc->drawable.bitsPerPixel < 8)
196572b676d7Smrg	   return FALSE;
196672b676d7Smrg
196772b676d7Smrg	src += (x * pSrc->drawable.bitsPerPixel / 8) + (y * src_pitch);
196872b676d7Smrg	while(h--) {
196972b676d7Smrg	   SiSMemCopyFromVideoRam(pSiS, (unsigned char *)dst, src, size);
197072b676d7Smrg	   src += src_pitch;
197172b676d7Smrg	   dst += dst_pitch;
197272b676d7Smrg	}
197372b676d7Smrg
197472b676d7Smrg	return TRUE;
197572b676d7Smrg}
197672b676d7Smrg#endif /* EXA */
197772b676d7Smrg
197872b676d7Smrg/* Helper for xv video blitter */
197972b676d7Smrg
198072b676d7Smrg#ifdef INCL_YUV_BLIT_ADAPTOR
198172b676d7Smrgvoid
198272b676d7SmrgSISWriteBlitPacket(SISPtr pSiS, CARD32 *packet)
198372b676d7Smrg{
198472b676d7Smrg	CARD32 dummybuf;
198572b676d7Smrg
198672b676d7Smrg	SiSWritePacketPart(packet[0], packet[1], packet[2], packet[3]);
198772b676d7Smrg	SiSWritePacketPart(packet[4], packet[5], packet[6], packet[7]);
198872b676d7Smrg	SiSWritePacketPart(packet[8], packet[9], packet[10], packet[11]);
198972b676d7Smrg	SiSWritePacketPart(packet[12], packet[13], packet[14], packet[15]);
199072b676d7Smrg	SiSWritePacketPart(packet[16], packet[17], packet[18], packet[19]);
199172b676d7Smrg	SiSSyncWP;
199272b676d7Smrg	(void)dummybuf; /* Suppress compiler warning */
199372b676d7Smrg}
199472b676d7Smrg#endif
199572b676d7Smrg
199672b676d7Smrg/* For DGA usage */
199772b676d7Smrg
199872b676d7Smrgstatic void
199972b676d7SmrgSiSDGAFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h, int color)
200072b676d7Smrg{
200172b676d7Smrg	SiSSetupForSolidFill(pScrn, color, GXcopy, ~0);
200272b676d7Smrg	SiSSubsequentSolidFillRect(pScrn, x, y, w, h);
200372b676d7Smrg}
200472b676d7Smrg
200572b676d7Smrgstatic void
200672b676d7SmrgSiSDGABlitRect(ScrnInfoPtr pScrn, int srcx, int srcy, int dstx, int dsty, int w, int h, int color)
200772b676d7Smrg{
200872b676d7Smrg	/* Don't need xdir, ydir */
200972b676d7Smrg	SiSSetupForScreenToScreenCopy(pScrn, 0, 0, GXcopy, (CARD32)~0, color);
201072b676d7Smrg	SiSSubsequentScreenToScreenCopy(pScrn, srcx, srcy, dstx, dsty, w, h);
201172b676d7Smrg}
201272b676d7Smrg
201372b676d7Smrg/* Initialisation */
201472b676d7Smrg
201572b676d7SmrgBool
201672b676d7SmrgSiS315AccelInit(ScreenPtr pScreen)
201772b676d7Smrg{
201872b676d7Smrg	ScrnInfoPtr     pScrn = xf86Screens[pScreen->myNum];
201972b676d7Smrg	SISPtr          pSiS = SISPTR(pScrn);
202072b676d7Smrg#ifdef SIS_USE_XAA
202172b676d7Smrg	XAAInfoRecPtr   infoPtr = NULL;
202272b676d7Smrg	int		topFB, reservedFbSize, usableFbSize;
202372b676d7Smrg	BoxRec          Avail;
202472b676d7Smrg#ifdef CTSCE
202572b676d7Smrg	unsigned char   *AvailBufBase;
202672b676d7Smrg#ifndef CTSCE_DIRECT
202772b676d7Smrg	int             i;
202872b676d7Smrg#endif
202972b676d7Smrg#endif
203072b676d7Smrg#endif /* XAA */
203172b676d7Smrg
203272b676d7Smrg	pSiS->ColorExpandBufferNumber = 0;
203372b676d7Smrg	pSiS->PerColorExpandBufferSize = 0;
203472b676d7Smrg	pSiS->RenderAccelArray = NULL;
203572b676d7Smrg#ifdef SIS_USE_XAA
203672b676d7Smrg	pSiS->AccelInfoPtr = NULL;
203772b676d7Smrg#endif
203872b676d7Smrg#ifdef SIS_USE_EXA
203972b676d7Smrg	pSiS->EXADriverPtr = NULL;
204072b676d7Smrg	pSiS->exa_scratch = NULL;
204172b676d7Smrg#endif
204272b676d7Smrg
204372b676d7Smrg	if((pScrn->bitsPerPixel != 8)  &&
204472b676d7Smrg	   (pScrn->bitsPerPixel != 16) &&
204572b676d7Smrg	   (pScrn->bitsPerPixel != 32)) {
204672b676d7Smrg	   pSiS->NoAccel = TRUE;
204772b676d7Smrg	}
204872b676d7Smrg
204972b676d7Smrg	if(!pSiS->NoAccel) {
205072b676d7Smrg#ifdef SIS_USE_XAA
205172b676d7Smrg	   if(!pSiS->useEXA) {
205272b676d7Smrg	      pSiS->AccelInfoPtr = infoPtr = XAACreateInfoRec();
205372b676d7Smrg	      if(!infoPtr) pSiS->NoAccel = TRUE;
205472b676d7Smrg	   }
205572b676d7Smrg#endif
205672b676d7Smrg#ifdef SIS_USE_EXA
205772b676d7Smrg	   if(pSiS->useEXA) {
205872b676d7Smrg	      if(!(pSiS->EXADriverPtr = exaDriverAlloc())) {
205972b676d7Smrg		 pSiS->NoAccel = TRUE;
206072b676d7Smrg		 pSiS->NoXvideo = TRUE; /* No fbmem manager -> no xv */
206172b676d7Smrg	      }
206272b676d7Smrg	   }
206372b676d7Smrg#endif
206472b676d7Smrg	}
206572b676d7Smrg
206672b676d7Smrg	if(!pSiS->NoAccel) {
206772b676d7Smrg
206872b676d7Smrg	   SiSInitializeAccelerator(pScrn);
206972b676d7Smrg
207072b676d7Smrg	   pSiS->InitAccel = SiSInitializeAccelerator;
207172b676d7Smrg	   pSiS->SyncAccel = SiSSyncAccel;
207272b676d7Smrg	   pSiS->FillRect  = SiSDGAFillRect;
207372b676d7Smrg	   pSiS->BlitRect  = SiSDGABlitRect;
207472b676d7Smrg
207572b676d7Smrg#ifdef SIS_USE_XAA	/* ----------------------- XAA ----------------------- */
207672b676d7Smrg	   if(!pSiS->useEXA) {
207772b676d7Smrg
207872b676d7Smrg	      infoPtr->Flags = LINEAR_FRAMEBUFFER |
207972b676d7Smrg			       OFFSCREEN_PIXMAPS |
208072b676d7Smrg			       PIXMAP_CACHE;
208172b676d7Smrg
208272b676d7Smrg	      /* sync */
208372b676d7Smrg	      infoPtr->Sync = SiSSync;
208472b676d7Smrg
208572b676d7Smrg	      /* BitBlt */
208672b676d7Smrg	      infoPtr->SetupForScreenToScreenCopy = SiSSetupForScreenToScreenCopy;
208772b676d7Smrg	      infoPtr->SubsequentScreenToScreenCopy = SiSSubsequentScreenToScreenCopy;
208872b676d7Smrg	      infoPtr->ScreenToScreenCopyFlags = NO_PLANEMASK | TRANSPARENCY_GXCOPY_ONLY;
208972b676d7Smrg
209072b676d7Smrg	      /* solid fills */
209172b676d7Smrg	      infoPtr->SetupForSolidFill = SiSSetupForSolidFill;
209272b676d7Smrg	      infoPtr->SubsequentSolidFillRect = SiSSubsequentSolidFillRect;
209372b676d7Smrg#ifdef TRAP
209472b676d7Smrg	      if((pSiS->Chipset != PCI_CHIP_SIS660) &&
209572b676d7Smrg	         (pSiS->Chipset != PCI_CHIP_SIS330) &&
209672b676d7Smrg	         (pSiS->Chipset != PCI_CHIP_SIS340) &&
209772b676d7Smrg		 (pSiS->Chipset != PCI_CHIP_XGIXG20) &&
209872b676d7Smrg		 (pSiS->Chipset != PCI_CHIP_XGIXG40)) {
209972b676d7Smrg	         infoPtr->SubsequentSolidFillTrap = SiSSubsequentSolidFillTrap;
210072b676d7Smrg	      }
210172b676d7Smrg#endif
210272b676d7Smrg	      infoPtr->SolidFillFlags = NO_PLANEMASK;
210372b676d7Smrg
210472b676d7Smrg	      /* solid line */
210572b676d7Smrg	      infoPtr->SetupForSolidLine = SiSSetupForSolidLine;
210672b676d7Smrg	      infoPtr->SubsequentSolidTwoPointLine = SiSSubsequentSolidTwoPointLine;
210772b676d7Smrg	      infoPtr->SubsequentSolidHorVertLine = SiSSubsequentSolidHorzVertLine;
210872b676d7Smrg	      infoPtr->SolidLineFlags = NO_PLANEMASK;
210972b676d7Smrg
211072b676d7Smrg	      /* dashed line */
211172b676d7Smrg	      infoPtr->SetupForDashedLine = SiSSetupForDashedLine;
211272b676d7Smrg	      infoPtr->SubsequentDashedTwoPointLine = SiSSubsequentDashedTwoPointLine;
211372b676d7Smrg	      infoPtr->DashPatternMaxLength = 64;
211472b676d7Smrg	      infoPtr->DashedLineFlags = NO_PLANEMASK |
211572b676d7Smrg					 LINE_PATTERN_MSBFIRST_LSBJUSTIFIED;
211672b676d7Smrg
211772b676d7Smrg	      /* 8x8 mono pattern fill */
211872b676d7Smrg	      infoPtr->SetupForMono8x8PatternFill = SiSSetupForMonoPatternFill;
211972b676d7Smrg	      infoPtr->SubsequentMono8x8PatternFillRect = SiSSubsequentMonoPatternFill;
212072b676d7Smrg#ifdef TRAP
212172b676d7Smrg              if((pSiS->Chipset != PCI_CHIP_SIS660) &&
212272b676d7Smrg	         (pSiS->Chipset != PCI_CHIP_SIS330) &&
212372b676d7Smrg	         (pSiS->Chipset != PCI_CHIP_SIS340) &&
212472b676d7Smrg		 (pSiS->Chipset != PCI_CHIP_XGIXG20) &&
212572b676d7Smrg		 (pSiS->Chipset != PCI_CHIP_XGIXG40)) {
212672b676d7Smrg	         infoPtr->SubsequentMono8x8PatternFillTrap = SiSSubsequentMonoPatternFillTrap;
212772b676d7Smrg	      }
212872b676d7Smrg#endif
212972b676d7Smrg	      infoPtr->Mono8x8PatternFillFlags = NO_PLANEMASK |
213072b676d7Smrg						 HARDWARE_PATTERN_SCREEN_ORIGIN |
213172b676d7Smrg						 HARDWARE_PATTERN_PROGRAMMED_BITS |
213272b676d7Smrg						 BIT_ORDER_IN_BYTE_MSBFIRST;
213372b676d7Smrg
213472b676d7Smrg#ifdef SISVRAMQ
213572b676d7Smrg	      /* 8x8 color pattern fill (MMIO support not implemented) */
213672b676d7Smrg	      infoPtr->SetupForColor8x8PatternFill = SiSSetupForColor8x8PatternFill;
213772b676d7Smrg	      infoPtr->SubsequentColor8x8PatternFillRect = SiSSubsequentColor8x8PatternFillRect;
213872b676d7Smrg	      infoPtr->Color8x8PatternFillFlags = NO_PLANEMASK |
213972b676d7Smrg						  HARDWARE_PATTERN_SCREEN_ORIGIN |
214072b676d7Smrg						  NO_TRANSPARENCY;
214172b676d7Smrg#endif
214272b676d7Smrg
214372b676d7Smrg#ifdef STSCE
214472b676d7Smrg	      /* Screen To Screen Color Expand */
214572b676d7Smrg	      /* The hardware does not support this the way we need it, because
214672b676d7Smrg	       * the mono-bitmap is not provided with a pitch of (width), but
214772b676d7Smrg	       * with a pitch of scrnOffset (= width * bpp / 8).
214872b676d7Smrg	       */
214972b676d7Smrg	      infoPtr->SetupForScreenToScreenColorExpandFill =
215072b676d7Smrg				SiSSetupForScreenToScreenColorExpand;
215172b676d7Smrg	      infoPtr->SubsequentScreenToScreenColorExpandFill =
215272b676d7Smrg				SiSSubsequentScreenToScreenColorExpand;
215372b676d7Smrg	      infoPtr->ScreenToScreenColorExpandFillFlags = NO_PLANEMASK |
215472b676d7Smrg							    BIT_ORDER_IN_BYTE_MSBFIRST ;
215572b676d7Smrg#endif
215672b676d7Smrg
215772b676d7Smrg#ifdef CTSCE
215872b676d7Smrg#ifdef CTSCE_DIRECT
215972b676d7Smrg	      /* CPU color expansion - direct method
216072b676d7Smrg	       *
216172b676d7Smrg	       * We somewhat fake this function here in the following way:
216272b676d7Smrg	       * XAA copies its mono-bitmap data not into an aperture, but
216372b676d7Smrg	       * into our video RAM buffer. We then do a ScreenToScreen
216472b676d7Smrg	       * color expand.
216572b676d7Smrg	       * Unfortunately, XAA sends the data to the aperture AFTER
216672b676d7Smrg	       * the call to Subsequent(), therefore we do not execute the
216772b676d7Smrg	       * command in Subsequent, but in the following call to Sync().
216872b676d7Smrg	       * (Hence, the SYNC_AFTER_COLOR_EXPAND flag MUST BE SET)
216972b676d7Smrg	       *
217072b676d7Smrg	       * This is slower than doing it by the CPU.
217172b676d7Smrg	       */
217272b676d7Smrg
217372b676d7Smrg	       pSiS->ColorExpandBufferNumber = 48;
217472b676d7Smrg	       pSiS->PerColorExpandBufferSize = ((pScrn->virtualX + 31)/32) * 4;
217572b676d7Smrg	       infoPtr->SetupForCPUToScreenColorExpandFill = SiSSetupForCPUToScreenColorExpandFill;
217672b676d7Smrg	       infoPtr->SubsequentCPUToScreenColorExpandFill = SiSSubsequentCPUToScreenColorExpandFill;
217772b676d7Smrg	       infoPtr->ColorExpandRange = pSiS->ColorExpandBufferNumber * pSiS->PerColorExpandBufferSize;
217872b676d7Smrg	       infoPtr->CPUToScreenColorExpandFillFlags =
217972b676d7Smrg			NO_PLANEMASK |
218072b676d7Smrg			CPU_TRANSFER_PAD_DWORD |
218172b676d7Smrg			SCANLINE_PAD_DWORD |
218272b676d7Smrg			BIT_ORDER_IN_BYTE_MSBFIRST |
218372b676d7Smrg			LEFT_EDGE_CLIPPING |
218472b676d7Smrg			SYNC_AFTER_COLOR_EXPAND;
218572b676d7Smrg#else
218672b676d7Smrg              /* CPU color expansion - per-scanline / indirect method
218772b676d7Smrg	       *
218872b676d7Smrg	       * SLOW! SLOWER! SLOWEST!
218972b676d7Smrg	       *
219072b676d7Smrg	       * Does not work on 330 series, hangs the engine (both VRAM and MMIO).
219172b676d7Smrg	       * Does not work in VRAM queue mode.
219272b676d7Smrg	       */
219372b676d7Smrg#ifndef SISVRAMQ
219472b676d7Smrg	      if((pSiS->Chipset != PCI_CHIP_SIS650) &&
219572b676d7Smrg	         (pSiS->Chipset != PCI_CHIP_SIS660) &&
219672b676d7Smrg	         (pSiS->Chipset != PCI_CHIP_SIS330) &&
219772b676d7Smrg	         (pSiS->Chipset != PCI_CHIP_SIS340) &&
219872b676d7Smrg		 (pSiS->Chipset != PCI_CHIP_XGIXG20) &&
219972b676d7Smrg		 (pSiS->Chipset != PCI_CHIP_XGIXG40)) {
220072b676d7Smrg		 pSiS->ColorExpandBufferNumber = 16;
220172b676d7Smrg		 pSiS->ColorExpandBufferCountMask = 0x0F;
220272b676d7Smrg		 pSiS->PerColorExpandBufferSize = ((pScrn->virtualX + 31)/32) * 4;
220372b676d7Smrg		 infoPtr->NumScanlineColorExpandBuffers = pSiS->ColorExpandBufferNumber;
220472b676d7Smrg		 infoPtr->ScanlineColorExpandBuffers = (unsigned char **)&pSiS->ColorExpandBufferAddr[0];
220572b676d7Smrg		 infoPtr->SetupForScanlineCPUToScreenColorExpandFill = SiSSetupForScanlineCPUToScreenColorExpandFill;
220672b676d7Smrg		 infoPtr->SubsequentScanlineCPUToScreenColorExpandFill = SiSSubsequentScanlineCPUToScreenColorExpandFill;
220772b676d7Smrg		 infoPtr->SubsequentColorExpandScanline = SiSSubsequentColorExpandScanline;
220872b676d7Smrg		 infoPtr->ScanlineCPUToScreenColorExpandFillFlags =
220972b676d7Smrg				NO_PLANEMASK |
221072b676d7Smrg				CPU_TRANSFER_PAD_DWORD |
221172b676d7Smrg				SCANLINE_PAD_DWORD |
221272b676d7Smrg				BIT_ORDER_IN_BYTE_MSBFIRST |
221372b676d7Smrg				LEFT_EDGE_CLIPPING;
221472b676d7Smrg	      }
221572b676d7Smrg#endif
221672b676d7Smrg#endif
221772b676d7Smrg#endif
221872b676d7Smrg
221972b676d7Smrg#ifdef INCL_RENDER
222072b676d7Smrg#ifdef RENDER
222172b676d7Smrg	      /* Render */
222272b676d7Smrg	      SiSCalcRenderAccelArray(pScrn);
222372b676d7Smrg
222472b676d7Smrg	      if(pSiS->RenderAccelArray) {
222572b676d7Smrg	         pSiS->AccelLinearScratch = NULL;
222672b676d7Smrg
222772b676d7Smrg#ifdef SISNEWRENDER
222872b676d7Smrg		 infoPtr->SetupForCPUToScreenAlphaTexture2 = SiSSetupForCPUToScreenAlphaTexture;
222972b676d7Smrg		 infoPtr->CPUToScreenAlphaTextureDstFormats = (pScrn->bitsPerPixel == 16) ?
223072b676d7Smrg				SiSDstTextureFormats16 : SiSDstTextureFormats32;
223172b676d7Smrg#else
223272b676d7Smrg		 infoPtr->SetupForCPUToScreenAlphaTexture = SiSSetupForCPUToScreenAlphaTexture;
223372b676d7Smrg#endif
223472b676d7Smrg		 infoPtr->SubsequentCPUToScreenAlphaTexture = SiSSubsequentCPUToScreenTexture;
223572b676d7Smrg		 infoPtr->CPUToScreenAlphaTextureFormats = SiSAlphaTextureFormats;
223672b676d7Smrg		 infoPtr->CPUToScreenAlphaTextureFlags = XAA_RENDER_NO_TILE;
223772b676d7Smrg
223872b676d7Smrg#ifdef SISNEWRENDER
223972b676d7Smrg		 infoPtr->SetupForCPUToScreenTexture2 = SiSSetupForCPUToScreenTexture;
224072b676d7Smrg		 infoPtr->CPUToScreenTextureDstFormats = (pScrn->bitsPerPixel == 16) ?
224172b676d7Smrg				SiSDstTextureFormats16 : SiSDstTextureFormats32;
224272b676d7Smrg#else
224372b676d7Smrg		 infoPtr->SetupForCPUToScreenTexture = SiSSetupForCPUToScreenTexture;
224472b676d7Smrg#endif
224572b676d7Smrg		 infoPtr->SubsequentCPUToScreenTexture = SiSSubsequentCPUToScreenTexture;
224672b676d7Smrg		 infoPtr->CPUToScreenTextureFormats = SiSTextureFormats;
224772b676d7Smrg		 infoPtr->CPUToScreenTextureFlags = XAA_RENDER_NO_TILE;
224872b676d7Smrg
224972b676d7Smrg		 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "RENDER acceleration enabled\n");
225072b676d7Smrg	      }
225172b676d7Smrg#endif
225272b676d7Smrg#endif
225372b676d7Smrg
225472b676d7Smrg#ifdef SISDUALHEAD
225572b676d7Smrg	      if(pSiS->DualHeadMode) {
225672b676d7Smrg		 infoPtr->RestoreAccelState = SiSRestoreAccelState;
225772b676d7Smrg	      }
225872b676d7Smrg#endif
225972b676d7Smrg	   }  /* !EXA */
226072b676d7Smrg#endif /* XAA */
226172b676d7Smrg
226272b676d7Smrg#ifdef SIS_USE_EXA	/* ----------------------- EXA ----------------------- */
226372b676d7Smrg	   if(pSiS->useEXA) {
226472b676d7Smrg	      pSiS->EXADriverPtr->exa_major = 2;
226572b676d7Smrg	      pSiS->EXADriverPtr->exa_minor = 0;
226672b676d7Smrg
226772b676d7Smrg	      /* data */
226872b676d7Smrg	      pSiS->EXADriverPtr->memoryBase = pSiS->FbBase;
226972b676d7Smrg	      pSiS->EXADriverPtr->memorySize = pSiS->maxxfbmem;
227072b676d7Smrg	      pSiS->EXADriverPtr->offScreenBase = pScrn->virtualX * pScrn->virtualY
227172b676d7Smrg						* ((pScrn->bitsPerPixel + 7) / 8);
227272b676d7Smrg	      if(pSiS->EXADriverPtr->memorySize > pSiS->EXADriverPtr->offScreenBase) {
227372b676d7Smrg		 pSiS->EXADriverPtr->flags = EXA_OFFSCREEN_PIXMAPS;
227472b676d7Smrg	      } else {
227572b676d7Smrg		 pSiS->NoXvideo = TRUE;
227672b676d7Smrg		 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
227772b676d7Smrg			"Not enough video RAM for offscreen memory manager. Xv disabled\n");
227872b676d7Smrg	      }
227972b676d7Smrg	      pSiS->EXADriverPtr->pixmapOffsetAlign = 16;	/* src/dst: double quad word boundary */
228072b676d7Smrg	      pSiS->EXADriverPtr->pixmapPitchAlign = 4;	/* pitch:   double word boundary      */
228172b676d7Smrg	      pSiS->EXADriverPtr->maxX = 4095;
228272b676d7Smrg	      pSiS->EXADriverPtr->maxY = 4095;
228372b676d7Smrg
228472b676d7Smrg	      /* Sync */
228572b676d7Smrg	      pSiS->EXADriverPtr->WaitMarker = SiSEXASync;
228672b676d7Smrg
228772b676d7Smrg	      /* Solid fill */
228872b676d7Smrg	      pSiS->EXADriverPtr->PrepareSolid = SiSPrepareSolid;
228972b676d7Smrg	      pSiS->EXADriverPtr->Solid = SiSSolid;
229072b676d7Smrg	      pSiS->EXADriverPtr->DoneSolid = SiSDoneSolid;
229172b676d7Smrg
229272b676d7Smrg	      /* Copy */
229372b676d7Smrg	      pSiS->EXADriverPtr->PrepareCopy = SiSPrepareCopy;
229472b676d7Smrg	      pSiS->EXADriverPtr->Copy = SiSCopy;
229572b676d7Smrg	      pSiS->EXADriverPtr->DoneCopy = SiSDoneCopy;
229672b676d7Smrg
229772b676d7Smrg	      /* Composite */
229872b676d7Smrg#ifdef SIS_HAVE_COMPOSITE
229972b676d7Smrg	      SiSCalcRenderAccelArray(pScrn);
230072b676d7Smrg	      if(pSiS->RenderAccelArray) {
230172b676d7Smrg		 pSiS->EXADriverPtr->CheckComposite = SiSCheckComposite;
230272b676d7Smrg		 pSiS->EXADriverPtr->PrepareComposite = SiSPrepareComposite;
230372b676d7Smrg		 pSiS->EXADriverPtr->Composite = SiSComposite;
230472b676d7Smrg		 pSiS->EXADriverPtr->DoneComposite = SiSDoneComposite;
230572b676d7Smrg	      }
230672b676d7Smrg#endif
230772b676d7Smrg
230872b676d7Smrg	      /* Upload, download to/from Screen */
230972b676d7Smrg	      pSiS->EXADriverPtr->UploadToScreen = SiSUploadToScreen;
231072b676d7Smrg	      pSiS->EXADriverPtr->DownloadFromScreen = SiSDownloadFromScreen;
231172b676d7Smrg
231272b676d7Smrg	   }
231372b676d7Smrg#endif
231472b676d7Smrg
231572b676d7Smrg	}  /* NoAccel */
231672b676d7Smrg
231772b676d7Smrg	/* Init framebuffer memory manager */
231872b676d7Smrg
231972b676d7Smrg	/* Traditional layout:
232072b676d7Smrg	 *   |-----------------++++++++++++++++++++^************==========~~~~~~~~~~~~|
232172b676d7Smrg	 *   |  UsableFbSize    ColorExpandBuffers |  DRI-Heap   HWCursor  CommandQueue
232272b676d7Smrg	 * FbBase                                topFB
232372b676d7Smrg	 *   +-------------maxxfbmem---------------+
232472b676d7Smrg	 *
232572b676d7Smrg	 * On SiS76x with UMA+LFB:
232672b676d7Smrg	 * |UUUUUUUUUUUUUUU--------------++++++++++++++++++++^==========~~~~~~~~~~~~|
232772b676d7Smrg	 *     DRI heap    |UsableFbSize  ColorExpandBuffers | HWCursor  CommandQueue
232872b676d7Smrg	 *  (in UMA and   FbBase                           topFB
232972b676d7Smrg	 *   eventually    +---------- maxxfbmem ------------+
233072b676d7Smrg	 *  beginning of
233172b676d7Smrg	 *      LFB)
233272b676d7Smrg	 */
233372b676d7Smrg
233472b676d7Smrg#ifdef SIS_USE_XAA
233572b676d7Smrg	if(!pSiS->useEXA) {
233672b676d7Smrg
233772b676d7Smrg	   topFB = pSiS->maxxfbmem; /* relative to FbBase */
233872b676d7Smrg
233972b676d7Smrg	   reservedFbSize = pSiS->ColorExpandBufferNumber * pSiS->PerColorExpandBufferSize;
234072b676d7Smrg
234172b676d7Smrg	   usableFbSize = topFB - reservedFbSize;
234272b676d7Smrg
234372b676d7Smrg#ifdef CTSCE
234472b676d7Smrg	   AvailBufBase = pSiS->FbBase + usableFbSize;
234572b676d7Smrg	   if(pSiS->ColorExpandBufferNumber) {
234672b676d7Smrg#ifdef CTSCE_DIRECT
234772b676d7Smrg	      infoPtr->ColorExpandBase = (unsigned char *)AvailBufBase;
234872b676d7Smrg	      pSiS->ColorExpandBase = usableFbSize;
234972b676d7Smrg#else
235072b676d7Smrg	      for(i = 0; i < pSiS->ColorExpandBufferNumber; i++) {
235172b676d7Smrg		 pSiS->ColorExpandBufferAddr[i] = AvailBufBase +
235272b676d7Smrg		       i * pSiS->PerColorExpandBufferSize;
235372b676d7Smrg		 pSiS->ColorExpandBufferScreenOffset[i] = usableFbSize +
235472b676d7Smrg		       i * pSiS->PerColorExpandBufferSize;
235572b676d7Smrg	      }
235672b676d7Smrg#endif
235772b676d7Smrg	   }
235872b676d7Smrg#endif
235972b676d7Smrg
236072b676d7Smrg	   Avail.x1 = 0;
236172b676d7Smrg	   Avail.y1 = 0;
236272b676d7Smrg	   Avail.x2 = pScrn->displayWidth;
236372b676d7Smrg	   Avail.y2 = (usableFbSize / (pScrn->displayWidth * pScrn->bitsPerPixel/8)) - 1;
236472b676d7Smrg
236572b676d7Smrg	   if(Avail.y2 < 0) Avail.y2 = 32767;
236672b676d7Smrg
236772b676d7Smrg	   if(Avail.y2 < pScrn->currentMode->VDisplay) {
236872b676d7Smrg	      xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
236972b676d7Smrg			"Not enough video RAM for accelerator. At least "
237072b676d7Smrg			"%dKB needed, %dKB available\n",
237172b676d7Smrg			((((pScrn->displayWidth * pScrn->bitsPerPixel/8)   /* +8 for make it sure */
237272b676d7Smrg			     * pScrn->currentMode->VDisplay) + reservedFbSize) / 1024) + 8,
237372b676d7Smrg			pSiS->maxxfbmem/1024);
237472b676d7Smrg	      pSiS->NoAccel = TRUE;
237572b676d7Smrg	      pSiS->NoXvideo = TRUE;
237672b676d7Smrg	      XAADestroyInfoRec(pSiS->AccelInfoPtr);
237772b676d7Smrg	      pSiS->AccelInfoPtr = NULL;
237872b676d7Smrg	      return FALSE;   /* Don't even init fb manager */
237972b676d7Smrg	   }
238072b676d7Smrg
238172b676d7Smrg	   xf86DrvMsg(pScrn->scrnIndex, X_INFO,
238272b676d7Smrg		   "Framebuffer from (%d,%d) to (%d,%d)\n",
238372b676d7Smrg		   Avail.x1, Avail.y1, Avail.x2 - 1, Avail.y2 - 1);
238472b676d7Smrg
238572b676d7Smrg	   xf86InitFBManager(pScreen, &Avail);
238672b676d7Smrg
238772b676d7Smrg	   if(!pSiS->NoAccel) {
238872b676d7Smrg	      return XAAInit(pScreen, infoPtr);
238972b676d7Smrg	   }
239072b676d7Smrg	} /* !EXA */
239172b676d7Smrg#endif /* XAA */
239272b676d7Smrg
239372b676d7Smrg#ifdef SIS_USE_EXA
239472b676d7Smrg	if(pSiS->useEXA) {
239572b676d7Smrg
239672b676d7Smrg	   if(!pSiS->NoAccel) {
239772b676d7Smrg
239872b676d7Smrg	      if(!exaDriverInit(pScreen, pSiS->EXADriverPtr)) {
239972b676d7Smrg		 pSiS->NoAccel = TRUE;
240072b676d7Smrg		 pSiS->NoXvideo = TRUE; /* No fbmem manager -> no xv */
240172b676d7Smrg		 return FALSE;
240272b676d7Smrg	      }
240372b676d7Smrg
240472b676d7Smrg	      /* Reserve locked offscreen scratch area of 128K for glyph data */
240572b676d7Smrg	      pSiS->exa_scratch = exaOffscreenAlloc(pScreen, 128 * 1024, 16, TRUE,
240672b676d7Smrg						SiSScratchSave, pSiS);
240772b676d7Smrg	      if(pSiS->exa_scratch) {
240872b676d7Smrg		 pSiS->exa_scratch_next = pSiS->exa_scratch->offset;
240972b676d7Smrg		 pSiS->EXADriverPtr->UploadToScratch = SiSUploadToScratch;
241072b676d7Smrg	      }
241172b676d7Smrg
241272b676d7Smrg	   } else {
241372b676d7Smrg
241472b676d7Smrg	      pSiS->NoXvideo = TRUE; /* No fbmem manager -> no xv */
241572b676d7Smrg
241672b676d7Smrg	   }
241772b676d7Smrg
241872b676d7Smrg	}
241972b676d7Smrg#endif /* EXA */
242072b676d7Smrg
242172b676d7Smrg	return TRUE;
242272b676d7Smrg}
242372b676d7Smrg
242472b676d7Smrg
242572b676d7Smrg
242672b676d7Smrg
2427