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