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