apm_accel.c revision 8e0ed500
1
2#ifdef HAVE_CONFIG_H
3#include "config.h"
4#endif
5
6#include "apm.h"
7#include "miline.h"
8
9/* Defines */
10#define MAXLOOP 1000000
11
12/* Translation from X ROP's to APM ROP's. */
13static unsigned char apmROP[] = {
14  0,
15  0x88,
16  0x44,
17  0xCC,
18  0x22,
19  0xAA,
20  0x66,
21  0xEE,
22  0x11,
23  0x99,
24  0x55,
25  0xDD,
26  0x33,
27  0xBB,
28  0x77,
29  0xFF
30};
31
32
33#include "apm_funcs.c"
34
35#define IOP_ACCESS
36#include "apm_funcs.c"
37
38#define PSZ	24
39#include "apm_funcs.c"
40
41#define PSZ	24
42#define IOP_ACCESS
43#include "apm_funcs.c"
44
45static void
46ApmRemoveStipple(FBAreaPtr area)
47{
48    ((struct ApmStippleCacheRec *)area->devPrivate.ptr)->apmStippleCached = FALSE;
49}
50
51static void
52ApmMoveStipple(FBAreaPtr from, FBAreaPtr to)
53{
54    struct ApmStippleCacheRec *pApm = (struct ApmStippleCacheRec *)to->devPrivate.ptr;
55
56    pApm->apmStippleCache.x = to->box.x1;
57    pApm->apmStippleCache.y += to->box.y1 - from->box.y1;
58    /* TODO : move data */
59}
60
61/*
62 * ApmCacheMonoStipple
63 * because my poor AT3D needs stipples stored linearly in memory.
64 */
65static XAACacheInfoPtr
66ApmCacheMonoStipple(ScrnInfoPtr pScrn, PixmapPtr pPix)
67{
68    APMDECL(pScrn);
69    int		w = pPix->drawable.width, W = (w + 31) & ~31;
70    int		h = pPix->drawable.height;
71    int		i, j, dwords, mem, width, funcNo;
72    FBAreaPtr	draw;
73    struct ApmStippleCacheRec	*pCache;
74    unsigned char	*srcPtr;
75    CARD32		*dstPtr;
76    static StippleScanlineProcPtr *StippleTab = NULL;
77
78    if (!StippleTab)
79        StippleTab = XAAGetStippleScanlineFuncMSBFirst();
80
81    for (i = 0; i < APM_CACHE_NUMBER; i++)
82	if ((pApm->apmCache[i].apmStippleCache.serialNumber == pPix->drawable.serialNumber)
83		&& pApm->apmCache[i].apmStippleCached &&
84		(pApm->apmCache[i].apmStippleCache.fg == -1) &&
85		(pApm->apmCache[i].apmStippleCache.bg == -1)) {
86	    pApm->apmCache[i].apmStippleCache.trans_color = -1;
87	    return &pApm->apmCache[i].apmStippleCache;
88	}
89    if ((i = ++pApm->apmCachePtr) >= APM_CACHE_NUMBER)
90	i = pApm->apmCachePtr = 0;
91    pCache = &pApm->apmCache[i];
92    if (pCache->apmStippleCached) {
93	pCache->apmStippleCached = FALSE;
94	xf86FreeOffscreenArea(pCache->area);
95    }
96
97    draw = xf86AllocateLinearOffscreenArea(pApm->pScreen, (W * h + 7) / 8,
98				    (pApm->CurrentLayout.mask32 + 1) << 1,
99				    ApmMoveStipple, ApmRemoveStipple, pCache);
100    if (!draw)
101	return NULL;	/* Let's hope this will never happen... */
102
103    pCache->area = draw;
104    pCache->apmStippleCache.serialNumber = pPix->drawable.serialNumber;
105    pCache->apmStippleCache.trans_color =
106	pCache->apmStippleCache.bg =
107	pCache->apmStippleCache.fg = -1;
108    pCache->apmStippleCache.orig_w = w;
109    pCache->apmStippleCache.orig_h = h;
110    pCache->apmStippleCache.x = draw->box.x1;
111    pCache->apmStippleCache.y = draw->box.y1 + ((pCache - pApm->apmCache) + 1) * pApm->CurrentLayout.Scanlines;
112    mem = ((draw->box.x2 - draw->box.x1) * (draw->box.y2 - draw->box.y1) *
113			pScrn->bitsPerPixel) / (W * h);
114    width = 2;
115    while (width * width <= mem)
116	width++;
117    width--;
118    pCache->apmStippleCache.w = (width * W + pScrn->bitsPerPixel - 1) /
119			pScrn->bitsPerPixel;
120    pCache->apmStippleCache.h = ((draw->box.x2 - draw->box.x1) *
121			(draw->box.y2 - draw->box.y1)) /
122			pCache->apmStippleCache.w;
123    pCache->apmStippleCached = TRUE;
124
125    if (w < 32) {
126	if (w & (w - 1))	funcNo = 1;
127	else			funcNo = 0;
128    } else			funcNo = 2;
129
130    dstPtr = ((CARD32 *)pApm->FbBase) + (draw->box.x1 +
131			draw->box.y1*pApm->CurrentLayout.bytesPerScanline) / 4;
132    j = 0;
133    dwords = (pCache->apmStippleCache.w * pScrn->bitsPerPixel) / 32;
134    while (j + h <= pCache->apmStippleCache.h) {
135	srcPtr = (unsigned char *)pPix->devPrivate.ptr;
136	for (i = h; --i >= 0; ) {
137	    StippleTab[funcNo](dstPtr, (CARD32 *)srcPtr, 0, w, dwords);
138	    srcPtr += pPix->devKind;
139	    dstPtr += dwords;
140	}
141	j += h;
142    }
143    srcPtr = (unsigned char *)pPix->devPrivate.ptr;
144    for (i = pCache->apmStippleCache.h - j ; --i >= 0; ) {
145	StippleTab[funcNo](dstPtr, (CARD32 *)srcPtr, 0, w, dwords);
146	srcPtr += pPix->devKind;
147	dstPtr += dwords;
148    }
149
150    return &pCache->apmStippleCache;
151}
152
153#if 0
154extern GCOps XAAPixmapOps;
155static RegionPtr (*SaveCopyAreaPixmap)(DrawablePtr, DrawablePtr, GC *, int, int, int, int, int, int);
156
157static RegionPtr
158ApmCopyAreaPixmap(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GC *pGC,
159		int srcx, int srcy,
160		int width, int height,
161		int dstx, int dsty )
162{
163    register int Scanlines;
164    int is;
165    int id;
166    int sx = 0, sy = 0, dx = 0, dy = 0, pitch;
167    RegionPtr pReg;
168
169    if (APMPTR(xf86Screens[(pGC)->pScreen->myNum])->Chipset == AT3D) {
170	Scanlines = APMPTR(xf86Screens[(pGC)->pScreen->myNum])->CurrentLayout.Scanlines;
171	is = (pSrcDrawable->type == DRAWABLE_PIXMAP) ? APM_GET_PIXMAP_PRIVATE(pSrcDrawable)->num : 0;
172	id = (pDstDrawable->type == DRAWABLE_PIXMAP) ? APM_GET_PIXMAP_PRIVATE(pDstDrawable)->num : 0;
173	if (is) {
174	    sx = pSrcDrawable->x;
175	    sy = pSrcDrawable->y % Scanlines;
176	    pitch = 2 * pSrcDrawable->width;
177	    pSrcDrawable->x = (sx + ((PixmapPtr)pSrcDrawable)->devKind * sy) % pitch;
178	    pSrcDrawable->y = (sx + ((PixmapPtr)pSrcDrawable)->devKind * sy) / pitch;
179	    ((PixmapPtr)pSrcDrawable)->devKind = pitch;
180	    pSrcDrawable->depth = 16;
181	}
182	if (id) {
183	    dx = pDstDrawable->x;
184	    dy = pDstDrawable->y % Scanlines;
185	    pitch = 2 * pDstDrawable->width;
186	    pDstDrawable->x = (dx + ((PixmapPtr)pDstDrawable)->devKind * dy) % pitch;
187	    pDstDrawable->y = (dx + ((PixmapPtr)pDstDrawable)->devKind * dy) / pitch;
188	    ((PixmapPtr)pDstDrawable)->devKind = pitch;
189	    pDstDrawable->depth = 16;
190	}
191	pReg = (*SaveCopyAreaPixmap)(pSrcDrawable, pDstDrawable, pGC,
192					    srcx, srcy % Scanlines,
193					    width, height,
194					    dstx, dsty % Scanlines);
195	if (is) {
196	    pSrcDrawable->x = sx;
197	    pSrcDrawable->y = sy + is * Scanlines;
198	}
199	if (id) {
200	    pDstDrawable->x = dx;
201	    pDstDrawable->y = dy + id * Scanlines;
202	}
203	return pReg;
204    }
205    return (*SaveCopyAreaPixmap)(pSrcDrawable, pDstDrawable, pGC,
206					srcx, srcy,
207					width, height,
208					dstx, dsty);
209}
210#endif
211
212void ApmAccelReserveSpace(ApmPtr pApm)
213{
214    memType	mem, ScratchMemOffset;
215
216    mem			= xf86Screens[pApm->pScreen->myNum]->videoRam << 10;
217    /*
218     * Reserve at least four lines for mono to color expansion
219     */
220    ScratchMemOffset	= ((mem - pApm->OffscreenReserved) /
221			pApm->CurrentLayout.bytesPerScanline - 4) *
222			pApm->CurrentLayout.bytesPerScanline;
223    pApm->ScratchMemSize= mem - ScratchMemOffset - pApm->OffscreenReserved;
224    pApm->ScratchMemPtr	= pApm->ScratchMemOffset
225			= (memType)pApm->FbBase + ScratchMemOffset;
226    pApm->ScratchMemEnd	= (memType)pApm->FbBase + mem - pApm->OffscreenReserved;
227}
228
229/*********************************************************************************************/
230
231int
232ApmAccelInit(ScreenPtr pScreen)
233{
234    ScrnInfoPtr		pScrn = xf86Screens[pScreen->myNum];
235    APMDECL(pScrn);
236    XAAInfoRecPtr	pXAAinfo;
237    BoxRec		AvailFBArea;
238    memType		mem, ScratchMemOffset;
239    int			i, stat;
240
241    pApm->AccelInfoRec	= pXAAinfo = XAACreateInfoRec();
242    if (!pXAAinfo)
243	return FALSE;
244
245    mem			= pScrn->videoRam << 10;
246    ScratchMemOffset	= pApm->ScratchMemOffset - (memType)pApm->FbBase;
247    switch (pApm->CurrentLayout.bitsPerPixel) {
248    case 8:
249    case 24:
250	pApm->ScratchMemWidth =
251		(mem - ScratchMemOffset - pApm->OffscreenReserved) / 1;
252	pApm->ScratchMem =
253		((ScratchMemOffset & 0xFFF000) << 4) |
254		    (ScratchMemOffset & 0xFFF);
255	break;
256
257    case 16:
258	pApm->ScratchMemWidth =
259		(mem - ScratchMemOffset - pApm->OffscreenReserved) / 2;
260	pApm->ScratchMem =
261		((ScratchMemOffset & 0xFFE000) << 3) |
262		    ((ScratchMemOffset & 0x1FFE) >> 1);
263	break;
264
265    case 32:
266	pApm->ScratchMemWidth =
267		(mem - ScratchMemOffset - pApm->OffscreenReserved) / 4;
268	pApm->ScratchMem =
269		((ScratchMemOffset & 0xFFC000) << 2) |
270		    ((ScratchMemOffset & 0x3FFC) >> 2);
271	break;
272    }
273    pApm->OffscreenReserved = mem - ScratchMemOffset;
274
275    /*
276     * Abort
277     */
278    if (pApm->Chipset == AP6422)
279	i = 4;
280    else
281	i = 8;
282    if (pApm->noLinear) {
283	stat = RDXL_IOP(0x1FC);
284	while ((stat & (STATUS_HOSTBLTBUSY | STATUS_ENGINEBUSY)) ||
285		((stat & STATUS_FIFO) < i)) {
286	    WRXB_IOP(0x1FC, 0);
287	    stat = RDXL_IOP(0x1FC);
288	}
289    }
290    else {
291	stat = RDXL_M(0x1FC);
292	while ((stat & (STATUS_HOSTBLTBUSY | STATUS_ENGINEBUSY)) ||
293		((stat & STATUS_FIFO) < i)) {
294	    WRXB_M(0x1FC, 0);
295	    stat = RDXL_M(0x1FC);
296	}
297    }
298
299    /* Setup current register values */
300    for (i = 0; i < sizeof(pApm->regcurr) / 4; i++)
301	((CARD32 *)curr)[i] = RDXL(0x30 + 4*i);
302
303    SETCLIP_CTRL(1);
304    SETCLIP_CTRL(0);
305    SETBYTEMASK(0x00);
306    SETBYTEMASK(0xFF);
307    SETROP(ROP_S_xor_D);
308    SETROP(ROP_S);
309
310#if 0
311    if (XAAPixmapOps.CopyArea != ApmCopyAreaPixmap) {
312	SaveCopyAreaPixmap = XAAPixmapOps.CopyArea;
313	XAAPixmapOps.CopyArea = ApmCopyAreaPixmap;
314    }
315#endif
316
317    ApmSetupXAAInfo(pApm, pXAAinfo);
318
319    if (!pApm->noLinear) {
320	pApm->SetupForSolidFill			= ApmSetupForSolidFill;
321	pApm->SubsequentSolidFillRect		= ApmSubsequentSolidFillRect;
322	pApm->SetupForSolidFill24		= ApmSetupForSolidFill24;
323	pApm->SubsequentSolidFillRect24		= ApmSubsequentSolidFillRect24;
324	pApm->SetupForScreenToScreenCopy	= ApmSetupForScreenToScreenCopy;
325	pApm->SubsequentScreenToScreenCopy	= ApmSubsequentScreenToScreenCopy;
326	pApm->SetupForScreenToScreenCopy24	= ApmSetupForScreenToScreenCopy24;
327	pApm->SubsequentScreenToScreenCopy24	= ApmSubsequentScreenToScreenCopy24;
328    }
329    else {
330	pApm->SetupForSolidFill			= ApmSetupForSolidFill_IOP;
331	pApm->SubsequentSolidFillRect		= ApmSubsequentSolidFillRect_IOP;
332	pApm->SetupForSolidFill24		= ApmSetupForSolidFill24_IOP;
333	pApm->SubsequentSolidFillRect24		= ApmSubsequentSolidFillRect24_IOP;
334	pApm->SetupForScreenToScreenCopy	= ApmSetupForScreenToScreenCopy_IOP;
335	pApm->SubsequentScreenToScreenCopy	= ApmSubsequentScreenToScreenCopy_IOP;
336	pApm->SetupForScreenToScreenCopy24	= ApmSetupForScreenToScreenCopy24_IOP;
337	pApm->SubsequentScreenToScreenCopy24	= ApmSubsequentScreenToScreenCopy24_IOP;
338    }
339
340    /*
341     * Init Rush extension.
342     * Must be initialized once per generation.
343     */
344#ifdef XF86RUSH_EXT
345    if (!pApm->CreatePixmap) {
346	pApm->CreatePixmap	= pScreen->CreatePixmap;
347	pApm->DestroyPixmap	= pScreen->DestroyPixmap;
348    }
349    XFree86RushExtensionInit(pScreen);
350#endif
351
352    /* Pixmap cache setup */
353    pXAAinfo->CachePixelGranularity = (pApm->CurrentLayout.mask32 + 1) << 1;
354    AvailFBArea.x1 = 0;
355    AvailFBArea.y1 = 0;
356    AvailFBArea.x2 = pScrn->displayWidth;
357    AvailFBArea.y2 = (pScrn->videoRam * 1024 - pApm->OffscreenReserved) /
358	(pScrn->displayWidth * ((pScrn->bitsPerPixel + 7) >> 3));
359
360    xf86InitFBManager(pScreen, &AvailFBArea);
361
362    bzero(pApm->apmCache, sizeof pApm->apmCache);
363
364    return XAAInit(pScreen, pXAAinfo);
365}
366
367void ApmSetupXAAInfo(ApmPtr pApm, XAAInfoRecPtr pXAAinfo)
368{
369    pApm->CurrentLayout.Setup_DEC = 0;
370    switch(pApm->CurrentLayout.bitsPerPixel)
371    {
372      case 8:
373           pApm->CurrentLayout.Setup_DEC |= DEC_BITDEPTH_8;
374           break;
375      case 16:
376           pApm->CurrentLayout.Setup_DEC |= DEC_BITDEPTH_16;
377           break;
378      case 24:
379	   /* Note : in 24 bpp, the accelerator wants linear coordinates */
380           pApm->CurrentLayout.Setup_DEC |= DEC_BITDEPTH_24 | DEC_SOURCE_LINEAR |
381				   DEC_DEST_LINEAR;
382           break;
383      case 32:
384           pApm->CurrentLayout.Setup_DEC |= DEC_BITDEPTH_32;
385           break;
386      default:
387           xf86DrvMsg(xf86Screens[pApm->pScreen->myNum]->scrnIndex, X_WARNING,
388		    "Cannot set up drawing engine control for bpp = %d\n",
389		    pApm->CurrentLayout.bitsPerPixel);
390           break;
391    }
392
393    switch(pApm->CurrentLayout.displayWidth)
394    {
395      case 640:
396           pApm->CurrentLayout.Setup_DEC |= DEC_WIDTH_640;
397           break;
398      case 800:
399           pApm->CurrentLayout.Setup_DEC |= DEC_WIDTH_800;
400           break;
401      case 1024:
402           pApm->CurrentLayout.Setup_DEC |= DEC_WIDTH_1024;
403           break;
404      case 1152:
405           pApm->CurrentLayout.Setup_DEC |= DEC_WIDTH_1152;
406           break;
407      case 1280:
408           pApm->CurrentLayout.Setup_DEC |= DEC_WIDTH_1280;
409           break;
410      case 1600:
411           pApm->CurrentLayout.Setup_DEC |= DEC_WIDTH_1600;
412           break;
413      default:
414           xf86DrvMsg(xf86Screens[pApm->pScreen->myNum]->scrnIndex, X_WARNING,
415		       "Cannot set up drawing engine control "
416		       "for screen width = %d\n", pApm->CurrentLayout.displayWidth);
417           break;
418    }
419
420    if (!pXAAinfo)
421	return;
422
423    /*
424     * Set up the main acceleration flags.
425     */
426    pXAAinfo->Flags = PIXMAP_CACHE | LINEAR_FRAMEBUFFER | OFFSCREEN_PIXMAPS;
427    pXAAinfo->CacheMonoStipple = ApmCacheMonoStipple;
428
429    if (pApm->CurrentLayout.bitsPerPixel != 24) {
430	if (!pApm->noLinear) {
431#define	XAA(s)		pXAAinfo->s = Apm##s
432	    if (pApm->Chipset < AT24)
433		pXAAinfo->Sync = ApmSync6422;
434	    else
435		XAA(Sync);
436
437	    /* Accelerated filled rectangles */
438	    pXAAinfo->SolidFillFlags = NO_PLANEMASK;
439	    XAA(SetupForSolidFill);
440	    XAA(SubsequentSolidFillRect);
441
442	    /* Accelerated screen to screen color expansion */
443	    pXAAinfo->ScreenToScreenColorExpandFillFlags = NO_PLANEMASK;
444	    XAA(SetupForScreenToScreenColorExpandFill);
445	    XAA(SubsequentScreenToScreenColorExpandFill);
446
447#if 0
448	    The constraints of the transfer range are incompatible with the
449	    XAA architecture. I rewrote the XAA functions using ImageWrite
450	    /* Accelerated CPU to screen color expansion */
451	    if ((pApm->Chipset == AT24 && pApm->ChipRev >= 4) ||
452		    pApm->Chipset == AT3D) {
453		pXAAinfo->CPUToScreenColorExpandFillFlags =
454		  NO_PLANEMASK | SCANLINE_PAD_DWORD | CPU_TRANSFER_PAD_QWORD
455		  | BIT_ORDER_IN_BYTE_MSBFIRST | LEFT_EDGE_CLIPPING |
456		  LEFT_EDGE_CLIPPING_NEGATIVE_X | SYNC_AFTER_COLOR_EXPAND;
457		XAA(SetupForCPUToScreenColorExpandFill);
458		XAA(SubsequentCPUToScreenColorExpandFill);
459		pXAAinfo->ColorExpandBase	= pApm->BltMap;
460		pXAAinfo->ColorExpandRange	= (pApm->Chipset >= AT3D) ? 32*1024 : 30*1024;
461	    }
462
463	    /* Accelerated image transfers */
464	    pXAAinfo->ImageWriteFlags	=
465			    LEFT_EDGE_CLIPPING | NO_PLANEMASK |
466			    SCANLINE_PAD_DWORD | CPU_TRANSFER_PAD_QWORD |
467			    LEFT_EDGE_CLIPPING_NEGATIVE_X |
468			    SYNC_AFTER_IMAGE_WRITE;
469	    pXAAinfo->ImageWriteBase	= pApm->BltMap;
470	    pXAAinfo->ImageWriteRange	= (pApm->Chipset >= AT3D) ? 32*1024 : 30*1024;
471	    XAA(SetupForImageWrite);
472	    XAA(SubsequentImageWriteRect);
473#endif
474	    pXAAinfo->WritePixmapFlags = LEFT_EDGE_CLIPPING | NO_PLANEMASK |
475			    LEFT_EDGE_CLIPPING_NEGATIVE_X;
476	    XAA(WritePixmap);
477	    pXAAinfo->FillImageWriteRectsFlags	=
478			    LEFT_EDGE_CLIPPING | NO_PLANEMASK |
479			    LEFT_EDGE_CLIPPING_NEGATIVE_X;
480	    XAA(FillImageWriteRects);
481	    pXAAinfo->WriteBitmapFlags = LEFT_EDGE_CLIPPING | NO_PLANEMASK |
482			    LEFT_EDGE_CLIPPING_NEGATIVE_X |
483			    BIT_ORDER_IN_BYTE_LSBFIRST;
484	    XAA(WriteBitmap);
485	    pXAAinfo->TEGlyphRendererFlags = LEFT_EDGE_CLIPPING | NO_PLANEMASK |
486			    LEFT_EDGE_CLIPPING_NEGATIVE_X;
487	    XAA(TEGlyphRenderer);
488
489	    /* Accelerated screen-screen bitblts */
490	    pXAAinfo->ScreenToScreenCopyFlags = NO_PLANEMASK;
491	    XAA(SetupForScreenToScreenCopy);
492	    XAA(SubsequentScreenToScreenCopy);
493
494	    /* Accelerated Line drawing */
495	    pXAAinfo->SolidLineFlags = NO_PLANEMASK | HARDWARE_CLIP_LINE;
496	    XAA(SetClippingRectangle);
497	    pXAAinfo->SolidBresenhamLineErrorTermBits = 15;
498
499	    if (pApm->Chipset >= AT24) {
500		XAA(SubsequentSolidBresenhamLine);
501
502		/* Pattern fill */
503		pXAAinfo->Mono8x8PatternFillFlags = NO_PLANEMASK |
504				HARDWARE_PATTERN_PROGRAMMED_BITS |
505				HARDWARE_PATTERN_SCREEN_ORIGIN;
506		XAA(SetupForMono8x8PatternFill);
507		XAA(SubsequentMono8x8PatternFillRect);
508		if (pApm->CurrentLayout.bitsPerPixel == 8) {
509		    pXAAinfo->Color8x8PatternFillFlags = NO_PLANEMASK |
510				    HARDWARE_PATTERN_SCREEN_ORIGIN;
511		    XAA(SetupForColor8x8PatternFill);
512		    XAA(SubsequentColor8x8PatternFillRect);
513		}
514	    }
515	    else
516		pXAAinfo->SubsequentSolidBresenhamLine =
517		    ApmSubsequentSolidBresenhamLine6422;
518#undef XAA
519	}
520	else {
521#define	XAA(s)		pXAAinfo->s = Apm##s##_IOP
522	    if (pApm->Chipset < AT24)
523		pXAAinfo->Sync = ApmSync6422_IOP;
524	    else
525		XAA(Sync);
526
527	    /* Accelerated filled rectangles */
528	    pXAAinfo->SolidFillFlags = NO_PLANEMASK;
529	    XAA(SetupForSolidFill);
530	    XAA(SubsequentSolidFillRect);
531
532	    /* Accelerated screen to screen color expansion */
533	    pXAAinfo->ScreenToScreenColorExpandFillFlags = NO_PLANEMASK;
534	    XAA(SetupForScreenToScreenColorExpandFill);
535	    XAA(SubsequentScreenToScreenColorExpandFill);
536
537#if 0
538	    The constraints of the transfer range are incompatible with the
539	    XAA architecture. I rewrote the XAA functions using ImageWrite
540	    /* Accelerated CPU to screen color expansion */
541	    if ((pApm->Chipset == AT24 && pApm->ChipRev >= 4) ||
542		    pApm->Chipset == AT3D) {
543		pXAAinfo->CPUToScreenColorExpandFillFlags =
544		  NO_PLANEMASK | SCANLINE_PAD_DWORD | CPU_TRANSFER_PAD_QWORD
545		  | BIT_ORDER_IN_BYTE_MSBFIRST | LEFT_EDGE_CLIPPING |
546		  LEFT_EDGE_CLIPPING_NEGATIVE_X | SYNC_AFTER_COLOR_EXPAND;
547		XAA(SetupForCPUToScreenColorExpandFill);
548		XAA(SubsequentCPUToScreenColorExpandFill);
549		pXAAinfo->ColorExpandBase	= pApm->BltMap;
550		pXAAinfo->ColorExpandRange	= (pApm->Chipset >= AT3D) ? 32*1024 : 30*1024;
551	    }
552
553	    /* Accelerated image transfers */
554	    pXAAinfo->ImageWriteFlags	=
555			    LEFT_EDGE_CLIPPING | NO_PLANEMASK |
556			    SCANLINE_PAD_DWORD | CPU_TRANSFER_PAD_QWORD;
557	    pXAAinfo->ImageWriteBase	= pApm->BltMap;
558	    pXAAinfo->ImageWriteRange	= (pApm->Chipset >= AT3D) ? 32*1024 : 30*1024;
559	    XAA(SetupForImageWrite);
560	    XAA(SubsequentImageWriteRect);
561#endif
562	    pXAAinfo->WritePixmapFlags = LEFT_EDGE_CLIPPING | NO_PLANEMASK |
563			    LEFT_EDGE_CLIPPING_NEGATIVE_X;
564	    XAA(WritePixmap);
565	    pXAAinfo->FillImageWriteRectsFlags	=
566			    LEFT_EDGE_CLIPPING | NO_PLANEMASK |
567			    LEFT_EDGE_CLIPPING_NEGATIVE_X;
568	    XAA(FillImageWriteRects);
569	    pXAAinfo->WriteBitmapFlags = LEFT_EDGE_CLIPPING | NO_PLANEMASK |
570			    LEFT_EDGE_CLIPPING_NEGATIVE_X |
571			    BIT_ORDER_IN_BYTE_LSBFIRST;
572	    XAA(WriteBitmap);
573	    pXAAinfo->TEGlyphRendererFlags = LEFT_EDGE_CLIPPING | NO_PLANEMASK |
574			    LEFT_EDGE_CLIPPING_NEGATIVE_X;
575	    XAA(TEGlyphRenderer);
576
577	    /* Accelerated screen-screen bitblts */
578	    pXAAinfo->ScreenToScreenCopyFlags = NO_PLANEMASK;
579	    XAA(SetupForScreenToScreenCopy);
580	    XAA(SubsequentScreenToScreenCopy);
581
582	    /* Accelerated Line drawing */
583	    pXAAinfo->SolidLineFlags = NO_PLANEMASK | HARDWARE_CLIP_LINE;
584	    XAA(SetClippingRectangle);
585	    pXAAinfo->SolidBresenhamLineErrorTermBits = 15;
586
587	    if (pApm->Chipset >= AT24) {
588		XAA(SubsequentSolidBresenhamLine);
589
590		/* Pattern fill */
591		pXAAinfo->Mono8x8PatternFillFlags = NO_PLANEMASK |
592				HARDWARE_PATTERN_PROGRAMMED_BITS |
593				HARDWARE_PATTERN_SCREEN_ORIGIN;
594		XAA(SetupForMono8x8PatternFill);
595		XAA(SubsequentMono8x8PatternFillRect);
596		if (pApm->CurrentLayout.bitsPerPixel == 8) {
597		    pXAAinfo->Color8x8PatternFillFlags = NO_PLANEMASK |
598				    HARDWARE_PATTERN_SCREEN_ORIGIN;
599		    XAA(SetupForColor8x8PatternFill);
600		    XAA(SubsequentColor8x8PatternFillRect);
601		}
602	    }
603	    else
604		pXAAinfo->SubsequentSolidBresenhamLine =
605		    ApmSubsequentSolidBresenhamLine6422_IOP;
606#undef XAA
607	}
608    }
609    else {
610	if (!pApm->noLinear) {
611#define	XAA(s)		pXAAinfo->s = Apm##s##24
612	    XAA(Sync);
613
614	    /* Accelerated filled rectangles */
615	    pXAAinfo->SolidFillFlags = NO_PLANEMASK;
616	    XAA(SetupForSolidFill);
617	    XAA(SubsequentSolidFillRect);
618
619#if 0
620	    /* Accelerated screen to screen color expansion */
621	    pXAAinfo->ScreenToScreenColorExpandFillFlags = NO_PLANEMASK;
622	    XAA(SetupForScreenToScreenColorExpandFill);
623	    XAA(SubsequentScreenToScreenColorExpandFill);
624
625#if 0
626	    The constraints of the transfer range are incompatible with the
627	    XAA architecture. I rewrote the XAA functions using ImageWrite
628	    /* Accelerated CPU to screen color expansion */
629	    if (pApm->Chipset == AT3D && pApm->ChipRev >= 4) {
630		pXAAinfo->CPUToScreenColorExpandFillFlags =
631		  NO_PLANEMASK | SCANLINE_PAD_DWORD | CPU_TRANSFER_PAD_QWORD
632		  | BIT_ORDER_IN_BYTE_MSBFIRST | LEFT_EDGE_CLIPPING |
633		  LEFT_EDGE_CLIPPING_NEGATIVE_X | SYNC_AFTER_COLOR_EXPAND;
634		XAA(SetupForCPUToScreenColorExpandFill);
635		XAA(SubsequentCPUToScreenColorExpandFill);
636		pXAAinfo->ColorExpandBase	= pApm->BltMap;
637		pXAAinfo->ColorExpandRange	= 32*1024;
638	    }
639
640	    /* Accelerated image transfers */
641	    pXAAinfo->ImageWriteFlags	=
642			    LEFT_EDGE_CLIPPING | NO_PLANEMASK |
643			    SCANLINE_PAD_DWORD | CPU_TRANSFER_PAD_QWORD |
644			    SYNC_AFTER_IMAGE_WRITE;
645	    pXAAinfo->ImageWriteBase	= pApm->BltMap;
646	    pXAAinfo->ImageWriteRange	= 32*1024;
647	    XAA(SetupForImageWrite);
648	    XAA(SubsequentImageWriteRect);
649#endif
650	    pXAAinfo->WritePixmapFlags = LEFT_EDGE_CLIPPING | NO_PLANEMASK |
651			    LEFT_EDGE_CLIPPING_NEGATIVE_X;
652	    XAA(WritePixmap);
653	    pXAAinfo->FillImageWriteRectsFlags	=
654			    LEFT_EDGE_CLIPPING | NO_PLANEMASK |
655			    LEFT_EDGE_CLIPPING_NEGATIVE_X;
656	    XAA(FillImageWriteRects);
657	    pXAAinfo->WriteBitmapFlags = LEFT_EDGE_CLIPPING | NO_PLANEMASK |
658			    LEFT_EDGE_CLIPPING_NEGATIVE_X |
659			    BIT_ORDER_IN_BYTE_LSBFIRST;
660	    XAA(WriteBitmap);
661	    pXAAinfo->TEGlyphRendererFlags = LEFT_EDGE_CLIPPING | NO_PLANEMASK |
662			    LEFT_EDGE_CLIPPING_NEGATIVE_X;
663	    XAA(TEGlyphRenderer);
664
665	    /* Accelerated Line drawing */
666	    pXAAinfo->SolidLineFlags = NO_PLANEMASK | HARDWARE_CLIP_LINE;
667	    XAA(SubsequentSolidBresenhamLine);
668	    XAA(SetClippingRectangle);
669	    pXAAinfo->SolidBresenhamLineErrorTermBits = 15;
670
671	    /* Pattern fill */
672	    pXAAinfo->Mono8x8PatternFillFlags = NO_PLANEMASK | NO_TRANSPARENCY |
673			    HARDWARE_PATTERN_PROGRAMMED_BITS |
674			    HARDWARE_PATTERN_SCREEN_ORIGIN;
675	    XAA(SetupForMono8x8PatternFill);
676	    XAA(SubsequentMono8x8PatternFillRect);
677#endif
678
679	    /* Accelerated screen-screen bitblts */
680	    pXAAinfo->ScreenToScreenCopyFlags = NO_PLANEMASK | NO_TRANSPARENCY;
681	    XAA(SetupForScreenToScreenCopy);
682	    XAA(SubsequentScreenToScreenCopy);
683#undef XAA
684	}
685	else {
686#define	XAA(s)		pXAAinfo->s = Apm##s##24##_IOP
687	    XAA(Sync);
688
689	    /* Accelerated filled rectangles */
690	    pXAAinfo->SolidFillFlags = NO_PLANEMASK;
691	    XAA(SetupForSolidFill);
692	    XAA(SubsequentSolidFillRect);
693
694#if 0
695	    /* Accelerated screen to screen color expansion */
696	    pXAAinfo->ScreenToScreenColorExpandFillFlags = NO_PLANEMASK;
697	    XAA(SetupForScreenToScreenColorExpandFill);
698	    XAA(SubsequentScreenToScreenColorExpandFill);
699
700#if 0
701	    The constraints of the transfer range are incompatible with the
702	    XAA architecture. I rewrote the XAA functions using ImageWrite
703	    /* Accelerated CPU to screen color expansion */
704	    if (pApm->Chipset == AT3D && pApm->ChipRev >= 4) {
705		pXAAinfo->CPUToScreenColorExpandFillFlags =
706		  NO_PLANEMASK | SCANLINE_PAD_DWORD | CPU_TRANSFER_PAD_QWORD
707		  | BIT_ORDER_IN_BYTE_MSBFIRST | LEFT_EDGE_CLIPPING |
708		  LEFT_EDGE_CLIPPING_NEGATIVE_X | SYNC_AFTER_COLOR_EXPAND;
709		XAA(SetupForCPUToScreenColorExpandFill);
710		XAA(SubsequentCPUToScreenColorExpandFill);
711		pXAAinfo->ColorExpandBase	= pApm->BltMap;
712		pXAAinfo->ColorExpandRange	= 32*1024;
713	    }
714
715	    /* Accelerated image transfers */
716	    pXAAinfo->ImageWriteFlags	=
717			    LEFT_EDGE_CLIPPING | NO_PLANEMASK |
718			    SCANLINE_PAD_DWORD | CPU_TRANSFER_PAD_QWORD;
719	    pXAAinfo->ImageWriteBase	= pApm->BltMap;
720	    pXAAinfo->ImageWriteRange	= 32*1024;
721	    XAA(SetupForImageWrite);
722	    XAA(SubsequentImageWriteRect);
723#endif
724	    pXAAinfo->WritePixmapFlags = LEFT_EDGE_CLIPPING | NO_PLANEMASK |
725			    LEFT_EDGE_CLIPPING_NEGATIVE_X;
726	    XAA(WritePixmap);
727	    pXAAinfo->FillImageWriteRectsFlags	=
728			    LEFT_EDGE_CLIPPING | NO_PLANEMASK |
729			    LEFT_EDGE_CLIPPING_NEGATIVE_X;
730	    XAA(FillImageWriteRects);
731	    pXAAinfo->WriteBitmapFlags = LEFT_EDGE_CLIPPING | NO_PLANEMASK |
732			    LEFT_EDGE_CLIPPING_NEGATIVE_X |
733			    BIT_ORDER_IN_BYTE_LSBFIRST;
734	    XAA(WriteBitmap);
735	    pXAAinfo->TEGlyphRendererFlags = LEFT_EDGE_CLIPPING | NO_PLANEMASK |
736			    LEFT_EDGE_CLIPPING_NEGATIVE_X;
737	    XAA(TEGlyphRenderer);
738
739	    /* Accelerated Line drawing */
740	    pXAAinfo->SolidLineFlags = NO_PLANEMASK | HARDWARE_CLIP_LINE;
741	    XAA(SubsequentSolidBresenhamLine);
742	    XAA(SetClippingRectangle);
743	    pXAAinfo->SolidBresenhamLineErrorTermBits = 15;
744
745	    /* Pattern fill */
746	    pXAAinfo->Mono8x8PatternFillFlags = NO_PLANEMASK | NO_TRANSPARENCY |
747			    HARDWARE_PATTERN_PROGRAMMED_BITS |
748			    HARDWARE_PATTERN_SCREEN_ORIGIN;
749	    XAA(SetupForMono8x8PatternFill);
750	    XAA(SubsequentMono8x8PatternFillRect);
751#endif
752
753	    /* Accelerated screen-screen bitblts */
754	    pXAAinfo->ScreenToScreenCopyFlags = NO_PLANEMASK | NO_TRANSPARENCY;
755	    XAA(SetupForScreenToScreenCopy);
756	    XAA(SubsequentScreenToScreenCopy);
757#undef XAA
758	}
759    }
760}
761