ffb_accel.c revision 89b0bd4c
1/*
2 * Acceleration for the Creator and Creator3D framebuffer.
3 *
4 * Copyright (C) 1998,1999,2000 Jakub Jelinek (jakub@redhat.com)
5 * Copyright (C) 1998 Michal Rehacek (majkl@iname.com)
6 * Copyright (C) 1999,2000 David S. Miller (davem@redhat.com)
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a copy
9 * of this software and associated documentation files (the "Software"), to deal
10 * in the Software without restriction, including without limitation the rights
11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 * copies of the Software, and to permit persons to whom the Software is
13 * furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
21 * JAKUB JELINEK, MICHAL REHACEK, OR DAVID MILLER BE LIABLE FOR ANY CLAIM,
22 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
23 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
24 * USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 */
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include	"scrnintstr.h"
33#include	"pixmapstr.h"
34#include	"regionstr.h"
35#include	"mistruct.h"
36#include	"miline.h"
37#include	"fb.h"
38
39#include	"ffb.h"
40#include	"ffb_fifo.h"
41#include	"ffb_rcache.h"
42#include	"ffb_loops.h"
43#include	"ffb_regs.h"
44
45#ifdef HAVE_XAA_H
46/* VISmoveImage.s */
47extern void VISmoveImageRL(unsigned char *src, unsigned char *dst, long w, long h, long skind, long dkind);
48extern void VISmoveImageLR(unsigned char *src, unsigned char *dst, long w, long h, long skind, long dkind);
49
50/* Indexed by ffb resolution enum. */
51struct fastfill_parms ffb_fastfill_parms[] = {
52	/* fsmall, psmall,  ffh,  ffw,  pfh,  pfw */
53	{  0x00c0, 0x1400, 0x04, 0x08, 0x10, 0x50 },	/* Standard: 1280 x 1024 */
54	{  0x0140, 0x2800, 0x04, 0x10, 0x10, 0xa0 },	/* High:     1920 x 1360 */
55	{  0x0080, 0x0a00, 0x02, 0x08, 0x08, 0x50 },	/* Stereo:   960  x 580  */
56/*XXX*/	{  0x00c0, 0x0a00, 0x04, 0x08, 0x08, 0x50 },	/* Portrait: 1280 x 2048 XXX */
57};
58
59void
60CreatorVtChange (ScreenPtr pScreen, int enter)
61{
62	ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
63	FFBPtr pFfb = GET_FFB_FROM_SCRN (pScrn);
64	ffb_fbcPtr ffb = pFfb->regs;
65
66	pFfb->rp_active = 1;
67	FFBWait(pFfb, ffb);
68	pFfb->fifo_cache = -1;
69	pFfb->fbc_cache = (FFB_FBC_WB_A | FFB_FBC_WM_COMBINED |
70			   FFB_FBC_RB_A | FFB_FBC_SB_BOTH| FFB_FBC_XE_OFF |
71			   FFB_FBC_ZE_OFF | FFB_FBC_YE_OFF | FFB_FBC_RGBE_MASK);
72	pFfb->ppc_cache = (FFB_PPC_FW_DISABLE |
73			   FFB_PPC_VCE_DISABLE | FFB_PPC_APE_DISABLE | FFB_PPC_CS_CONST |
74			   FFB_PPC_XS_CONST | FFB_PPC_YS_CONST | FFB_PPC_ZS_CONST|
75			   FFB_PPC_DCE_DISABLE | FFB_PPC_ABE_DISABLE | FFB_PPC_TBE_OPAQUE);
76
77	pFfb->pmask_cache = ~0;
78	pFfb->rop_cache = FFB_ROP_EDIT_BIT;
79	pFfb->drawop_cache = FFB_DRAWOP_RECTANGLE;
80	pFfb->fg_cache = pFfb->bg_cache = 0;
81	pFfb->fontw_cache = 32;
82	pFfb->fontinc_cache = (1 << 16) | 0;
83	pFfb->laststipple = NULL;
84	FFBFifo(pFfb, 9);
85	ffb->fbc = pFfb->fbc_cache;
86	ffb->ppc = pFfb->ppc_cache;
87	ffb->pmask = pFfb->pmask_cache;
88	ffb->rop = pFfb->rop_cache;
89	ffb->drawop = pFfb->drawop_cache;
90	ffb->fg = pFfb->fg_cache;
91	ffb->bg = pFfb->bg_cache;
92	ffb->fontw = pFfb->fontw_cache;
93	ffb->fontinc = pFfb->fontinc_cache;
94	pFfb->rp_active = 1;
95	FFBWait(pFfb, ffb);
96
97	/* Fixup the FBC/PPC caches to deal with actually using
98	 * a WID for every ROP.
99	 */
100	pFfb->fbc_cache = (FFB_FBC_WB_A | FFB_FBC_WM_COMBINED |
101			   FFB_FBC_RB_A | FFB_FBC_SB_BOTH | FFB_FBC_XE_ON |
102			   FFB_FBC_ZE_OFF | FFB_FBC_YE_OFF | FFB_FBC_RGBE_ON);
103	pFfb->ppc_cache &= ~FFB_PPC_XS_MASK;
104	pFfb->ppc_cache |= FFB_PPC_XS_WID;
105	pFfb->wid_cache = (enter ? pFfb->wid : 0xff);
106	FFBFifo(pFfb, 11);
107	ffb->fbc = pFfb->fbc_cache;
108	ffb->ppc = FFB_PPC_XS_WID;
109	ffb->wid = pFfb->wid_cache;
110	ffb->xpmask = 0xff;
111	ffb->xclip = FFB_XCLIP_TEST_ALWAYS;
112	ffb->cmp = 0x80808080;
113	ffb->matchab = 0x80808080;
114	ffb->magnab = 0x80808080;
115	ffb->blendc = (FFB_BLENDC_FORCE_ONE |
116		       FFB_BLENDC_DF_ONE_M_A |
117		       FFB_BLENDC_SF_A);
118	ffb->blendc1 = 0;
119	ffb->blendc2 = 0;
120	pFfb->rp_active = 1;
121	FFBWait(pFfb, ffb);
122
123	if (enter) {
124		pFfb->drawop_cache = FFB_DRAWOP_RECTANGLE;
125
126		FFBFifo(pFfb, 5);
127		ffb->drawop = pFfb->drawop_cache;
128		FFB_WRITE64(&ffb->by, 0, 0);
129		FFB_WRITE64_2(&ffb->bh, pFfb->psdp->height, pFfb->psdp->width);
130		pFfb->rp_active = 1;
131		FFBWait(pFfb, ffb);
132
133		SET_SYNC_FLAG(pFfb->pXAAInfo);
134	}
135}
136
137#ifdef DEBUG_FFB
138FILE *FDEBUG_FD = NULL;
139#endif
140
141static CARD32 FFBAlphaTextureFormats[2] = { PICT_a8, 0 };
142static CARD32 FFBTextureFormats[2] = { PICT_a8b8g8r8, 0 };
143static CARD32 FFBTextureDstFormats[3] = { PICT_a8b8g8r8, PICT_x8b8g8r8, 0 };
144
145static void FFB_SetupTextureAttrs(FFBPtr pFfb)
146{
147       ffb_fbcPtr ffb = pFfb->regs;
148       unsigned int ppc = FFB_PPC_APE_DISABLE | FFB_PPC_CS_VAR | FFB_PPC_XS_VAR;
149       unsigned int ppc_mask = FFB_PPC_APE_MASK | FFB_PPC_CS_MASK | FFB_PPC_XS_MASK;
150       unsigned int rop = FFB_ROP_NEW | (FFB_ROP_NEW << 8);
151       unsigned int fbc = pFfb->fbc;
152       unsigned int wid = pFfb->wid;
153
154       ppc |= FFB_PPC_ABE_ENABLE;
155       ppc_mask |= FFB_PPC_ABE_MASK;
156
157       if ((pFfb->ppc_cache & ppc_mask) != ppc ||
158           pFfb->fbc_cache != fbc ||
159           pFfb->wid_cache != wid ||
160           pFfb->rop_cache != rop ||
161           pFfb->pmask_cache != 0xffffffff)
162               __FFB_Attr_SFB_VAR(pFfb, ppc, ppc_mask, fbc,
163                                  wid, rop, 0xffffffff);
164       FFBWait(pFfb, ffb);
165}
166
167static Bool FFB_SetupForCPUToScreenAlphaTexture(
168	ScrnInfoPtr	pScrn,
169	int		op,
170	CARD16		red,
171	CARD16		green,
172	CARD16		blue,
173	CARD16		alpha,
174	CARD32		maskFormat,
175	CARD32		dstFormat,
176	CARD8		*alphaPtr,
177	int		alphaPitch,
178	int		width,
179	int		height,
180	int		flags
181)
182{
183       FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn);
184
185       FFBLOG(("FFB_SetupForCPUToScreenAlphaTexture: "
186               "argb[%04x:%04x:%04x:%04x] alpha[T(%x):P(%d)] "
187               "wh[%d:%d] flgs[%x]\n",
188               alpha, red, green, blue,
189               maskFormat, alphaPitch,
190               width, height, flags));
191
192       FFB_SetupTextureAttrs(pFfb);
193
194       pFfb->xaa_tex = (unsigned char *) alphaPtr;
195       pFfb->xaa_tex_pitch = alphaPitch;
196       pFfb->xaa_tex_width = width;
197       pFfb->xaa_tex_height = height;
198       pFfb->xaa_tex_color = (/*((alpha >> 8) << 24) |*/
199                              ((blue >> 8) << 16) |
200                              ((green >> 8) << 8) |
201                              ((red >> 8) << 0));
202       return TRUE;
203}
204
205static void FFB_SubsequentCPUToScreenAlphaTexture(ScrnInfoPtr pScrn,
206                                                 int dstx, int dsty,
207                                                 int srcx, int srcy,
208                                                 int width, int height)
209{
210       FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn);
211       unsigned char *dst_base, *alpha_base, *sfb32;
212       unsigned int pixel_base;
213       int psz_shift = 2;
214
215       FFBLOG(("FFB_SubsequentCPUToScreenAlphaTexture: "
216               "dst[%d:%d] src[%d:%d] wh[%d:%d]\n",
217               dstx, dsty, srcx, srcy, width, height));
218
219       sfb32 = (unsigned char *) pFfb->sfb32;
220       dst_base = sfb32 + (dsty * (2048 << psz_shift)) + (dstx << psz_shift);
221       alpha_base = pFfb->xaa_tex;
222       alpha_base += srcx;
223       if (srcy)
224               alpha_base += (srcy * pFfb->xaa_tex_pitch);
225       pixel_base = pFfb->xaa_tex_color;
226       while (height--) {
227               unsigned int *dst = (unsigned int *) dst_base;
228               unsigned char *alpha = alpha_base;
229               int w = width;
230
231               while (w--) {
232                       (*dst) = (((unsigned int)*alpha << 24) | pixel_base);
233                       dst++;
234                       alpha++;
235	       }
236	       dst_base += (2048 << psz_shift);
237	       alpha_base += pFfb->xaa_tex_pitch;
238       }
239}
240
241
242static Bool FFB_SetupForCPUToScreenTexture(
243	ScrnInfoPtr	pScrn,
244	int		op,
245	CARD32		srcFormat,
246	CARD32		dstFormat,
247	CARD8		*texPtr,
248	int		texPitch,
249	int		width,
250	int		height,
251	int		flags
252)
253{
254       FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn);
255
256       FFBLOG(("FFB_SetupForCPUToScreenTexture: "
257               "TEX[T(%x):P(%d)] "
258               "wh[%d:%d] flgs[%x]\n",
259               srcFormat, texPitch,
260               width, height, flags));
261
262       FFB_SetupTextureAttrs(pFfb);
263
264       pFfb->xaa_tex = (unsigned char *) texPtr;
265       pFfb->xaa_tex_pitch = texPitch;
266       pFfb->xaa_tex_width = width;
267       pFfb->xaa_tex_height = height;
268
269       return TRUE;
270}
271
272static void FFB_SubsequentCPUToScreenTexture(ScrnInfoPtr pScrn,
273                                            int dstx, int dsty,
274                                            int srcx, int srcy,
275                                            int width, int height)
276{
277       FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn);
278       unsigned char *dst_base, *sfb32;
279       unsigned int *tex_base;
280       int psz_shift = 2;
281
282       FFBLOG(("FFB_SubsequentCPUToScreenAlphaTexture: "
283               "dst[%d:%d] src[%d:%d] wh[%d:%d]\n",
284               dstx, dsty, srcx, srcy, width, height));
285
286       sfb32 = (unsigned char *) pFfb->sfb32;
287       dst_base = sfb32 + (dsty * (2048 << psz_shift)) + (dstx << psz_shift);
288       tex_base = (unsigned int *) pFfb->xaa_tex;
289       tex_base += srcx;
290       if (srcy)
291               tex_base += (srcy * pFfb->xaa_tex_pitch);
292       while (height--) {
293               unsigned int *dst = (unsigned int *) dst_base;
294               unsigned int *tex = tex_base;
295               int w = width;
296               while (w--) {
297                       (*dst) = *tex;
298
299                       dst++;
300                       tex++;
301               }
302               dst_base += (2048 << psz_shift);
303               tex_base += pFfb->xaa_tex_pitch;
304       }
305}
306
307static void FFB_WritePixmap(ScrnInfoPtr pScrn,
308                           int x, int y, int w, int h,
309                           unsigned char *src,
310                           int srcwidth,
311                           int rop,
312                           unsigned int planemask,
313                           int trans, int bpp, int depth)
314{
315       FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn);
316       unsigned char *dst, *sfb32;
317       int psz_shift = 2;
318       ffb_fbcPtr ffb = pFfb->regs;
319
320       FFBLOG(("FFB_WritePixmap: "
321               "x[%d] y[%d] w[%d] h[%d] srcw[%d] rop[%d] pmask[%x] "
322               "trans[%d] bpp[%d] depth[%d]\n",
323               x, y, w, h, srcwidth, rop, planemask,
324               trans, bpp, depth));
325
326       FFB_ATTR_SFB_VAR_XAA(pFfb, planemask, rop);
327       FFBWait(pFfb, ffb);
328
329       sfb32 = (unsigned char *) pFfb->sfb32;
330       dst = sfb32 + (y * (2048 << psz_shift)) + (x << psz_shift);
331       VISmoveImageLR(src, dst, w << psz_shift, h,
332                      srcwidth, (2048 << psz_shift));
333}
334
335static void FFB_SetupForMono8x8PatternFill(ScrnInfoPtr pScrn,
336                                          int pat_word1, int pat_word2,
337                                          int fg, int bg, int rop,
338                                          unsigned int planemask)
339{
340       FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn);
341       ffb_fbcPtr ffb = pFfb->regs;
342       unsigned int ppc, ppc_mask, fbc;
343       int i;
344
345       FFBLOG(("FFB_SetupForMono8x8PatternFill: "
346               "pat[%08x:%08x] fg[%x] bg[%x] rop[%d] pmask[%x]\n",
347               pat_word1, pat_word2,
348               fg, bg, rop, planemask));
349
350       ppc = FFB_PPC_ABE_DISABLE | FFB_PPC_APE_ENABLE | FFB_PPC_CS_CONST;
351       if (bg < 0)
352               ppc |= FFB_PPC_TBE_TRANSPARENT;
353       else
354               ppc |= FFB_PPC_TBE_OPAQUE;
355       ppc_mask = FFB_PPC_ABE_MASK | FFB_PPC_APE_MASK |
356         FFB_PPC_TBE_MASK | FFB_PPC_CS_MASK;
357       fbc = pFfb->fbc;
358       rop = (rop | FFB_ROP_EDIT_BIT) | (FFB_ROP_NEW << 8);
359
360       FFB_ATTR_RAW(pFfb, ppc, ppc_mask, planemask, rop,
361                    FFB_DRAWOP_RECTANGLE, fg, fbc, pFfb->wid);
362       if (bg >= 0)
363               FFB_WRITE_BG(pFfb, ffb, bg);
364
365       FFBFifo(pFfb, 32);
366       for (i = 0; i < 32; i += 2) {
367               CARD32 val1, val2;
368               int shift = (24 - ((i % 4) * 8));
369
370               if ((i % 8) < 4) {
371                       val1 = (pat_word1 >> shift) & 0xff;
372                       val2 = (pat_word1 >> (shift + 8)) & 0xff;
373               } else {
374                       val1 = (pat_word2 >> shift) & 0xff;
375                       val2 = (pat_word2 >> (shift + 8)) & 0xff;
376               }
377               val1 |= (val1 << 8) | (val1 << 16) | (val1 << 24);
378               val2 |= (val2 << 8) | (val2 << 16) | (val2 << 24);
379               FFB_WRITE64(&ffb->pattern[i], val1, val2);
380       }
381       pFfb->rp_active = 1;
382}
383
384static void FFB_SubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn,
385                                                int pat_word1, int pat_word2,
386                                                int x, int y, int w, int h)
387{
388       FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn);
389       ffb_fbcPtr ffb = pFfb->regs;
390
391       FFBLOG(("FFB_SubsequentMono8x8PatternFillRect: "
392               "x[%d] y[%d] w[%d] h[%d]\n", x, y, w, h));
393
394       FFBFifo(pFfb, 4);
395       FFB_WRITE64(&ffb->by, y, x);
396       FFB_WRITE64_2(&ffb->bh, h, w);
397}
398
399static void FFB_SetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
400                                                          int fg, int bg,
401                                                          int rop,
402                                                          unsigned int planemask)
403{
404       FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn);
405       ffb_fbcPtr ffb = pFfb->regs;
406       unsigned int ppc, ppc_mask, fbc;
407
408       FFBLOG(("FFB_SetupForScanlineCPUToScreenColorExpandFill: "
409               "fg[%x] bg[%x] rop[%d] pmask[%x]\n",
410               fg, bg, rop, planemask));
411
412       ppc = FFB_PPC_ABE_DISABLE | FFB_PPC_APE_DISABLE | FFB_PPC_CS_CONST;
413       if (bg < 0)
414               ppc |= FFB_PPC_TBE_TRANSPARENT;
415       else
416               ppc |= FFB_PPC_TBE_OPAQUE;
417       ppc_mask = FFB_PPC_ABE_MASK | FFB_PPC_APE_MASK |
418         FFB_PPC_TBE_MASK | FFB_PPC_CS_MASK;
419       fbc = pFfb->fbc;
420       rop = (rop | FFB_ROP_EDIT_BIT) | (FFB_ROP_NEW << 8);
421
422       if ((pFfb->ppc_cache & ppc_mask) != ppc ||
423           pFfb->fg_cache != fg ||
424           pFfb->fbc_cache != fbc ||
425           pFfb->rop_cache != rop ||
426           pFfb->pmask_cache != planemask ||
427           pFfb->fontinc_cache != ((0<<16) | 32) ||
428           (bg >= 0 && pFfb->bg_cache != bg)) {
429               pFfb->ppc_cache &= ~ppc_mask;
430               pFfb->ppc_cache |= ppc;
431               pFfb->fg_cache = fg;
432               pFfb->fbc_cache = fbc;
433               pFfb->rop_cache = rop;
434               pFfb->pmask_cache = planemask;
435               pFfb->fontinc_cache = ((0<<16) | 32);
436               if (bg >= 0)
437                       pFfb->bg_cache = bg;
438               FFBFifo(pFfb, (bg >= 0 ? 7 : 6));
439               ffb->ppc = ppc;
440               ffb->fg = fg;
441               ffb->fbc = fbc;
442               ffb->rop = rop;
443               ffb->pmask = planemask;
444               ffb->fontinc = ((0 << 16) | 32);
445               if(bg >= 0)
446                       ffb->bg = bg;
447       }
448       pFfb->rp_active = 1;
449}
450
451static void FFB_SubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
452                                                            int x, int y, int w, int h,
453                                                            int skipleft)
454{
455       FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn);
456       FFBLOG(("FFB_SubsequentCPUToScreenColorExpandFill: "
457               "x[%d] y[%d] w[%d] h[%d] skipleft[%d]\n",
458               x, y, w, h, skipleft));
459
460       pFfb->xaa_scanline_x = x;
461       pFfb->xaa_scanline_y = y;
462       pFfb->xaa_scanline_w = w;
463}
464
465static void FFB_SubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno)
466{
467       FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn);
468       ffb_fbcPtr ffb = pFfb->regs;
469       CARD32 *bits = (CARD32 *) pFfb->xaa_scanline_buffers[bufno];
470       int w;
471
472       FFBFifo(pFfb, 1);
473       ffb->fontxy = ((pFfb->xaa_scanline_y << 16) | pFfb->xaa_scanline_x);
474
475       w = pFfb->xaa_scanline_w;
476       if (w >= 32) {
477               FFB_WRITE_FONTW(pFfb, ffb, 32);
478               FFBFifo(pFfb, (w / 32));
479               do {
480                       ffb->font = *bits++;
481                       w -= 32;
482               } while (w >= 32);
483       }
484       if (w > 0) {
485               FFB_WRITE_FONTW(pFfb, ffb, w);
486               FFBFifo(pFfb, 1);
487               ffb->font = *bits++;
488       }
489
490       pFfb->xaa_scanline_y++;
491}
492
493static void FFB_SetupForDashedLine(ScrnInfoPtr pScrn,
494                                  int fg, int bg, int rop,
495                                  unsigned int planemask,
496                                  int length, unsigned char *pattern)
497{
498       FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn);
499       CARD32 *pat_ptr = (CARD32 *)pattern;
500       unsigned int ppc, ppc_mask, fbc;
501
502       FFBLOG(("FFB_SetupForDashedLine: "
503               "fg[%x] bg[%x] rop[%d] pmask[%x] patlen[%d] pat[%x]\n",
504               fg, bg, rop, planemask, length, *pat_ptr));
505
506       pFfb->planemask = planemask;
507       pFfb->xaa_rop = rop;
508       pFfb->xaa_linepat =
509               (*pat_ptr << FFB_LPAT_PATTERN_SHIFT) |
510               (1 << FFB_LPAT_SCALEVAL_SHIFT) |
511               ((length & 0xf) << FFB_LPAT_PATLEN_SHIFT);
512
513       fbc = pFfb->fbc;
514       ppc = FFB_PPC_ABE_DISABLE | FFB_PPC_APE_DISABLE | FFB_PPC_CS_CONST | FFB_PPC_XS_WID;
515       ppc_mask = FFB_PPC_ABE_MASK | FFB_PPC_APE_MASK | FFB_PPC_CS_MASK | FFB_PPC_XS_MASK;
516
517       FFB_ATTR_RAW(pFfb, ppc, ppc_mask, planemask,
518                    (FFB_ROP_EDIT_BIT | rop) | (FFB_ROP_NEW << 8),
519                    FFB_DRAWOP_BRLINEOPEN, fg, fbc, pFfb->wid);
520       pFfb->rp_active = 1;
521}
522
523static void FFB_SubsequentDashedTwoPointLine( ScrnInfoPtr pScrn,
524                                             int x1, int y1,
525                                             int x2, int y2,
526                                             int flags, int phase)
527{
528       FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn);
529       ffb_fbcPtr ffb = pFfb->regs;
530       unsigned int linepat = pFfb->xaa_linepat;
531       unsigned int drawop;
532
533       FFBLOG(("FFB_SubsequentDashedTwoPointLine: "
534               "x1[%d] y1[%d] x2[%d] y2[%d] flgs[%x] phase[%d]\n",
535               x1, y2, x2, y2, flags, phase));
536
537       linepat |= (phase & 0xf) << FFB_LPAT_PATPTR_SHIFT;
538
539       drawop = (flags & OMIT_LAST) ?
540         FFB_DRAWOP_BRLINEOPEN : FFB_DRAWOP_BRLINECAP;
541       FFB_WRITE_DRAWOP(pFfb, ffb, drawop);
542
543       if (pFfb->has_brline_bug) {
544               FFBFifo(pFfb, 6);
545               ffb->ppc = 0;
546       } else
547               FFBFifo(pFfb, 5);
548       ffb->lpat = linepat;
549       FFB_WRITE64(&ffb->by, y1, x1);
550       FFB_WRITE64_2(&ffb->bh, y2, x2);
551}
552
553static void FFB_SetupForSolidLine(ScrnInfoPtr pScrn,
554                                 int color, int rop, unsigned int planemask)
555{
556       FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn);
557       ffb_fbcPtr ffb = pFfb->regs;
558       unsigned int ppc, ppc_mask, fbc;
559       FFBLOG(("FFB_SetupForSolidLine: "
560               "color[%d] rop[%d] pmask[%x]\n",
561               color, rop, planemask));
562
563       pFfb->planemask = planemask;
564       pFfb->xaa_rop = rop;
565
566       fbc = pFfb->fbc;
567       ppc = FFB_PPC_ABE_DISABLE | FFB_PPC_APE_DISABLE | FFB_PPC_CS_CONST | FFB_PPC_XS_WID;
568       ppc_mask = FFB_PPC_ABE_MASK | FFB_PPC_APE_MASK | FFB_PPC_CS_MASK | FFB_PPC_XS_MASK;
569
570       FFB_ATTR_RAW(pFfb, ppc, ppc_mask, planemask,
571                    (FFB_ROP_EDIT_BIT | rop) | (FFB_ROP_NEW << 8),
572                    FFB_DRAWOP_BRLINEOPEN, color, fbc, pFfb->wid);
573       FFBFifo(pFfb, 1);
574       ffb->lpat = 0;
575       pFfb->rp_active = 1;
576}
577
578static void FFB_SubsequentSolidTwoPointLine(ScrnInfoPtr pScrn,
579                                           int x1, int y1,
580                                           int x2, int y2,
581                                           int flags)
582{
583       FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn);
584       ffb_fbcPtr ffb = pFfb->regs;
585       int drawop;
586
587       FFBLOG(("FFB_SubsequentSolidTwoPointLine: "
588               "x1[%d] y1[%d] x2[%d] y2[%d] flags[%d]\n",
589               x1, y1, x2, y2, flags));
590
591       drawop = (flags & OMIT_LAST) ?
592         FFB_DRAWOP_BRLINEOPEN : FFB_DRAWOP_BRLINECAP;
593       FFB_WRITE_DRAWOP(pFfb, ffb, drawop);
594
595       if (pFfb->has_brline_bug) {
596               FFBFifo(pFfb, 5);
597               ffb->ppc = 0;
598       } else
599               FFBFifo(pFfb, 4);
600       FFB_WRITE64(&ffb->by, y1, x1);
601       FFB_WRITE64_2(&ffb->bh, y2, x2);
602}
603
604void FFB_SetupForSolidFill(ScrnInfoPtr pScrn,
605                          int color, int rop, unsigned int planemask)
606{
607       FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn);
608       unsigned int ppc, ppc_mask, fbc;
609
610       FFBLOG(("FFB_SetupForSolidFill: "
611               "color[%d] rop[%d] pmask[%u]\n",
612               color, rop, planemask));
613
614       pFfb->planemask = planemask;
615       pFfb->xaa_rop = rop;
616
617       fbc = pFfb->fbc;
618       if (pFfb->ffb_res == ffb_res_high)
619               fbc |= FFB_FBC_WB_B;
620       ppc = FFB_PPC_ABE_DISABLE | FFB_PPC_APE_DISABLE | FFB_PPC_CS_CONST | FFB_PPC_XS_WID;
621       ppc_mask = FFB_PPC_ABE_MASK | FFB_PPC_APE_MASK | FFB_PPC_CS_MASK | FFB_PPC_XS_MASK;
622
623       FFB_ATTR_RAW(pFfb, ppc, ppc_mask, planemask,
624                    (FFB_ROP_EDIT_BIT | rop) | (FFB_ROP_NEW << 8),
625                    FFB_DRAWOP_RECTANGLE, color, fbc, pFfb->wid);
626       pFfb->rp_active = 1;
627}
628
629void FFB_SubsequentSolidFillRect(ScrnInfoPtr pScrn,
630                                int x, int y,
631                                int w, int h)
632{
633       FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn);
634       ffb_fbcPtr ffb = pFfb->regs;
635
636       FFBLOG(("FFB_SubsequentSolidFillRect: "
637               "x[%d] y[%d] w[%d] h[%d]\n", x, y, w, h));
638
639       FFBFifo(pFfb, 4);
640       FFB_WRITE64(&ffb->by, y, x);
641       FFB_WRITE64_2(&ffb->bh, h, w);
642}
643
644static void FFB_ScreenToScreenBitBlt(ScrnInfoPtr pScrn,
645                                    int nbox,
646                                    DDXPointPtr pptSrc,
647                                    BoxPtr pbox,
648                                    int xdir, int ydir,
649                                    int rop, unsigned int planemask)
650{
651       FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn);
652       ffb_fbcPtr ffb = pFfb->regs;
653       int use_vscroll;
654
655       FFBLOG(("FFB_ScreenToScreenBitBlt: "
656               "nbox[%d] xdir[%d] ydir[%d] rop[%d] pmask[%x]\n",
657               nbox, xdir, ydir, rop, planemask));
658
659       use_vscroll = 0;
660       if (!pFfb->disable_vscroll &&
661           rop == GXcopy) {
662               int i;
663
664               for (i = 0; i < nbox; i++)
665                       if (pptSrc[i].x != pbox[i].x1 ||
666                           pptSrc[i].y == pbox[i].y1)
667                               break;
668               if (i == nbox) {
669                       /* If/When double buffer extension is re-enabled
670                        * check buffers here.
671                        */
672                       use_vscroll = 1;
673               }
674       }
675       if (use_vscroll) {
676               FFB_ATTR_VSCROLL_XAA(pFfb, planemask);
677               while (nbox--) {
678                       FFBFifo(pFfb, 7);
679                       ffb->drawop = FFB_DRAWOP_VSCROLL;
680                       FFB_WRITE64(&ffb->by, pptSrc->y, pptSrc->x);
681                       FFB_WRITE64_2(&ffb->dy, pbox->y1, pbox->x1);
682                       FFB_WRITE64_3(&ffb->bh, (pbox->y2 - pbox->y1),
683                                     (pbox->x2 - pbox->x1));
684
685                       pbox++;
686                       pptSrc++;
687               }
688               pFfb->rp_active = 1;
689               SET_SYNC_FLAG(pFfb->pXAAInfo);
690       } else {
691               unsigned char *sfb32 = (unsigned char *) pFfb->sfb32;
692               int psz_shift = 2;
693
694               FFB_ATTR_SFB_VAR_XAA(pFfb, planemask, rop);
695               if (pFfb->use_blkread_prefetch) {
696                       unsigned int bit;
697
698                       if (xdir < 0)
699                               bit = FFB_MER_EDRA;
700                       else
701                               bit = FFB_MER_EIRA;
702                       FFBFifo(pFfb, 1);
703                       ffb->mer = bit;
704                       pFfb->rp_active = 1;
705               }
706               FFBWait(pFfb, ffb);
707
708               while (nbox--) {
709                       unsigned char *src, *dst;
710                       int x1, y1, x2, y2;
711                       int width, height;
712                       int sdkind;
713
714                       x1 = pptSrc->x;
715                       y1 = pptSrc->y;
716                       x2 = pbox->x1;
717                       y2 = pbox->y1;
718                       width = (pbox->x2 - pbox->x1);
719                       height = (pbox->y2 - pbox->y1);
720
721                       src = sfb32 + (y1 * (2048 << psz_shift))
722                               + (x1 << psz_shift);
723                       dst = sfb32 + (y2 * (2048 << psz_shift))
724                               + (x2 << psz_shift);
725                       sdkind = (2048 << psz_shift);
726
727                       if (ydir < 0) {
728                               src += ((height - 1) * (2048 << psz_shift));
729                               dst += ((height - 1) * (2048 << psz_shift));
730                               sdkind = -sdkind;
731                       }
732                       width <<= psz_shift;
733                       if (xdir < 0)
734                               VISmoveImageRL(src, dst, width, height,
735                                              sdkind, sdkind);
736                       else
737                               VISmoveImageLR(src, dst, width, height,
738                                              sdkind, sdkind);
739                       pbox++;
740                       pptSrc++;
741	       }
742               if (pFfb->use_blkread_prefetch) {
743                       FFBFifo(pFfb, 1);
744                       ffb->mer = FFB_MER_DRA;
745                       pFfb->rp_active = 1;
746                       FFBWait(pFfb, ffb);
747               }
748       }
749}
750
751void FFB_SetupForScreenToScreenCopy(ScrnInfoPtr pScrn,
752                                   int xdir, int ydir, int rop,
753                                   unsigned int planemask,
754                                   int trans_color)
755{
756       FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn);
757       ffb_fbcPtr ffb = pFfb->regs;
758       FFBLOG(("FFB_SetupForScreenToScreenCopy: "
759               "xdir[%d] ydir[%d] rop[%d] pmask[%x] tcolor[%d]\n",
760               xdir, ydir, rop, planemask, trans_color));
761
762       pFfb->planemask = planemask;
763       pFfb->xaa_xdir = xdir;
764       pFfb->xaa_ydir = ydir;
765       pFfb->xaa_rop = rop;
766       FFB_ATTR_SFB_VAR_XAA(pFfb, planemask, rop);
767       FFBWait(pFfb, ffb);
768}
769
770void FFB_SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn,
771                                     int x1, int y1,
772                                     int x2, int y2,
773                                     int width, int height)
774{
775       FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn);
776       unsigned char *src, *dst, *sfb32;
777       int psz_shift = 2;
778       int sdkind;
779
780       FFBLOG(("FFB_SubsequentScreenToScreenCopy: "
781               "x1[%d] y1[%d] x2[%d] y2[%u] w[%d] h[%d]\n",
782               x1, y1, x2, y2, width, height));
783
784       sfb32 = (unsigned char *) pFfb->sfb32;
785       src = sfb32 + (y1 * (2048 << psz_shift)) + (x1 << psz_shift);
786       dst = sfb32 + (y2 * (2048 << psz_shift)) + (x2 << psz_shift);
787       sdkind = (2048 << psz_shift);
788
789       if (pFfb->xaa_ydir < 0) {
790               src += ((height - 1) * (2048 << psz_shift));
791               dst += ((height - 1) * (2048 << psz_shift));
792               sdkind = -sdkind;
793       }
794
795       width <<= psz_shift;
796       if (pFfb->xaa_xdir < 0)
797               VISmoveImageRL(src, dst, width, height, sdkind, sdkind);
798       else
799               VISmoveImageLR(src, dst, width, height, sdkind, sdkind);
800}
801
802static void FFB_Sync(ScrnInfoPtr pScrn)
803{
804       FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn);
805       ffb_fbcPtr ffb = pFfb->regs;
806
807       FFB_ATTR_SFB_VAR_XAA(pFfb, 0xffffffff, GXcopy);
808       FFBWait(pFfb, ffb);
809}
810
811/* Multiplies and divides suck... */
812static void CreatorAlignTabInit(FFBPtr pFfb)
813{
814	struct fastfill_parms *ffp = &FFB_FFPARMS(pFfb);
815	short *tab = pFfb->Pf_AlignTab;
816	int i;
817
818	for(i = 0; i < 0x800; i++) {
819		int alignval;
820
821		alignval = (i / ffp->pagefill_width) * ffp->pagefill_width;
822		*tab++ = alignval;
823	}
824}
825
826#endif
827
828Bool FFBAccelInit(ScreenPtr pScreen, FFBPtr pFfb)
829{
830#ifdef HAVE_XAA_H
831	XAAInfoRecPtr infoRec;
832	ffb_fbcPtr ffb = pFfb->regs;
833
834	pFfb->fbc = (FFB_FBC_WB_A | FFB_FBC_WM_COMBINED | FFB_FBC_RB_A |
835			 FFB_FBC_WE_FORCEON |
836			 FFB_FBC_SB_BOTH |
837			 FFB_FBC_ZE_OFF | FFB_FBC_YE_OFF |
838			 FFB_FBC_RGBE_MASK |
839			 FFB_FBC_XE_ON);
840	pFfb->wid = FFBWidAlloc(pFfb, TrueColor, 0, TRUE);
841	if (pFfb->wid == (unsigned int) -1)
842		return FALSE;
843
844	pFfb->pXAAInfo = infoRec = XAACreateInfoRec();
845	if (!infoRec) {
846		FFBWidFree(pFfb, pFfb->wid);
847		return FALSE;
848	}
849
850	pFfb->xaa_scanline_buffers[0] = malloc(2048 * 4);
851	if (!pFfb->xaa_scanline_buffers[0]) {
852		XAADestroyInfoRec(infoRec);
853		return FALSE;
854	}
855
856	pFfb->xaa_scanline_buffers[1] = malloc(2048 * 4);
857	if (!pFfb->xaa_scanline_buffers[1]) {
858		free(pFfb->xaa_scanline_buffers[0]);
859		XAADestroyInfoRec(infoRec);
860		return FALSE;
861	}
862
863	infoRec->Sync = FFB_Sync;
864
865	/* Use VIS and VSCROLL for screen to screen copies.  */
866	infoRec->ScreenToScreenCopyFlags = NO_TRANSPARENCY;
867	infoRec->SetupForScreenToScreenCopy =
868		FFB_SetupForScreenToScreenCopy;
869	infoRec->SubsequentScreenToScreenCopy =
870		FFB_SubsequentScreenToScreenCopy;
871
872	/* In order to optimize VSCROLL and prefetching properly we
873	 * have to use our own mid-layer routine.
874	 */
875	infoRec->ScreenToScreenBitBltFlags = NO_TRANSPARENCY;
876	infoRec->ScreenToScreenBitBlt =
877		FFB_ScreenToScreenBitBlt;
878
879	infoRec->SolidFillFlags = 0;
880	infoRec->SetupForSolidFill =
881		FFB_SetupForSolidFill;
882	infoRec->SubsequentSolidFillRect =
883		FFB_SubsequentSolidFillRect;
884
885	infoRec->SolidLineFlags = 0;
886	infoRec->SetupForSolidLine =
887		FFB_SetupForSolidLine;
888	infoRec->SubsequentSolidTwoPointLine =
889		FFB_SubsequentSolidTwoPointLine;
890	miSetZeroLineBias(pScreen, OCTANT3 | OCTANT4 | OCTANT6 | OCTANT1);
891
892	infoRec->DashedLineFlags = (TRANSPARENCY_ONLY |
893				    LINE_PATTERN_LSBFIRST_LSBJUSTIFIED);
894	infoRec->DashPatternMaxLength = 16;
895	infoRec->SetupForDashedLine =
896		FFB_SetupForDashedLine;
897	infoRec->SubsequentDashedTwoPointLine =
898		FFB_SubsequentDashedTwoPointLine;
899
900	/* We cannot use the non-scanline color expansion mechanism on FFB
901	 * for two reasons:
902	 *
903	 * 1) A render pass can only render 32-pixels wide on FFB, XAA expects
904	 *    that arbitrary widths are possible per render pass.
905	 *
906	 * 2) The FFB accelerator FIFO is only 100 or so words deep, and
907	 *    XAA gives no way to limit the number of words it writes into
908	 *    the ColorExpandBase register per rendering pass.
909	 */
910	infoRec->ScanlineColorExpandBuffers = pFfb->xaa_scanline_buffers;
911	infoRec->NumScanlineColorExpandBuffers = 2;
912	infoRec->ScanlineCPUToScreenColorExpandFillFlags =
913		CPU_TRANSFER_PAD_DWORD |
914		SCANLINE_PAD_DWORD |
915		CPU_TRANSFER_BASE_FIXED |
916		BIT_ORDER_IN_BYTE_LSBFIRST;
917	infoRec->SetupForScanlineCPUToScreenColorExpandFill =
918		FFB_SetupForScanlineCPUToScreenColorExpandFill;
919	infoRec->SubsequentScanlineCPUToScreenColorExpandFill =
920		FFB_SubsequentScanlineCPUToScreenColorExpandFill;
921	infoRec->SubsequentColorExpandScanline =
922		FFB_SubsequentColorExpandScanline;
923
924	infoRec->Mono8x8PatternFillFlags =
925		HARDWARE_PATTERN_PROGRAMMED_BITS |
926		HARDWARE_PATTERN_SCREEN_ORIGIN |
927		BIT_ORDER_IN_BYTE_LSBFIRST;
928	infoRec->SetupForMono8x8PatternFill =
929		FFB_SetupForMono8x8PatternFill;
930	infoRec->SubsequentMono8x8PatternFillRect =
931		FFB_SubsequentMono8x8PatternFillRect;
932
933	/* Use VIS for pixmap writes.  */
934	infoRec->WritePixmap = FFB_WritePixmap;
935
936	/* RENDER optimizations.  */
937	infoRec->CPUToScreenAlphaTextureFlags =
938		XAA_RENDER_NO_TILE |
939		XAA_RENDER_NO_SRC_ALPHA;
940	infoRec->CPUToScreenAlphaTextureFormats = FFBAlphaTextureFormats;
941	infoRec->CPUToScreenAlphaTextureDstFormats = FFBTextureDstFormats;
942	infoRec->SetupForCPUToScreenAlphaTexture2 =
943		FFB_SetupForCPUToScreenAlphaTexture;
944	infoRec->SubsequentCPUToScreenAlphaTexture =
945		FFB_SubsequentCPUToScreenAlphaTexture;
946
947	infoRec->CPUToScreenTextureFlags =
948		XAA_RENDER_NO_TILE |
949		XAA_RENDER_NO_SRC_ALPHA;
950	infoRec->CPUToScreenTextureFormats = FFBTextureFormats;
951	infoRec->CPUToScreenTextureDstFormats = FFBTextureDstFormats;
952	infoRec->SetupForCPUToScreenTexture2 =
953		FFB_SetupForCPUToScreenTexture;
954	infoRec->SubsequentCPUToScreenTexture =
955		FFB_SubsequentCPUToScreenTexture;
956
957	pFfb->fifo_cache = 0;
958
959	FFB_DEBUG_init();
960	FDEBUG((FDEBUG_FD,
961		"FFB: cfg0(%08x) cfg1(%08x) cfg2(%08x) cfg3(%08x) ppcfg(%08x)\n",
962		ffb->fbcfg0, ffb->fbcfg1, ffb->fbcfg2, ffb->fbcfg3, ffb->ppcfg));
963
964	/* Determine the current screen resolution type.  This is
965	 * needed to figure out the fastfill/pagefill parameters.
966	 */
967	switch(ffb->fbcfg0 & FFB_FBCFG0_RES_MASK) {
968	default:
969	case FFB_FBCFG0_RES_STD:
970		pFfb->ffb_res = ffb_res_standard;
971		break;
972	case FFB_FBCFG0_RES_HIGH:
973		pFfb->ffb_res = ffb_res_high;
974		break;
975	case FFB_FBCFG0_RES_STEREO:
976		pFfb->ffb_res = ffb_res_stereo;
977		break;
978	case FFB_FBCFG0_RES_PRTRAIT:
979		pFfb->ffb_res = ffb_res_portrait;
980		break;
981	};
982	CreatorAlignTabInit(pFfb);
983
984	/* Next, determine the hwbug workarounds and feature enables
985	 * we should be using on this board.
986	 */
987	pFfb->disable_pagefill = 0;
988	pFfb->disable_vscroll = 0;
989	pFfb->has_brline_bug = 0;
990	pFfb->use_blkread_prefetch = 0;
991	if (pFfb->ffb_type == ffb1_prototype ||
992	    pFfb->ffb_type == ffb1_standard ||
993	    pFfb->ffb_type == ffb1_speedsort) {
994		pFfb->has_brline_bug = 1;
995		if (pFfb->ffb_res == ffb_res_high)
996			pFfb->disable_vscroll = 1;
997		if (pFfb->ffb_res == ffb_res_high ||
998		    pFfb->ffb_res == ffb_res_stereo)
999			pFfb->disable_pagefill = 1;
1000
1001	} else {
1002		/* FFB2 has blkread prefetch.  AFB supposedly does too
1003		 * but the chip locks up on me when I try to use it. -DaveM
1004		 */
1005#define AFB_PREFETCH_IS_BUGGY	1
1006		if (!AFB_PREFETCH_IS_BUGGY ||
1007		    (pFfb->ffb_type != afb_m3 &&
1008		     pFfb->ffb_type != afb_m6)) {
1009			pFfb->use_blkread_prefetch = 1;
1010		}
1011		/* XXX I still cannot get page/block fast fills
1012		 * XXX to work reliably on any of my AFB boards. -DaveM
1013		 */
1014#define AFB_FASTFILL_IS_BUGGY	1
1015		if (AFB_FASTFILL_IS_BUGGY &&
1016		    (pFfb->ffb_type == afb_m3 ||
1017		     pFfb->ffb_type == afb_m6))
1018			pFfb->disable_pagefill = 1;
1019	}
1020	pFfb->disable_fastfill_ap = 0;
1021	if (pFfb->ffb_res == ffb_res_stereo ||
1022	    pFfb->ffb_res == ffb_res_high)
1023		pFfb->disable_fastfill_ap = 1;
1024
1025	pFfb->ppc_cache = (FFB_PPC_FW_DISABLE |
1026			   FFB_PPC_VCE_DISABLE | FFB_PPC_APE_DISABLE | FFB_PPC_CS_CONST |
1027			   FFB_PPC_XS_WID | FFB_PPC_YS_CONST | FFB_PPC_ZS_CONST |
1028			   FFB_PPC_DCE_DISABLE | FFB_PPC_ABE_DISABLE | FFB_PPC_TBE_OPAQUE);
1029	pFfb->wid_cache = pFfb->wid;
1030	pFfb->pmask_cache = ~0;
1031	pFfb->rop_cache = (FFB_ROP_NEW | (FFB_ROP_NEW << 8));
1032	pFfb->drawop_cache = FFB_DRAWOP_RECTANGLE;
1033	pFfb->fg_cache = pFfb->bg_cache = 0;
1034	pFfb->fontw_cache = 32;
1035	pFfb->fontinc_cache = (1 << 16) | 0;
1036	pFfb->fbc_cache = (FFB_FBC_WB_A | FFB_FBC_WM_COMBINED | FFB_FBC_RB_A |
1037			   FFB_FBC_WE_FORCEON |
1038			   FFB_FBC_SB_BOTH |
1039			   FFB_FBC_ZE_OFF | FFB_FBC_YE_OFF |
1040			   FFB_FBC_RGBE_OFF |
1041			   FFB_FBC_XE_ON);
1042	pFfb->laststipple = NULL;
1043
1044	/* We will now clear the screen: we'll draw a rectangle covering all the
1045	 * viewscreen, using a 'blackness' ROP.
1046	 */
1047	FFBFifo(pFfb, 22);
1048	ffb->fbc = pFfb->fbc_cache;
1049	ffb->ppc = pFfb->ppc_cache;
1050	ffb->wid = pFfb->wid_cache;
1051	ffb->xpmask = 0xff;
1052	ffb->pmask = pFfb->pmask_cache;
1053	ffb->rop = pFfb->rop_cache;
1054	ffb->drawop = pFfb->drawop_cache;
1055	ffb->fg = pFfb->fg_cache;
1056	ffb->bg = pFfb->bg_cache;
1057	ffb->fontw = pFfb->fontw_cache;
1058	ffb->fontinc = pFfb->fontinc_cache;
1059	ffb->xclip = FFB_XCLIP_TEST_ALWAYS;
1060	ffb->cmp = 0x80808080;
1061	ffb->matchab = 0x80808080;
1062	ffb->magnab = 0x80808080;
1063	ffb->blendc = (FFB_BLENDC_FORCE_ONE |
1064		       FFB_BLENDC_DF_ONE_M_A |
1065		       FFB_BLENDC_SF_A);
1066	ffb->blendc1 = 0;
1067	ffb->blendc2 = 0;
1068	FFB_WRITE64(&ffb->by, 0, 0);
1069	FFB_WRITE64_2(&ffb->bh, pFfb->psdp->height, pFfb->psdp->width);
1070	pFfb->rp_active = 1;
1071	FFBWait(pFfb, ffb);
1072
1073	FFB_ATTR_SFB_VAR_XAA(pFfb, 0xffffffff, GXcopy);
1074	FFBWait(pFfb, ffb);
1075
1076	if (!XAAInit(pScreen, infoRec)) {
1077		XAADestroyInfoRec(infoRec);
1078		free(pFfb->xaa_scanline_buffers[0]);
1079		free(pFfb->xaa_scanline_buffers[1]);
1080		pFfb->pXAAInfo = NULL;
1081		FFBWidFree(pFfb, pFfb->wid);
1082		return FALSE;
1083	}
1084	/* Success */
1085	return TRUE;
1086#else
1087	return FALSE;
1088#endif
1089}
1090