sx_accel.c revision c35d236e
1/*
2 * Copyright 1997-2001 by Alan Hourihane, Wigan, England.
3 *
4 * Permission to use, copy, modify, distribute, and sell this software and its
5 * documentation for any purpose is hereby granted without fee, provided that
6 * the above copyright notice appear in all copies and that both that
7 * copyright notice and this permission notice appear in supporting
8 * documentation, and that the name of Alan Hourihane not be used in
9 * advertising or publicity pertaining to distribution of the software without
10 * specific, written prior permission.  Alan Hourihane makes no representations
11 * about the suitability of this software for any purpose.  It is provided
12 * "as is" without express or implied warranty.
13 *
14 * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16 * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
20 * PERFORMANCE OF THIS SOFTWARE.
21 *
22 * Authors:  Alan Hourihane, <alanh@fairlite.demon.co.uk>
23 *           Dirk Hohndel, <hohndel@suse.de>
24 *           Stefan Dirsch, <sndirsch@suse.de>
25 *
26 * this work is sponsored by S.u.S.E. GmbH, Fuerth, Elsa GmbH, Aachen and
27 * Siemens Nixdorf Informationssysteme
28 *
29 * GLINT 300SX accelerated options.
30 */
31/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glint/sx_accel.c,v 1.7 2001/05/29 11:23:38 alanh Exp $ */
32
33#ifdef HAVE_CONFIG_H
34#include "config.h"
35#endif
36
37#include "xf86.h"
38#include "xf86_OSproc.h"
39
40#include "xf86PciInfo.h"
41#include "xf86Pci.h"
42
43#include "fb.h"
44
45#include "miline.h"
46
47#include "glint_regs.h"
48#include "glint.h"
49
50#include "xaalocal.h"	/* For replacements */
51
52static void SXSync(ScrnInfoPtr pScrn);
53static void SXSetupForFillRectSolid(ScrnInfoPtr pScrn, int color, int rop,
54						unsigned int planemask);
55static void SXSubsequentFillRectSolid(ScrnInfoPtr pScrn, int x, int y,
56						int w, int h);
57static void SXSetupForMono8x8PatternFill(ScrnInfoPtr pScrn, int patternx,
58						int patterny,
59					   	int fg, int bg, int rop,
60					   	unsigned int planemask);
61static void SXSubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, int patternx,
62						int patterny, int x, int y,
63				   		int w, int h);
64static void SXSetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir,
65						int rop, unsigned int planemask,
66				    		int transparency_color);
67static void SXSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, int y1,
68						int x2, int y2, int w, int h);
69#if 0
70static void SXWriteBitmap(ScrnInfoPtr pScrn, int x, int y, int w, int h,
71    				unsigned char *src, int srcwidth,
72				int skipleft, int fg, int bg, int rop,
73    				unsigned int planemask);
74static void SXWritePixmap(ScrnInfoPtr pScrn, int x, int y, int w, int h,
75   				unsigned char *src, int srcwidth, int rop,
76   				unsigned int planemask, int trans,
77   				int bpp, int depth);
78static void SXSetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, int fg,
79				int bg, int rop, unsigned int planemask);
80static void SXSubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, int x,
81				int y, int w, int h, int skipleft);
82static void SXSubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno);
83#endif
84static void SXSetClippingRectangle(ScrnInfoPtr pScrn, int x1, int y1,
85						int x2,int y2);
86static void SXDisableClipping(ScrnInfoPtr pScrn);
87static void SXLoadCoord(ScrnInfoPtr pScrn, int x, int y, int w, int h,
88				int a, int d);
89static void SXSetupForSolidLine(ScrnInfoPtr pScrn, int color, int rop,
90				unsigned int planemask);
91static void SXSubsequentHorVertLine(ScrnInfoPtr pScrn, int x1, int y1,
92				int len, int dir);
93static void SXSubsequentSolidBresenhamLine(ScrnInfoPtr pScrn,
94        			int x, int y, int dmaj, int dmin, int e,
95				int len, int octant);
96static void SXPolylinesThinSolidWrapper(DrawablePtr pDraw, GCPtr pGC,
97   				int mode, int npt, DDXPointPtr pPts);
98static void SXPolySegmentThinSolidWrapper(DrawablePtr pDraw, GCPtr pGC,
99 				int nseg, xSegment *pSeg);
100
101#define MAX_FIFO_ENTRIES		15
102
103void
104SXInitializeEngine(ScrnInfoPtr pScrn)
105{
106    GLINTPtr pGlint = GLINTPTR(pScrn);
107    /* Initialize the Accelerator Engine to defaults */
108
109    GLINT_SLOW_WRITE_REG(UNIT_DISABLE,	DitherMode);
110    GLINT_SLOW_WRITE_REG(0x400,		FilterMode);
111    GLINT_SLOW_WRITE_REG(UNIT_DISABLE,  ScissorMode);
112    GLINT_SLOW_WRITE_REG(pGlint->pprod,	LBReadMode);
113    GLINT_SLOW_WRITE_REG(pGlint->pprod,	FBReadMode);
114    GLINT_SLOW_WRITE_REG(UNIT_DISABLE,	LBWriteMode);
115    GLINT_SLOW_WRITE_REG(UNIT_ENABLE,	FBWriteMode);
116    GLINT_SLOW_WRITE_REG(UNIT_DISABLE,	AlphaBlendMode);
117    GLINT_SLOW_WRITE_REG(UNIT_DISABLE,	ColorDDAMode);
118    GLINT_SLOW_WRITE_REG(UNIT_DISABLE,	TextureColorMode);
119    GLINT_SLOW_WRITE_REG(UNIT_DISABLE,	TextureAddressMode);
120    GLINT_SLOW_WRITE_REG(UNIT_DISABLE,  TextureReadMode);
121    GLINT_SLOW_WRITE_REG(UNIT_DISABLE,  GLINTWindow);
122    GLINT_SLOW_WRITE_REG(UNIT_DISABLE,  AlphaBlendMode);
123    GLINT_SLOW_WRITE_REG(UNIT_DISABLE,  DepthMode);
124    GLINT_SLOW_WRITE_REG(UNIT_DISABLE,  RouterMode);
125    GLINT_SLOW_WRITE_REG(UNIT_DISABLE,	FogMode);
126    GLINT_SLOW_WRITE_REG(UNIT_DISABLE,	AntialiasMode);
127    GLINT_SLOW_WRITE_REG(UNIT_DISABLE,	AlphaTestMode);
128    GLINT_SLOW_WRITE_REG(UNIT_DISABLE,	StencilMode);
129    GLINT_SLOW_WRITE_REG(UNIT_DISABLE,	AreaStippleMode);
130    GLINT_SLOW_WRITE_REG(UNIT_DISABLE,	LineStippleMode);
131    GLINT_SLOW_WRITE_REG(0,		UpdateLineStippleCounters);
132    GLINT_SLOW_WRITE_REG(UNIT_DISABLE,	LogicalOpMode);
133    GLINT_SLOW_WRITE_REG(UNIT_DISABLE,	DepthMode);
134    GLINT_SLOW_WRITE_REG(UNIT_DISABLE,	StatisticMode);
135    GLINT_SLOW_WRITE_REG(0xffffffff,	FBHardwareWriteMask);
136    GLINT_SLOW_WRITE_REG(0xffffffff,	FBSoftwareWriteMask);
137    GLINT_SLOW_WRITE_REG(UNIT_DISABLE,	RasterizerMode);
138    GLINT_SLOW_WRITE_REG(UNIT_DISABLE,	GLINTDepth);
139    GLINT_SLOW_WRITE_REG(UNIT_DISABLE,	FBSourceOffset);
140    GLINT_SLOW_WRITE_REG(UNIT_DISABLE,	FBPixelOffset);
141    GLINT_SLOW_WRITE_REG(UNIT_DISABLE,	LBSourceOffset);
142    GLINT_SLOW_WRITE_REG(UNIT_DISABLE,	WindowOrigin);
143    GLINT_SLOW_WRITE_REG(UNIT_DISABLE,	FBWindowBase);
144    GLINT_SLOW_WRITE_REG(UNIT_DISABLE,	LBWindowBase);
145    GLINT_SLOW_WRITE_REG(UNIT_DISABLE,	TextureAddressMode);
146    GLINT_SLOW_WRITE_REG(UNIT_DISABLE,	RouterMode);
147
148    pGlint->ROP = 0xFF;
149    pGlint->ClippingOn = FALSE;
150    pGlint->startxsub = 0;
151    pGlint->startxdom = 0;
152    pGlint->starty = 0;
153    pGlint->count = 0;
154    pGlint->dxdom = 0;
155    pGlint->dy = 1;
156    pGlint->planemask = 0;
157    GLINT_SLOW_WRITE_REG(0, StartXSub);
158    GLINT_SLOW_WRITE_REG(0, StartXDom);
159    GLINT_SLOW_WRITE_REG(0, StartY);
160    GLINT_SLOW_WRITE_REG(0, GLINTCount);
161    GLINT_SLOW_WRITE_REG(0, dXDom);
162    GLINT_SLOW_WRITE_REG(0, dXSub);
163    GLINT_SLOW_WRITE_REG(1<<16, dY);
164}
165
166Bool
167SXAccelInit(ScreenPtr pScreen)
168{
169    XAAInfoRecPtr infoPtr;
170    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
171    GLINTPtr pGlint = GLINTPTR(pScrn);
172    long memory = pGlint->FbMapSize;
173    BoxRec AvailFBArea;
174
175    pGlint->AccelInfoRec = infoPtr = XAACreateInfoRec();
176    if (!infoPtr) return FALSE;
177
178    SXInitializeEngine(pScrn);
179
180    infoPtr->Flags = PIXMAP_CACHE |
181		     LINEAR_FRAMEBUFFER |
182		     OFFSCREEN_PIXMAPS;
183
184    infoPtr->Sync = SXSync;
185
186    infoPtr->SetClippingRectangle = SXSetClippingRectangle;
187    infoPtr->DisableClipping = SXDisableClipping;
188    infoPtr->ClippingFlags = HARDWARE_CLIP_MONO_8x8_FILL |
189			     HARDWARE_CLIP_SCREEN_TO_SCREEN_COPY |
190			     HARDWARE_CLIP_SOLID_FILL;
191
192    infoPtr->SolidFillFlags = 0;
193    infoPtr->SetupForSolidFill = SXSetupForFillRectSolid;
194    infoPtr->SubsequentSolidFillRect = SXSubsequentFillRectSolid;
195
196    infoPtr->SolidLineFlags = 0;
197    infoPtr->PolySegmentThinSolidFlags = 0;
198    infoPtr->PolylinesThinSolidFlags = 0;
199    infoPtr->SetupForSolidLine = SXSetupForSolidLine;
200    infoPtr->SubsequentSolidHorVertLine = SXSubsequentHorVertLine;
201    infoPtr->SubsequentSolidBresenhamLine =
202					SXSubsequentSolidBresenhamLine;
203    infoPtr->PolySegmentThinSolid = SXPolySegmentThinSolidWrapper;
204    infoPtr->PolylinesThinSolid = SXPolylinesThinSolidWrapper;
205
206    infoPtr->ScreenToScreenCopyFlags = NO_TRANSPARENCY |
207				       ONLY_LEFT_TO_RIGHT_BITBLT;
208    infoPtr->SetupForScreenToScreenCopy = SXSetupForScreenToScreenCopy;
209    infoPtr->SubsequentScreenToScreenCopy = SXSubsequentScreenToScreenCopy;
210
211    infoPtr->Mono8x8PatternFillFlags = HARDWARE_PATTERN_PROGRAMMED_ORIGIN |
212				       HARDWARE_PATTERN_SCREEN_ORIGIN |
213				       HARDWARE_PATTERN_PROGRAMMED_BITS;
214    infoPtr->SetupForMono8x8PatternFill = SXSetupForMono8x8PatternFill;
215    infoPtr->SubsequentMono8x8PatternFillRect =
216					SXSubsequentMono8x8PatternFillRect;
217
218#if 0
219    infoPtr->ScanlineCPUToScreenColorExpandFillFlags =
220					       TRANSPARENCY_ONLY |
221					       BIT_ORDER_IN_BYTE_LSBFIRST;
222
223    infoPtr->NumScanlineColorExpandBuffers = 1;
224    pGlint->ScratchBuffer                 = xalloc(((pScrn->virtualX+62)/32*4)
225					    + (pScrn->virtualX
226					    * pScrn->bitsPerPixel / 8));
227    infoPtr->ScanlineColorExpandBuffers =
228					pGlint->XAAScanlineColorExpandBuffers;
229    pGlint->XAAScanlineColorExpandBuffers[0] =
230					pGlint->IOBase + OutputFIFO + 4;
231
232    infoPtr->SetupForScanlineCPUToScreenColorExpandFill =
233				SXSetupForScanlineCPUToScreenColorExpandFill;
234    infoPtr->SubsequentScanlineCPUToScreenColorExpandFill =
235				SXSubsequentScanlineCPUToScreenColorExpandFill;
236    infoPtr->SubsequentColorExpandScanline =
237				SXSubsequentColorExpandScanline;
238
239    infoPtr->WriteBitmap = SXWriteBitmap;
240    infoPtr->ColorExpandRange = MAX_FIFO_ENTRIES;
241
242    infoPtr->WritePixmap = SXWritePixmap;
243#endif
244
245    AvailFBArea.x1 = 0;
246    AvailFBArea.y1 = 0;
247    AvailFBArea.x2 = pScrn->displayWidth;
248    if (memory > (16383*1024)) memory = 16383*1024;
249    AvailFBArea.y2 = memory / (pScrn->displayWidth *
250					  pScrn->bitsPerPixel / 8);
251
252    if (AvailFBArea.y2 > 2047) AvailFBArea.y2 = 2047;
253
254    xf86InitFBManager(pScreen, &AvailFBArea);
255
256    return (XAAInit(pScreen, infoPtr));
257}
258
259static void SXLoadCoord(
260	ScrnInfoPtr pScrn,
261	int x, int y,
262	int w, int h,
263	int a, int d
264){
265    GLINTPtr pGlint = GLINTPTR(pScrn);
266
267    if (w != pGlint->startxsub) {
268    	GLINT_WRITE_REG(w<<16, StartXSub);
269	pGlint->startxsub = w;
270    }
271    if (x != pGlint->startxdom) {
272    	GLINT_WRITE_REG(x<<16,StartXDom);
273	pGlint->startxdom = x;
274    }
275    if (y != pGlint->starty) {
276    	GLINT_WRITE_REG(y<<16,StartY);
277	pGlint->starty = y;
278    }
279    if (h != pGlint->count) {
280    	GLINT_WRITE_REG(h,GLINTCount);
281	pGlint->count = h;
282    }
283    if (a != pGlint->dxdom) {
284    	GLINT_WRITE_REG(a<<16,dXDom);
285	pGlint->dxdom = a;
286    }
287    if (d != pGlint->dy) {
288    	GLINT_WRITE_REG(d<<16,dY);
289	pGlint->dy = d;
290    }
291}
292
293static void
294SXSync(
295	ScrnInfoPtr pScrn
296){
297    GLINTPtr pGlint = GLINTPTR(pScrn);
298    CARD32 readValue;
299
300    CHECKCLIPPING;
301
302    while (GLINT_READ_REG(DMACount) != 0);
303    GLINT_WAIT(3);
304    GLINT_WRITE_REG(0x400, FilterMode);
305    GLINT_WRITE_REG(0, GlintSync);
306    do {
307   	while(GLINT_READ_REG(OutFIFOWords) == 0);
308	readValue = GLINT_READ_REG(OutputFIFO);
309    } while (readValue != Sync_tag);
310}
311
312static void
313SXSetupForFillRectSolid(
314	ScrnInfoPtr pScrn,
315	int color, int rop,
316	unsigned int planemask
317){
318    GLINTPtr pGlint = GLINTPTR(pScrn);
319    pGlint->ForeGroundColor = color;
320
321    GLINT_WAIT(6);
322    REPLICATE(color);
323    DO_PLANEMASK(planemask);
324    if (pScrn->bitsPerPixel >= 24) {
325	GLINT_WRITE_REG(pGlint->pprod | FBRM_DstEnable, FBReadMode);
326	GLINT_WRITE_REG(UNIT_ENABLE, ColorDDAMode);
327	GLINT_WRITE_REG(color, ConstantColor);
328	pGlint->FrameBufferReadMode = 0;
329    } else
330    if (rop == GXcopy) {
331	GLINT_WRITE_REG(pGlint->pprod, FBReadMode);
332	GLINT_WRITE_REG(UNIT_DISABLE, ColorDDAMode);
333	GLINT_WRITE_REG(color, FBBlockColor);
334	pGlint->FrameBufferReadMode = FastFillEnable;
335    } else {
336	GLINT_WRITE_REG(pGlint->pprod | FBRM_DstEnable, FBReadMode);
337	GLINT_WRITE_REG(UNIT_ENABLE, ColorDDAMode);
338	GLINT_WRITE_REG(color, ConstantColor);
339	pGlint->FrameBufferReadMode = 0;
340    }
341    LOADROP(rop);
342}
343
344static void
345SXSubsequentFillRectSolid(
346	ScrnInfoPtr pScrn,
347	int x, int y,
348	int w, int h
349){
350    GLINTPtr pGlint = GLINTPTR(pScrn);
351
352    GLINT_WAIT(8);
353    SXLoadCoord(pScrn, x, y, x+w, h, 0, 1);
354    GLINT_WRITE_REG(PrimitiveTrapezoid | pGlint->FrameBufferReadMode,Render);
355}
356
357static void
358SXSetClippingRectangle(
359	ScrnInfoPtr pScrn,
360	int x1, int y1,
361	int x2, int y2
362){
363    GLINTPtr pGlint = GLINTPTR(pScrn);
364
365    GLINT_WAIT(5);
366    GLINT_WRITE_REG((y1&0xFFFF)<<16|(x1&0xFFFF), ScissorMinXY);
367    GLINT_WRITE_REG((y2&0xFFFF)<<16|(x2&0xFFFF), ScissorMaxXY);
368    GLINT_WRITE_REG(1, ScissorMode); /* Enable Scissor Mode */
369    pGlint->ClippingOn = TRUE;
370}
371
372static void
373SXDisableClipping(
374	ScrnInfoPtr pScrn
375){
376    GLINTPtr pGlint = GLINTPTR(pScrn);
377    CHECKCLIPPING;
378}
379
380static void
381SXSetupForScreenToScreenCopy(
382	ScrnInfoPtr pScrn,
383	int xdir, int  ydir,
384	int rop,
385	unsigned int planemask,
386	int transparency_color
387){
388    GLINTPtr pGlint = GLINTPTR(pScrn);
389
390    pGlint->BltScanDirection = ydir;
391
392    GLINT_WAIT(6);
393    DO_PLANEMASK(planemask);
394
395    if (rop == GXcopy) {
396	GLINT_WRITE_REG(pGlint->pprod | FBRM_SrcEnable, FBReadMode);
397    } else {
398	GLINT_WRITE_REG(pGlint->pprod | FBRM_SrcEnable | FBRM_DstEnable, FBReadMode);
399    }
400    LOADROP(rop);
401}
402
403static void
404SXSubsequentScreenToScreenCopy(
405	ScrnInfoPtr pScrn,
406	int x1, int y1,
407	int x2, int y2,
408	int w, int h
409){
410    GLINTPtr pGlint = GLINTPTR(pScrn);
411    int srcaddr, dstaddr;
412
413    GLINT_WAIT(10);
414
415    srcaddr = y1 * pScrn->displayWidth + x1;
416    dstaddr = y2 * pScrn->displayWidth + x2;
417    GLINT_WRITE_REG(srcaddr - dstaddr, FBSourceOffset);
418
419    if (pGlint->BltScanDirection != 1) {
420	y1 += h - 1;
421	y2 += h - 1;
422        SXLoadCoord(pScrn, x2, y2, x2+w, h, 0, -1);
423    } else {
424        SXLoadCoord(pScrn, x2, y2, x2+w, h, 0, 1);
425    }
426
427    GLINT_WRITE_REG(PrimitiveTrapezoid, Render);
428}
429
430#if 0
431static void
432SXSetupForScanlineCPUToScreenColorExpandFill(
433	ScrnInfoPtr pScrn,
434	int fg, int bg,
435	int rop,
436	unsigned int planemask
437){
438    GLINTPtr pGlint = GLINTPTR(pScrn);
439    REPLICATE(fg);
440    REPLICATE(bg);
441    GLINT_WAIT(6);
442    DO_PLANEMASK(planemask);
443    GLINT_WRITE_REG(0, RasterizerMode);
444    if (rop == GXcopy) {
445        GLINT_WRITE_REG(pGlint->pprod, FBReadMode);
446        GLINT_WRITE_REG(UNIT_DISABLE, PatternRamMode);
447        pGlint->FrameBufferReadMode = FastFillEnable;
448	GLINT_WRITE_REG(fg, FBBlockColor);
449    } else {
450        GLINT_WRITE_REG(pGlint->pprod | FBRM_DstEnable, FBReadMode);
451        GLINT_WRITE_REG(UNIT_ENABLE, PatternRamMode);
452        pGlint->FrameBufferReadMode = FastFillEnable | SpanOperation;
453	GLINT_WRITE_REG(fg, PatternRamData0);
454    }
455    LOADROP(rop);
456}
457
458static void
459SXSubsequentScanlineCPUToScreenColorExpandFill(
460	ScrnInfoPtr pScrn,
461	int x, int y, int w, int h,
462	int skipleft
463){
464    GLINTPtr pGlint = GLINTPTR(pScrn);
465
466    pGlint->dwords = ((w + 31) >> 5); /* dwords per scanline */
467
468    pGlint->cpucount = h;
469
470    GLINT_WAIT(8);
471    SXLoadCoord(pScrn, x, y, x+w, 1, 0, 1);
472    GLINT_WRITE_REG(PrimitiveTrapezoid | pGlint->FrameBufferReadMode | SyncOnBitMask,
473							Render);
474#if defined(__alpha__)
475    if (0) /* force Alpha to use indirect always */
476#else
477    if ((pGlint->dwords*h) < pGlint->FIFOSize)
478#endif
479    {
480	/* Turn on direct for less than FIFOSize dword colour expansion */
481    	pGlint->XAAScanlineColorExpandBuffers[0] = pGlint->IOBase+OutputFIFO+4;
482	pGlint->ScanlineDirect = 1;
483    	GLINT_WRITE_REG(((pGlint->dwords*h)-1)<<16 | 0x0D, OutputFIFO);
484    	GLINT_WAIT(pGlint->dwords*h);
485    } else {
486	/* Use indirect for anything else */
487    	pGlint->XAAScanlineColorExpandBuffers[0] = pGlint->ScratchBuffer;
488	pGlint->ScanlineDirect   = 0;
489    }
490
491    pGlint->cpucount--;
492}
493
494static void
495SXSubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno)
496{
497    GLINTPtr pGlint = GLINTPTR(pScrn);
498    CARD32 *srcp = (CARD32*)pGlint->XAAScanlineColorExpandBuffers[bufno];
499    int dwords = pGlint->dwords;
500
501    if (!pGlint->ScanlineDirect) {
502	while(dwords >= pGlint->FIFOSize) {
503	    GLINT_WAIT(pGlint->FIFOSize);
504            GLINT_WRITE_REG(((pGlint->FIFOSize - 2) << 16) | 0x0D, OutputFIFO);
505	    GLINT_MoveDWORDS(
506			(CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4),
507	 		(CARD32*)srcp, pGlint->FIFOSize - 1);
508	    dwords -= pGlint->FIFOSize - 1;
509	    srcp += pGlint->FIFOSize - 1;
510	}
511	if(dwords) {
512	    GLINT_WAIT(dwords + 1);
513            GLINT_WRITE_REG(((dwords - 1) << 16) | 0x0D, OutputFIFO);
514	    GLINT_MoveDWORDS(
515			(CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4),
516	 		(CARD32*)srcp, dwords);
517	}
518    }
519}
520#endif
521
522void SXSetupForMono8x8PatternFill(
523	ScrnInfoPtr pScrn,
524	int patternx, int patterny,
525	int fg, int bg, int rop,
526	unsigned int planemask
527){
528    GLINTPtr pGlint = GLINTPTR(pScrn);
529
530    if (bg == -1) pGlint->FrameBufferReadMode = -1;
531	else    pGlint->FrameBufferReadMode = 0;
532    pGlint->ForeGroundColor = fg;
533    pGlint->BackGroundColor = bg;
534    REPLICATE(pGlint->ForeGroundColor);
535    REPLICATE(pGlint->BackGroundColor);
536
537    GLINT_WAIT(13);
538    DO_PLANEMASK(planemask);
539    GLINT_WRITE_REG((patternx & 0x000000FF),       AreaStipplePattern0);
540    GLINT_WRITE_REG((patternx & 0x0000FF00) >> 8,  AreaStipplePattern1);
541    GLINT_WRITE_REG((patternx & 0x00FF0000) >> 16, AreaStipplePattern2);
542    GLINT_WRITE_REG((patternx & 0xFF000000) >> 24, AreaStipplePattern3);
543    GLINT_WRITE_REG((patterny & 0x000000FF),       AreaStipplePattern4);
544    GLINT_WRITE_REG((patterny & 0x0000FF00) >> 8,  AreaStipplePattern5);
545    GLINT_WRITE_REG((patterny & 0x00FF0000) >> 16, AreaStipplePattern6);
546    GLINT_WRITE_REG((patterny & 0xFF000000) >> 24, AreaStipplePattern7);
547
548    GLINT_WRITE_REG(UNIT_ENABLE, ColorDDAMode);
549    if (rop == GXcopy)
550    	GLINT_WRITE_REG(pGlint->pprod, FBReadMode);
551    else
552    	GLINT_WRITE_REG(pGlint->pprod | FBRM_DstEnable, FBReadMode);
553    LOADROP(rop);
554}
555
556static void
557SXSubsequentMono8x8PatternFillRect(
558	ScrnInfoPtr pScrn,
559	int patternx, int patterny,
560	int x, int y,
561	int w, int h
562){
563    GLINTPtr pGlint = GLINTPTR(pScrn);
564
565    GLINT_WAIT(12);
566    SXLoadCoord(pScrn, x, y, x+w, h, 0, 1);
567
568    if (pGlint->FrameBufferReadMode != -1) {
569  	GLINT_WRITE_REG(pGlint->BackGroundColor, ConstantColor);
570	GLINT_WRITE_REG(2<<1|2<<4|patternx<<7|patterny<<12|ASM_InvertPattern |
571					UNIT_ENABLE, AreaStippleMode);
572	GLINT_WRITE_REG(AreaStippleEnable | PrimitiveTrapezoid, Render);
573    }
574
575    GLINT_WRITE_REG(pGlint->ForeGroundColor, ConstantColor);
576    GLINT_WRITE_REG(2<<1|2<<4|patternx<<7|patterny<<12|
577  						UNIT_ENABLE, AreaStippleMode);
578    GLINT_WRITE_REG(AreaStippleEnable | PrimitiveTrapezoid, Render);
579}
580
581#if 0
582static void
583SXWriteBitmap(ScrnInfoPtr pScrn,
584    int x, int y, int w, int h,
585    unsigned char *src,
586    int srcwidth,
587    int skipleft,
588    int fg, int bg,
589    int rop,
590    unsigned int planemask
591){
592    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
593    GLINTPtr pGlint = GLINTPTR(pScrn);
594    unsigned char *srcpntr;
595    int dwords, height, mode;
596    Bool SecondPass = FALSE;
597    register int count;
598    register CARD32* pattern;
599
600    w += skipleft;
601    x -= skipleft;
602    dwords = (w + 31) >> 5;
603
604    SXSetClippingRectangle(pScrn,x+skipleft, y, x+w, y+h);
605
606    GLINT_WAIT(11);
607    DO_PLANEMASK(planemask);
608    GLINT_WRITE_REG(0, RasterizerMode);
609    LOADROP(rop);
610    if (rop == GXcopy) {
611	mode = FastFillEnable;
612	GLINT_WRITE_REG(UNIT_DISABLE, ColorDDAMode);
613	GLINT_WRITE_REG(pGlint->pprod, FBReadMode);
614    } else {
615	mode = 0;
616	GLINT_WRITE_REG(UNIT_ENABLE, ColorDDAMode);
617	GLINT_WRITE_REG(pGlint->pprod | FBRM_DstEnable, FBReadMode);
618    }
619    SXLoadCoord(pScrn, x, y, x+w, h, 0, 1);
620
621    if(bg == -1) {
622	REPLICATE(fg);
623	GLINT_WAIT(3);
624	if (rop == GXcopy) {
625	    GLINT_WRITE_REG(fg, FBBlockColor);
626	} else {
627	    GLINT_WRITE_REG(fg, PatternRamData0);
628	}
629    } else if(rop == GXcopy) {
630	REPLICATE(bg);
631	GLINT_WAIT(5);
632	if (rop == GXcopy) {
633	    GLINT_WRITE_REG(bg, FBBlockColor);
634	} else {
635	    GLINT_WRITE_REG(bg, PatternRamData0);
636	}
637	GLINT_WRITE_REG(PrimitiveTrapezoid |mode|FastFillEnable,Render);
638	REPLICATE(fg);
639	if (rop == GXcopy) {
640	    GLINT_WRITE_REG(fg, FBBlockColor);
641	} else {
642	    GLINT_WRITE_REG(fg, PatternRamData0);
643	}
644    } else {
645	SecondPass = TRUE;
646	REPLICATE(fg);
647	GLINT_WAIT(3);
648	if (rop == GXcopy) {
649	    GLINT_WRITE_REG(fg, FBBlockColor);
650	} else {
651	    GLINT_WRITE_REG(fg, PatternRamData0);
652	}
653    }
654
655SECOND_PASS:
656    GLINT_WRITE_REG(PrimitiveTrapezoid | FastFillEnable | mode | SyncOnBitMask, Render);
657
658    height = h;
659    srcpntr = src;
660    while(height--) {
661	count = dwords >> 3;
662	pattern = (CARD32*)srcpntr;
663	while(count--) {
664		GLINT_WAIT(8);
665		GLINT_WRITE_REG(*(pattern), BitMaskPattern);
666		GLINT_WRITE_REG(*(pattern+1), BitMaskPattern);
667		GLINT_WRITE_REG(*(pattern+2), BitMaskPattern);
668		GLINT_WRITE_REG(*(pattern+3), BitMaskPattern);
669		GLINT_WRITE_REG(*(pattern+4), BitMaskPattern);
670		GLINT_WRITE_REG(*(pattern+5), BitMaskPattern);
671		GLINT_WRITE_REG(*(pattern+6), BitMaskPattern);
672		GLINT_WRITE_REG(*(pattern+7), BitMaskPattern);
673		pattern+=8;
674	}
675	count = dwords & 0x07;
676	GLINT_WAIT(count);
677	while (count--)
678		GLINT_WRITE_REG(*(pattern++), BitMaskPattern);
679	srcpntr += srcwidth;
680    }
681
682    if(SecondPass) {
683	SecondPass = FALSE;
684	REPLICATE(bg);
685	GLINT_WAIT(4);
686	GLINT_WRITE_REG(InvertBitMask, RasterizerMode);
687	if (rop == GXcopy) {
688	    GLINT_WRITE_REG(bg, FBBlockColor);
689	} else {
690	    GLINT_WRITE_REG(bg, PatternRamData0);
691	}
692	goto SECOND_PASS;
693    }
694
695    GLINT_WAIT(2);
696    GLINT_WRITE_REG(0, RasterizerMode);
697    CHECKCLIPPING;
698    SET_SYNC_FLAG(infoRec);
699}
700
701static void
702SXWritePixmap(
703   ScrnInfoPtr pScrn,
704   int x, int y, int w, int h,
705   unsigned char *src,
706   int srcwidth,	/* bytes */
707   int rop,
708   unsigned int planemask,
709   int trans,
710   int bpp, int depth
711){
712    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
713    GLINTPtr pGlint = GLINTPTR(pScrn);
714    CARD32 *srcp;
715    int count,dwords, skipleft, Bpp = bpp >> 3;
716
717    if((skipleft = (long)src & 0x03L)) {
718	skipleft /= Bpp;
719
720	x -= skipleft;
721	w += skipleft;
722
723	src = (unsigned char*)((long)src & ~0x03L);
724    }
725
726    switch(Bpp) {
727    case 1:	dwords = (w + 3) >> 2;
728		break;
729    case 2:	dwords = (w + 1) >> 1;
730		break;
731    case 4:	dwords = w;
732		break;
733    default: return;
734    }
735
736    SXSetClippingRectangle(pScrn,x+skipleft, y, x+w, y+h);
737
738    GLINT_WAIT(12);
739    DO_PLANEMASK(planemask);
740    GLINT_WRITE_REG(UNIT_DISABLE, ColorDDAMode);
741    if (rop == GXcopy) {
742        GLINT_WRITE_REG(pGlint->pprod, FBReadMode);
743    } else {
744        GLINT_WRITE_REG(pGlint->pprod | FBRM_DstEnable, FBReadMode);
745    }
746    LOADROP(rop);
747    SXLoadCoord(pScrn, x, y, x+w, h, 0, 1);
748    GLINT_WRITE_REG(PrimitiveTrapezoid | SyncOnHostData, Render);
749
750    while(h--) {
751      count = dwords;
752      srcp = (CARD32*)src;
753      while(count >= infoRec->ColorExpandRange) {
754	GLINT_WAIT(infoRec->ColorExpandRange);
755	/* (0x0f << 4) | 0x0e is the TAG for GLINTColor */
756       	GLINT_WRITE_REG(((infoRec->ColorExpandRange - 2) << 16) | (0x0F << 4) |
757				0x0E, OutputFIFO);
758	GLINT_MoveDWORDS(
759		(CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4),
760 		(CARD32*)srcp, infoRec->ColorExpandRange - 1);
761	count -= infoRec->ColorExpandRange - 1;
762	srcp += infoRec->ColorExpandRange - 1;
763      }
764      if(count) {
765	GLINT_WAIT(count);
766	/* (0x0F << 4) | 0x0E is the TAG for GLINTColor */
767       	GLINT_WRITE_REG(((count - 1) << 16) | (0x0f << 4) |
768				0x0e, OutputFIFO);
769	GLINT_MoveDWORDS(
770		(CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4),
771 		(CARD32*)srcp, count);
772      }
773      src += srcwidth;
774    }
775    CHECKCLIPPING;
776    SET_SYNC_FLAG(infoRec);
777}
778#endif
779
780static void
781SXPolylinesThinSolidWrapper(
782   DrawablePtr     pDraw,
783   GCPtr           pGC,
784   int             mode,
785   int             npt,
786   DDXPointPtr     pPts
787){
788    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
789    GLINTPtr pGlint = GLINTPTR(infoRec->pScrn);
790    pGlint->CurrentGC = pGC;
791    pGlint->CurrentDrawable = pDraw;
792    if(infoRec->NeedToSync) (*infoRec->Sync)(infoRec->pScrn);
793    XAAPolyLines(pDraw, pGC, mode, npt, pPts);
794}
795
796static void
797SXPolySegmentThinSolidWrapper(
798   DrawablePtr     pDraw,
799   GCPtr           pGC,
800   int             nseg,
801   xSegment        *pSeg
802){
803    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
804    GLINTPtr pGlint = GLINTPTR(infoRec->pScrn);
805    pGlint->CurrentGC = pGC;
806    pGlint->CurrentDrawable = pDraw;
807    if(infoRec->NeedToSync) (*infoRec->Sync)(infoRec->pScrn);
808    XAAPolySegment(pDraw, pGC, nseg, pSeg);
809}
810
811static void
812SXSetupForSolidLine(ScrnInfoPtr pScrn, int color,
813					 int rop, unsigned int planemask)
814{
815    GLINTPtr pGlint = GLINTPTR(pScrn);
816
817    GLINT_WAIT(7);
818    DO_PLANEMASK(planemask);
819    GLINT_WRITE_REG(color, GLINTColor);
820    GLINT_WRITE_REG(UNIT_DISABLE, ColorDDAMode);
821    if (rop == GXcopy) {
822  	GLINT_WRITE_REG(pGlint->pprod, FBReadMode);
823    } else {
824  	GLINT_WRITE_REG(pGlint->pprod | FBRM_DstEnable, FBReadMode);
825    }
826    LOADROP(rop);
827}
828
829static void
830SXSubsequentHorVertLine(ScrnInfoPtr pScrn,int x,int y,int len,int dir)
831{
832    GLINTPtr pGlint = GLINTPTR(pScrn);
833
834    GLINT_WAIT(9);
835    if (dir == DEGREES_0) {
836        SXLoadCoord(pScrn, x, y, 0, len, 1, 0);
837    } else {
838        SXLoadCoord(pScrn, x, y, 0, len, 0, 1);
839    }
840
841    GLINT_WRITE_REG(PrimitiveLine, Render);
842}
843
844static void
845SXSubsequentSolidBresenhamLine( ScrnInfoPtr pScrn,
846        int x, int y, int dmaj, int dmin, int e, int len, int octant)
847{
848    GLINTPtr pGlint = GLINTPTR(pScrn);
849    int dxdom, dy;
850
851    if(dmaj == dmin) {
852	GLINT_WAIT(9);
853	if(octant & YDECREASING) {
854	    dy = -1;
855	} else {
856	    dy = 1;
857	}
858
859	if(octant & XDECREASING) {
860	    dxdom = -1;
861	} else {
862	    dxdom = 1;
863	}
864
865        SXLoadCoord(pScrn, x, y, 0, len, dxdom, dy);
866	GLINT_WRITE_REG(PrimitiveLine, Render);
867	return;
868    }
869
870    fbBres(pGlint->CurrentDrawable, pGlint->CurrentGC, 0,
871                (octant & XDECREASING) ? -1 : 1,
872                (octant & YDECREASING) ? -1 : 1,
873                (octant & YMAJOR) ? Y_AXIS : X_AXIS,
874                x, y,  e, dmin, -dmaj, len);
875}
876