ffb_accel.c revision d4df137b
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	"ffb.h"
33#include	"ffb_fifo.h"
34#include	"ffb_rcache.h"
35#include	"ffb_loops.h"
36#include	"ffb_regs.h"
37
38#include	"scrnintstr.h"
39#include	"pixmapstr.h"
40#include	"regionstr.h"
41#include	"mistruct.h"
42#include	"miline.h"
43#include	"fb.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
51void
52CreatorVtChange (ScreenPtr pScreen, int enter)
53{
54	ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
55	FFBPtr pFfb = GET_FFB_FROM_SCRN (pScrn);
56	ffb_fbcPtr ffb = pFfb->regs;
57
58	pFfb->rp_active = 1;
59	FFBWait(pFfb, ffb);
60	pFfb->fifo_cache = -1;
61	pFfb->fbc_cache = (FFB_FBC_WB_A | FFB_FBC_WM_COMBINED |
62			   FFB_FBC_RB_A | FFB_FBC_SB_BOTH| FFB_FBC_XE_OFF |
63			   FFB_FBC_ZE_OFF | FFB_FBC_YE_OFF | FFB_FBC_RGBE_MASK);
64	pFfb->ppc_cache = (FFB_PPC_FW_DISABLE |
65			   FFB_PPC_VCE_DISABLE | FFB_PPC_APE_DISABLE | FFB_PPC_CS_CONST |
66			   FFB_PPC_XS_CONST | FFB_PPC_YS_CONST | FFB_PPC_ZS_CONST|
67			   FFB_PPC_DCE_DISABLE | FFB_PPC_ABE_DISABLE | FFB_PPC_TBE_OPAQUE);
68
69	pFfb->pmask_cache = ~0;
70	pFfb->rop_cache = FFB_ROP_EDIT_BIT;
71	pFfb->drawop_cache = FFB_DRAWOP_RECTANGLE;
72	pFfb->fg_cache = pFfb->bg_cache = 0;
73	pFfb->fontw_cache = 32;
74	pFfb->fontinc_cache = (1 << 16) | 0;
75	pFfb->laststipple = NULL;
76	FFBFifo(pFfb, 9);
77	ffb->fbc = pFfb->fbc_cache;
78	ffb->ppc = pFfb->ppc_cache;
79	ffb->pmask = pFfb->pmask_cache;
80	ffb->rop = pFfb->rop_cache;
81	ffb->drawop = pFfb->drawop_cache;
82	ffb->fg = pFfb->fg_cache;
83	ffb->bg = pFfb->bg_cache;
84	ffb->fontw = pFfb->fontw_cache;
85	ffb->fontinc = pFfb->fontinc_cache;
86	pFfb->rp_active = 1;
87	FFBWait(pFfb, ffb);
88
89	/* Fixup the FBC/PPC caches to deal with actually using
90	 * a WID for every ROP.
91	 */
92	pFfb->fbc_cache = (FFB_FBC_WB_A | FFB_FBC_WM_COMBINED |
93			   FFB_FBC_RB_A | FFB_FBC_SB_BOTH | FFB_FBC_XE_ON |
94			   FFB_FBC_ZE_OFF | FFB_FBC_YE_OFF | FFB_FBC_RGBE_ON);
95	pFfb->ppc_cache &= ~FFB_PPC_XS_MASK;
96	pFfb->ppc_cache |= FFB_PPC_XS_WID;
97	pFfb->wid_cache = (enter ? pFfb->wid : 0xff);
98	FFBFifo(pFfb, 11);
99	ffb->fbc = pFfb->fbc_cache;
100	ffb->ppc = FFB_PPC_XS_WID;
101	ffb->wid = pFfb->wid_cache;
102	ffb->xpmask = 0xff;
103	ffb->xclip = FFB_XCLIP_TEST_ALWAYS;
104	ffb->cmp = 0x80808080;
105	ffb->matchab = 0x80808080;
106	ffb->magnab = 0x80808080;
107	ffb->blendc = (FFB_BLENDC_FORCE_ONE |
108		       FFB_BLENDC_DF_ONE_M_A |
109		       FFB_BLENDC_SF_A);
110	ffb->blendc1 = 0;
111	ffb->blendc2 = 0;
112	pFfb->rp_active = 1;
113	FFBWait(pFfb, ffb);
114
115	if (enter) {
116		pFfb->drawop_cache = FFB_DRAWOP_RECTANGLE;
117
118		FFBFifo(pFfb, 5);
119		ffb->drawop = pFfb->drawop_cache;
120		FFB_WRITE64(&ffb->by, 0, 0);
121		FFB_WRITE64_2(&ffb->bh, pFfb->psdp->height, pFfb->psdp->width);
122		pFfb->rp_active = 1;
123		FFBWait(pFfb, ffb);
124
125		SET_SYNC_FLAG(pFfb->pXAAInfo);
126	}
127}
128
129#ifdef DEBUG_FFB
130FILE *FDEBUG_FD = NULL;
131#endif
132
133static CARD32 FFBAlphaTextureFormats[2] = { PICT_a8, 0 };
134static CARD32 FFBTextureFormats[2] = { PICT_a8b8g8r8, 0 };
135static CARD32 FFBTextureDstFormats[3] = { PICT_a8b8g8r8, PICT_x8b8g8r8, 0 };
136
137static Bool FFB_SetupForCPUToScreenAlphaTexture(
138	ScrnInfoPtr	pScrn,
139	int		op,
140	CARD16		red,
141	CARD16		green,
142	CARD16		blue,
143	CARD16		alpha,
144	CARD32		maskFormat,
145	CARD32		dstFormat,
146	CARD8		*alphaPtr,
147	int		alphaPitch,
148	int		width,
149	int		height,
150	int		flags
151)
152{
153       FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn);
154
155       FFBLOG(("FFB_SetupForCPUToScreenAlphaTexture: "
156               "argb[%04x:%04x:%04x:%04x] alpha[T(%x):P(%d)] "
157               "wh[%d:%d] flgs[%x]\n",
158               alpha, red, green, blue,
159               maskFormat, alphaPitch,
160               width, height, flags));
161
162       FFB_SetupTextureAttrs(pFfb);
163
164       pFfb->xaa_tex = (unsigned char *) alphaPtr;
165       pFfb->xaa_tex_pitch = alphaPitch;
166       pFfb->xaa_tex_width = width;
167       pFfb->xaa_tex_height = height;
168       pFfb->xaa_tex_color = (/*((alpha >> 8) << 24) |*/
169                              ((blue >> 8) << 16) |
170                              ((green >> 8) << 8) |
171                              ((red >> 8) << 0));
172       return TRUE;
173}
174
175static void FFB_SubsequentCPUToScreenAlphaTexture(ScrnInfoPtr pScrn,
176                                                 int dstx, int dsty,
177                                                 int srcx, int srcy,
178                                                 int width, int height)
179{
180       FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn);
181       unsigned char *dst_base, *alpha_base, *sfb32;
182       unsigned int pixel_base;
183       int psz_shift = 2;
184
185       FFBLOG(("FFB_SubsequentCPUToScreenAlphaTexture: "
186               "dst[%d:%d] src[%d:%d] wh[%d:%d]\n",
187               dstx, dsty, srcx, srcy, width, height));
188
189       sfb32 = (unsigned char *) pFfb->sfb32;
190       dst_base = sfb32 + (dsty * (2048 << psz_shift)) + (dstx << psz_shift);
191       alpha_base = pFfb->xaa_tex;
192       alpha_base += srcx;
193       if (srcy)
194               alpha_base += (srcy * pFfb->xaa_tex_pitch);
195       pixel_base = pFfb->xaa_tex_color;
196       while (height--) {
197               unsigned int *dst = (unsigned int *) dst_base;
198               unsigned char *alpha = alpha_base;
199               int w = width;
200
201               while (w--) {
202                       (*dst) = (((unsigned int)*alpha << 24) | pixel_base);
203                       dst++;
204                       alpha++;
205	       }
206	       dst_base += (2048 << psz_shift);
207	       alpha_base += pFfb->xaa_tex_pitch;
208       }
209}
210
211
212static Bool FFB_SetupForCPUToScreenTexture(
213	ScrnInfoPtr	pScrn,
214	int		op,
215	CARD32		srcFormat,
216	CARD32		dstFormat,
217	CARD8		*texPtr,
218	int		texPitch,
219	int		width,
220	int		height,
221	int		flags
222)
223{
224       FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn);
225
226       FFBLOG(("FFB_SetupForCPUToScreenTexture: "
227               "TEX[T(%x):P(%d)] "
228               "wh[%d:%d] flgs[%x]\n",
229               srcFormat, texPitch,
230               width, height, flags));
231
232       FFB_SetupTextureAttrs(pFfb);
233
234       pFfb->xaa_tex = (unsigned char *) texPtr;
235       pFfb->xaa_tex_pitch = texPitch;
236       pFfb->xaa_tex_width = width;
237       pFfb->xaa_tex_height = height;
238
239       return TRUE;
240}
241
242static void FFB_SubsequentCPUToScreenTexture(ScrnInfoPtr pScrn,
243                                            int dstx, int dsty,
244                                            int srcx, int srcy,
245                                            int width, int height)
246{
247       FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn);
248       unsigned char *dst_base, *sfb32;
249       unsigned int *tex_base;
250       int psz_shift = 2;
251
252       FFBLOG(("FFB_SubsequentCPUToScreenAlphaTexture: "
253               "dst[%d:%d] src[%d:%d] wh[%d:%d]\n",
254               dstx, dsty, srcx, srcy, width, height));
255
256       sfb32 = (unsigned char *) pFfb->sfb32;
257       dst_base = sfb32 + (dsty * (2048 << psz_shift)) + (dstx << psz_shift);
258       tex_base = (unsigned int *) pFfb->xaa_tex;
259       tex_base += srcx;
260       if (srcy)
261               tex_base += (srcy * pFfb->xaa_tex_pitch);
262       while (height--) {
263               unsigned int *dst = (unsigned int *) dst_base;
264               unsigned int *tex = tex_base;
265               int w = width;
266               while (w--) {
267                       (*dst) = *tex;
268
269                       dst++;
270                       tex++;
271               }
272               dst_base += (2048 << psz_shift);
273               tex_base += pFfb->xaa_tex_pitch;
274       }
275}
276
277static void FFB_WritePixmap(ScrnInfoPtr pScrn,
278                           int x, int y, int w, int h,
279                           unsigned char *src,
280                           int srcwidth,
281                           int rop,
282                           unsigned int planemask,
283                           int trans, int bpp, int depth)
284{
285       FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn);
286       unsigned char *dst, *sfb32;
287       int psz_shift = 2;
288       ffb_fbcPtr ffb = pFfb->regs;
289
290       FFBLOG(("FFB_WritePixmap: "
291               "x[%d] y[%d] w[%d] h[%d] srcw[%d] rop[%d] pmask[%x] "
292               "trans[%d] bpp[%d] depth[%d]\n",
293               x, y, w, h, srcwidth, rop, planemask,
294               trans, bpp, depth));
295
296       FFB_ATTR_SFB_VAR_XAA(pFfb, planemask, rop);
297       FFBWait(pFfb, ffb);
298
299       sfb32 = (unsigned char *) pFfb->sfb32;
300       dst = sfb32 + (y * (2048 << psz_shift)) + (x << psz_shift);
301       VISmoveImageLR(src, dst, w << psz_shift, h,
302                      srcwidth, (2048 << psz_shift));
303}
304
305static void FFB_SetupForMono8x8PatternFill(ScrnInfoPtr pScrn,
306                                          int pat_word1, int pat_word2,
307                                          int fg, int bg, int rop,
308                                          unsigned int planemask)
309{
310       FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn);
311       ffb_fbcPtr ffb = pFfb->regs;
312       unsigned int ppc, ppc_mask, fbc;
313       int i;
314
315       FFBLOG(("FFB_SetupForMono8x8PatternFill: "
316               "pat[%08x:%08x] fg[%x] bg[%x] rop[%d] pmask[%x]\n",
317               pat_word1, pat_word2,
318               fg, bg, rop, planemask));
319
320       ppc = FFB_PPC_ABE_DISABLE | FFB_PPC_APE_ENABLE | FFB_PPC_CS_CONST;
321       if (bg < 0)
322               ppc |= FFB_PPC_TBE_TRANSPARENT;
323       else
324               ppc |= FFB_PPC_TBE_OPAQUE;
325       ppc_mask = FFB_PPC_ABE_MASK | FFB_PPC_APE_MASK |
326         FFB_PPC_TBE_MASK | FFB_PPC_CS_MASK;
327       fbc = pFfb->fbc;
328       rop = (rop | FFB_ROP_EDIT_BIT) | (FFB_ROP_NEW << 8);
329
330       FFB_ATTR_RAW(pFfb, ppc, ppc_mask, planemask, rop,
331                    FFB_DRAWOP_RECTANGLE, fg, fbc, pFfb->wid);
332       if (bg >= 0)
333               FFB_WRITE_BG(pFfb, ffb, bg);
334
335       FFBFifo(pFfb, 32);
336       for (i = 0; i < 32; i += 2) {
337               CARD32 val1, val2;
338               int shift = (24 - ((i % 4) * 8));
339
340               if ((i % 8) < 4) {
341                       val1 = (pat_word1 >> shift) & 0xff;
342                       val2 = (pat_word1 >> (shift + 8)) & 0xff;
343               } else {
344                       val1 = (pat_word2 >> shift) & 0xff;
345                       val2 = (pat_word2 >> (shift + 8)) & 0xff;
346               }
347               val1 |= (val1 << 8) | (val1 << 16) | (val1 << 24);
348               val2 |= (val2 << 8) | (val2 << 16) | (val2 << 24);
349               FFB_WRITE64(&ffb->pattern[i], val1, val2);
350       }
351       pFfb->rp_active = 1;
352}
353
354static void FFB_SubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn,
355                                                int pat_word1, int pat_word2,
356                                                int x, int y, int w, int h)
357{
358       FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn);
359       ffb_fbcPtr ffb = pFfb->regs;
360
361       FFBLOG(("FFB_SubsequentMono8x8PatternFillRect: "
362               "x[%d] y[%d] w[%d] h[%d]\n", x, y, w, h));
363
364       FFBFifo(pFfb, 4);
365       FFB_WRITE64(&ffb->by, y, x);
366       FFB_WRITE64_2(&ffb->bh, h, w);
367}
368
369static void FFB_SetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
370                                                          int fg, int bg,
371                                                          int rop,
372                                                          unsigned int planemask)
373{
374       FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn);
375       ffb_fbcPtr ffb = pFfb->regs;
376       unsigned int ppc, ppc_mask, fbc;
377
378       FFBLOG(("FFB_SetupForScanlineCPUToScreenColorExpandFill: "
379               "fg[%x] bg[%x] rop[%d] pmask[%x]\n",
380               fg, bg, rop, planemask));
381
382       ppc = FFB_PPC_ABE_DISABLE | FFB_PPC_APE_DISABLE | FFB_PPC_CS_CONST;
383       if (bg < 0)
384               ppc |= FFB_PPC_TBE_TRANSPARENT;
385       else
386               ppc |= FFB_PPC_TBE_OPAQUE;
387       ppc_mask = FFB_PPC_ABE_MASK | FFB_PPC_APE_MASK |
388         FFB_PPC_TBE_MASK | FFB_PPC_CS_MASK;
389       fbc = pFfb->fbc;
390       rop = (rop | FFB_ROP_EDIT_BIT) | (FFB_ROP_NEW << 8);
391
392       if ((pFfb->ppc_cache & ppc_mask) != ppc ||
393           pFfb->fg_cache != fg ||
394           pFfb->fbc_cache != fbc ||
395           pFfb->rop_cache != rop ||
396           pFfb->pmask_cache != planemask ||
397           pFfb->fontinc_cache != ((0<<16) | 32) ||
398           (bg >= 0 && pFfb->bg_cache != bg)) {
399               pFfb->ppc_cache &= ~ppc_mask;
400               pFfb->ppc_cache |= ppc;
401               pFfb->fg_cache = fg;
402               pFfb->fbc_cache = fbc;
403               pFfb->rop_cache = rop;
404               pFfb->pmask_cache = planemask;
405               pFfb->fontinc_cache = ((0<<16) | 32);
406               if (bg >= 0)
407                       pFfb->bg_cache = bg;
408               FFBFifo(pFfb, (bg >= 0 ? 7 : 6));
409               ffb->ppc = ppc;
410               ffb->fg = fg;
411               ffb->fbc = fbc;
412               ffb->rop = rop;
413               ffb->pmask = planemask;
414               ffb->fontinc = ((0 << 16) | 32);
415               if(bg >= 0)
416                       ffb->bg = bg;
417       }
418       pFfb->rp_active = 1;
419}
420
421static void FFB_SubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
422                                                            int x, int y, int w, int h,
423                                                            int skipleft)
424{
425       FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn);
426       FFBLOG(("FFB_SubsequentCPUToScreenColorExpandFill: "
427               "x[%d] y[%d] w[%d] h[%d] skipleft[%d]\n",
428               x, y, w, h, skipleft));
429
430       pFfb->xaa_scanline_x = x;
431       pFfb->xaa_scanline_y = y;
432       pFfb->xaa_scanline_w = w;
433}
434
435static void FFB_SubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno)
436{
437       FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn);
438       ffb_fbcPtr ffb = pFfb->regs;
439       CARD32 *bits = (CARD32 *) pFfb->xaa_scanline_buffers[bufno];
440       int w;
441
442       FFBFifo(pFfb, 1);
443       ffb->fontxy = ((pFfb->xaa_scanline_y << 16) | pFfb->xaa_scanline_x);
444
445       w = pFfb->xaa_scanline_w;
446       if (w >= 32) {
447               FFB_WRITE_FONTW(pFfb, ffb, 32);
448               FFBFifo(pFfb, (w / 32));
449               do {
450                       ffb->font = *bits++;
451                       w -= 32;
452               } while (w >= 32);
453       }
454       if (w > 0) {
455               FFB_WRITE_FONTW(pFfb, ffb, w);
456               FFBFifo(pFfb, 1);
457               ffb->font = *bits++;
458       }
459
460       pFfb->xaa_scanline_y++;
461}
462
463static void FFB_SetupForDashedLine(ScrnInfoPtr pScrn,
464                                  int fg, int bg, int rop,
465                                  unsigned int planemask,
466                                  int length, unsigned char *pattern)
467{
468       FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn);
469       CARD32 *pat_ptr = (CARD32 *)pattern;
470       unsigned int ppc, ppc_mask, fbc;
471
472       FFBLOG(("FFB_SetupForDashedLine: "
473               "fg[%x] bg[%x] rop[%d] pmask[%x] patlen[%d] pat[%x]\n",
474               fg, bg, rop, planemask, length, *pat_ptr));
475
476       pFfb->planemask = planemask;
477       pFfb->xaa_rop = rop;
478       pFfb->xaa_linepat =
479               (*pat_ptr << FFB_LPAT_PATTERN_SHIFT) |
480               (1 << FFB_LPAT_SCALEVAL_SHIFT) |
481               ((length & 0xf) << FFB_LPAT_PATLEN_SHIFT);
482
483       fbc = pFfb->fbc;
484       ppc = FFB_PPC_ABE_DISABLE | FFB_PPC_APE_DISABLE | FFB_PPC_CS_CONST | FFB_PPC_XS_WID;
485       ppc_mask = FFB_PPC_ABE_MASK | FFB_PPC_APE_MASK | FFB_PPC_CS_MASK | FFB_PPC_XS_MASK;
486
487       FFB_ATTR_RAW(pFfb, ppc, ppc_mask, planemask,
488                    (FFB_ROP_EDIT_BIT | rop) | (FFB_ROP_NEW << 8),
489                    FFB_DRAWOP_BRLINEOPEN, fg, fbc, pFfb->wid);
490       pFfb->rp_active = 1;
491}
492
493static void FFB_SubsequentDashedTwoPointLine( ScrnInfoPtr pScrn,
494                                             int x1, int y1,
495                                             int x2, int y2,
496                                             int flags, int phase)
497{
498       FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn);
499       ffb_fbcPtr ffb = pFfb->regs;
500       unsigned int linepat = pFfb->xaa_linepat;
501       unsigned int drawop;
502
503       FFBLOG(("FFB_SubsequentDashedTwoPointLine: "
504               "x1[%d] y1[%d] x2[%d] y2[%d] flgs[%x] phase[%d]\n",
505               x1, y2, x2, y2, flags, phase));
506
507       linepat |= (phase & 0xf) << FFB_LPAT_PATPTR_SHIFT;
508
509       drawop = (flags & OMIT_LAST) ?
510         FFB_DRAWOP_BRLINEOPEN : FFB_DRAWOP_BRLINECAP;
511       FFB_WRITE_DRAWOP(pFfb, ffb, drawop);
512
513       if (pFfb->has_brline_bug) {
514               FFBFifo(pFfb, 6);
515               ffb->ppc = 0;
516       } else
517               FFBFifo(pFfb, 5);
518       ffb->lpat = linepat;
519       FFB_WRITE64(&ffb->by, y1, x1);
520       FFB_WRITE64_2(&ffb->bh, y2, x2);
521}
522
523static void FFB_SetupForSolidLine(ScrnInfoPtr pScrn,
524                                 int color, int rop, unsigned int planemask)
525{
526       FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn);
527       ffb_fbcPtr ffb = pFfb->regs;
528       unsigned int ppc, ppc_mask, fbc;
529       FFBLOG(("FFB_SetupForSolidLine: "
530               "color[%d] rop[%d] pmask[%x]\n",
531               color, rop, planemask));
532
533       pFfb->planemask = planemask;
534       pFfb->xaa_rop = rop;
535
536       fbc = pFfb->fbc;
537       ppc = FFB_PPC_ABE_DISABLE | FFB_PPC_APE_DISABLE | FFB_PPC_CS_CONST | FFB_PPC_XS_WID;
538       ppc_mask = FFB_PPC_ABE_MASK | FFB_PPC_APE_MASK | FFB_PPC_CS_MASK | FFB_PPC_XS_MASK;
539
540       FFB_ATTR_RAW(pFfb, ppc, ppc_mask, planemask,
541                    (FFB_ROP_EDIT_BIT | rop) | (FFB_ROP_NEW << 8),
542                    FFB_DRAWOP_BRLINEOPEN, color, fbc, pFfb->wid);
543       FFBFifo(pFfb, 1);
544       ffb->lpat = 0;
545       pFfb->rp_active = 1;
546}
547
548static void FFB_SubsequentSolidTwoPointLine(ScrnInfoPtr pScrn,
549                                           int x1, int y1,
550                                           int x2, int y2,
551                                           int flags)
552{
553       FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn);
554       ffb_fbcPtr ffb = pFfb->regs;
555       int drawop;
556
557       FFBLOG(("FFB_SubsequentSolidTwoPointLine: "
558               "x1[%d] y1[%d] x2[%d] y2[%d] flags[%d]\n",
559               x1, y1, x2, y2, flags));
560
561       drawop = (flags & OMIT_LAST) ?
562         FFB_DRAWOP_BRLINEOPEN : FFB_DRAWOP_BRLINECAP;
563       FFB_WRITE_DRAWOP(pFfb, ffb, drawop);
564
565       if (pFfb->has_brline_bug) {
566               FFBFifo(pFfb, 5);
567               ffb->ppc = 0;
568       } else
569               FFBFifo(pFfb, 4);
570       FFB_WRITE64(&ffb->by, y1, x1);
571       FFB_WRITE64_2(&ffb->bh, y2, x2);
572}
573
574void FFB_SetupForSolidFill(ScrnInfoPtr pScrn,
575                          int color, int rop, unsigned int planemask)
576{
577       FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn);
578       unsigned int ppc, ppc_mask, fbc;
579
580       FFBLOG(("FFB_SetupForSolidFill: "
581               "color[%d] rop[%d] pmask[%u]\n",
582               color, rop, planemask));
583
584       pFfb->planemask = planemask;
585       pFfb->xaa_rop = rop;
586
587       fbc = pFfb->fbc;
588       if (pFfb->ffb_res == ffb_res_high)
589               fbc |= FFB_FBC_WB_B;
590       ppc = FFB_PPC_ABE_DISABLE | FFB_PPC_APE_DISABLE | FFB_PPC_CS_CONST | FFB_PPC_XS_WID;
591       ppc_mask = FFB_PPC_ABE_MASK | FFB_PPC_APE_MASK | FFB_PPC_CS_MASK | FFB_PPC_XS_MASK;
592
593       FFB_ATTR_RAW(pFfb, ppc, ppc_mask, planemask,
594                    (FFB_ROP_EDIT_BIT | rop) | (FFB_ROP_NEW << 8),
595                    FFB_DRAWOP_RECTANGLE, color, fbc, pFfb->wid);
596       pFfb->rp_active = 1;
597}
598
599void FFB_SubsequentSolidFillRect(ScrnInfoPtr pScrn,
600                                int x, int y,
601                                int w, int h)
602{
603       FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn);
604       ffb_fbcPtr ffb = pFfb->regs;
605
606       FFBLOG(("FFB_SubsequentSolidFillRect: "
607               "x[%d] y[%d] w[%d] h[%d]\n", x, y, w, h));
608
609       FFBFifo(pFfb, 4);
610       FFB_WRITE64(&ffb->by, y, x);
611       FFB_WRITE64_2(&ffb->bh, h, w);
612}
613
614static void FFB_ScreenToScreenBitBlt(ScrnInfoPtr pScrn,
615                                    int nbox,
616                                    DDXPointPtr pptSrc,
617                                    BoxPtr pbox,
618                                    int xdir, int ydir,
619                                    int rop, unsigned int planemask)
620{
621       FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn);
622       ffb_fbcPtr ffb = pFfb->regs;
623       int use_vscroll;
624
625       FFBLOG(("FFB_ScreenToScreenBitBlt: "
626               "nbox[%d] xdir[%d] ydir[%d] rop[%d] pmask[%x]\n",
627               nbox, xdir, ydir, rop, planemask));
628
629       use_vscroll = 0;
630       if (!pFfb->disable_vscroll &&
631           rop == GXcopy) {
632               int i;
633
634               for (i = 0; i < nbox; i++)
635                       if (pptSrc[i].x != pbox[i].x1 ||
636                           pptSrc[i].y == pbox[i].y1)
637                               break;
638               if (i == nbox) {
639                       /* If/When double buffer extension is re-enabled
640                        * check buffers here.
641                        */
642                       use_vscroll = 1;
643               }
644       }
645       if (use_vscroll) {
646               FFB_ATTR_VSCROLL_XAA(pFfb, planemask);
647               while (nbox--) {
648                       FFBFifo(pFfb, 7);
649                       ffb->drawop = FFB_DRAWOP_VSCROLL;
650                       FFB_WRITE64(&ffb->by, pptSrc->y, pptSrc->x);
651                       FFB_WRITE64_2(&ffb->dy, pbox->y1, pbox->x1);
652                       FFB_WRITE64_3(&ffb->bh, (pbox->y2 - pbox->y1),
653                                     (pbox->x2 - pbox->x1));
654
655                       pbox++;
656                       pptSrc++;
657               }
658               pFfb->rp_active = 1;
659               SET_SYNC_FLAG(pFfb->pXAAInfo);
660       } else {
661               unsigned char *sfb32 = (unsigned char *) pFfb->sfb32;
662               int psz_shift = 2;
663
664               FFB_ATTR_SFB_VAR_XAA(pFfb, planemask, rop);
665               if (pFfb->use_blkread_prefetch) {
666                       unsigned int bit;
667
668                       if (xdir < 0)
669                               bit = FFB_MER_EDRA;
670                       else
671                               bit = FFB_MER_EIRA;
672                       FFBFifo(pFfb, 1);
673                       ffb->mer = bit;
674                       pFfb->rp_active = 1;
675               }
676               FFBWait(pFfb, ffb);
677
678               while (nbox--) {
679                       unsigned char *src, *dst;
680                       int x1, y1, x2, y2;
681                       int width, height;
682                       int sdkind;
683
684                       x1 = pptSrc->x;
685                       y1 = pptSrc->y;
686                       x2 = pbox->x1;
687                       y2 = pbox->y1;
688                       width = (pbox->x2 - pbox->x1);
689                       height = (pbox->y2 - pbox->y1);
690
691                       src = sfb32 + (y1 * (2048 << psz_shift))
692                               + (x1 << psz_shift);
693                       dst = sfb32 + (y2 * (2048 << psz_shift))
694                               + (x2 << psz_shift);
695                       sdkind = (2048 << psz_shift);
696
697                       if (ydir < 0) {
698                               src += ((height - 1) * (2048 << psz_shift));
699                               dst += ((height - 1) * (2048 << psz_shift));
700                               sdkind = -sdkind;
701                       }
702                       width <<= psz_shift;
703                       if (xdir < 0)
704                               VISmoveImageRL(src, dst, width, height,
705                                              sdkind, sdkind);
706                       else
707                               VISmoveImageLR(src, dst, width, height,
708                                              sdkind, sdkind);
709                       pbox++;
710                       pptSrc++;
711	       }
712               if (pFfb->use_blkread_prefetch) {
713                       FFBFifo(pFfb, 1);
714                       ffb->mer = FFB_MER_DRA;
715                       pFfb->rp_active = 1;
716                       FFBWait(pFfb, ffb);
717               }
718       }
719}
720
721void FFB_SetupForScreenToScreenCopy(ScrnInfoPtr pScrn,
722                                   int xdir, int ydir, int rop,
723                                   unsigned int planemask,
724                                   int trans_color)
725{
726       FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn);
727       ffb_fbcPtr ffb = pFfb->regs;
728       FFBLOG(("FFB_SetupForScreenToScreenCopy: "
729               "xdir[%d] ydir[%d] rop[%d] pmask[%x] tcolor[%d]\n",
730               xdir, ydir, rop, planemask, trans_color));
731
732       pFfb->planemask = planemask;
733       pFfb->xaa_xdir = xdir;
734       pFfb->xaa_ydir = ydir;
735       pFfb->xaa_rop = rop;
736       FFB_ATTR_SFB_VAR_XAA(pFfb, planemask, rop);
737       FFBWait(pFfb, ffb);
738}
739
740void FFB_SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn,
741                                     int x1, int y1,
742                                     int x2, int y2,
743                                     int width, int height)
744{
745       FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn);
746       unsigned char *src, *dst, *sfb32;
747       int psz_shift = 2;
748       int sdkind;
749
750       FFBLOG(("FFB_SubsequentScreenToScreenCopy: "
751               "x1[%d] y1[%d] x2[%d] y2[%u] w[%d] h[%d]\n",
752               x1, y1, x2, y2, width, height));
753
754       sfb32 = (unsigned char *) pFfb->sfb32;
755       src = sfb32 + (y1 * (2048 << psz_shift)) + (x1 << psz_shift);
756       dst = sfb32 + (y2 * (2048 << psz_shift)) + (x2 << psz_shift);
757       sdkind = (2048 << psz_shift);
758
759       if (pFfb->xaa_ydir < 0) {
760               src += ((height - 1) * (2048 << psz_shift));
761               dst += ((height - 1) * (2048 << psz_shift));
762               sdkind = -sdkind;
763       }
764
765       width <<= psz_shift;
766       if (pFfb->xaa_xdir < 0)
767               VISmoveImageRL(src, dst, width, height, sdkind, sdkind);
768       else
769               VISmoveImageLR(src, dst, width, height, sdkind, sdkind);
770}
771
772static void FFB_Sync(ScrnInfoPtr pScrn)
773{
774       FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn);
775       ffb_fbcPtr ffb = pFfb->regs;
776
777       FFB_ATTR_SFB_VAR_XAA(pFfb, 0xffffffff, GXcopy);
778       FFBWait(pFfb, ffb);
779}
780
781#endif
782
783Bool FFBAccelInit(ScreenPtr pScreen, FFBPtr pFfb)
784{
785#ifdef HAVE_XAA_H
786	XAAInfoRecPtr infoRec;
787	ffb_fbcPtr ffb = pFfb->regs;
788
789	pFfb->fbc = (FFB_FBC_WB_A | FFB_FBC_WM_COMBINED | FFB_FBC_RB_A |
790			 FFB_FBC_WE_FORCEON |
791			 FFB_FBC_SB_BOTH |
792			 FFB_FBC_ZE_OFF | FFB_FBC_YE_OFF |
793			 FFB_FBC_RGBE_MASK |
794			 FFB_FBC_XE_ON);
795	pFfb->wid = FFBWidAlloc(pFfb, TrueColor, 0, TRUE);
796	if (pFfb->wid == (unsigned int) -1)
797		return FALSE;
798
799	pFfb->pXAAInfo = infoRec = XAACreateInfoRec();
800	if (!infoRec) {
801		FFBWidFree(pFfb, pFfb->wid);
802		return FALSE;
803	}
804
805	pFfb->xaa_scanline_buffers[0] = malloc(2048 * 4);
806	if (!pFfb->xaa_scanline_buffers[0]) {
807		XAADestroyInfoRec(infoRec);
808		return FALSE;
809	}
810
811	pFfb->xaa_scanline_buffers[1] = malloc(2048 * 4);
812	if (!pFfb->xaa_scanline_buffers[1]) {
813		free(pFfb->xaa_scanline_buffers[0]);
814		XAADestroyInfoRec(infoRec);
815		return FALSE;
816	}
817
818	infoRec->Sync = FFB_Sync;
819
820	/* Use VIS and VSCROLL for screen to screen copies.  */
821	infoRec->ScreenToScreenCopyFlags = NO_TRANSPARENCY;
822	infoRec->SetupForScreenToScreenCopy =
823		FFB_SetupForScreenToScreenCopy;
824	infoRec->SubsequentScreenToScreenCopy =
825		FFB_SubsequentScreenToScreenCopy;
826
827	/* In order to optimize VSCROLL and prefetching properly we
828	 * have to use our own mid-layer routine.
829	 */
830	infoRec->ScreenToScreenBitBltFlags = NO_TRANSPARENCY;
831	infoRec->ScreenToScreenBitBlt =
832		FFB_ScreenToScreenBitBlt;
833
834	infoRec->SolidFillFlags = 0;
835	infoRec->SetupForSolidFill =
836		FFB_SetupForSolidFill;
837	infoRec->SubsequentSolidFillRect =
838		FFB_SubsequentSolidFillRect;
839
840	infoRec->SolidLineFlags = 0;
841	infoRec->SetupForSolidLine =
842		FFB_SetupForSolidLine;
843	infoRec->SubsequentSolidTwoPointLine =
844		FFB_SubsequentSolidTwoPointLine;
845	miSetZeroLineBias(pScreen, OCTANT3 | OCTANT4 | OCTANT6 | OCTANT1);
846
847	infoRec->DashedLineFlags = (TRANSPARENCY_ONLY |
848				    LINE_PATTERN_LSBFIRST_LSBJUSTIFIED);
849	infoRec->DashPatternMaxLength = 16;
850	infoRec->SetupForDashedLine =
851		FFB_SetupForDashedLine;
852	infoRec->SubsequentDashedTwoPointLine =
853		FFB_SubsequentDashedTwoPointLine;
854
855	/* We cannot use the non-scanline color expansion mechanism on FFB
856	 * for two reasons:
857	 *
858	 * 1) A render pass can only render 32-pixels wide on FFB, XAA expects
859	 *    that arbitrary widths are possible per render pass.
860	 *
861	 * 2) The FFB accelerator FIFO is only 100 or so words deep, and
862	 *    XAA gives no way to limit the number of words it writes into
863	 *    the ColorExpandBase register per rendering pass.
864	 */
865	infoRec->ScanlineColorExpandBuffers = pFfb->xaa_scanline_buffers;
866	infoRec->NumScanlineColorExpandBuffers = 2;
867	infoRec->ScanlineCPUToScreenColorExpandFillFlags =
868		CPU_TRANSFER_PAD_DWORD |
869		SCANLINE_PAD_DWORD |
870		CPU_TRANSFER_BASE_FIXED |
871		BIT_ORDER_IN_BYTE_LSBFIRST;
872	infoRec->SetupForScanlineCPUToScreenColorExpandFill =
873		FFB_SetupForScanlineCPUToScreenColorExpandFill;
874	infoRec->SubsequentScanlineCPUToScreenColorExpandFill =
875		FFB_SubsequentScanlineCPUToScreenColorExpandFill;
876	infoRec->SubsequentColorExpandScanline =
877		FFB_SubsequentColorExpandScanline;
878
879	infoRec->Mono8x8PatternFillFlags =
880		HARDWARE_PATTERN_PROGRAMMED_BITS |
881		HARDWARE_PATTERN_SCREEN_ORIGIN |
882		BIT_ORDER_IN_BYTE_LSBFIRST;
883	infoRec->SetupForMono8x8PatternFill =
884		FFB_SetupForMono8x8PatternFill;
885	infoRec->SubsequentMono8x8PatternFillRect =
886		FFB_SubsequentMono8x8PatternFillRect;
887
888	/* Use VIS for pixmap writes.  */
889	infoRec->WritePixmap = FFB_WritePixmap;
890
891	/* RENDER optimizations.  */
892	infoRec->CPUToScreenAlphaTextureFlags =
893		XAA_RENDER_NO_TILE |
894		XAA_RENDER_NO_SRC_ALPHA;
895	infoRec->CPUToScreenAlphaTextureFormats = FFBAlphaTextureFormats;
896	infoRec->CPUToScreenAlphaTextureDstFormats = FFBTextureDstFormats;
897	infoRec->SetupForCPUToScreenAlphaTexture2 =
898		FFB_SetupForCPUToScreenAlphaTexture;
899	infoRec->SubsequentCPUToScreenAlphaTexture =
900		FFB_SubsequentCPUToScreenAlphaTexture;
901
902	infoRec->CPUToScreenTextureFlags =
903		XAA_RENDER_NO_TILE |
904		XAA_RENDER_NO_SRC_ALPHA;
905	infoRec->CPUToScreenTextureFormats = FFBTextureFormats;
906	infoRec->CPUToScreenTextureDstFormats = FFBTextureDstFormats;
907	infoRec->SetupForCPUToScreenTexture2 =
908		FFB_SetupForCPUToScreenTexture;
909	infoRec->SubsequentCPUToScreenTexture =
910		FFB_SubsequentCPUToScreenTexture;
911
912	pFfb->fifo_cache = 0;
913
914	FFB_DEBUG_init();
915	FDEBUG((FDEBUG_FD,
916		"FFB: cfg0(%08x) cfg1(%08x) cfg2(%08x) cfg3(%08x) ppcfg(%08x)\n",
917		ffb->fbcfg0, ffb->fbcfg1, ffb->fbcfg2, ffb->fbcfg3, ffb->ppcfg));
918
919	FFB_HardwareSetup(pFfb);
920
921	pFfb->ppc_cache = (FFB_PPC_FW_DISABLE |
922			   FFB_PPC_VCE_DISABLE | FFB_PPC_APE_DISABLE | FFB_PPC_CS_CONST |
923			   FFB_PPC_XS_WID | FFB_PPC_YS_CONST | FFB_PPC_ZS_CONST |
924			   FFB_PPC_DCE_DISABLE | FFB_PPC_ABE_DISABLE | FFB_PPC_TBE_OPAQUE);
925	pFfb->wid_cache = pFfb->wid;
926	pFfb->pmask_cache = ~0;
927	pFfb->rop_cache = (FFB_ROP_NEW | (FFB_ROP_NEW << 8));
928	pFfb->drawop_cache = FFB_DRAWOP_RECTANGLE;
929	pFfb->fg_cache = pFfb->bg_cache = 0;
930	pFfb->fontw_cache = 32;
931	pFfb->fontinc_cache = (1 << 16) | 0;
932	pFfb->fbc_cache = (FFB_FBC_WB_A | FFB_FBC_WM_COMBINED | FFB_FBC_RB_A |
933			   FFB_FBC_WE_FORCEON |
934			   FFB_FBC_SB_BOTH |
935			   FFB_FBC_ZE_OFF | FFB_FBC_YE_OFF |
936			   FFB_FBC_RGBE_OFF |
937			   FFB_FBC_XE_ON);
938	pFfb->laststipple = NULL;
939
940	/* We will now clear the screen: we'll draw a rectangle covering all the
941	 * viewscreen, using a 'blackness' ROP.
942	 */
943	FFBFifo(pFfb, 22);
944	ffb->fbc = pFfb->fbc_cache;
945	ffb->ppc = pFfb->ppc_cache;
946	ffb->wid = pFfb->wid_cache;
947	ffb->xpmask = 0xff;
948	ffb->pmask = pFfb->pmask_cache;
949	ffb->rop = pFfb->rop_cache;
950	ffb->drawop = pFfb->drawop_cache;
951	ffb->fg = pFfb->fg_cache;
952	ffb->bg = pFfb->bg_cache;
953	ffb->fontw = pFfb->fontw_cache;
954	ffb->fontinc = pFfb->fontinc_cache;
955	ffb->xclip = FFB_XCLIP_TEST_ALWAYS;
956	ffb->cmp = 0x80808080;
957	ffb->matchab = 0x80808080;
958	ffb->magnab = 0x80808080;
959	ffb->blendc = (FFB_BLENDC_FORCE_ONE |
960		       FFB_BLENDC_DF_ONE_M_A |
961		       FFB_BLENDC_SF_A);
962	ffb->blendc1 = 0;
963	ffb->blendc2 = 0;
964	FFB_WRITE64(&ffb->by, 0, 0);
965	FFB_WRITE64_2(&ffb->bh, pFfb->psdp->height, pFfb->psdp->width);
966	pFfb->rp_active = 1;
967	FFBWait(pFfb, ffb);
968
969	FFB_ATTR_SFB_VAR_XAA(pFfb, 0xffffffff, GXcopy);
970	FFBWait(pFfb, ffb);
971
972	if (!XAAInit(pScreen, infoRec)) {
973		XAADestroyInfoRec(infoRec);
974		free(pFfb->xaa_scanline_buffers[0]);
975		free(pFfb->xaa_scanline_buffers[1]);
976		pFfb->pXAAInfo = NULL;
977		FFBWidFree(pFfb, pFfb->wid);
978		return FALSE;
979	}
980	/* Success */
981	return TRUE;
982#else
983	return FALSE;
984#endif
985}
986