1f502a9faSjoerg/* $NetBSD: ffb_exa.c,v 1.5 2016/09/27 19:12:53 joerg 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 34dda79b8eSmrg#ifdef HAVE_CONFIG_H 35dda79b8eSmrg#include "config.h" 36dda79b8eSmrg#endif 37dda79b8eSmrg 38f1295e53Smrg#include "ffb_fifo.h" 39f1295e53Smrg#include "ffb_rcache.h" 40f1295e53Smrg#include "ffb.h" 41f1295e53Smrg#include "ffb_regs.h" 42f1295e53Smrg 4389b0bd4cSmacallan/* all driver need this */ 4489b0bd4cSmacallan#include "xf86.h" 4589b0bd4cSmacallan#include "xf86_OSproc.h" 4689b0bd4cSmacallan#include "compiler.h" 4789b0bd4cSmacallan#include "exa.h" 4889b0bd4cSmacallan 4989b0bd4cSmacallanextern void VISmoveImageRL(unsigned char *, unsigned char *, long, long, long, long); 5089b0bd4cSmacallanextern void VISmoveImageLR(unsigned char *, unsigned char *, long, long, long, long); 5189b0bd4cSmacallan 5289b0bd4cSmacallan/*#define FFB_DEBUG*/ 5389b0bd4cSmacallan 5489b0bd4cSmacallan#ifdef FFB_DEBUG 5589b0bd4cSmacallan#define ENTER xf86Msg(X_ERROR, "%s>\n", __func__); 5689b0bd4cSmacallan#define DPRINTF xf86Msg 5789b0bd4cSmacallan#else 5889b0bd4cSmacallan#define ENTER 5989b0bd4cSmacallan#define DPRINTF while (0) xf86Msg 6089b0bd4cSmacallan#endif 6189b0bd4cSmacallan 62504f16bcSmacallan#define arraysize(ary) (sizeof(ary) / sizeof(ary[0])) 63504f16bcSmacallan 64504f16bcSmacallanint src_formats[] = {PICT_a8r8g8b8, PICT_x8r8g8b8, 65504f16bcSmacallan PICT_a8b8g8r8, PICT_x8b8g8r8, PICT_a8}; 66504f16bcSmacallanint tex_formats[] = {PICT_a8r8g8b8, PICT_a8b8g8r8, PICT_a8}; 67504f16bcSmacallan 6889b0bd4cSmacallanstatic void 6989b0bd4cSmacallanFFBWaitMarker(ScreenPtr pScreen, int Marker) 7089b0bd4cSmacallan{ 7189b0bd4cSmacallan ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 7289b0bd4cSmacallan FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn); 7389b0bd4cSmacallan ffb_fbcPtr ffb = pFfb->regs; 7489b0bd4cSmacallan 7589b0bd4cSmacallan FFBWait(pFfb, ffb); 7689b0bd4cSmacallan} 7789b0bd4cSmacallan 7889b0bd4cSmacallanstatic Bool 7989b0bd4cSmacallanFFBPrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, 8089b0bd4cSmacallan int xdir, int ydir, int alu, Pixel planemask) 8189b0bd4cSmacallan{ 8289b0bd4cSmacallan ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum]; 8389b0bd4cSmacallan FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn); 8489b0bd4cSmacallan ffb_fbcPtr ffb = pFfb->regs; 8589b0bd4cSmacallan 8689b0bd4cSmacallan ENTER; 8789b0bd4cSmacallan pFfb->srcpitch = exaGetPixmapPitch(pSrcPixmap); 8889b0bd4cSmacallan pFfb->srcoff = exaGetPixmapOffset(pSrcPixmap); 8989b0bd4cSmacallan pFfb->xdir = xdir; 9089b0bd4cSmacallan pFfb->ydir = ydir; 9189b0bd4cSmacallan pFfb->rop = alu; 9289b0bd4cSmacallan pFfb->planemask = planemask; 9389b0bd4cSmacallan return TRUE; 9489b0bd4cSmacallan} 9589b0bd4cSmacallan 9689b0bd4cSmacallanstatic void 9789b0bd4cSmacallanFFBCopy(PixmapPtr pDstPixmap, 9889b0bd4cSmacallan int srcX, int srcY, int dstX, int dstY, int w, int h) 9989b0bd4cSmacallan{ 10089b0bd4cSmacallan ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum]; 10189b0bd4cSmacallan FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn); 10289b0bd4cSmacallan ffb_fbcPtr ffb = pFfb->regs; 10389b0bd4cSmacallan unsigned char *src, *dst, *sfb32; 10489b0bd4cSmacallan int psz_shift = 2; 10589b0bd4cSmacallan int sdkind; 10689b0bd4cSmacallan 10789b0bd4cSmacallan ENTER; 10889b0bd4cSmacallan if ((srcX == dstX) && (srcY != dstY) && (pFfb->rop == GXcopy)) { 10989b0bd4cSmacallan /* we can use the vscroll command */ 11089b0bd4cSmacallan FFB_ATTR_VSCROLL_XAA(pFfb, pFfb->planemask); 11189b0bd4cSmacallan FFBFifo(pFfb, 7); 11289b0bd4cSmacallan ffb->drawop = FFB_DRAWOP_VSCROLL; 11389b0bd4cSmacallan FFB_WRITE64(&ffb->by, srcY, srcX); 11489b0bd4cSmacallan FFB_WRITE64_2(&ffb->dy, dstY, dstX); 11589b0bd4cSmacallan FFB_WRITE64_3(&ffb->bh, h, w); 11689b0bd4cSmacallan exaMarkSync(pDstPixmap->drawable.pScreen); 11789b0bd4cSmacallan return; 11889b0bd4cSmacallan } 11989b0bd4cSmacallan FFB_ATTR_SFB_VAR_XAA(pFfb, pFfb->planemask, pFfb->rop); 120504f16bcSmacallan if (pFfb->use_blkread_prefetch) { 121504f16bcSmacallan FFBFifo(pFfb, 1); 122504f16bcSmacallan if (pFfb->xdir < 0) 123504f16bcSmacallan ffb->mer = FFB_MER_EDRA; 124504f16bcSmacallan else 125504f16bcSmacallan ffb->mer = FFB_MER_EIRA; 126504f16bcSmacallan } 12789b0bd4cSmacallan FFBWait(pFfb, ffb); 12889b0bd4cSmacallan sfb32 = (unsigned char *) pFfb->sfb32; 12989b0bd4cSmacallan src = sfb32 + (srcY * (2048 << psz_shift)) + (srcX << psz_shift); 13089b0bd4cSmacallan dst = sfb32 + (dstY * (2048 << psz_shift)) + (dstX << psz_shift); 13189b0bd4cSmacallan sdkind = (2048 << psz_shift); 13289b0bd4cSmacallan 13389b0bd4cSmacallan if (pFfb->ydir < 0) { 13489b0bd4cSmacallan src += ((h - 1) * (2048 << psz_shift)); 13589b0bd4cSmacallan dst += ((h - 1) * (2048 << psz_shift)); 13689b0bd4cSmacallan sdkind = -sdkind; 13789b0bd4cSmacallan } 13889b0bd4cSmacallan w <<= psz_shift; 13989b0bd4cSmacallan if (pFfb->xdir < 0) 14089b0bd4cSmacallan VISmoveImageRL(src, dst, w, h, sdkind, sdkind); 14189b0bd4cSmacallan else 14289b0bd4cSmacallan VISmoveImageLR(src, dst, w, h, sdkind, sdkind); 143504f16bcSmacallan if (pFfb->use_blkread_prefetch) { 144504f16bcSmacallan FFBFifo(pFfb, 1); 145504f16bcSmacallan ffb->mer = FFB_MER_DRA; 146504f16bcSmacallan } 14789b0bd4cSmacallan} 14889b0bd4cSmacallan 14989b0bd4cSmacallanstatic void 15089b0bd4cSmacallanFFBDoneCopy(PixmapPtr pDstPixmap) 15189b0bd4cSmacallan{ 15289b0bd4cSmacallan} 15389b0bd4cSmacallan 15489b0bd4cSmacallanstatic Bool 15589b0bd4cSmacallanFFBPrepareSolid(PixmapPtr pPixmap, int alu, Pixel planemask, Pixel fg) 15689b0bd4cSmacallan{ 15789b0bd4cSmacallan ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum]; 15889b0bd4cSmacallan FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn); 15989b0bd4cSmacallan ffb_fbcPtr ffb = pFfb->regs; 16089b0bd4cSmacallan unsigned int ppc, ppc_mask, fbc; 16189b0bd4cSmacallan 16289b0bd4cSmacallan ENTER; 16389b0bd4cSmacallan FFBWait(pFfb, ffb); 16489b0bd4cSmacallan pFfb->planemask = planemask; 16589b0bd4cSmacallan pFfb->rop = alu; 16689b0bd4cSmacallan 16789b0bd4cSmacallan fbc = pFfb->fbc; 16889b0bd4cSmacallan if (pFfb->ffb_res == ffb_res_high) 16989b0bd4cSmacallan fbc |= FFB_FBC_WB_B; 17089b0bd4cSmacallan ppc = FFB_PPC_ABE_DISABLE | FFB_PPC_APE_DISABLE | FFB_PPC_CS_CONST | FFB_PPC_XS_WID; 17189b0bd4cSmacallan ppc_mask = FFB_PPC_ABE_MASK | FFB_PPC_APE_MASK | FFB_PPC_CS_MASK | FFB_PPC_XS_MASK; 17289b0bd4cSmacallan 17389b0bd4cSmacallan FFB_ATTR_RAW(pFfb, ppc, ppc_mask, planemask, 17489b0bd4cSmacallan (FFB_ROP_EDIT_BIT | alu) | (FFB_ROP_NEW << 8), 17589b0bd4cSmacallan FFB_DRAWOP_RECTANGLE, fg, fbc, pFfb->wid); 17689b0bd4cSmacallan 17789b0bd4cSmacallan return TRUE; 17889b0bd4cSmacallan} 17989b0bd4cSmacallan 18089b0bd4cSmacallanstatic void 18189b0bd4cSmacallanFFBSolid(PixmapPtr pPixmap, int x1, int y1, int x2, int y2) 18289b0bd4cSmacallan{ 18389b0bd4cSmacallan ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum]; 18489b0bd4cSmacallan FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn); 18589b0bd4cSmacallan ffb_fbcPtr ffb = pFfb->regs; 18689b0bd4cSmacallan 18789b0bd4cSmacallan ENTER; 18889b0bd4cSmacallan FFBFifo(pFfb, 4); 18989b0bd4cSmacallan FFB_WRITE64(&ffb->by, y1, x1); 19089b0bd4cSmacallan FFB_WRITE64_2(&ffb->bh, y2 - y1, x2 - x1); 19189b0bd4cSmacallan exaMarkSync(pPixmap->drawable.pScreen); 19289b0bd4cSmacallan} 19389b0bd4cSmacallan 19489b0bd4cSmacallanstatic Bool 19589b0bd4cSmacallanFFBUploadToScreen(PixmapPtr pDst, int x, int y, int w, int h, 19689b0bd4cSmacallan char *src, int src_pitch) 19789b0bd4cSmacallan{ 19889b0bd4cSmacallan ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum]; 19989b0bd4cSmacallan FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn); 20089b0bd4cSmacallan unsigned char *dst, *sfb32; 20189b0bd4cSmacallan int psz_shift = 2; 20289b0bd4cSmacallan ffb_fbcPtr ffb = pFfb->regs; 20389b0bd4cSmacallan 20489b0bd4cSmacallan ENTER; 20589b0bd4cSmacallan FFB_ATTR_SFB_VAR_XAA(pFfb, 0xffffffff, GXcopy); 20689b0bd4cSmacallan FFBWait(pFfb, ffb); 20789b0bd4cSmacallan 20889b0bd4cSmacallan sfb32 = (unsigned char *) pFfb->sfb32; 20989b0bd4cSmacallan dst = sfb32 + (y * (2048 << psz_shift)) + (x << psz_shift); 21089b0bd4cSmacallan VISmoveImageLR(src, dst, w << psz_shift, h, 21189b0bd4cSmacallan src_pitch, (2048 << psz_shift)); 21289b0bd4cSmacallan return TRUE; 21389b0bd4cSmacallan} 21489b0bd4cSmacallan 21589b0bd4cSmacallanstatic Bool 21689b0bd4cSmacallanFFBDownloadFromScreen(PixmapPtr pSrc, int x, int y, int w, int h, 21789b0bd4cSmacallan char *dst, int dst_pitch) 21889b0bd4cSmacallan{ 21989b0bd4cSmacallan ScrnInfoPtr pScrn = xf86Screens[pSrc->drawable.pScreen->myNum]; 22089b0bd4cSmacallan FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn); 22189b0bd4cSmacallan unsigned char *src, *sfb32; 22289b0bd4cSmacallan int psz_shift = 2; 22389b0bd4cSmacallan ffb_fbcPtr ffb = pFfb->regs; 22489b0bd4cSmacallan 22589b0bd4cSmacallan ENTER; 22689b0bd4cSmacallan FFB_ATTR_SFB_VAR_XAA(pFfb, 0xffffffff, GXcopy); 227504f16bcSmacallan if (pFfb->use_blkread_prefetch) { 228504f16bcSmacallan FFBFifo(pFfb, 1); 229504f16bcSmacallan ffb->mer = FFB_MER_EIRA; 230504f16bcSmacallan } 23189b0bd4cSmacallan FFBWait(pFfb, ffb); 23289b0bd4cSmacallan 23389b0bd4cSmacallan sfb32 = (unsigned char *) pFfb->sfb32; 23489b0bd4cSmacallan src = sfb32 + (y * (2048 << psz_shift)) + (x << psz_shift); 23589b0bd4cSmacallan VISmoveImageLR(src, dst, w << psz_shift, h, 23689b0bd4cSmacallan (2048 << psz_shift), dst_pitch); 237504f16bcSmacallan if (pFfb->use_blkread_prefetch) { 238504f16bcSmacallan FFBFifo(pFfb, 1); 239504f16bcSmacallan ffb->mer = FFB_MER_DRA; 240504f16bcSmacallan } 24189b0bd4cSmacallan return TRUE; 24289b0bd4cSmacallan} 24389b0bd4cSmacallan 244504f16bcSmacallanstatic Bool 24589b0bd4cSmacallanFFBCheckComposite(int op, PicturePtr pSrcPicture, 24689b0bd4cSmacallan PicturePtr pMaskPicture, 24789b0bd4cSmacallan PicturePtr pDstPicture) 24889b0bd4cSmacallan{ 249504f16bcSmacallan int i, ok = FALSE; 250504f16bcSmacallan 251504f16bcSmacallan ENTER; 252504f16bcSmacallan 253504f16bcSmacallan i = 0; 254504f16bcSmacallan while ((i < arraysize(src_formats)) && (!ok)) { 255504f16bcSmacallan ok = (pSrcPicture->format == src_formats[i]); 256504f16bcSmacallan i++; 257504f16bcSmacallan } 258504f16bcSmacallan 259504f16bcSmacallan if (!ok) { 260504f16bcSmacallan xf86Msg(X_ERROR, "%s: unsupported src format %x\n", 261504f16bcSmacallan __func__, pSrcPicture->format); 262504f16bcSmacallan return FALSE; 263504f16bcSmacallan } 264504f16bcSmacallan 265504f16bcSmacallan DPRINTF(X_ERROR, "src is %x, %d: %d %d\n", pSrcPicture->format, op, 266504f16bcSmacallan pSrcPicture->pDrawable->width, pSrcPicture->pDrawable->height); 267504f16bcSmacallan 268504f16bcSmacallan if (pMaskPicture != NULL) { 269504f16bcSmacallan DPRINTF(X_ERROR, "mask is %x %d %d\n", pMaskPicture->format, 270504f16bcSmacallan pMaskPicture->pDrawable->width, 271504f16bcSmacallan pMaskPicture->pDrawable->height); 272504f16bcSmacallan } 273504f16bcSmacallan return TRUE; 27489b0bd4cSmacallan} 27589b0bd4cSmacallan 276504f16bcSmacallanstatic Bool 27789b0bd4cSmacallanFFBPrepareComposite(int op, PicturePtr pSrcPicture, 27889b0bd4cSmacallan PicturePtr pMaskPicture, 27989b0bd4cSmacallan PicturePtr pDstPicture, 28089b0bd4cSmacallan PixmapPtr pSrc, 28189b0bd4cSmacallan PixmapPtr pMask, 28289b0bd4cSmacallan PixmapPtr pDst) 28389b0bd4cSmacallan{ 28489b0bd4cSmacallan ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum]; 28589b0bd4cSmacallan FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn); 28689b0bd4cSmacallan 28789b0bd4cSmacallan ENTER; 288504f16bcSmacallan 289504f16bcSmacallan pFfb->no_source_pixmap = FALSE; 290504f16bcSmacallan pFfb->source_is_solid = FALSE; 291504f16bcSmacallan 292504f16bcSmacallan if (pSrcPicture->format == PICT_a1) { 293504f16bcSmacallan xf86Msg(X_ERROR, "src mono, dst %x, op %d\n", 294504f16bcSmacallan pDstPicture->format, op); 295504f16bcSmacallan if (pMaskPicture != NULL) { 296504f16bcSmacallan xf86Msg(X_ERROR, "msk %x\n", pMaskPicture->format); 297504f16bcSmacallan } 298504f16bcSmacallan } 299504f16bcSmacallan if (pSrcPicture->pSourcePict != NULL) { 300504f16bcSmacallan if (pSrcPicture->pSourcePict->type == SourcePictTypeSolidFill) { 301504f16bcSmacallan pFfb->fillcolour = 302504f16bcSmacallan pSrcPicture->pSourcePict->solidFill.color; 303f502a9faSjoerg DPRINTF(X_ERROR, "%s: solid src %08"PRIx32"\n", 304f502a9faSjoerg __func__, (uint32_t)pFfb->fillcolour); 305504f16bcSmacallan pFfb->no_source_pixmap = TRUE; 306504f16bcSmacallan pFfb->source_is_solid = TRUE; 307504f16bcSmacallan } 308504f16bcSmacallan } 309504f16bcSmacallan if ((pMaskPicture != NULL) && (pMaskPicture->pSourcePict != NULL)) { 310504f16bcSmacallan if (pMaskPicture->pSourcePict->type == 311504f16bcSmacallan SourcePictTypeSolidFill) { 312504f16bcSmacallan pFfb->fillcolour = 313504f16bcSmacallan pMaskPicture->pSourcePict->solidFill.color; 314f502a9faSjoerg xf86Msg(X_ERROR, "%s: solid mask %08"PRIx32"\n", 315f502a9faSjoerg __func__, (uint32_t)pFfb->fillcolour); 316504f16bcSmacallan } 317504f16bcSmacallan } 318504f16bcSmacallan if (pMaskPicture != NULL) { 319504f16bcSmacallan pFfb->mskoff = exaGetPixmapOffset(pMask); 320504f16bcSmacallan pFfb->mskpitch = exaGetPixmapPitch(pMask); 321504f16bcSmacallan pFfb->mskformat = pMaskPicture->format; 322504f16bcSmacallan } else { 323504f16bcSmacallan pFfb->mskoff = 0; 324504f16bcSmacallan pFfb->mskpitch = 0; 325504f16bcSmacallan pFfb->mskformat = 0; 326504f16bcSmacallan } 327504f16bcSmacallan if (pSrc != NULL) { 328504f16bcSmacallan pFfb->source_is_solid = 329504f16bcSmacallan ((pSrc->drawable.width == 1) && (pSrc->drawable.height == 1)); 330504f16bcSmacallan pFfb->srcoff = exaGetPixmapOffset(pSrc); 331504f16bcSmacallan pFfb->srcpitch = exaGetPixmapPitch(pSrc); 332504f16bcSmacallan if (pFfb->source_is_solid) { 333504f16bcSmacallan pFfb->fillcolour = *(uint32_t *)(pFfb->fb + pFfb->srcoff); 334504f16bcSmacallan } 335504f16bcSmacallan } 336504f16bcSmacallan pFfb->srcformat = pSrcPicture->format; 337504f16bcSmacallan pFfb->dstformat = pDstPicture->format; 338504f16bcSmacallan 339504f16bcSmacallan if (pFfb->source_is_solid) { 340504f16bcSmacallan uint32_t temp; 341504f16bcSmacallan 342504f16bcSmacallan /* swap solid source as needed */ 343504f16bcSmacallan switch (pFfb->srcformat) { 344504f16bcSmacallan case PICT_a8r8g8b8: 345504f16bcSmacallan case PICT_x8r8g8b8: 346504f16bcSmacallan temp = (pFfb->fillcolour & 0x000000ff) << 16; 347504f16bcSmacallan temp |= (pFfb->fillcolour & 0x00ff0000) >> 16; 348504f16bcSmacallan temp |= (pFfb->fillcolour & 0xff00ff00); 349504f16bcSmacallan pFfb->fillcolour = temp; 350504f16bcSmacallan break; 351504f16bcSmacallan } 352504f16bcSmacallan } 353504f16bcSmacallan pFfb->op = op; 354504f16bcSmacallan return TRUE; 35589b0bd4cSmacallan} 35689b0bd4cSmacallan 357504f16bcSmacallanstatic void 35889b0bd4cSmacallanFFBComposite(PixmapPtr pDst, int srcX, int srcY, 35989b0bd4cSmacallan int maskX, int maskY, 36089b0bd4cSmacallan int dstX, int dstY, 36189b0bd4cSmacallan int width, int height) 36289b0bd4cSmacallan{ 36389b0bd4cSmacallan ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum]; 36489b0bd4cSmacallan FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn); 36589b0bd4cSmacallan exaMarkSync(pDst->drawable.pScreen); 36689b0bd4cSmacallan} 36789b0bd4cSmacallan 36889b0bd4cSmacallanstatic Bool 36989b0bd4cSmacallanFFBPrepareAccess(PixmapPtr pPix, int index) 37089b0bd4cSmacallan{ 37189b0bd4cSmacallan ScrnInfoPtr pScrn = xf86Screens[pPix->drawable.pScreen->myNum]; 37289b0bd4cSmacallan FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn); 37389b0bd4cSmacallan ffb_fbcPtr ffb = pFfb->regs; 37489b0bd4cSmacallan 37589b0bd4cSmacallan ENTER; 37689b0bd4cSmacallan FFB_ATTR_SFB_VAR_XAA(pFfb, 0xffffffff, GXcopy); 37789b0bd4cSmacallan FFBWait(pFfb, ffb); 37889b0bd4cSmacallan 37989b0bd4cSmacallan return TRUE; 38089b0bd4cSmacallan} 38189b0bd4cSmacallan 38289b0bd4cSmacallanstatic void 38389b0bd4cSmacallanFFBFinishAccess(PixmapPtr pPix, int index) 38489b0bd4cSmacallan{ 38589b0bd4cSmacallan} 38689b0bd4cSmacallan 38789b0bd4cSmacallanBool 38889b0bd4cSmacallanFFBInitEXA(ScreenPtr pScreen) 38989b0bd4cSmacallan{ 39089b0bd4cSmacallan ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 39189b0bd4cSmacallan FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn); 39289b0bd4cSmacallan ffb_fbcPtr ffb = pFfb->regs; 39389b0bd4cSmacallan ExaDriverPtr pExa; 39489b0bd4cSmacallan 39589b0bd4cSmacallan pFfb->fbc = (FFB_FBC_WB_A | FFB_FBC_WM_COMBINED | FFB_FBC_RB_A | 39689b0bd4cSmacallan FFB_FBC_WE_FORCEON | 39789b0bd4cSmacallan FFB_FBC_SB_BOTH | 39889b0bd4cSmacallan FFB_FBC_ZE_OFF | FFB_FBC_YE_OFF | 39989b0bd4cSmacallan FFB_FBC_RGBE_MASK | 40089b0bd4cSmacallan FFB_FBC_XE_ON); 40189b0bd4cSmacallan pFfb->wid = FFBWidAlloc(pFfb, TrueColor, 0, TRUE); 40289b0bd4cSmacallan if (pFfb->wid == (unsigned int) -1) 40389b0bd4cSmacallan return FALSE; 40489b0bd4cSmacallan 40589b0bd4cSmacallan pFfb->ppc_cache = (FFB_PPC_FW_DISABLE | 40689b0bd4cSmacallan FFB_PPC_VCE_DISABLE | FFB_PPC_APE_DISABLE | FFB_PPC_CS_CONST | 40789b0bd4cSmacallan FFB_PPC_XS_WID | FFB_PPC_YS_CONST | FFB_PPC_ZS_CONST | 40889b0bd4cSmacallan FFB_PPC_DCE_DISABLE | FFB_PPC_ABE_DISABLE | FFB_PPC_TBE_OPAQUE); 40989b0bd4cSmacallan pFfb->wid_cache = pFfb->wid; 41089b0bd4cSmacallan pFfb->pmask_cache = ~0; 41189b0bd4cSmacallan pFfb->rop_cache = (FFB_ROP_NEW | (FFB_ROP_NEW << 8)); 41289b0bd4cSmacallan pFfb->drawop_cache = FFB_DRAWOP_RECTANGLE; 41389b0bd4cSmacallan pFfb->fg_cache = pFfb->bg_cache = 0; 41489b0bd4cSmacallan pFfb->fontw_cache = 32; 41589b0bd4cSmacallan pFfb->fontinc_cache = (1 << 16) | 0; 41689b0bd4cSmacallan pFfb->fbc_cache = (FFB_FBC_WB_A | FFB_FBC_WM_COMBINED | FFB_FBC_RB_A | 41789b0bd4cSmacallan FFB_FBC_WE_FORCEON | 41889b0bd4cSmacallan FFB_FBC_SB_BOTH | 41989b0bd4cSmacallan FFB_FBC_ZE_OFF | FFB_FBC_YE_OFF | 42089b0bd4cSmacallan FFB_FBC_RGBE_OFF | 42189b0bd4cSmacallan FFB_FBC_XE_ON); 42289b0bd4cSmacallan 42389b0bd4cSmacallan /* We will now clear the screen: we'll draw a rectangle covering all the 42489b0bd4cSmacallan * viewscreen, using a 'blackness' ROP. 42589b0bd4cSmacallan */ 42689b0bd4cSmacallan FFBFifo(pFfb, 22); 42789b0bd4cSmacallan ffb->fbc = pFfb->fbc_cache; 42889b0bd4cSmacallan ffb->ppc = pFfb->ppc_cache; 42989b0bd4cSmacallan ffb->wid = pFfb->wid_cache; 43089b0bd4cSmacallan ffb->xpmask = 0xff; 43189b0bd4cSmacallan ffb->pmask = pFfb->pmask_cache; 43289b0bd4cSmacallan ffb->rop = pFfb->rop_cache; 43389b0bd4cSmacallan ffb->drawop = pFfb->drawop_cache; 43489b0bd4cSmacallan ffb->fg = pFfb->fg_cache; 43589b0bd4cSmacallan ffb->bg = pFfb->bg_cache; 43689b0bd4cSmacallan ffb->fontw = pFfb->fontw_cache; 43789b0bd4cSmacallan ffb->fontinc = pFfb->fontinc_cache; 43889b0bd4cSmacallan ffb->xclip = FFB_XCLIP_TEST_ALWAYS; 43989b0bd4cSmacallan ffb->cmp = 0x80808080; 44089b0bd4cSmacallan ffb->matchab = 0x80808080; 44189b0bd4cSmacallan ffb->magnab = 0x80808080; 44289b0bd4cSmacallan ffb->blendc = (FFB_BLENDC_FORCE_ONE | 44389b0bd4cSmacallan FFB_BLENDC_DF_ONE_M_A | 44489b0bd4cSmacallan FFB_BLENDC_SF_A); 44589b0bd4cSmacallan ffb->blendc1 = 0; 44689b0bd4cSmacallan ffb->blendc2 = 0; 44789b0bd4cSmacallan FFB_WRITE64(&ffb->by, 0, 0); 44889b0bd4cSmacallan FFB_WRITE64_2(&ffb->bh, pFfb->psdp->height, pFfb->psdp->width); 44989b0bd4cSmacallan FFBWait(pFfb, ffb); 45089b0bd4cSmacallan 45189b0bd4cSmacallan FFB_ATTR_SFB_VAR_XAA(pFfb, 0xffffffff, GXcopy); 45289b0bd4cSmacallan FFBWait(pFfb, ffb); 45389b0bd4cSmacallan 454504f16bcSmacallan FFB_HardwareSetup(pFfb); 45589b0bd4cSmacallan pExa = exaDriverAlloc(); 45689b0bd4cSmacallan if (!pExa) 45789b0bd4cSmacallan return FALSE; 45889b0bd4cSmacallan 45989b0bd4cSmacallan pFfb->pExa = pExa; 46089b0bd4cSmacallan 46189b0bd4cSmacallan pExa->exa_major = EXA_VERSION_MAJOR; 46289b0bd4cSmacallan pExa->exa_minor = EXA_VERSION_MINOR; 46389b0bd4cSmacallan 46489b0bd4cSmacallan 46589b0bd4cSmacallan pExa->memoryBase = (char *)pFfb->sfb32; 46689b0bd4cSmacallan /* 46789b0bd4cSmacallan * we don't have usable off-screen memory but EXA craps out if we don't 46889b0bd4cSmacallan * pretend that we do, so register a ridiculously small amount and 46989b0bd4cSmacallan * cross fingers 47089b0bd4cSmacallan */ 47189b0bd4cSmacallan pExa->memorySize = 8192 * pFfb->psdp->height + 4; 47289b0bd4cSmacallan pExa->offScreenBase = pExa->memorySize - 4; 47389b0bd4cSmacallan 47489b0bd4cSmacallan /* we want to use 64bit aligned accesses */ 47589b0bd4cSmacallan pExa->pixmapOffsetAlign = 8; 47689b0bd4cSmacallan pExa->pixmapPitchAlign = 8; 47789b0bd4cSmacallan 47889b0bd4cSmacallan pExa->flags = EXA_OFFSCREEN_PIXMAPS | 47989b0bd4cSmacallan /*EXA_SUPPORTS_OFFSCREEN_OVERLAPS |*/ 48089b0bd4cSmacallan EXA_MIXED_PIXMAPS; 48189b0bd4cSmacallan 48289b0bd4cSmacallan pExa->maxX = 2048; 48389b0bd4cSmacallan pExa->maxY = 2048; 48489b0bd4cSmacallan 48589b0bd4cSmacallan pExa->WaitMarker = FFBWaitMarker; 48689b0bd4cSmacallan 48789b0bd4cSmacallan pExa->PrepareSolid = FFBPrepareSolid; 48889b0bd4cSmacallan pExa->Solid = FFBSolid; 48989b0bd4cSmacallan pExa->DoneSolid = FFBDoneCopy; 490504f16bcSmacallan 49189b0bd4cSmacallan pExa->PrepareCopy = FFBPrepareCopy; 49289b0bd4cSmacallan pExa->Copy = FFBCopy; 49389b0bd4cSmacallan pExa->DoneCopy = FFBDoneCopy; 494504f16bcSmacallan 49589b0bd4cSmacallan pExa->UploadToScreen = FFBUploadToScreen; 49689b0bd4cSmacallan pExa->DownloadFromScreen = FFBDownloadFromScreen; 497504f16bcSmacallan 49889b0bd4cSmacallan pExa->PrepareAccess = FFBPrepareAccess; 49989b0bd4cSmacallan pExa->FinishAccess = FFBFinishAccess; 50089b0bd4cSmacallan 501504f16bcSmacallanif(0) { 502504f16bcSmacallan pExa->CheckComposite = FFBCheckComposite; 503504f16bcSmacallan pExa->PrepareComposite = FFBPrepareComposite; 504504f16bcSmacallan pExa->Composite = FFBComposite; 505504f16bcSmacallan pExa->DoneComposite = FFBDoneCopy; 506504f16bcSmacallan} 50789b0bd4cSmacallan return exaDriverInit(pScreen, pExa); 50889b0bd4cSmacallan} 509