ffb_exa.c revision 504f16bc
1504f16bcSmacallan/* $NetBSD: ffb_exa.c,v 1.2 2015/08/16 17:47:39 macallan Exp $ */
289b0bd4cSmacallan/*
389b0bd4cSmacallan * Copyright (c) 2015 Michael Lorenz
489b0bd4cSmacallan * All rights reserved.
589b0bd4cSmacallan *
689b0bd4cSmacallan * Redistribution and use in source and binary forms, with or without
789b0bd4cSmacallan * modification, are permitted provided that the following conditions
889b0bd4cSmacallan * are met:
989b0bd4cSmacallan *
1089b0bd4cSmacallan *    - Redistributions of source code must retain the above copyright
1189b0bd4cSmacallan *      notice, this list of conditions and the following disclaimer.
1289b0bd4cSmacallan *    - Redistributions in binary form must reproduce the above
1389b0bd4cSmacallan *      copyright notice, this list of conditions and the following
1489b0bd4cSmacallan *      disclaimer in the documentation and/or other materials provided
1589b0bd4cSmacallan *      with the distribution.
1689b0bd4cSmacallan *
1789b0bd4cSmacallan * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1889b0bd4cSmacallan * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1989b0bd4cSmacallan * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
2089b0bd4cSmacallan * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
2189b0bd4cSmacallan * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
2289b0bd4cSmacallan * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
2389b0bd4cSmacallan * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
2489b0bd4cSmacallan * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
2589b0bd4cSmacallan * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2689b0bd4cSmacallan * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
2789b0bd4cSmacallan * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2889b0bd4cSmacallan * POSSIBILITY OF SUCH DAMAGE.
2989b0bd4cSmacallan *
3089b0bd4cSmacallan */
3189b0bd4cSmacallan
3289b0bd4cSmacallan#include <sys/types.h>
3389b0bd4cSmacallan
3489b0bd4cSmacallan/* all driver need this */
3589b0bd4cSmacallan#include "xf86.h"
3689b0bd4cSmacallan#include "xf86_OSproc.h"
3789b0bd4cSmacallan#include "compiler.h"
3889b0bd4cSmacallan#include "exa.h"
3989b0bd4cSmacallan
4089b0bd4cSmacallan#include "ffb_fifo.h"
4189b0bd4cSmacallan#include "ffb_rcache.h"
4289b0bd4cSmacallan#include "ffb.h"
4389b0bd4cSmacallan#include "ffb_regs.h"
4489b0bd4cSmacallan
4589b0bd4cSmacallanextern void VISmoveImageRL(unsigned char *, unsigned char *, long, long, long, long);
4689b0bd4cSmacallanextern void VISmoveImageLR(unsigned char *, unsigned char *, long, long, long, long);
4789b0bd4cSmacallan
4889b0bd4cSmacallan/*#define FFB_DEBUG*/
4989b0bd4cSmacallan
5089b0bd4cSmacallan#ifdef FFB_DEBUG
5189b0bd4cSmacallan#define ENTER xf86Msg(X_ERROR, "%s>\n", __func__);
5289b0bd4cSmacallan#define DPRINTF xf86Msg
5389b0bd4cSmacallan#else
5489b0bd4cSmacallan#define ENTER
5589b0bd4cSmacallan#define DPRINTF while (0) xf86Msg
5689b0bd4cSmacallan#endif
5789b0bd4cSmacallan
58504f16bcSmacallan#define arraysize(ary)        (sizeof(ary) / sizeof(ary[0]))
59504f16bcSmacallan
60504f16bcSmacallanint src_formats[] = {PICT_a8r8g8b8, PICT_x8r8g8b8,
61504f16bcSmacallan		     PICT_a8b8g8r8, PICT_x8b8g8r8, PICT_a8};
62504f16bcSmacallanint tex_formats[] = {PICT_a8r8g8b8, PICT_a8b8g8r8, PICT_a8};
63504f16bcSmacallan
6489b0bd4cSmacallanstatic void
6589b0bd4cSmacallanFFBWaitMarker(ScreenPtr pScreen, int Marker)
6689b0bd4cSmacallan{
6789b0bd4cSmacallan	ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
6889b0bd4cSmacallan	FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn);
6989b0bd4cSmacallan	ffb_fbcPtr ffb = pFfb->regs;
7089b0bd4cSmacallan
7189b0bd4cSmacallan	FFBWait(pFfb, ffb);
7289b0bd4cSmacallan}
7389b0bd4cSmacallan
7489b0bd4cSmacallanstatic Bool
7589b0bd4cSmacallanFFBPrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap,
7689b0bd4cSmacallan		int xdir, int ydir, int alu, Pixel planemask)
7789b0bd4cSmacallan{
7889b0bd4cSmacallan	ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum];
7989b0bd4cSmacallan	FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn);
8089b0bd4cSmacallan	ffb_fbcPtr ffb = pFfb->regs;
8189b0bd4cSmacallan
8289b0bd4cSmacallan	ENTER;
8389b0bd4cSmacallan	pFfb->srcpitch = exaGetPixmapPitch(pSrcPixmap);
8489b0bd4cSmacallan	pFfb->srcoff = exaGetPixmapOffset(pSrcPixmap);
8589b0bd4cSmacallan	pFfb->xdir = xdir;
8689b0bd4cSmacallan	pFfb->ydir = ydir;
8789b0bd4cSmacallan	pFfb->rop = alu;
8889b0bd4cSmacallan	pFfb->planemask = planemask;
8989b0bd4cSmacallan	return TRUE;
9089b0bd4cSmacallan}
9189b0bd4cSmacallan
9289b0bd4cSmacallanstatic void
9389b0bd4cSmacallanFFBCopy(PixmapPtr pDstPixmap,
9489b0bd4cSmacallan         int srcX, int srcY, int dstX, int dstY, int w, int h)
9589b0bd4cSmacallan{
9689b0bd4cSmacallan	ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum];
9789b0bd4cSmacallan	FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn);
9889b0bd4cSmacallan	ffb_fbcPtr ffb = pFfb->regs;
9989b0bd4cSmacallan	unsigned char *src, *dst, *sfb32;
10089b0bd4cSmacallan	int psz_shift = 2;
10189b0bd4cSmacallan	int sdkind;
10289b0bd4cSmacallan
10389b0bd4cSmacallan	ENTER;
10489b0bd4cSmacallan	if ((srcX == dstX) && (srcY != dstY) && (pFfb->rop == GXcopy)) {
10589b0bd4cSmacallan		/* we can use the vscroll command */
10689b0bd4cSmacallan		FFB_ATTR_VSCROLL_XAA(pFfb, pFfb->planemask);
10789b0bd4cSmacallan		FFBFifo(pFfb, 7);
10889b0bd4cSmacallan		ffb->drawop = FFB_DRAWOP_VSCROLL;
10989b0bd4cSmacallan		FFB_WRITE64(&ffb->by, srcY, srcX);
11089b0bd4cSmacallan                       FFB_WRITE64_2(&ffb->dy, dstY, dstX);
11189b0bd4cSmacallan                       FFB_WRITE64_3(&ffb->bh, h, w);
11289b0bd4cSmacallan		exaMarkSync(pDstPixmap->drawable.pScreen);
11389b0bd4cSmacallan		return;
11489b0bd4cSmacallan	}
11589b0bd4cSmacallan	FFB_ATTR_SFB_VAR_XAA(pFfb, pFfb->planemask, pFfb->rop);
116504f16bcSmacallan	if (pFfb->use_blkread_prefetch) {
117504f16bcSmacallan		FFBFifo(pFfb, 1);
118504f16bcSmacallan		if (pFfb->xdir < 0)
119504f16bcSmacallan			ffb->mer = FFB_MER_EDRA;
120504f16bcSmacallan		else
121504f16bcSmacallan			ffb->mer = FFB_MER_EIRA;
122504f16bcSmacallan	}
12389b0bd4cSmacallan	FFBWait(pFfb, ffb);
12489b0bd4cSmacallan	sfb32 = (unsigned char *) pFfb->sfb32;
12589b0bd4cSmacallan	src = sfb32 + (srcY * (2048 << psz_shift)) + (srcX << psz_shift);
12689b0bd4cSmacallan	dst = sfb32 + (dstY * (2048 << psz_shift)) + (dstX << psz_shift);
12789b0bd4cSmacallan	sdkind = (2048 << psz_shift);
12889b0bd4cSmacallan
12989b0bd4cSmacallan	if (pFfb->ydir < 0) {
13089b0bd4cSmacallan		src += ((h - 1) * (2048 << psz_shift));
13189b0bd4cSmacallan		dst += ((h - 1) * (2048 << psz_shift));
13289b0bd4cSmacallan		sdkind = -sdkind;
13389b0bd4cSmacallan	}
13489b0bd4cSmacallan	w <<= psz_shift;
13589b0bd4cSmacallan	if (pFfb->xdir < 0)
13689b0bd4cSmacallan		VISmoveImageRL(src, dst, w, h, sdkind, sdkind);
13789b0bd4cSmacallan	else
13889b0bd4cSmacallan		VISmoveImageLR(src, dst, w, h, sdkind, sdkind);
139504f16bcSmacallan	if (pFfb->use_blkread_prefetch) {
140504f16bcSmacallan		FFBFifo(pFfb, 1);
141504f16bcSmacallan		ffb->mer = FFB_MER_DRA;
142504f16bcSmacallan	}
14389b0bd4cSmacallan}
14489b0bd4cSmacallan
14589b0bd4cSmacallanstatic void
14689b0bd4cSmacallanFFBDoneCopy(PixmapPtr pDstPixmap)
14789b0bd4cSmacallan{
14889b0bd4cSmacallan}
14989b0bd4cSmacallan
15089b0bd4cSmacallanstatic Bool
15189b0bd4cSmacallanFFBPrepareSolid(PixmapPtr pPixmap, int alu, Pixel planemask, Pixel fg)
15289b0bd4cSmacallan{
15389b0bd4cSmacallan	ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
15489b0bd4cSmacallan	FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn);
15589b0bd4cSmacallan	ffb_fbcPtr ffb = pFfb->regs;
15689b0bd4cSmacallan	unsigned int ppc, ppc_mask, fbc;
15789b0bd4cSmacallan
15889b0bd4cSmacallan	ENTER;
15989b0bd4cSmacallan	FFBWait(pFfb, ffb);
16089b0bd4cSmacallan	pFfb->planemask = planemask;
16189b0bd4cSmacallan	pFfb->rop = alu;
16289b0bd4cSmacallan
16389b0bd4cSmacallan	fbc = pFfb->fbc;
16489b0bd4cSmacallan	if (pFfb->ffb_res == ffb_res_high)
16589b0bd4cSmacallan		fbc |= FFB_FBC_WB_B;
16689b0bd4cSmacallan	ppc = FFB_PPC_ABE_DISABLE | FFB_PPC_APE_DISABLE | FFB_PPC_CS_CONST | FFB_PPC_XS_WID;
16789b0bd4cSmacallan	ppc_mask = FFB_PPC_ABE_MASK | FFB_PPC_APE_MASK | FFB_PPC_CS_MASK | FFB_PPC_XS_MASK;
16889b0bd4cSmacallan
16989b0bd4cSmacallan	FFB_ATTR_RAW(pFfb, ppc, ppc_mask, planemask,
17089b0bd4cSmacallan                    (FFB_ROP_EDIT_BIT | alu) | (FFB_ROP_NEW << 8),
17189b0bd4cSmacallan                    FFB_DRAWOP_RECTANGLE, fg, fbc, pFfb->wid);
17289b0bd4cSmacallan
17389b0bd4cSmacallan	return TRUE;
17489b0bd4cSmacallan}
17589b0bd4cSmacallan
17689b0bd4cSmacallanstatic void
17789b0bd4cSmacallanFFBSolid(PixmapPtr pPixmap, int x1, int y1, int x2, int y2)
17889b0bd4cSmacallan{
17989b0bd4cSmacallan	ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
18089b0bd4cSmacallan	FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn);
18189b0bd4cSmacallan	ffb_fbcPtr ffb = pFfb->regs;
18289b0bd4cSmacallan
18389b0bd4cSmacallan	ENTER;
18489b0bd4cSmacallan	FFBFifo(pFfb, 4);
18589b0bd4cSmacallan	FFB_WRITE64(&ffb->by, y1, x1);
18689b0bd4cSmacallan	FFB_WRITE64_2(&ffb->bh, y2 - y1, x2 - x1);
18789b0bd4cSmacallan	exaMarkSync(pPixmap->drawable.pScreen);
18889b0bd4cSmacallan}
18989b0bd4cSmacallan
19089b0bd4cSmacallanstatic Bool
19189b0bd4cSmacallanFFBUploadToScreen(PixmapPtr pDst, int x, int y, int w, int h,
19289b0bd4cSmacallan    char *src, int src_pitch)
19389b0bd4cSmacallan{
19489b0bd4cSmacallan	ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum];
19589b0bd4cSmacallan	FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn);
19689b0bd4cSmacallan	unsigned char *dst, *sfb32;
19789b0bd4cSmacallan	int psz_shift = 2;
19889b0bd4cSmacallan	ffb_fbcPtr ffb = pFfb->regs;
19989b0bd4cSmacallan
20089b0bd4cSmacallan	ENTER;
20189b0bd4cSmacallan	FFB_ATTR_SFB_VAR_XAA(pFfb, 0xffffffff, GXcopy);
20289b0bd4cSmacallan	FFBWait(pFfb, ffb);
20389b0bd4cSmacallan
20489b0bd4cSmacallan	sfb32 = (unsigned char *) pFfb->sfb32;
20589b0bd4cSmacallan	dst = sfb32 + (y * (2048 << psz_shift)) + (x << psz_shift);
20689b0bd4cSmacallan	VISmoveImageLR(src, dst, w << psz_shift, h,
20789b0bd4cSmacallan		src_pitch, (2048 << psz_shift));
20889b0bd4cSmacallan	return TRUE;
20989b0bd4cSmacallan}
21089b0bd4cSmacallan
21189b0bd4cSmacallanstatic Bool
21289b0bd4cSmacallanFFBDownloadFromScreen(PixmapPtr pSrc, int x, int y, int w, int h,
21389b0bd4cSmacallan    char *dst, int dst_pitch)
21489b0bd4cSmacallan{
21589b0bd4cSmacallan	ScrnInfoPtr pScrn = xf86Screens[pSrc->drawable.pScreen->myNum];
21689b0bd4cSmacallan	FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn);
21789b0bd4cSmacallan	unsigned char *src, *sfb32;
21889b0bd4cSmacallan	int psz_shift = 2;
21989b0bd4cSmacallan	ffb_fbcPtr ffb = pFfb->regs;
22089b0bd4cSmacallan
22189b0bd4cSmacallan	ENTER;
22289b0bd4cSmacallan	FFB_ATTR_SFB_VAR_XAA(pFfb, 0xffffffff, GXcopy);
223504f16bcSmacallan	if (pFfb->use_blkread_prefetch) {
224504f16bcSmacallan		FFBFifo(pFfb, 1);
225504f16bcSmacallan		ffb->mer = FFB_MER_EIRA;
226504f16bcSmacallan	}
22789b0bd4cSmacallan	FFBWait(pFfb, ffb);
22889b0bd4cSmacallan
22989b0bd4cSmacallan	sfb32 = (unsigned char *) pFfb->sfb32;
23089b0bd4cSmacallan	src = sfb32 + (y * (2048 << psz_shift)) + (x << psz_shift);
23189b0bd4cSmacallan	VISmoveImageLR(src, dst, w << psz_shift, h,
23289b0bd4cSmacallan		(2048 << psz_shift), dst_pitch);
233504f16bcSmacallan	if (pFfb->use_blkread_prefetch) {
234504f16bcSmacallan		FFBFifo(pFfb, 1);
235504f16bcSmacallan		ffb->mer = FFB_MER_DRA;
236504f16bcSmacallan	}
23789b0bd4cSmacallan	return TRUE;
23889b0bd4cSmacallan}
23989b0bd4cSmacallan
240504f16bcSmacallanstatic Bool
24189b0bd4cSmacallanFFBCheckComposite(int op, PicturePtr pSrcPicture,
24289b0bd4cSmacallan                           PicturePtr pMaskPicture,
24389b0bd4cSmacallan                           PicturePtr pDstPicture)
24489b0bd4cSmacallan{
245504f16bcSmacallan	int i, ok = FALSE;
246504f16bcSmacallan
247504f16bcSmacallan	ENTER;
248504f16bcSmacallan
249504f16bcSmacallan	i = 0;
250504f16bcSmacallan	while ((i < arraysize(src_formats)) && (!ok)) {
251504f16bcSmacallan		ok =  (pSrcPicture->format == src_formats[i]);
252504f16bcSmacallan		i++;
253504f16bcSmacallan	}
254504f16bcSmacallan
255504f16bcSmacallan	if (!ok) {
256504f16bcSmacallan		xf86Msg(X_ERROR, "%s: unsupported src format %x\n",
257504f16bcSmacallan		    __func__, pSrcPicture->format);
258504f16bcSmacallan		return FALSE;
259504f16bcSmacallan	}
260504f16bcSmacallan
261504f16bcSmacallan	DPRINTF(X_ERROR, "src is %x, %d: %d %d\n", pSrcPicture->format, op,
262504f16bcSmacallan	    pSrcPicture->pDrawable->width, pSrcPicture->pDrawable->height);
263504f16bcSmacallan
264504f16bcSmacallan	if (pMaskPicture != NULL) {
265504f16bcSmacallan		DPRINTF(X_ERROR, "mask is %x %d %d\n", pMaskPicture->format,
266504f16bcSmacallan		    pMaskPicture->pDrawable->width,
267504f16bcSmacallan		    pMaskPicture->pDrawable->height);
268504f16bcSmacallan	}
269504f16bcSmacallan	return TRUE;
27089b0bd4cSmacallan}
27189b0bd4cSmacallan
272504f16bcSmacallanstatic Bool
27389b0bd4cSmacallanFFBPrepareComposite(int op, PicturePtr pSrcPicture,
27489b0bd4cSmacallan                             PicturePtr pMaskPicture,
27589b0bd4cSmacallan                             PicturePtr pDstPicture,
27689b0bd4cSmacallan                             PixmapPtr  pSrc,
27789b0bd4cSmacallan                             PixmapPtr  pMask,
27889b0bd4cSmacallan                             PixmapPtr  pDst)
27989b0bd4cSmacallan{
28089b0bd4cSmacallan	ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum];
28189b0bd4cSmacallan	FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn);
28289b0bd4cSmacallan
28389b0bd4cSmacallan	ENTER;
284504f16bcSmacallan
285504f16bcSmacallan	pFfb->no_source_pixmap = FALSE;
286504f16bcSmacallan	pFfb->source_is_solid = FALSE;
287504f16bcSmacallan
288504f16bcSmacallan	if (pSrcPicture->format == PICT_a1) {
289504f16bcSmacallan		xf86Msg(X_ERROR, "src mono, dst %x, op %d\n",
290504f16bcSmacallan		    pDstPicture->format, op);
291504f16bcSmacallan		if (pMaskPicture != NULL) {
292504f16bcSmacallan			xf86Msg(X_ERROR, "msk %x\n", pMaskPicture->format);
293504f16bcSmacallan		}
294504f16bcSmacallan	}
295504f16bcSmacallan	if (pSrcPicture->pSourcePict != NULL) {
296504f16bcSmacallan		if (pSrcPicture->pSourcePict->type == SourcePictTypeSolidFill) {
297504f16bcSmacallan			pFfb->fillcolour =
298504f16bcSmacallan			    pSrcPicture->pSourcePict->solidFill.color;
299504f16bcSmacallan			DPRINTF(X_ERROR, "%s: solid src %08x\n",
300504f16bcSmacallan			    __func__, pFfb->fillcolour);
301504f16bcSmacallan			pFfb->no_source_pixmap = TRUE;
302504f16bcSmacallan			pFfb->source_is_solid = TRUE;
303504f16bcSmacallan		}
304504f16bcSmacallan	}
305504f16bcSmacallan	if ((pMaskPicture != NULL) && (pMaskPicture->pSourcePict != NULL)) {
306504f16bcSmacallan		if (pMaskPicture->pSourcePict->type ==
307504f16bcSmacallan		    SourcePictTypeSolidFill) {
308504f16bcSmacallan			pFfb->fillcolour =
309504f16bcSmacallan			   pMaskPicture->pSourcePict->solidFill.color;
310504f16bcSmacallan			xf86Msg(X_ERROR, "%s: solid mask %08x\n",
311504f16bcSmacallan			    __func__, pFfb->fillcolour);
312504f16bcSmacallan		}
313504f16bcSmacallan	}
314504f16bcSmacallan	if (pMaskPicture != NULL) {
315504f16bcSmacallan		pFfb->mskoff = exaGetPixmapOffset(pMask);
316504f16bcSmacallan		pFfb->mskpitch = exaGetPixmapPitch(pMask);
317504f16bcSmacallan		pFfb->mskformat = pMaskPicture->format;
318504f16bcSmacallan	} else {
319504f16bcSmacallan		pFfb->mskoff = 0;
320504f16bcSmacallan		pFfb->mskpitch = 0;
321504f16bcSmacallan		pFfb->mskformat = 0;
322504f16bcSmacallan	}
323504f16bcSmacallan	if (pSrc != NULL) {
324504f16bcSmacallan		pFfb->source_is_solid =
325504f16bcSmacallan		   ((pSrc->drawable.width == 1) && (pSrc->drawable.height == 1));
326504f16bcSmacallan		pFfb->srcoff = exaGetPixmapOffset(pSrc);
327504f16bcSmacallan		pFfb->srcpitch = exaGetPixmapPitch(pSrc);
328504f16bcSmacallan		if (pFfb->source_is_solid) {
329504f16bcSmacallan			pFfb->fillcolour = *(uint32_t *)(pFfb->fb + pFfb->srcoff);
330504f16bcSmacallan		}
331504f16bcSmacallan	}
332504f16bcSmacallan	pFfb->srcformat = pSrcPicture->format;
333504f16bcSmacallan	pFfb->dstformat = pDstPicture->format;
334504f16bcSmacallan
335504f16bcSmacallan	if (pFfb->source_is_solid) {
336504f16bcSmacallan		uint32_t temp;
337504f16bcSmacallan
338504f16bcSmacallan		/* swap solid source as needed */
339504f16bcSmacallan		switch (pFfb->srcformat) {
340504f16bcSmacallan			case PICT_a8r8g8b8:
341504f16bcSmacallan			case PICT_x8r8g8b8:
342504f16bcSmacallan				temp = (pFfb->fillcolour & 0x000000ff) << 16;
343504f16bcSmacallan				temp |= (pFfb->fillcolour & 0x00ff0000) >> 16;
344504f16bcSmacallan				temp |= (pFfb->fillcolour & 0xff00ff00);
345504f16bcSmacallan				pFfb->fillcolour = temp;
346504f16bcSmacallan				break;
347504f16bcSmacallan		}
348504f16bcSmacallan	}
349504f16bcSmacallan	pFfb->op = op;
350504f16bcSmacallan	return TRUE;
35189b0bd4cSmacallan}
35289b0bd4cSmacallan
353504f16bcSmacallanstatic void
35489b0bd4cSmacallanFFBComposite(PixmapPtr pDst, int srcX, int srcY,
35589b0bd4cSmacallan                              int maskX, int maskY,
35689b0bd4cSmacallan                              int dstX, int dstY,
35789b0bd4cSmacallan                              int width, int height)
35889b0bd4cSmacallan{
35989b0bd4cSmacallan	ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum];
36089b0bd4cSmacallan	FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn);
36189b0bd4cSmacallan	exaMarkSync(pDst->drawable.pScreen);
36289b0bd4cSmacallan}
36389b0bd4cSmacallan
36489b0bd4cSmacallanstatic Bool
36589b0bd4cSmacallanFFBPrepareAccess(PixmapPtr pPix, int index)
36689b0bd4cSmacallan{
36789b0bd4cSmacallan	ScrnInfoPtr pScrn = xf86Screens[pPix->drawable.pScreen->myNum];
36889b0bd4cSmacallan	FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn);
36989b0bd4cSmacallan	ffb_fbcPtr ffb = pFfb->regs;
37089b0bd4cSmacallan
37189b0bd4cSmacallan	ENTER;
37289b0bd4cSmacallan	FFB_ATTR_SFB_VAR_XAA(pFfb, 0xffffffff, GXcopy);
37389b0bd4cSmacallan	FFBWait(pFfb, ffb);
37489b0bd4cSmacallan
37589b0bd4cSmacallan	return TRUE;
37689b0bd4cSmacallan}
37789b0bd4cSmacallan
37889b0bd4cSmacallanstatic void
37989b0bd4cSmacallanFFBFinishAccess(PixmapPtr pPix, int index)
38089b0bd4cSmacallan{
38189b0bd4cSmacallan}
38289b0bd4cSmacallan
38389b0bd4cSmacallanBool
38489b0bd4cSmacallanFFBInitEXA(ScreenPtr pScreen)
38589b0bd4cSmacallan{
38689b0bd4cSmacallan	ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
38789b0bd4cSmacallan	FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn);
38889b0bd4cSmacallan	ffb_fbcPtr ffb = pFfb->regs;
38989b0bd4cSmacallan	ExaDriverPtr pExa;
39089b0bd4cSmacallan
39189b0bd4cSmacallan	pFfb->fbc = (FFB_FBC_WB_A | FFB_FBC_WM_COMBINED | FFB_FBC_RB_A |
39289b0bd4cSmacallan			 FFB_FBC_WE_FORCEON |
39389b0bd4cSmacallan			 FFB_FBC_SB_BOTH |
39489b0bd4cSmacallan			 FFB_FBC_ZE_OFF | FFB_FBC_YE_OFF |
39589b0bd4cSmacallan			 FFB_FBC_RGBE_MASK |
39689b0bd4cSmacallan			 FFB_FBC_XE_ON);
39789b0bd4cSmacallan	pFfb->wid = FFBWidAlloc(pFfb, TrueColor, 0, TRUE);
39889b0bd4cSmacallan	if (pFfb->wid == (unsigned int) -1)
39989b0bd4cSmacallan		return FALSE;
40089b0bd4cSmacallan
40189b0bd4cSmacallan	pFfb->ppc_cache = (FFB_PPC_FW_DISABLE |
40289b0bd4cSmacallan			   FFB_PPC_VCE_DISABLE | FFB_PPC_APE_DISABLE | FFB_PPC_CS_CONST |
40389b0bd4cSmacallan			   FFB_PPC_XS_WID | FFB_PPC_YS_CONST | FFB_PPC_ZS_CONST |
40489b0bd4cSmacallan			   FFB_PPC_DCE_DISABLE | FFB_PPC_ABE_DISABLE | FFB_PPC_TBE_OPAQUE);
40589b0bd4cSmacallan	pFfb->wid_cache = pFfb->wid;
40689b0bd4cSmacallan	pFfb->pmask_cache = ~0;
40789b0bd4cSmacallan	pFfb->rop_cache = (FFB_ROP_NEW | (FFB_ROP_NEW << 8));
40889b0bd4cSmacallan	pFfb->drawop_cache = FFB_DRAWOP_RECTANGLE;
40989b0bd4cSmacallan	pFfb->fg_cache = pFfb->bg_cache = 0;
41089b0bd4cSmacallan	pFfb->fontw_cache = 32;
41189b0bd4cSmacallan	pFfb->fontinc_cache = (1 << 16) | 0;
41289b0bd4cSmacallan	pFfb->fbc_cache = (FFB_FBC_WB_A | FFB_FBC_WM_COMBINED | FFB_FBC_RB_A |
41389b0bd4cSmacallan			   FFB_FBC_WE_FORCEON |
41489b0bd4cSmacallan			   FFB_FBC_SB_BOTH |
41589b0bd4cSmacallan			   FFB_FBC_ZE_OFF | FFB_FBC_YE_OFF |
41689b0bd4cSmacallan			   FFB_FBC_RGBE_OFF |
41789b0bd4cSmacallan			   FFB_FBC_XE_ON);
41889b0bd4cSmacallan
41989b0bd4cSmacallan	/* We will now clear the screen: we'll draw a rectangle covering all the
42089b0bd4cSmacallan	 * viewscreen, using a 'blackness' ROP.
42189b0bd4cSmacallan	 */
42289b0bd4cSmacallan	FFBFifo(pFfb, 22);
42389b0bd4cSmacallan	ffb->fbc = pFfb->fbc_cache;
42489b0bd4cSmacallan	ffb->ppc = pFfb->ppc_cache;
42589b0bd4cSmacallan	ffb->wid = pFfb->wid_cache;
42689b0bd4cSmacallan	ffb->xpmask = 0xff;
42789b0bd4cSmacallan	ffb->pmask = pFfb->pmask_cache;
42889b0bd4cSmacallan	ffb->rop = pFfb->rop_cache;
42989b0bd4cSmacallan	ffb->drawop = pFfb->drawop_cache;
43089b0bd4cSmacallan	ffb->fg = pFfb->fg_cache;
43189b0bd4cSmacallan	ffb->bg = pFfb->bg_cache;
43289b0bd4cSmacallan	ffb->fontw = pFfb->fontw_cache;
43389b0bd4cSmacallan	ffb->fontinc = pFfb->fontinc_cache;
43489b0bd4cSmacallan	ffb->xclip = FFB_XCLIP_TEST_ALWAYS;
43589b0bd4cSmacallan	ffb->cmp = 0x80808080;
43689b0bd4cSmacallan	ffb->matchab = 0x80808080;
43789b0bd4cSmacallan	ffb->magnab = 0x80808080;
43889b0bd4cSmacallan	ffb->blendc = (FFB_BLENDC_FORCE_ONE |
43989b0bd4cSmacallan		       FFB_BLENDC_DF_ONE_M_A |
44089b0bd4cSmacallan		       FFB_BLENDC_SF_A);
44189b0bd4cSmacallan	ffb->blendc1 = 0;
44289b0bd4cSmacallan	ffb->blendc2 = 0;
44389b0bd4cSmacallan	FFB_WRITE64(&ffb->by, 0, 0);
44489b0bd4cSmacallan	FFB_WRITE64_2(&ffb->bh, pFfb->psdp->height, pFfb->psdp->width);
44589b0bd4cSmacallan	FFBWait(pFfb, ffb);
44689b0bd4cSmacallan
44789b0bd4cSmacallan	FFB_ATTR_SFB_VAR_XAA(pFfb, 0xffffffff, GXcopy);
44889b0bd4cSmacallan	FFBWait(pFfb, ffb);
44989b0bd4cSmacallan
450504f16bcSmacallan	FFB_HardwareSetup(pFfb);
45189b0bd4cSmacallan	pExa = exaDriverAlloc();
45289b0bd4cSmacallan	if (!pExa)
45389b0bd4cSmacallan		return FALSE;
45489b0bd4cSmacallan
45589b0bd4cSmacallan	pFfb->pExa = pExa;
45689b0bd4cSmacallan
45789b0bd4cSmacallan	pExa->exa_major = EXA_VERSION_MAJOR;
45889b0bd4cSmacallan	pExa->exa_minor = EXA_VERSION_MINOR;
45989b0bd4cSmacallan
46089b0bd4cSmacallan
46189b0bd4cSmacallan	pExa->memoryBase = (char *)pFfb->sfb32;
46289b0bd4cSmacallan	/*
46389b0bd4cSmacallan	 * we don't have usable off-screen memory but EXA craps out if we don't
46489b0bd4cSmacallan	 * pretend that we do, so register a ridiculously small amount and
46589b0bd4cSmacallan	 * cross fingers
46689b0bd4cSmacallan	 */
46789b0bd4cSmacallan	pExa->memorySize = 8192 * pFfb->psdp->height + 4;
46889b0bd4cSmacallan	pExa->offScreenBase = pExa->memorySize - 4;
46989b0bd4cSmacallan
47089b0bd4cSmacallan	/* we want to use 64bit aligned accesses */
47189b0bd4cSmacallan	pExa->pixmapOffsetAlign = 8;
47289b0bd4cSmacallan	pExa->pixmapPitchAlign = 8;
47389b0bd4cSmacallan
47489b0bd4cSmacallan	pExa->flags = EXA_OFFSCREEN_PIXMAPS |
47589b0bd4cSmacallan		      /*EXA_SUPPORTS_OFFSCREEN_OVERLAPS |*/
47689b0bd4cSmacallan		      EXA_MIXED_PIXMAPS;
47789b0bd4cSmacallan
47889b0bd4cSmacallan	pExa->maxX = 2048;
47989b0bd4cSmacallan	pExa->maxY = 2048;
48089b0bd4cSmacallan
48189b0bd4cSmacallan	pExa->WaitMarker = FFBWaitMarker;
48289b0bd4cSmacallan
48389b0bd4cSmacallan	pExa->PrepareSolid = FFBPrepareSolid;
48489b0bd4cSmacallan	pExa->Solid = FFBSolid;
48589b0bd4cSmacallan	pExa->DoneSolid = FFBDoneCopy;
486504f16bcSmacallan
48789b0bd4cSmacallan	pExa->PrepareCopy = FFBPrepareCopy;
48889b0bd4cSmacallan	pExa->Copy = FFBCopy;
48989b0bd4cSmacallan	pExa->DoneCopy = FFBDoneCopy;
490504f16bcSmacallan
49189b0bd4cSmacallan	pExa->UploadToScreen = FFBUploadToScreen;
49289b0bd4cSmacallan	pExa->DownloadFromScreen = FFBDownloadFromScreen;
493504f16bcSmacallan
49489b0bd4cSmacallan	pExa->PrepareAccess = FFBPrepareAccess;
49589b0bd4cSmacallan	pExa->FinishAccess = FFBFinishAccess;
49689b0bd4cSmacallan
497504f16bcSmacallanif(0) {
498504f16bcSmacallan	pExa->CheckComposite = FFBCheckComposite;
499504f16bcSmacallan	pExa->PrepareComposite = FFBPrepareComposite;
500504f16bcSmacallan	pExa->Composite = FFBComposite;
501504f16bcSmacallan	pExa->DoneComposite = FFBDoneCopy;
502504f16bcSmacallan}
50389b0bd4cSmacallan	return exaDriverInit(pScreen, pExa);
50489b0bd4cSmacallan}
505