1ab47cfaaSmrg/*
2ab47cfaaSmrg * The accel file for the Savage driver.
3ab47cfaaSmrg *
4ab47cfaaSmrg * Created 20/03/97 by Sebastien Marineau for 3.3.6
5ab47cfaaSmrg * Modified 17-Nov-2000 by Tim Roberts for 4.0.1
6ab47cfaaSmrg * Modified Feb-2004 by Alex Deucher - integrating DRI support
7ab47cfaaSmrg * Modified 2005-2006 by Alex Deucher - adding exa support
8ab47cfaaSmrg * Revision:
9ab47cfaaSmrg *
10ab47cfaaSmrg */
11ab47cfaaSmrg
12ab47cfaaSmrg#ifdef HAVE_CONFIG_H
13ab47cfaaSmrg#include "config.h"
14ab47cfaaSmrg#endif
15ab47cfaaSmrg
16ab47cfaaSmrg#include <X11/Xarch.h>
17aa9e3350Smrg#include "savage_driver.h"
18aa9e3350Smrg#ifdef HAVE_XAA_H
19ab47cfaaSmrg#include "xaalocal.h"
20ab47cfaaSmrg#include "xaarop.h"
21aa9e3350Smrg
22ab47cfaaSmrg#include "miline.h"
23aa9e3350Smrg
24ab47cfaaSmrg#include "savage_bci.h"
25ab47cfaaSmrg
26ab47cfaaSmrgextern int gSavageEntityIndex;
27ab47cfaaSmrg
28ab47cfaaSmrgstatic void SavageSetupForScreenToScreenCopy(
29ab47cfaaSmrg    ScrnInfoPtr pScrn,
30ab47cfaaSmrg    int xdir,
31ab47cfaaSmrg    int ydir,
32ab47cfaaSmrg    int rop,
33ab47cfaaSmrg    unsigned planemask,
34ab47cfaaSmrg    int transparency_color);
35ab47cfaaSmrg
36ab47cfaaSmrgstatic void SavageSubsequentScreenToScreenCopy(
37ab47cfaaSmrg    ScrnInfoPtr pScrn,
38ab47cfaaSmrg    int x1,
39ab47cfaaSmrg    int y1,
40ab47cfaaSmrg    int x2,
41ab47cfaaSmrg    int y2,
42ab47cfaaSmrg    int w,
43ab47cfaaSmrg    int h);
44ab47cfaaSmrg
45ab47cfaaSmrgstatic void SavageSetupForSolidFill(
46ab47cfaaSmrg    ScrnInfoPtr pScrn,
47ab47cfaaSmrg    int color,
48ab47cfaaSmrg    int rop,
49ab47cfaaSmrg    unsigned int planemask);
50ab47cfaaSmrg
51ab47cfaaSmrgstatic void SavageSubsequentSolidFillRect(
52ab47cfaaSmrg    ScrnInfoPtr pScrn,
53ab47cfaaSmrg    int x,
54ab47cfaaSmrg    int y,
55ab47cfaaSmrg    int w,
56ab47cfaaSmrg    int h);
57ab47cfaaSmrg
58ab47cfaaSmrgstatic void SavageSubsequentSolidBresenhamLine(
59ab47cfaaSmrg    ScrnInfoPtr pScrn,
60ab47cfaaSmrg    int x1,
61ab47cfaaSmrg    int y1,
62ab47cfaaSmrg    int e1,
63ab47cfaaSmrg    int e2,
64ab47cfaaSmrg    int err,
65ab47cfaaSmrg    int length,
66ab47cfaaSmrg    int octant);
67ab47cfaaSmrg
68ab47cfaaSmrgstatic void SavageSetupForCPUToScreenColorExpandFill(
69ab47cfaaSmrg    ScrnInfoPtr pScrn,
70ab47cfaaSmrg    int fg,
71ab47cfaaSmrg    int bg,
72ab47cfaaSmrg    int rop,
73ab47cfaaSmrg    unsigned int planemask);
74ab47cfaaSmrg
75ab47cfaaSmrgstatic void SavageSubsequentScanlineCPUToScreenColorExpandFill(
76ab47cfaaSmrg    ScrnInfoPtr pScrn,
77ab47cfaaSmrg    int x,
78ab47cfaaSmrg    int y,
79ab47cfaaSmrg    int w,
80ab47cfaaSmrg    int h,
81ab47cfaaSmrg    int skipleft);
82ab47cfaaSmrg
83ab47cfaaSmrgstatic void SavageSubsequentColorExpandScanline(
84ab47cfaaSmrg    ScrnInfoPtr pScrn,
85ab47cfaaSmrg    int buffer_no);
86ab47cfaaSmrg
87ab47cfaaSmrgstatic void SavageSetupForMono8x8PatternFill(
88ab47cfaaSmrg    ScrnInfoPtr pScrn,
89ab47cfaaSmrg    int patternx,
90ab47cfaaSmrg    int patterny,
91ab47cfaaSmrg    int fg,
92ab47cfaaSmrg    int bg,
93ab47cfaaSmrg    int rop,
94ab47cfaaSmrg    unsigned int planemask);
95ab47cfaaSmrg
96ab47cfaaSmrgstatic void SavageSubsequentMono8x8PatternFillRect(
97ab47cfaaSmrg    ScrnInfoPtr pScrn,
98ab47cfaaSmrg    int pattern0,
99ab47cfaaSmrg    int pattern1,
100ab47cfaaSmrg    int x,
101ab47cfaaSmrg    int y,
102ab47cfaaSmrg    int w,
103ab47cfaaSmrg    int h);
104ab47cfaaSmrg
105ab47cfaaSmrgstatic void SavageSetClippingRectangle(
106ab47cfaaSmrg    ScrnInfoPtr pScrn,
107ab47cfaaSmrg    int x1,
108ab47cfaaSmrg    int y1,
109ab47cfaaSmrg    int x2,
110ab47cfaaSmrg    int y2);
111ab47cfaaSmrg
112ab47cfaaSmrgstatic void SavageDisableClipping( ScrnInfoPtr );
113ab47cfaaSmrg
114ab47cfaaSmrg/* from savage_image.c: */
115ab47cfaaSmrg
116ab47cfaaSmrgvoid SavageSetupForImageWrite(
117ab47cfaaSmrg    ScrnInfoPtr pScrn,
118ab47cfaaSmrg    int rop,
119ab47cfaaSmrg    unsigned int planemask,
120ab47cfaaSmrg    int transparency_color,
121ab47cfaaSmrg    int bpp,
122ab47cfaaSmrg    int depth);
123ab47cfaaSmrg
124ab47cfaaSmrgvoid SavageSubsequentImageWriteRect(
125ab47cfaaSmrg    ScrnInfoPtr pScrn,
126ab47cfaaSmrg    int x,
127ab47cfaaSmrg    int y,
128ab47cfaaSmrg    int w,
129ab47cfaaSmrg    int h,
130ab47cfaaSmrg    int skipleft);
131ab47cfaaSmrg
132ab47cfaaSmrgvoid SavageWriteBitmapCPUToScreenColorExpand (
133ab47cfaaSmrg    ScrnInfoPtr pScrn,
134ab47cfaaSmrg    int x, int y, int w, int h,
135ab47cfaaSmrg    unsigned char * src,
136ab47cfaaSmrg    int srcwidth,
137ab47cfaaSmrg    int skipleft,
138ab47cfaaSmrg    int fg, int bg,
139ab47cfaaSmrg    int rop,
140ab47cfaaSmrg    unsigned int planemask
141ab47cfaaSmrg);
142ab47cfaaSmrg
143ab47cfaaSmrgstatic
144ab47cfaaSmrgvoid SavageRestoreAccelState(ScrnInfoPtr pScrn)
145ab47cfaaSmrg{
146ab47cfaaSmrg    SavagePtr psav = SAVPTR(pScrn);
147ab47cfaaSmrg
148ab47cfaaSmrg    psav->WaitIdleEmpty(psav);
149ab47cfaaSmrg
150ab47cfaaSmrg    return;
151ab47cfaaSmrg}
152aa9e3350Smrg#endif
153ab47cfaaSmrg
154ab47cfaaSmrgBool
155ab47cfaaSmrgSavageXAAInit(ScreenPtr pScreen)
156ab47cfaaSmrg{
157aa9e3350Smrg#ifdef HAVE_XAA_H
158aa9e3350Smrg    ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
159ab47cfaaSmrg    SavagePtr psav = SAVPTR(pScrn);
160ab47cfaaSmrg    XAAInfoRecPtr xaaptr;
161ab47cfaaSmrg    BoxRec AvailFBArea;
162ab47cfaaSmrg    int tmp;
163ab47cfaaSmrg
164ab47cfaaSmrg    /* Set-up our GE command primitive */
165ab47cfaaSmrg
166ab47cfaaSmrg    if (pScrn->depth == 8) {
167ab47cfaaSmrg	psav->PlaneMask = 0xFF;
168ab47cfaaSmrg    }
169ab47cfaaSmrg    else if (pScrn->depth == 15) {
170ab47cfaaSmrg	psav->PlaneMask = 0x7FFF;
171ab47cfaaSmrg    }
172ab47cfaaSmrg    else if (pScrn->depth == 16) {
173ab47cfaaSmrg	psav->PlaneMask = 0xFFFF;
174ab47cfaaSmrg    }
175ab47cfaaSmrg    else if (pScrn->depth == 24) {
176ab47cfaaSmrg	psav->PlaneMask = 0xFFFFFF;
177ab47cfaaSmrg    }
178ab47cfaaSmrg
179ab47cfaaSmrg    /* General acceleration flags */
180ab47cfaaSmrg
181ab47cfaaSmrg    if (!(xaaptr = psav->AccelInfoRec = XAACreateInfoRec())) {
182ab47cfaaSmrg	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
183ab47cfaaSmrg		"Failed to allocate XAAInfoRec.\n");
184ab47cfaaSmrg	return FALSE;
185ab47cfaaSmrg    }
186ab47cfaaSmrg
187ab47cfaaSmrg    xaaptr->Flags = 0
188ab47cfaaSmrg    	| PIXMAP_CACHE
189ab47cfaaSmrg	| OFFSCREEN_PIXMAPS
190ab47cfaaSmrg	| LINEAR_FRAMEBUFFER
191ab47cfaaSmrg	;
192ab47cfaaSmrg
193ab47cfaaSmrg
194ab47cfaaSmrg    if(xf86IsEntityShared(pScrn->entityList[0]))
195ab47cfaaSmrg    {
196ab47cfaaSmrg        DevUnion* pPriv;
197ab47cfaaSmrg        SavageEntPtr pEnt;
198ab47cfaaSmrg        pPriv = xf86GetEntityPrivate(pScrn->entityList[0],
199ab47cfaaSmrg                gSavageEntityIndex);
200ab47cfaaSmrg        pEnt = pPriv->ptr;
201ab47cfaaSmrg
202ab47cfaaSmrg        /*if there are more than one devices sharing this entity, we
203ab47cfaaSmrg          have to assign this call back, otherwise the XAA will be
204ab47cfaaSmrg          disabled */
205ab47cfaaSmrg        if(pEnt->HasSecondary)
206ab47cfaaSmrg           xaaptr->RestoreAccelState           = SavageRestoreAccelState;
207ab47cfaaSmrg    }
208ab47cfaaSmrg
209ab47cfaaSmrg    /* Clipping */
210ab47cfaaSmrg
211ab47cfaaSmrg    xaaptr->SetClippingRectangle = SavageSetClippingRectangle;
212ab47cfaaSmrg    xaaptr->DisableClipping = SavageDisableClipping;
213ab47cfaaSmrg    xaaptr->ClippingFlags = 0
214ab47cfaaSmrg#if 0
215ab47cfaaSmrg	| HARDWARE_CLIP_SOLID_FILL
216ab47cfaaSmrg	| HARDWARE_CLIP_SOLID_LINE
217ab47cfaaSmrg	| HARDWARE_CLIP_DASHED_LINE
218ab47cfaaSmrg#endif
219ab47cfaaSmrg	| HARDWARE_CLIP_SCREEN_TO_SCREEN_COPY
220ab47cfaaSmrg	| HARDWARE_CLIP_MONO_8x8_FILL
221ab47cfaaSmrg	| HARDWARE_CLIP_COLOR_8x8_FILL
222ab47cfaaSmrg	;
223ab47cfaaSmrg
224ab47cfaaSmrg    xaaptr->Sync = SavageAccelSync;
225ab47cfaaSmrg
226ab47cfaaSmrg    /* ScreenToScreen copies */
227ab47cfaaSmrg
228ab47cfaaSmrg#if 1
229ab47cfaaSmrg
230ab47cfaaSmrg    xaaptr->SetupForScreenToScreenCopy = SavageSetupForScreenToScreenCopy;
231ab47cfaaSmrg    xaaptr->SubsequentScreenToScreenCopy = SavageSubsequentScreenToScreenCopy;
232ab47cfaaSmrg    xaaptr->ScreenToScreenCopyFlags = 0
233ab47cfaaSmrg	| NO_TRANSPARENCY
234ab47cfaaSmrg	| NO_PLANEMASK
235ab47cfaaSmrg	| ROP_NEEDS_SOURCE;
236ab47cfaaSmrg
237ab47cfaaSmrg#endif
238ab47cfaaSmrg
239ab47cfaaSmrg
240ab47cfaaSmrg    /* Solid filled rectangles */
241ab47cfaaSmrg
242ab47cfaaSmrg#if 1
243ab47cfaaSmrg    xaaptr->SetupForSolidFill = SavageSetupForSolidFill;
244ab47cfaaSmrg    xaaptr->SubsequentSolidFillRect = SavageSubsequentSolidFillRect;
245ab47cfaaSmrg    xaaptr->SolidFillFlags = NO_PLANEMASK | ROP_NEEDS_SOURCE;
246ab47cfaaSmrg#endif
247ab47cfaaSmrg
248ab47cfaaSmrg    /* Mono 8x8 pattern fills */
249ab47cfaaSmrg
250ab47cfaaSmrg#if 1
251ab47cfaaSmrg    xaaptr->SetupForMono8x8PatternFill = SavageSetupForMono8x8PatternFill;
252ab47cfaaSmrg    xaaptr->SubsequentMono8x8PatternFillRect
253ab47cfaaSmrg    	= SavageSubsequentMono8x8PatternFillRect;
254ab47cfaaSmrg    xaaptr->Mono8x8PatternFillFlags = 0
255ab47cfaaSmrg	| HARDWARE_PATTERN_PROGRAMMED_BITS
256ab47cfaaSmrg	| HARDWARE_PATTERN_SCREEN_ORIGIN
257ab47cfaaSmrg	| BIT_ORDER_IN_BYTE_MSBFIRST
258ab47cfaaSmrg	| ROP_NEEDS_SOURCE
259ab47cfaaSmrg	;
260ab47cfaaSmrg    if( psav->Chipset == S3_SAVAGE4 )
261ab47cfaaSmrg	xaaptr->Mono8x8PatternFillFlags |= NO_TRANSPARENCY;
262ab47cfaaSmrg#endif
263ab47cfaaSmrg
264ab47cfaaSmrg    /* Solid lines */
265ab47cfaaSmrg
266ab47cfaaSmrg#if 1
267ab47cfaaSmrg    xaaptr->SolidLineFlags = NO_PLANEMASK;
268ab47cfaaSmrg    xaaptr->SetupForSolidLine = SavageSetupForSolidFill;
269ab47cfaaSmrg    xaaptr->SubsequentSolidBresenhamLine = SavageSubsequentSolidBresenhamLine;
270ab47cfaaSmrg#if 0
271ab47cfaaSmrg    xaaptr->SubsequentSolidFillTrap = SavageSubsequentSolidFillTrap;
272ab47cfaaSmrg#endif
273ab47cfaaSmrg
274ab47cfaaSmrg    xaaptr->SolidBresenhamLineErrorTermBits = 13;
275ab47cfaaSmrg#endif
276ab47cfaaSmrg
277ab47cfaaSmrg    /* ImageWrite */
278ab47cfaaSmrg
279ab47cfaaSmrg    xaaptr->ImageWriteFlags = 0
280ab47cfaaSmrg	| NO_PLANEMASK
281ab47cfaaSmrg	| CPU_TRANSFER_PAD_DWORD
282ab47cfaaSmrg	| SCANLINE_PAD_DWORD
283ab47cfaaSmrg	| BIT_ORDER_IN_BYTE_MSBFIRST
284ab47cfaaSmrg	| LEFT_EDGE_CLIPPING
285ab47cfaaSmrg	;
286ab47cfaaSmrg    xaaptr->SetupForImageWrite = SavageSetupForImageWrite;
287ab47cfaaSmrg    xaaptr->SubsequentImageWriteRect = SavageSubsequentImageWriteRect;
288ab47cfaaSmrg    xaaptr->NumScanlineImageWriteBuffers = 1;
289ab47cfaaSmrg    xaaptr->ImageWriteBase = psav->BciMem;
290ab47cfaaSmrg    xaaptr->ImageWriteRange = 120 * 1024;
291ab47cfaaSmrg
292ab47cfaaSmrg
293ab47cfaaSmrg    /* CPU to Screen color expansion */
294ab47cfaaSmrg
295ab47cfaaSmrg    xaaptr->ScanlineCPUToScreenColorExpandFillFlags = 0
296ab47cfaaSmrg	| NO_PLANEMASK
297ab47cfaaSmrg	| CPU_TRANSFER_PAD_DWORD
298ab47cfaaSmrg	| SCANLINE_PAD_DWORD
299ab47cfaaSmrg	| BIT_ORDER_IN_BYTE_MSBFIRST
300ab47cfaaSmrg	| LEFT_EDGE_CLIPPING
301ab47cfaaSmrg	| ROP_NEEDS_SOURCE
302ab47cfaaSmrg	;
303ab47cfaaSmrg
304ab47cfaaSmrg    xaaptr->SetupForScanlineCPUToScreenColorExpandFill =
305ab47cfaaSmrg            SavageSetupForCPUToScreenColorExpandFill;
306ab47cfaaSmrg    xaaptr->SubsequentScanlineCPUToScreenColorExpandFill =
307ab47cfaaSmrg            SavageSubsequentScanlineCPUToScreenColorExpandFill;
308ab47cfaaSmrg    xaaptr->SubsequentColorExpandScanline =
309ab47cfaaSmrg	    SavageSubsequentColorExpandScanline;
310ab47cfaaSmrg    xaaptr->ColorExpandBase = psav->BciMem;
311ab47cfaaSmrg    xaaptr->ScanlineColorExpandBuffers = &xaaptr->ColorExpandBase;
312ab47cfaaSmrg    xaaptr->NumScanlineColorExpandBuffers = 1;
313ab47cfaaSmrg
314ab47cfaaSmrg    /* Set up screen parameters. */
315ab47cfaaSmrg
316ab47cfaaSmrg    psav->Bpp = pScrn->bitsPerPixel / 8;
317ab47cfaaSmrg    psav->Bpl = pScrn->displayWidth * psav->Bpp;
318ab47cfaaSmrg    psav->ScissB = (psav->CursorKByte << 10) / psav->Bpl;
319ab47cfaaSmrg    if (psav->ScissB > 2047)
320ab47cfaaSmrg        psav->ScissB = 2047;
321ab47cfaaSmrg
322ab47cfaaSmrg    /*
323ab47cfaaSmrg     * Finally, we set up the video memory space available to the pixmap
324ab47cfaaSmrg     * cache. In this case, all memory from the end of the virtual screen
325ab47cfaaSmrg     * to the end of the command overflow buffer can be used. If you haven't
326ab47cfaaSmrg     * enabled the PIXMAP_CACHE flag, then these lines can be omitted.
327ab47cfaaSmrg     */
328ab47cfaaSmrg
329ab47cfaaSmrg    AvailFBArea.x1 = 0;
330ab47cfaaSmrg    AvailFBArea.y1 = 0;
331ab47cfaaSmrg    AvailFBArea.x2 = psav->cxMemory;
332ab47cfaaSmrg    AvailFBArea.y2 = psav->cyMemory;
333ab47cfaaSmrg    xf86InitFBManager(pScreen, &AvailFBArea);
334ab47cfaaSmrg    /*
335ab47cfaaSmrg     * because the alignment requirement,the on-screen need more memory
336ab47cfaaSmrg     * than (0,0,virtualX,virtualY), but xf86InitFBManager only subtract
337ab47cfaaSmrg     * (pScrn->virtualX * pScrn->virtualY from (0,0,cxMemory,cyMemory),so
338ab47cfaaSmrg     * here,we should reserver some memory for on-screen
339ab47cfaaSmrg     */
340ab47cfaaSmrg    tmp = ((psav->cxMemory * pScrn->virtualY - pScrn->virtualX * pScrn->virtualY)
341ab47cfaaSmrg               + psav->cxMemory -1) / (psav->cxMemory);
342ab47cfaaSmrg    if (tmp)
343ab47cfaaSmrg        xf86AllocateOffscreenArea(pScreen, psav->cxMemory,tmp, 0, NULL, NULL, NULL);
344ab47cfaaSmrg
345ab47cfaaSmrg    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
346ab47cfaaSmrg                   "Using %d lines for offscreen memory.\n",
347ab47cfaaSmrg                   psav->cyMemory - pScrn->virtualY );
348ab47cfaaSmrg
349ab47cfaaSmrg
350ab47cfaaSmrg    return XAAInit(pScreen, xaaptr);
351aa9e3350Smrg#else
352aa9e3350Smrg    return FALSE;
353aa9e3350Smrg#endif
354ab47cfaaSmrg}
355ab47cfaaSmrg
356ab47cfaaSmrg/* The sync function for the GE */
357ab47cfaaSmrgvoid
358ab47cfaaSmrgSavageAccelSync(ScrnInfoPtr pScrn)
359ab47cfaaSmrg{
360ab47cfaaSmrg    SavagePtr psav = SAVPTR(pScrn);
361ab47cfaaSmrg    psav->WaitIdleEmpty(psav);
362ab47cfaaSmrg}
363ab47cfaaSmrg
364aa9e3350Smrg#ifdef HAVE_XAA_H
365ab47cfaaSmrg/*
366ab47cfaaSmrg * The XAA ROP helper routines all assume that a solid color is a
367ab47cfaaSmrg * "pattern".  The Savage chips, however, apply a non-stippled solid
368ab47cfaaSmrg * color as "source".  Thus, we use a slightly customized version.
369ab47cfaaSmrg */
370ab47cfaaSmrg
371ab47cfaaSmrgstatic int
372ab47cfaaSmrgSavageHelpPatternROP(ScrnInfoPtr pScrn, int *fg, int *bg, unsigned int pm, int *rop)
373ab47cfaaSmrg{
374ab47cfaaSmrg    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
375ab47cfaaSmrg    int ret = 0;
376ab47cfaaSmrg
377ab47cfaaSmrg    pm &= infoRec->FullPlanemask;
378ab47cfaaSmrg
379ab47cfaaSmrg    if(pm == infoRec->FullPlanemask) {
380ab47cfaaSmrg	if(!NO_SRC_ROP(*rop))
381ab47cfaaSmrg	   ret |= ROP_PAT;
382ab47cfaaSmrg	*rop = XAAGetCopyROP(*rop);
383ab47cfaaSmrg    } else {
384ab47cfaaSmrg	switch(*rop) {
385ab47cfaaSmrg	case GXnoop:
386ab47cfaaSmrg	    break;
387ab47cfaaSmrg	case GXset:
388ab47cfaaSmrg	case GXclear:
389ab47cfaaSmrg	case GXinvert:
390ab47cfaaSmrg	    ret |= ROP_PAT;
391ab47cfaaSmrg	    *fg = pm;
392ab47cfaaSmrg	    if(*bg != -1)
393ab47cfaaSmrg		*bg = pm;
394ab47cfaaSmrg	    break;
395ab47cfaaSmrg	default:
396ab47cfaaSmrg	    ret |= ROP_PAT | ROP_SRC;
397ab47cfaaSmrg	    break;
398ab47cfaaSmrg	}
399ab47cfaaSmrg	*rop = XAAGetCopyROP_PM(*rop);
400ab47cfaaSmrg    }
401ab47cfaaSmrg
402ab47cfaaSmrg    return ret;
403ab47cfaaSmrg}
404ab47cfaaSmrg
405ab47cfaaSmrg
406ab47cfaaSmrgstatic int
407ab47cfaaSmrgSavageHelpSolidROP(ScrnInfoPtr pScrn, int *fg, unsigned int pm, int *rop)
408ab47cfaaSmrg{
409ab47cfaaSmrg    XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
410ab47cfaaSmrg    int ret = 0;
411ab47cfaaSmrg
412ab47cfaaSmrg    pm &= infoRec->FullPlanemask;
413ab47cfaaSmrg
414ab47cfaaSmrg    if(pm == infoRec->FullPlanemask) {
415ab47cfaaSmrg	if(!NO_SRC_ROP(*rop))
416ab47cfaaSmrg	   ret |= ROP_PAT;
417ab47cfaaSmrg	*rop = XAAGetCopyROP(*rop);
418ab47cfaaSmrg    } else {
419ab47cfaaSmrg	switch(*rop) {
420ab47cfaaSmrg	case GXnoop:
421ab47cfaaSmrg	    break;
422ab47cfaaSmrg	case GXset:
423ab47cfaaSmrg	case GXclear:
424ab47cfaaSmrg	case GXinvert:
425ab47cfaaSmrg	    ret |= ROP_PAT;
426ab47cfaaSmrg	    *fg = pm;
427ab47cfaaSmrg	    break;
428ab47cfaaSmrg	default:
429ab47cfaaSmrg	    ret |= ROP_PAT | ROP_SRC;
430ab47cfaaSmrg	    break;
431ab47cfaaSmrg	}
432ab47cfaaSmrg	*rop = XAAGetCopyROP_PM(*rop);
433ab47cfaaSmrg    }
434ab47cfaaSmrg
435ab47cfaaSmrg    return ret;
436ab47cfaaSmrg}
437ab47cfaaSmrg
438ab47cfaaSmrg
439ab47cfaaSmrg
440ab47cfaaSmrg/* These are the ScreenToScreen bitblt functions. We support all ROPs, all
441ab47cfaaSmrg * directions, and a planemask by adjusting the ROP and using the mono pattern
442ab47cfaaSmrg * registers.
443ab47cfaaSmrg *
444ab47cfaaSmrg * (That's a lie; we don't really support planemask.)
445ab47cfaaSmrg */
446ab47cfaaSmrg
447ab47cfaaSmrgstatic void
448ab47cfaaSmrgSavageSetupForScreenToScreenCopy(
449ab47cfaaSmrg    ScrnInfoPtr pScrn,
450ab47cfaaSmrg    int xdir,
451ab47cfaaSmrg    int ydir,
452ab47cfaaSmrg    int rop,
453ab47cfaaSmrg    unsigned planemask,
454ab47cfaaSmrg    int transparency_color)
455ab47cfaaSmrg{
456ab47cfaaSmrg    SavagePtr psav = SAVPTR(pScrn);
457ab47cfaaSmrg    int cmd;
458ab47cfaaSmrg
459ab47cfaaSmrg    cmd = BCI_CMD_RECT | BCI_CMD_DEST_PBD_NEW | BCI_CMD_SRC_SBD_COLOR_NEW;
460ab47cfaaSmrg
461ab47cfaaSmrg    BCI_CMD_SET_ROP( cmd, XAAGetCopyROP(rop) );
462ab47cfaaSmrg    if (transparency_color != -1)
463ab47cfaaSmrg        cmd |= BCI_CMD_SEND_COLOR | BCI_CMD_SRC_TRANSPARENT;
464ab47cfaaSmrg
465ab47cfaaSmrg    if (xdir == 1 ) cmd |= BCI_CMD_RECT_XP;
466ab47cfaaSmrg    if (ydir == 1 ) cmd |= BCI_CMD_RECT_YP;
467ab47cfaaSmrg
468ab47cfaaSmrg    psav->SavedBciCmd = cmd;
469ab47cfaaSmrg    psav->SavedBgColor = transparency_color;
470ab47cfaaSmrg}
471ab47cfaaSmrg
472ab47cfaaSmrgstatic void
473ab47cfaaSmrgSavageSubsequentScreenToScreenCopy(
474ab47cfaaSmrg    ScrnInfoPtr pScrn,
475ab47cfaaSmrg    int x1,
476ab47cfaaSmrg    int y1,
477ab47cfaaSmrg    int x2,
478ab47cfaaSmrg    int y2,
479ab47cfaaSmrg    int w,
480ab47cfaaSmrg    int h)
481ab47cfaaSmrg{
482ab47cfaaSmrg    SavagePtr psav = SAVPTR(pScrn);
483ab47cfaaSmrg
484ab47cfaaSmrg    BCI_GET_PTR;
485ab47cfaaSmrg
486ab47cfaaSmrg    if (!w || !h) return;
487ab47cfaaSmrg
488ab47cfaaSmrg    if (!(psav->SavedBciCmd & BCI_CMD_RECT_XP)) {
489ab47cfaaSmrg        w --;
490ab47cfaaSmrg        x1 += w;
491ab47cfaaSmrg        x2 += w;
492ab47cfaaSmrg        w ++;
493ab47cfaaSmrg    }
494ab47cfaaSmrg    if (!(psav->SavedBciCmd & BCI_CMD_RECT_YP)) {
495ab47cfaaSmrg        h --;
496ab47cfaaSmrg        y1 += h;
497ab47cfaaSmrg        y2 += h;
498ab47cfaaSmrg        h ++;
499ab47cfaaSmrg    }
500ab47cfaaSmrg
501ab47cfaaSmrg    psav->WaitQueue(psav,9);
502ab47cfaaSmrg
503ab47cfaaSmrg
504ab47cfaaSmrg    BCI_SEND(psav->SavedBciCmd);
505ab47cfaaSmrg
506ab47cfaaSmrg    BCI_SEND(psav->GlobalBD.bd2.LoPart);
507ab47cfaaSmrg    BCI_SEND(psav->GlobalBD.bd2.HiPart);
508ab47cfaaSmrg
509ab47cfaaSmrg    BCI_SEND(psav->GlobalBD.bd2.LoPart);
510ab47cfaaSmrg    BCI_SEND(psav->GlobalBD.bd2.HiPart);
511ab47cfaaSmrg
512ab47cfaaSmrg    if (psav->SavedBgColor != 0xffffffff)
513ab47cfaaSmrg	BCI_SEND(psav->SavedBgColor);
514ab47cfaaSmrg    BCI_SEND(BCI_X_Y(x1, y1));
515ab47cfaaSmrg    BCI_SEND(BCI_X_Y(x2, y2));
516ab47cfaaSmrg    BCI_SEND(BCI_W_H(w, h));
517ab47cfaaSmrg}
518ab47cfaaSmrg
519ab47cfaaSmrg
520ab47cfaaSmrg/*
521ab47cfaaSmrg * SetupForSolidFill is also called to set up for lines.
522ab47cfaaSmrg */
523ab47cfaaSmrg
524ab47cfaaSmrgstatic void
525ab47cfaaSmrgSavageSetupForSolidFill(
526ab47cfaaSmrg    ScrnInfoPtr pScrn,
527ab47cfaaSmrg    int color,
528ab47cfaaSmrg    int rop,
529ab47cfaaSmrg    unsigned int planemask)
530ab47cfaaSmrg{
531ab47cfaaSmrg    SavagePtr psav = SAVPTR(pScrn);
532ab47cfaaSmrg    XAAInfoRecPtr xaaptr = GET_XAAINFORECPTR_FROM_SCRNINFOPTR( pScrn );
533ab47cfaaSmrg    int cmd;
534ab47cfaaSmrg    int mix;
535ab47cfaaSmrg
536ab47cfaaSmrg    cmd = BCI_CMD_RECT
537ab47cfaaSmrg        | BCI_CMD_RECT_XP | BCI_CMD_RECT_YP
538ab47cfaaSmrg        | BCI_CMD_DEST_PBD_NEW | BCI_CMD_SRC_SOLID;
539ab47cfaaSmrg
540ab47cfaaSmrg    /* Don't send a color if we don't have to. */
541ab47cfaaSmrg
542ab47cfaaSmrg    if( rop == GXcopy )
543ab47cfaaSmrg    {
544ab47cfaaSmrg	if( color == 0 )
545ab47cfaaSmrg	    rop = GXclear;
546ab47cfaaSmrg	else if( (unsigned int)color == xaaptr->FullPlanemask )
547ab47cfaaSmrg	    rop = GXset;
548ab47cfaaSmrg    }
549ab47cfaaSmrg
550ab47cfaaSmrg    mix = SavageHelpSolidROP( pScrn, &color, planemask, &rop );
551ab47cfaaSmrg
552ab47cfaaSmrg    if( mix & ROP_PAT )
553ab47cfaaSmrg	cmd |= BCI_CMD_SEND_COLOR;
554ab47cfaaSmrg
555ab47cfaaSmrg    BCI_CMD_SET_ROP( cmd, rop );
556ab47cfaaSmrg
557ab47cfaaSmrg    psav->SavedBciCmd = cmd;
558ab47cfaaSmrg    psav->SavedFgColor = color;
559ab47cfaaSmrg}
560ab47cfaaSmrg
561ab47cfaaSmrg
562ab47cfaaSmrgstatic void
563ab47cfaaSmrgSavageSubsequentSolidFillRect(
564ab47cfaaSmrg    ScrnInfoPtr pScrn,
565ab47cfaaSmrg    int x,
566ab47cfaaSmrg    int y,
567ab47cfaaSmrg    int w,
568ab47cfaaSmrg    int h)
569ab47cfaaSmrg{
570ab47cfaaSmrg    SavagePtr psav = SAVPTR(pScrn);
571ab47cfaaSmrg    BCI_GET_PTR;
572ab47cfaaSmrg
573ab47cfaaSmrg    if( !w || !h )
574ab47cfaaSmrg	return;
575ab47cfaaSmrg
576ab47cfaaSmrg    psav->WaitQueue(psav,7);
577ab47cfaaSmrg
578ab47cfaaSmrg    BCI_SEND(psav->SavedBciCmd);
579ab47cfaaSmrg
580ab47cfaaSmrg    BCI_SEND(psav->GlobalBD.bd2.LoPart);
581ab47cfaaSmrg    BCI_SEND(psav->GlobalBD.bd2.HiPart);
582ab47cfaaSmrg
583ab47cfaaSmrg    if( psav->SavedBciCmd & BCI_CMD_SEND_COLOR )
584ab47cfaaSmrg	BCI_SEND(psav->SavedFgColor);
585ab47cfaaSmrg    BCI_SEND(BCI_X_Y(x, y));
586ab47cfaaSmrg    BCI_SEND(BCI_W_H(w, h));
587ab47cfaaSmrg}
588ab47cfaaSmrg
589ab47cfaaSmrgstatic void
590ab47cfaaSmrgSavageSetupForCPUToScreenColorExpandFill(
591ab47cfaaSmrg    ScrnInfoPtr pScrn,
592ab47cfaaSmrg    int fg,
593ab47cfaaSmrg    int bg,
594ab47cfaaSmrg    int rop,
595ab47cfaaSmrg    unsigned int planemask)
596ab47cfaaSmrg{
597ab47cfaaSmrg    SavagePtr psav = SAVPTR(pScrn);
598ab47cfaaSmrg    int cmd;
599ab47cfaaSmrg    int mix;
600ab47cfaaSmrg
601ab47cfaaSmrg    cmd = BCI_CMD_RECT | BCI_CMD_RECT_XP | BCI_CMD_RECT_YP
602ab47cfaaSmrg	| BCI_CMD_CLIP_LR
603ab47cfaaSmrg        | BCI_CMD_DEST_PBD_NEW | BCI_CMD_SRC_MONO;
604ab47cfaaSmrg
605ab47cfaaSmrg    mix = SavageHelpPatternROP( pScrn, &fg, &bg, planemask, &rop );
606ab47cfaaSmrg
607ab47cfaaSmrg    if( mix & ROP_PAT )
608ab47cfaaSmrg        cmd |= BCI_CMD_SEND_COLOR;
609ab47cfaaSmrg
610ab47cfaaSmrg    BCI_CMD_SET_ROP( cmd, rop );
611ab47cfaaSmrg
612ab47cfaaSmrg    if (bg != -1)
613ab47cfaaSmrg        cmd |= BCI_CMD_SEND_COLOR;
614ab47cfaaSmrg    else
615ab47cfaaSmrg	cmd |= BCI_CMD_SRC_TRANSPARENT;
616ab47cfaaSmrg
617ab47cfaaSmrg    psav->SavedBciCmd = cmd;
618ab47cfaaSmrg    psav->SavedFgColor = fg;
619ab47cfaaSmrg    psav->SavedBgColor = bg;
620ab47cfaaSmrg}
621ab47cfaaSmrg
622ab47cfaaSmrg
623ab47cfaaSmrgstatic void
624ab47cfaaSmrgSavageSubsequentScanlineCPUToScreenColorExpandFill(
625ab47cfaaSmrg    ScrnInfoPtr pScrn,
626ab47cfaaSmrg    int x,
627ab47cfaaSmrg    int y,
628ab47cfaaSmrg    int w,
629ab47cfaaSmrg    int h,
630ab47cfaaSmrg    int skipleft)
631ab47cfaaSmrg{
632ab47cfaaSmrg    SavagePtr psav = SAVPTR(pScrn);
633ab47cfaaSmrg    BCI_GET_PTR;
634ab47cfaaSmrg
635ab47cfaaSmrg    /* XAA will be sending bitmap data next.  */
636ab47cfaaSmrg    /* We should probably wait for empty/idle here. */
637ab47cfaaSmrg
638ab47cfaaSmrg    psav->WaitQueue(psav,22);
639ab47cfaaSmrg
640ab47cfaaSmrg    BCI_SEND(psav->SavedBciCmd);
641ab47cfaaSmrg
642ab47cfaaSmrg    BCI_SEND(psav->GlobalBD.bd2.LoPart);
643ab47cfaaSmrg    BCI_SEND(psav->GlobalBD.bd2.HiPart);
644ab47cfaaSmrg
645ab47cfaaSmrg    BCI_SEND(BCI_CLIP_LR(x+skipleft, x+w-1));
646ab47cfaaSmrg    w = (w + 31) & ~31;
647ab47cfaaSmrg    if( psav->SavedBciCmd & BCI_CMD_SEND_COLOR )
648ab47cfaaSmrg	BCI_SEND(psav->SavedFgColor);
649ab47cfaaSmrg    if( psav->SavedBgColor != 0xffffffff )
650ab47cfaaSmrg	BCI_SEND(psav->SavedBgColor);
651ab47cfaaSmrg    BCI_SEND(BCI_X_Y(x, y));
652ab47cfaaSmrg    BCI_SEND(BCI_W_H(w, 1));
653ab47cfaaSmrg
654ab47cfaaSmrg    psav->Rect.x = x;
655ab47cfaaSmrg    psav->Rect.y = y + 1;
656ab47cfaaSmrg    psav->Rect.width = w;
657ab47cfaaSmrg    psav->Rect.height = h - 1;
658ab47cfaaSmrg}
659ab47cfaaSmrg
660ab47cfaaSmrgstatic void
661ab47cfaaSmrgSavageSubsequentColorExpandScanline(
662ab47cfaaSmrg    ScrnInfoPtr pScrn,
663ab47cfaaSmrg    int buffer_no)
664ab47cfaaSmrg{
665ab47cfaaSmrg    /* This gets call after each scanline's image data has been sent. */
666ab47cfaaSmrg    SavagePtr psav = SAVPTR(pScrn);
667ab47cfaaSmrg    xRectangle xr = psav->Rect;
668ab47cfaaSmrg    BCI_GET_PTR;
669ab47cfaaSmrg
670ab47cfaaSmrg    if( xr.height )
671ab47cfaaSmrg    {
672ab47cfaaSmrg	psav->WaitQueue(psav,20);
673ab47cfaaSmrg	BCI_SEND(BCI_X_Y( xr.x, xr.y));
674ab47cfaaSmrg	BCI_SEND(BCI_W_H( xr.width, 1 ));
675ab47cfaaSmrg        psav->Rect.height--;
676ab47cfaaSmrg	psav->Rect.y++;
677ab47cfaaSmrg    }
678ab47cfaaSmrg}
679ab47cfaaSmrg
680ab47cfaaSmrg
681ab47cfaaSmrg/*
6822b2b4fcbSmrg * The meaning of the two pattern parameters to Setup & Subsequent for
683ab47cfaaSmrg * Mono8x8Patterns varies depending on the flag bits.  We specify
684ab47cfaaSmrg * HW_PROGRAMMED_BITS, which means our hardware can handle 8x8 patterns
685ab47cfaaSmrg * without caching in the frame buffer.  Thus, Setup gets the pattern bits.
686ab47cfaaSmrg * There is no way with BCI to rotate an 8x8 pattern, so we do NOT specify
6872b2b4fcbSmrg * HW_PROGRAMMED_ORIGIN.  XAA will rotate it for us and pass the rotated
688ab47cfaaSmrg * pattern to both Setup and Subsequent.  If we DID specify PROGRAMMED_ORIGIN,
689ab47cfaaSmrg * then Setup would get the unrotated pattern, and Subsequent gets the
690ab47cfaaSmrg * origin values.
691ab47cfaaSmrg */
692ab47cfaaSmrg
693ab47cfaaSmrgstatic void
694ab47cfaaSmrgSavageSetupForMono8x8PatternFill(
695ab47cfaaSmrg    ScrnInfoPtr pScrn,
696ab47cfaaSmrg    int patternx,
697ab47cfaaSmrg    int patterny,
698ab47cfaaSmrg    int fg,
699ab47cfaaSmrg    int bg,
700ab47cfaaSmrg    int rop,
701ab47cfaaSmrg    unsigned int planemask)
702ab47cfaaSmrg{
703ab47cfaaSmrg    SavagePtr psav = SAVPTR(pScrn);
704ab47cfaaSmrg    int cmd;
705ab47cfaaSmrg    int mix;
706ab47cfaaSmrg
707ab47cfaaSmrg    mix = XAAHelpPatternROP( pScrn, &fg, &bg, planemask, &rop );
708ab47cfaaSmrg
709ab47cfaaSmrg    cmd = BCI_CMD_RECT | BCI_CMD_RECT_XP | BCI_CMD_RECT_YP
710ab47cfaaSmrg        | BCI_CMD_DEST_PBD_NEW;
711ab47cfaaSmrg
712ab47cfaaSmrg    if( mix & ROP_PAT )
713ab47cfaaSmrg	cmd |= BCI_CMD_SEND_COLOR | BCI_CMD_PAT_MONO;
714ab47cfaaSmrg
715ab47cfaaSmrg    if (bg == -1)
716ab47cfaaSmrg	cmd |= BCI_CMD_PAT_TRANSPARENT;
717ab47cfaaSmrg
718ab47cfaaSmrg    BCI_CMD_SET_ROP(cmd, rop);
719ab47cfaaSmrg
720ab47cfaaSmrg    psav->SavedBciCmd = cmd;
721ab47cfaaSmrg    psav->SavedFgColor = fg;
722ab47cfaaSmrg    psav->SavedBgColor = bg;
723ab47cfaaSmrg}
724ab47cfaaSmrg
725ab47cfaaSmrg
726ab47cfaaSmrgstatic void
727ab47cfaaSmrgSavageSubsequentMono8x8PatternFillRect(
728ab47cfaaSmrg    ScrnInfoPtr pScrn,
729ab47cfaaSmrg    int pattern0,
730ab47cfaaSmrg    int pattern1,
731ab47cfaaSmrg    int x,
732ab47cfaaSmrg    int y,
733ab47cfaaSmrg    int w,
734ab47cfaaSmrg    int h)
735ab47cfaaSmrg{
736ab47cfaaSmrg    SavagePtr psav = SAVPTR(pScrn);
737ab47cfaaSmrg    BCI_GET_PTR;
738ab47cfaaSmrg
739ab47cfaaSmrg    /*
740ab47cfaaSmrg     * I didn't think it was my job to do trivial rejection, but
741ab47cfaaSmrg     * miFillGeneralPolygon definitely generates null spans, and XAA
742ab47cfaaSmrg     * just passes them through.
743ab47cfaaSmrg     */
744ab47cfaaSmrg
745ab47cfaaSmrg    if( !w || !h )
746ab47cfaaSmrg	return;
747ab47cfaaSmrg
748ab47cfaaSmrg    psav->WaitQueue(psav,9);
749ab47cfaaSmrg    BCI_SEND(psav->SavedBciCmd);
750ab47cfaaSmrg
751ab47cfaaSmrg    BCI_SEND(psav->GlobalBD.bd2.LoPart);
752ab47cfaaSmrg    BCI_SEND(psav->GlobalBD.bd2.HiPart);
753ab47cfaaSmrg
754ab47cfaaSmrg    if( psav->SavedBciCmd & BCI_CMD_SEND_COLOR )
755ab47cfaaSmrg	BCI_SEND(psav->SavedFgColor);
756ab47cfaaSmrg    if( psav->SavedBgColor != 0xffffffff )
757ab47cfaaSmrg	BCI_SEND(psav->SavedBgColor);
758ab47cfaaSmrg    BCI_SEND(BCI_X_Y(x, y));
759ab47cfaaSmrg    BCI_SEND(BCI_W_H(w, h));
760ab47cfaaSmrg    if( psav->SavedBciCmd & BCI_CMD_PAT_MONO )
761ab47cfaaSmrg    {
762ab47cfaaSmrg	BCI_SEND(pattern0);
763ab47cfaaSmrg	BCI_SEND(pattern1);
764ab47cfaaSmrg    }
765ab47cfaaSmrg}
766ab47cfaaSmrg
767ab47cfaaSmrg
768ab47cfaaSmrg#if 0
769ab47cfaaSmrgstatic void
770ab47cfaaSmrgSavageSetupForColor8x8PatternFill(
771ab47cfaaSmrg    ScrnInfoPtr pScrn,
772ab47cfaaSmrg    int patternx,
773ab47cfaaSmrg    int patterny,
774ab47cfaaSmrg    int rop,
775ab47cfaaSmrg    unsigned planemask,
776ab47cfaaSmrg    int trans_col)
777ab47cfaaSmrg{
778ab47cfaaSmrg    SavagePtr psav = SAVPTR(pScrn);
779ab47cfaaSmrg
780ab47cfaaSmrg    int cmd;
781ab47cfaaSmrg    unsigned int bd;
782ab47cfaaSmrg    int pat_offset;
783ab47cfaaSmrg
784ab47cfaaSmrg    /* ViRGEs and Savages do not support transparent color patterns. */
785ab47cfaaSmrg    /* We set the NO_TRANSPARENCY bit, so we should never receive one. */
786ab47cfaaSmrg
787ab47cfaaSmrg    pat_offset = (int) (patternx * psav->Bpp + patterny * psav->Bpl);
788ab47cfaaSmrg
789ab47cfaaSmrg    cmd = BCI_CMD_RECT | BCI_CMD_RECT_XP | BCI_CMD_RECT_YP
790ab47cfaaSmrg        | BCI_CMD_DEST_GBD | BCI_CMD_PAT_PBD_COLOR_NEW;
791ab47cfaaSmrg
792ab47cfaaSmrg    (void) XAAHelpSolidROP( pScrn, &trans_col, planemask, &rop );
793ab47cfaaSmrg
794ab47cfaaSmrg    BCI_CMD_SET_ROP(cmd, rop);
795ab47cfaaSmrg    bd = BCI_BD_BW_DISABLE;
796ab47cfaaSmrg    BCI_BD_SET_BPP(bd, pScrn->bitsPerPixel);
797ab47cfaaSmrg    BCI_BD_SET_STRIDE(bd, 8);
798ab47cfaaSmrg
799ab47cfaaSmrg    psav->SavedBciCmd = cmd;
800ab47cfaaSmrg    psav->SavedSbdOffset = pat_offset;
801ab47cfaaSmrg    psav->SavedSbd = bd;
802ab47cfaaSmrg    psav->SavedBgColor = trans_col;
803ab47cfaaSmrg}
804ab47cfaaSmrg
805ab47cfaaSmrg
806ab47cfaaSmrgstatic void
807ab47cfaaSmrgSavageSubsequentColor8x8PatternFillRect(
808ab47cfaaSmrg    ScrnInfoPtr pScrn,
809ab47cfaaSmrg    int patternx,
810ab47cfaaSmrg    int patterny,
811ab47cfaaSmrg    int x,
812ab47cfaaSmrg    int y,
813ab47cfaaSmrg    int w,
814ab47cfaaSmrg    int h)
815ab47cfaaSmrg{
816ab47cfaaSmrg    SavagePtr psav = SAVPTR(pScrn);
817ab47cfaaSmrg    BCI_GET_PTR;
818ab47cfaaSmrg
819ab47cfaaSmrg    if( !w || !h )
820ab47cfaaSmrg	return;
821ab47cfaaSmrg
822ab47cfaaSmrg    psav->WaitQueue(psav,6);
823ab47cfaaSmrg    BCI_SEND(psav->SavedBciCmd);
824ab47cfaaSmrg    BCI_SEND(psav->SavedSbdOffset);
825ab47cfaaSmrg    BCI_SEND(psav->SavedSbd);
826ab47cfaaSmrg    BCI_SEND(BCI_X_Y(patternx,patterny));
827ab47cfaaSmrg    BCI_SEND(BCI_X_Y(x, y));
828ab47cfaaSmrg    BCI_SEND(BCI_W_H(w, h));
829ab47cfaaSmrg}
830ab47cfaaSmrg#endif
831ab47cfaaSmrg
832ab47cfaaSmrgstatic void
833ab47cfaaSmrgSavageSubsequentSolidBresenhamLine(
834ab47cfaaSmrg    ScrnInfoPtr pScrn,
835ab47cfaaSmrg    int x1,
836ab47cfaaSmrg    int y1,
837ab47cfaaSmrg    int e1,
838ab47cfaaSmrg    int e2,
839ab47cfaaSmrg    int err,
840ab47cfaaSmrg    int length,
841ab47cfaaSmrg    int octant)
842ab47cfaaSmrg{
843ab47cfaaSmrg    SavagePtr psav = SAVPTR(pScrn);
844ab47cfaaSmrg    BCI_GET_PTR;
845ab47cfaaSmrg    int cmd;
846ab47cfaaSmrg
847ab47cfaaSmrg    cmd = (psav->SavedBciCmd & 0x00ffffff);
848ab47cfaaSmrg    cmd |= BCI_CMD_LINE_LAST_PIXEL;
849ab47cfaaSmrg
850ab47cfaaSmrg#ifdef DEBUG_EXTRA
851ab47cfaaSmrg    ErrorF("BresenhamLine, (%4d,%4d), len %4d, oct %d, err %4d,%4d,%4d clr %08x\n",
852ab47cfaaSmrg        x1, y1, length, octant, e1, e2, err, psav->SavedFgColor );
853ab47cfaaSmrg#endif
854ab47cfaaSmrg
855ab47cfaaSmrg    psav->WaitQueue(psav, 7 );
856ab47cfaaSmrg    BCI_SEND(cmd);
857ab47cfaaSmrg
858ab47cfaaSmrg    BCI_SEND(psav->GlobalBD.bd2.LoPart);
859ab47cfaaSmrg    BCI_SEND(psav->GlobalBD.bd2.HiPart);
860ab47cfaaSmrg
861ab47cfaaSmrg    if( cmd & BCI_CMD_SEND_COLOR )
862ab47cfaaSmrg	BCI_SEND( psav->SavedFgColor );
863ab47cfaaSmrg    BCI_SEND(BCI_LINE_X_Y(x1, y1));
864ab47cfaaSmrg    BCI_SEND(BCI_LINE_STEPS(e2-e1, e2));
865ab47cfaaSmrg    BCI_SEND(BCI_LINE_MISC(length,
866ab47cfaaSmrg    			   (octant & YMAJOR),
867ab47cfaaSmrg			   !(octant & XDECREASING),
868ab47cfaaSmrg			   !(octant & YDECREASING),
869ab47cfaaSmrg			   e2+err));
870ab47cfaaSmrg}
871ab47cfaaSmrg
872ab47cfaaSmrgstatic void
873ab47cfaaSmrgSavageSetClippingRectangle(
874ab47cfaaSmrg    ScrnInfoPtr pScrn,
875ab47cfaaSmrg    int x1,
876ab47cfaaSmrg    int y1,
877ab47cfaaSmrg    int x2,
878ab47cfaaSmrg    int y2)
879ab47cfaaSmrg{
880ab47cfaaSmrg    SavagePtr psav = SAVPTR(pScrn);
881ab47cfaaSmrg    BCI_GET_PTR;
882ab47cfaaSmrg    int cmd;
883ab47cfaaSmrg
884ab47cfaaSmrg#ifdef DEBUG_EXTRA
885ab47cfaaSmrg    ErrorF("ClipRect, (%4d,%4d)-(%4d,%4d) \n", x1, y1, x2, y2 );
886ab47cfaaSmrg#endif
887ab47cfaaSmrg
888ab47cfaaSmrg    cmd = BCI_CMD_NOP | BCI_CMD_CLIP_NEW;
889ab47cfaaSmrg    psav->WaitQueue(psav,3);
890ab47cfaaSmrg    BCI_SEND(cmd);
891ab47cfaaSmrg    BCI_SEND(BCI_CLIP_TL(y1, x1));
892ab47cfaaSmrg    BCI_SEND(BCI_CLIP_BR(y2, x2));
893ab47cfaaSmrg    psav->SavedBciCmd |= BCI_CMD_CLIP_CURRENT;
894ab47cfaaSmrg}
895ab47cfaaSmrg
896ab47cfaaSmrg
897ab47cfaaSmrgstatic void SavageDisableClipping( ScrnInfoPtr pScrn )
898ab47cfaaSmrg{
899ab47cfaaSmrg    SavagePtr psav = SAVPTR(pScrn);
900ab47cfaaSmrg#ifdef DEBUG_EXTRA
901ab47cfaaSmrg    ErrorF("Kill ClipRect\n");
902ab47cfaaSmrg#endif
903ab47cfaaSmrg    psav->SavedBciCmd &= ~BCI_CMD_CLIP_CURRENT;
904ab47cfaaSmrg}
905ab47cfaaSmrg
906ab47cfaaSmrgvoid
907ab47cfaaSmrgSavageWriteBitmapCPUToScreenColorExpand (
908ab47cfaaSmrg    ScrnInfoPtr pScrn,
909ab47cfaaSmrg    int x, int y, int w, int h,
910ab47cfaaSmrg    unsigned char * src,
911ab47cfaaSmrg    int srcwidth,
912ab47cfaaSmrg    int skipleft,
913ab47cfaaSmrg    int fg, int bg,
914ab47cfaaSmrg    int rop,
915ab47cfaaSmrg    unsigned int planemask
916ab47cfaaSmrg)
917ab47cfaaSmrg{
918ab47cfaaSmrg    SavagePtr psav = SAVPTR(pScrn);
919ab47cfaaSmrg    BCI_GET_PTR;
920ab47cfaaSmrg    int i, j, count, reset;
921ab47cfaaSmrg    unsigned int cmd;
922ab47cfaaSmrg    CARD32 * srcp;
923ab47cfaaSmrg
924ab47cfaaSmrg/* We aren't using planemask at all here... */
925ab47cfaaSmrg
926ab47cfaaSmrg    if( !srcwidth )
927ab47cfaaSmrg	return;
928ab47cfaaSmrg
929ab47cfaaSmrg    cmd = BCI_CMD_RECT | BCI_CMD_RECT_XP | BCI_CMD_RECT_YP
930ab47cfaaSmrg        | BCI_CMD_SEND_COLOR | BCI_CMD_CLIP_LR
931ab47cfaaSmrg        | BCI_CMD_DEST_PBD_NEW | BCI_CMD_SRC_MONO;
932ab47cfaaSmrg    cmd |= XAAGetCopyROP(rop) << 16;
933ab47cfaaSmrg
934ab47cfaaSmrg    if( bg == -1 )
935ab47cfaaSmrg        cmd |= BCI_CMD_SRC_TRANSPARENT;
936ab47cfaaSmrg
937ab47cfaaSmrg    BCI_SEND(cmd);
938ab47cfaaSmrg
939ab47cfaaSmrg    BCI_SEND(psav->GlobalBD.bd2.LoPart);
940ab47cfaaSmrg    BCI_SEND(psav->GlobalBD.bd2.HiPart);
941ab47cfaaSmrg
942ab47cfaaSmrg    BCI_SEND(BCI_CLIP_LR(x+skipleft, x+w-1));
943ab47cfaaSmrg    BCI_SEND(fg);
944ab47cfaaSmrg    if( bg != -1 )
945ab47cfaaSmrg	BCI_SEND(bg);
946ab47cfaaSmrg
947ab47cfaaSmrg    /* Bitmaps come in in units of DWORDS, LSBFirst.  This is exactly */
948ab47cfaaSmrg    /* reversed of what we expect.  */
949ab47cfaaSmrg
950ab47cfaaSmrg    count = (w + 31) / 32;
951ab47cfaaSmrg/*    src += ((srcx & ~31) / 8); */
952ab47cfaaSmrg
953ab47cfaaSmrg    /* The BCI region is 128k bytes.  A screen-sized mono bitmap can */
954ab47cfaaSmrg    /* exceed that. */
955ab47cfaaSmrg
956ab47cfaaSmrg    reset = 65536 / count;
957ab47cfaaSmrg
958ab47cfaaSmrg    for (j = 0; j < h; j ++) {
959ab47cfaaSmrg        BCI_SEND(BCI_X_Y(x, y+j));
960ab47cfaaSmrg        BCI_SEND(BCI_W_H(w, 1));
961ab47cfaaSmrg        srcp = (CARD32 *) src;
962ab47cfaaSmrg        for (i = count; i > 0; srcp ++, i --) {
963ab47cfaaSmrg            /* We have to invert the bits in each byte. */
964ab47cfaaSmrg            CARD32 u = *srcp;
965ab47cfaaSmrg            u = ((u & 0x0f0f0f0f) << 4) | ((u & 0xf0f0f0f0) >> 4);
966ab47cfaaSmrg            u = ((u & 0x33333333) << 2) | ((u & 0xcccccccc) >> 2);
967ab47cfaaSmrg            u = ((u & 0x55555555) << 1) | ((u & 0xaaaaaaaa) >> 1);
968ab47cfaaSmrg            BCI_SEND(u);
969ab47cfaaSmrg        }
970ab47cfaaSmrg        src += srcwidth;
971ab47cfaaSmrg        if( !--reset ) {
972ab47cfaaSmrg	    BCI_RESET;
973ab47cfaaSmrg            reset = 65536 / count;
974ab47cfaaSmrg        }
975ab47cfaaSmrg    }
976ab47cfaaSmrg}
977ab47cfaaSmrg
978ab47cfaaSmrgvoid
979ab47cfaaSmrgSavageSetupForImageWrite(
980ab47cfaaSmrg    ScrnInfoPtr pScrn,
981ab47cfaaSmrg    int rop,
982ab47cfaaSmrg    unsigned planemask,
983ab47cfaaSmrg    int transparency_color,
984ab47cfaaSmrg    int bpp,
985ab47cfaaSmrg    int depth)
986ab47cfaaSmrg{
987ab47cfaaSmrg    SavagePtr psav = SAVPTR(pScrn);
988ab47cfaaSmrg    int cmd;
989ab47cfaaSmrg
990ab47cfaaSmrg    cmd = BCI_CMD_RECT | BCI_CMD_RECT_XP | BCI_CMD_RECT_YP
991ab47cfaaSmrg        | BCI_CMD_CLIP_LR
992ab47cfaaSmrg        | BCI_CMD_DEST_PBD_NEW | BCI_CMD_SRC_COLOR;
993ab47cfaaSmrg
994ab47cfaaSmrg    cmd |= XAAGetCopyROP(rop) << 16;
995ab47cfaaSmrg
996ab47cfaaSmrg    if( transparency_color != -1 )
997ab47cfaaSmrg        cmd |= BCI_CMD_SRC_TRANSPARENT;
998ab47cfaaSmrg
999ab47cfaaSmrg    psav->SavedBciCmd = cmd;
1000ab47cfaaSmrg    psav->SavedBgColor = transparency_color;
1001ab47cfaaSmrg}
1002ab47cfaaSmrg
1003ab47cfaaSmrg
1004ab47cfaaSmrgvoid SavageSubsequentImageWriteRect
1005ab47cfaaSmrg(
1006ab47cfaaSmrg    ScrnInfoPtr pScrn,
1007ab47cfaaSmrg    int x,
1008ab47cfaaSmrg    int y,
1009ab47cfaaSmrg    int w,
1010ab47cfaaSmrg    int h,
1011ab47cfaaSmrg    int skipleft)
1012ab47cfaaSmrg{
1013ab47cfaaSmrg    SavagePtr psav = SAVPTR(pScrn);
1014ab47cfaaSmrg    BCI_GET_PTR;
1015ab47cfaaSmrg
1016ab47cfaaSmrg    psav->WaitQueue( psav, 8 );
1017ab47cfaaSmrg    BCI_SEND(psav->SavedBciCmd);
1018ab47cfaaSmrg
1019ab47cfaaSmrg    BCI_SEND(psav->GlobalBD.bd2.LoPart);
1020ab47cfaaSmrg    BCI_SEND(psav->GlobalBD.bd2.HiPart);
1021ab47cfaaSmrg
1022ab47cfaaSmrg    BCI_SEND(BCI_CLIP_LR(x+skipleft, x+w-1));
1023ab47cfaaSmrg    if( psav->SavedBgColor != 0xffffffff )
1024ab47cfaaSmrg        BCI_SEND(psav->SavedBgColor);
1025ab47cfaaSmrg    BCI_SEND(BCI_X_Y(x, y));
1026ab47cfaaSmrg    BCI_SEND(BCI_W_H(w, h));
1027ab47cfaaSmrg}
1028ab47cfaaSmrg
1029aa9e3350Smrg#endif
1030