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