1b3d5324cSmacallan/* 2b3d5324cSmacallan * Copyright 1997-2001 by Alan Hourihane, Wigan, England. 3b3d5324cSmacallan * Copyright 2016 by Michael Lorenz 4b3d5324cSmacallan * 5b3d5324cSmacallan * Permission to use, copy, modify, distribute, and sell this software and its 6b3d5324cSmacallan * documentation for any purpose is hereby granted without fee, provided that 7b3d5324cSmacallan * the above copyright notice appear in all copies and that both that 8b3d5324cSmacallan * copyright notice and this permission notice appear in supporting 9b3d5324cSmacallan * documentation, and that the name of Alan Hourihane not be used in 10b3d5324cSmacallan * advertising or publicity pertaining to distribution of the software without 11b3d5324cSmacallan * specific, written prior permission. Alan Hourihane makes no representations 12b3d5324cSmacallan * about the suitability of this software for any purpose. It is provided 13b3d5324cSmacallan * "as is" without express or implied warranty. 14b3d5324cSmacallan * 15b3d5324cSmacallan * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 16b3d5324cSmacallan * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 17b3d5324cSmacallan * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR 18b3d5324cSmacallan * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 19b3d5324cSmacallan * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 20b3d5324cSmacallan * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 21b3d5324cSmacallan * PERFORMANCE OF THIS SOFTWARE. 22b3d5324cSmacallan * 23b3d5324cSmacallan * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk> 24b3d5324cSmacallan * Dirk Hohndel, <hohndel@suse.de> 25b3d5324cSmacallan * Stefan Dirsch, <sndirsch@suse.de> 26b3d5324cSmacallan * Mark Vojkovich, <mvojkovi@ucsd.edu> 27b3d5324cSmacallan * Michel Dänzer, <michdaen@iiic.ethz.ch> 28b3d5324cSmacallan * 29b3d5324cSmacallan * this work is sponsored by S.u.S.E. GmbH, Fuerth, Elsa GmbH, Aachen and 30b3d5324cSmacallan * Siemens Nixdorf Informationssysteme 31b3d5324cSmacallan * 32b3d5324cSmacallan * Permedia 2 accelerated options, EXA style. 33b3d5324cSmacallan */ 34b3d5324cSmacallan 35b3d5324cSmacallan#ifdef HAVE_CONFIG_H 36b3d5324cSmacallan#include "config.h" 37b3d5324cSmacallan#endif 38b3d5324cSmacallan 39b3d5324cSmacallan#include <X11/Xarch.h> 40b3d5324cSmacallan#include "xf86.h" 41b3d5324cSmacallan#include "xf86_OSproc.h" 42b3d5324cSmacallan 43b3d5324cSmacallan#include "xf86Pci.h" 44b3d5324cSmacallan 45b3d5324cSmacallan#include "glint_regs.h" 46b3d5324cSmacallan#include "glint.h" 47b3d5324cSmacallan 48a3890ad9Smacallan/*#define PM2_DEBUG*/ 49b3d5324cSmacallan 50b3d5324cSmacallan#ifdef PM2_DEBUG 51b3d5324cSmacallan#define STATIC static 52b3d5324cSmacallan#define ENTER xf86Msg(X_ERROR, "%s>\n", __func__); 53b3d5324cSmacallan#define DPRINTF xf86Msg 54b3d5324cSmacallan#else 55b3d5324cSmacallan#define ENTER 56b3d5324cSmacallan#define STATIC 57b3d5324cSmacallan#define DPRINTF while (0) xf86Msg 58b3d5324cSmacallan#endif 59b3d5324cSmacallan 60a3890ad9Smacallanint src_formats[] = {PICT_a8r8g8b8, PICT_x8r8g8b8, 61a3890ad9Smacallan PICT_a8b8g8r8, PICT_x8b8g8r8}; 62a3890ad9Smacallanint tex_formats[] = {PICT_a8r8g8b8, PICT_a8b8g8r8}; 63a3890ad9Smacallan 64a3890ad9Smacallanstatic uint32_t Pm2BlendOps[] = { 65a3890ad9Smacallan /* Clear */ 66a3890ad9Smacallan ABM_SrcZERO | ABM_DstZERO, 67a3890ad9Smacallan /* Src */ 68a3890ad9Smacallan ABM_SrcONE | ABM_DstZERO, 69a3890ad9Smacallan /* Dst */ 70a3890ad9Smacallan ABM_SrcZERO | ABM_DstONE, 71a3890ad9Smacallan /* Over */ 72a3890ad9Smacallan ABM_SrcONE | ABM_DstONE_MINUS_SRC_ALPHA, 73a3890ad9Smacallan /* OverReverse */ 74a3890ad9Smacallan ABM_SrcONE_MINUS_DST_ALPHA | ABM_DstONE, 75a3890ad9Smacallan /* In */ 76a3890ad9Smacallan ABM_SrcDST_ALPHA | ABM_DstZERO, 77a3890ad9Smacallan /* InReverse */ 78a3890ad9Smacallan ABM_SrcZERO | ABM_DstSRC_ALPHA, 79a3890ad9Smacallan /* Out */ 80a3890ad9Smacallan ABM_SrcONE_MINUS_DST_ALPHA | ABM_DstZERO, 81a3890ad9Smacallan /* OutReverse */ 82a3890ad9Smacallan ABM_SrcZERO | ABM_DstONE_MINUS_SRC_ALPHA, 83a3890ad9Smacallan /* Atop */ 84a3890ad9Smacallan ABM_SrcDST_ALPHA | ABM_DstONE_MINUS_SRC_ALPHA, 85a3890ad9Smacallan /* AtopReverse */ 86a3890ad9Smacallan ABM_SrcONE_MINUS_DST_ALPHA | ABM_DstSRC_ALPHA, 87a3890ad9Smacallan /* Xor */ 88a3890ad9Smacallan ABM_SrcONE_MINUS_DST_ALPHA | ABM_DstONE_MINUS_SRC_ALPHA, 89a3890ad9Smacallan /* Add */ 90a3890ad9Smacallan ABM_SrcONE | ABM_DstONE 91a3890ad9Smacallan}; 92a3890ad9Smacallan 93a3890ad9Smacallan#define arraysize(ary) (sizeof(ary) / sizeof(ary[0])) 94a3890ad9Smacallan 95b3d5324cSmacallanSTATIC void 96b3d5324cSmacallanPm2WaitMarker(ScreenPtr pScreen, int Marker) 97b3d5324cSmacallan{ 98b3d5324cSmacallan ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 99b3d5324cSmacallan 100b3d5324cSmacallan Permedia2Sync(pScrn); 101b3d5324cSmacallan} 102b3d5324cSmacallan 103b3d5324cSmacallanSTATIC Bool 104b3d5324cSmacallanPm2PrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, 105b3d5324cSmacallan int xdir, int ydir, int rop, Pixel planemask) 106b3d5324cSmacallan{ 107b3d5324cSmacallan ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum]; 108b3d5324cSmacallan GLINTPtr pGlint = GLINTPTR(pScrn); 109b3d5324cSmacallan 110b3d5324cSmacallan ENTER; 111b3d5324cSmacallan 112b3d5324cSmacallan pGlint->BltScanDirection = 0; 113b3d5324cSmacallan if (xdir == 1) pGlint->BltScanDirection |= XPositive; 114b3d5324cSmacallan if (ydir == 1) pGlint->BltScanDirection |= YPositive; 115b3d5324cSmacallan 116a3890ad9Smacallan GLINT_WAIT(6); 117b3d5324cSmacallan DO_PLANEMASK(planemask); 118a3890ad9Smacallan GLINT_WRITE_REG(UNIT_DISABLE, AlphaBlendMode); 119a3890ad9Smacallan GLINT_WRITE_REG(UNIT_DISABLE, DitherMode); 120a3890ad9Smacallan GLINT_WRITE_REG(UNIT_DISABLE, TextureAddressMode); 121b3d5324cSmacallan 122b3d5324cSmacallan GLINT_WRITE_REG(UNIT_DISABLE, ColorDDAMode); 123b3d5324cSmacallan if ((rop == GXset) || (rop == GXclear)) { 124b3d5324cSmacallan pGlint->FrameBufferReadMode = pGlint->pprod; 125b3d5324cSmacallan } else 126b3d5324cSmacallan if ((rop == GXcopy) || (rop == GXcopyInverted)) { 127b3d5324cSmacallan pGlint->FrameBufferReadMode = pGlint->pprod |FBRM_SrcEnable; 128b3d5324cSmacallan } else { 129b3d5324cSmacallan pGlint->FrameBufferReadMode = pGlint->pprod | FBRM_SrcEnable | 130b3d5324cSmacallan FBRM_DstEnable; 131b3d5324cSmacallan } 132b3d5324cSmacallan LOADROP(rop); 133b3d5324cSmacallan pGlint->srcoff = exaGetPixmapOffset(pSrcPixmap); 134b3d5324cSmacallan return TRUE; 135b3d5324cSmacallan} 136b3d5324cSmacallan 137b3d5324cSmacallanSTATIC void 138b3d5324cSmacallanPm2Copy(PixmapPtr pDstPixmap, 139b3d5324cSmacallan int srcX, int srcY, int dstX, int dstY, int w, int h) 140b3d5324cSmacallan{ 141b3d5324cSmacallan ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum]; 142b3d5324cSmacallan GLINTPtr pGlint = GLINTPTR(pScrn); 143b3d5324cSmacallan int align; 144b3d5324cSmacallan int dstoff = exaGetPixmapOffset(pDstPixmap); 145b3d5324cSmacallan int pitch = exaGetPixmapPitch(pDstPixmap); 146b3d5324cSmacallan 147b3d5324cSmacallan ENTER; 148b3d5324cSmacallan 149b3d5324cSmacallan /* assuming constant pitch for now */ 150b3d5324cSmacallan srcY += pGlint->srcoff / pitch; 151b3d5324cSmacallan dstY += dstoff / pitch; 152b3d5324cSmacallan 153b3d5324cSmacallan /* We can only use GXcopy for Packed modes */ 154b3d5324cSmacallan if ((pGlint->ROP != GXcopy) || (pScrn->bitsPerPixel != 8)) { 155b3d5324cSmacallan GLINT_WAIT(5); 156b3d5324cSmacallan GLINT_WRITE_REG(pGlint->FrameBufferReadMode, FBReadMode); 157b3d5324cSmacallan Permedia2LoadCoord(pScrn, dstX, dstY, w, h); 158b3d5324cSmacallan GLINT_WRITE_REG(((srcY - dstY) & 0x0FFF) << 16 | 159b3d5324cSmacallan ((srcX - dstX) & 0x0FFF), FBSourceDelta); 160b3d5324cSmacallan } else { 161b3d5324cSmacallan align = (dstX & pGlint->bppalign) - (srcX & pGlint->bppalign); 162b3d5324cSmacallan GLINT_WAIT(6); 163b3d5324cSmacallan GLINT_WRITE_REG(pGlint->FrameBufferReadMode|FBRM_Packed, FBReadMode); 164b3d5324cSmacallan Permedia2LoadCoord(pScrn, dstX >> pGlint->BppShift, dstY, 165b3d5324cSmacallan (w + 7) >> pGlint->BppShift, h); 166b3d5324cSmacallan GLINT_WRITE_REG(align << 29 | dstX << 16 | (dstX + w), PackedDataLimits); 167b3d5324cSmacallan GLINT_WRITE_REG(((srcX - dstX) & 0x0FFF) << 16 | 168b3d5324cSmacallan (((srcX & ~pGlint->bppalign) - (dstX & ~pGlint->bppalign)) & 0x0FFF), 169b3d5324cSmacallan FBSourceDelta); 170b3d5324cSmacallan } 171b3d5324cSmacallan GLINT_WRITE_REG(PrimitiveRectangle | pGlint->BltScanDirection, Render); 172b3d5324cSmacallan} 173b3d5324cSmacallan 174b3d5324cSmacallanSTATIC void 175b3d5324cSmacallanPm2DoneCopy(PixmapPtr pPixmap) 176b3d5324cSmacallan{ 177b3d5324cSmacallan ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum]; 178b3d5324cSmacallan GLINTPtr pGlint = GLINTPTR(pScrn); 179b3d5324cSmacallan 180b3d5324cSmacallan} 181b3d5324cSmacallan 182b3d5324cSmacallanSTATIC Bool 183b3d5324cSmacallanPm2PrepareSolid(PixmapPtr pPixmap, int rop, Pixel planemask, Pixel color) 184b3d5324cSmacallan{ 185b3d5324cSmacallan ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum]; 186b3d5324cSmacallan GLINTPtr pGlint = GLINTPTR(pScrn); 187b3d5324cSmacallan 188b3d5324cSmacallan ENTER; 189b3d5324cSmacallan 190b3d5324cSmacallan REPLICATE(color); 191b3d5324cSmacallan 192a3890ad9Smacallan GLINT_WAIT(8); 193a3890ad9Smacallan GLINT_WRITE_REG(UNIT_DISABLE, AlphaBlendMode); 194a3890ad9Smacallan GLINT_WRITE_REG(UNIT_DISABLE, DitherMode); 195a3890ad9Smacallan GLINT_WRITE_REG(UNIT_DISABLE, TextureAddressMode); 196b3d5324cSmacallan DO_PLANEMASK(planemask); 197b3d5324cSmacallan if (rop == GXcopy) { 198b3d5324cSmacallan GLINT_WRITE_REG(UNIT_DISABLE, ColorDDAMode); 199b3d5324cSmacallan GLINT_WRITE_REG(pGlint->pprod, FBReadMode); 200b3d5324cSmacallan GLINT_WRITE_REG(color, FBBlockColor); 201b3d5324cSmacallan } else { 202b3d5324cSmacallan GLINT_WRITE_REG(UNIT_ENABLE, ColorDDAMode); 203b3d5324cSmacallan GLINT_WRITE_REG(color, ConstantColor); 204b3d5324cSmacallan /* We can use Packed mode for filling solid non-GXcopy rasters */ 205b3d5324cSmacallan GLINT_WRITE_REG(pGlint->pprod|FBRM_DstEnable|FBRM_Packed, FBReadMode); 206b3d5324cSmacallan } 207b3d5324cSmacallan LOADROP(rop); 208b3d5324cSmacallan 209b3d5324cSmacallan return TRUE; 210b3d5324cSmacallan} 211b3d5324cSmacallan 212b3d5324cSmacallanSTATIC void 213b3d5324cSmacallanPm2Solid(PixmapPtr pPixmap, int x1, int y1, int x2, int y2) 214b3d5324cSmacallan{ 215b3d5324cSmacallan ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum]; 216b3d5324cSmacallan GLINTPtr pGlint = GLINTPTR(pScrn); 217b3d5324cSmacallan int offset = exaGetPixmapOffset(pPixmap); 218b3d5324cSmacallan int pitch = exaGetPixmapPitch(pPixmap); 219b3d5324cSmacallan int w = x2 - x1, h = y2 - y1; 220b3d5324cSmacallan int speed = 0; 221b3d5324cSmacallan 222b3d5324cSmacallan ENTER; 223b3d5324cSmacallan 224b3d5324cSmacallan y1 += offset / pitch; 225b3d5324cSmacallan if (pGlint->ROP == GXcopy) { 226b3d5324cSmacallan GLINT_WAIT(3); 227b3d5324cSmacallan Permedia2LoadCoord(pScrn, x1, y1, w, h); 228b3d5324cSmacallan speed = FastFillEnable; 229b3d5324cSmacallan } else { 230b3d5324cSmacallan GLINT_WAIT(4); 231b3d5324cSmacallan Permedia2LoadCoord(pScrn, x1 >> pGlint->BppShift, y1, 232b3d5324cSmacallan (w + 7) >> pGlint->BppShift, h); 233b3d5324cSmacallan GLINT_WRITE_REG(x1 << 16 | (x1 + w), PackedDataLimits); 234b3d5324cSmacallan speed = 0; 235b3d5324cSmacallan } 236b3d5324cSmacallan GLINT_WRITE_REG(PrimitiveRectangle | XPositive | YPositive | speed, Render); 237b3d5324cSmacallan} 238b3d5324cSmacallan 239b3d5324cSmacallan/* 240b3d5324cSmacallan * Memcpy-based UTS. 241b3d5324cSmacallan */ 242b3d5324cSmacallanSTATIC Bool 243b3d5324cSmacallanPm2UploadToScreen(PixmapPtr pDst, int x, int y, int w, int h, 244b3d5324cSmacallan char *src, int src_pitch) 245b3d5324cSmacallan{ 246b3d5324cSmacallan ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum]; 247b3d5324cSmacallan GLINTPtr pGlint = GLINTPTR(pScrn); 248c2fa0f52Smacallan int offset = exaGetPixmapOffset(pDst); 249c2fa0f52Smacallan unsigned char *dst = pGlint->FbBase + offset; 250c2fa0f52Smacallan CARD32 *s; 251c2fa0f52Smacallan int dst_pitch = exaGetPixmapPitch(pDst); 252b3d5324cSmacallan 253b3d5324cSmacallan int bpp = pDst->drawable.bitsPerPixel; 254b3d5324cSmacallan int cpp = (bpp + 7) >> 3; 255b3d5324cSmacallan int wBytes = w * cpp; 256a2587576Smacallan int xx, i, fs = pGlint->FIFOSize, chunk, adr; 257b3d5324cSmacallan 258b3d5324cSmacallan ENTER; 259b3d5324cSmacallan 260a2587576Smacallan if (bpp < 24) { 261a2587576Smacallan /* for now */ 262a2587576Smacallan dst += (x * cpp) + (y * dst_pitch); 263b3d5324cSmacallan 264a2587576Smacallan Permedia2Sync(pScrn); 265a2587576Smacallan 266a2587576Smacallan while (h--) { 267a2587576Smacallan memcpy(dst, src, wBytes); 268a2587576Smacallan src += src_pitch; 269a2587576Smacallan dst += dst_pitch; 270a2587576Smacallan } 271a2587576Smacallan } else { 272a2587576Smacallan /* use host blit */ 273a2587576Smacallan y += offset / dst_pitch; 274a2587576Smacallan adr = y * (dst_pitch >> 2) + x; 275a3890ad9Smacallan DPRINTF(X_ERROR, "%d %d\n", x, y); 276a2587576Smacallan while (h--) { 277c2fa0f52Smacallan s = (CARD32 *)src; 278a2587576Smacallan xx = w; 279a3890ad9Smacallan GLINT_WAIT(2); 280a3890ad9Smacallan DO_PLANEMASK(0xffffffff); 281a2587576Smacallan GLINT_WRITE_REG(adr, TextureDownloadOffset); 282a2587576Smacallan while (xx > 0) { 283a2587576Smacallan chunk = min(fs - 1, xx); 284a2587576Smacallan GLINT_WAIT(chunk); 285a2587576Smacallan GLINT_WRITE_REG(((chunk - 1) << 16) | (0x11 << 4) | 286a2587576Smacallan 0x0d, OutputFIFO); 287a2587576Smacallan GLINT_MoveDWORDS( 288a2587576Smacallan (CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4), 289a2587576Smacallan s, chunk); 290a2587576Smacallan xx -= chunk; 291a2587576Smacallan s += chunk; 292a2587576Smacallan } 293a2587576Smacallan adr += (dst_pitch >> 2); 294a2587576Smacallan src += src_pitch; 295a2587576Smacallan } 296a2587576Smacallan exaMarkSync(pDst->drawable.pScreen); 297b3d5324cSmacallan } 298b3d5324cSmacallan return TRUE; 299b3d5324cSmacallan} 300b3d5324cSmacallan 301b3d5324cSmacallan/* 302b3d5324cSmacallan * Memcpy-based DFS. 303b3d5324cSmacallan */ 304b3d5324cSmacallanSTATIC Bool 305b3d5324cSmacallanPm2DownloadFromScreen(PixmapPtr pSrc, int x, int y, int w, int h, 306b3d5324cSmacallan char *dst, int dst_pitch) 307b3d5324cSmacallan{ 308b3d5324cSmacallan ScrnInfoPtr pScrn = xf86Screens[pSrc->drawable.pScreen->myNum]; 309c2fa0f52Smacallan GLINTPtr pGlint = GLINTPTR(pScrn); 310c2fa0f52Smacallan unsigned char *src = pGlint->FbBase + exaGetPixmapOffset(pSrc); 311c2fa0f52Smacallan int src_pitch = exaGetPixmapPitch(pSrc); 312b3d5324cSmacallan 313b3d5324cSmacallan ENTER; 314b3d5324cSmacallan int bpp = pSrc->drawable.bitsPerPixel; 315b3d5324cSmacallan int cpp = (bpp + 7) >> 3; 316b3d5324cSmacallan int wBytes = w * cpp; 317b3d5324cSmacallan 318b3d5324cSmacallan src += (x * cpp) + (y * src_pitch); 319b3d5324cSmacallan 3204bd90d63Smacallan Permedia2Sync(pScrn); 321b3d5324cSmacallan 322b3d5324cSmacallan while (h--) { 323b3d5324cSmacallan memcpy(dst, src, wBytes); 324b3d5324cSmacallan src += src_pitch; 325b3d5324cSmacallan dst += dst_pitch; 326b3d5324cSmacallan } 327b3d5324cSmacallan 328b3d5324cSmacallan return TRUE; 329b3d5324cSmacallan} 330b3d5324cSmacallan 331a3890ad9SmacallanBool 332a3890ad9SmacallanPm2CheckComposite(int op, PicturePtr pSrcPicture, 333a3890ad9Smacallan PicturePtr pMaskPicture, 334a3890ad9Smacallan PicturePtr pDstPicture) 335a3890ad9Smacallan{ 336a3890ad9Smacallan int i, ok = FALSE; 337a3890ad9Smacallan 338a3890ad9Smacallan ENTER; 339a3890ad9Smacallan 340a3890ad9Smacallan i = 0; 341a3890ad9Smacallan while ((i < arraysize(src_formats)) && (!ok)) { 342a3890ad9Smacallan ok = (pSrcPicture->format == src_formats[i]); 343a3890ad9Smacallan i++; 344a3890ad9Smacallan } 345a3890ad9Smacallan 346a3890ad9Smacallan if (!ok) { 347a3890ad9Smacallan DPRINTF(X_ERROR, "%s: unsupported src format %x\n", 348a3890ad9Smacallan __func__, pSrcPicture->format); 349a3890ad9Smacallan return FALSE; 350a3890ad9Smacallan } 351a3890ad9Smacallan 352a3890ad9Smacallan if (pDstPicture != NULL) { 353a3890ad9Smacallan i = 0; 354a3890ad9Smacallan while ((i < arraysize(src_formats)) && (!ok)) { 355a3890ad9Smacallan ok = (pDstPicture->format == src_formats[i]); 356a3890ad9Smacallan i++; 357a3890ad9Smacallan } 358a3890ad9Smacallan 359a3890ad9Smacallan if (!ok) { 360a3890ad9Smacallan DPRINTF(X_ERROR, "%s: unsupported dst format %x\n", 361a3890ad9Smacallan __func__, pDstPicture->format); 362a3890ad9Smacallan return FALSE; 363a3890ad9Smacallan } 364a3890ad9Smacallan } 365a3890ad9Smacallan 366a3890ad9Smacallan DPRINTF(X_ERROR, "src is %x, %d\n", pSrcPicture->format, op); 367a3890ad9Smacallan 368a3890ad9Smacallan if (pMaskPicture != NULL) { 369a3890ad9Smacallan i = 0; 370a3890ad9Smacallan ok = FALSE; 371a3890ad9Smacallan while ((i < arraysize(tex_formats)) && (!ok)) { 372a3890ad9Smacallan ok = (pMaskPicture->format == tex_formats[i]); 373a3890ad9Smacallan i++; 374a3890ad9Smacallan } 375a3890ad9Smacallan if (!ok) { 376a3890ad9Smacallan DPRINTF(X_ERROR, "%s: unsupported mask format %x\n", 377a3890ad9Smacallan __func__, pMaskPicture->format); 378a3890ad9Smacallan return FALSE; 379a3890ad9Smacallan } 380a3890ad9Smacallan DPRINTF(X_ERROR, "mask is %x %d %d\n", pMaskPicture->format, 381a3890ad9Smacallan pMaskPicture->pDrawable->width, 382a3890ad9Smacallan pMaskPicture->pDrawable->height); 383a3890ad9Smacallan if (op != PictOpOver) 384a3890ad9Smacallan return FALSE; 385a3890ad9Smacallan } 386a3890ad9Smacallan DPRINTF(X_ERROR, "true\n"); 387a3890ad9Smacallan return TRUE; 388a3890ad9Smacallan} 389a3890ad9Smacallan 390a3890ad9SmacallanBool 391a3890ad9SmacallanPm2PrepareComposite(int op, PicturePtr pSrcPicture, 392a3890ad9Smacallan PicturePtr pMaskPicture, 393a3890ad9Smacallan PicturePtr pDstPicture, 394a3890ad9Smacallan PixmapPtr pSrc, 395a3890ad9Smacallan PixmapPtr pMask, 396a3890ad9Smacallan PixmapPtr pDst) 397a3890ad9Smacallan{ 398a3890ad9Smacallan ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum]; 399a3890ad9Smacallan GLINTPtr pGlint = GLINTPTR(pScrn); 400a3890ad9Smacallan 401a3890ad9Smacallan ENTER; 402a3890ad9Smacallan 403a3890ad9Smacallan pGlint->no_source_pixmap = FALSE; 404a3890ad9Smacallan pGlint->source_is_solid = FALSE; 405a3890ad9Smacallan 406a3890ad9Smacallan if (pSrcPicture->pSourcePict != NULL) { 407a3890ad9Smacallan if (pSrcPicture->pSourcePict->type == SourcePictTypeSolidFill) { 408a3890ad9Smacallan pGlint->fillcolour = 409a3890ad9Smacallan pSrcPicture->pSourcePict->solidFill.color; 410a3890ad9Smacallan DPRINTF(X_ERROR, "%s: solid src %08x\n", 411a3890ad9Smacallan __func__, pGlint->fillcolour); 412a3890ad9Smacallan pGlint->no_source_pixmap = TRUE; 413a3890ad9Smacallan pGlint->source_is_solid = TRUE; 414a3890ad9Smacallan } 415a3890ad9Smacallan } 416a3890ad9Smacallan if ((pMaskPicture != NULL) && (pMaskPicture->pSourcePict != NULL)) { 417a3890ad9Smacallan if (pMaskPicture->pSourcePict->type == 418a3890ad9Smacallan SourcePictTypeSolidFill) { 419a3890ad9Smacallan pGlint->fillcolour = 420a3890ad9Smacallan pMaskPicture->pSourcePict->solidFill.color; 421a3890ad9Smacallan DPRINTF(X_ERROR, "%s: solid mask %08x\n", 422a3890ad9Smacallan __func__, pGlint->fillcolour); 423a3890ad9Smacallan } 424a3890ad9Smacallan } 425a3890ad9Smacallan if (pMaskPicture != NULL) { 426a3890ad9Smacallan pGlint->mskoff = exaGetPixmapOffset(pMask); 427a3890ad9Smacallan pGlint->mskpitch = exaGetPixmapPitch(pMask); 428a3890ad9Smacallan pGlint->mskformat = pMaskPicture->format; 429a3890ad9Smacallan } else { 430a3890ad9Smacallan pGlint->mskoff = 0; 431a3890ad9Smacallan pGlint->mskpitch = 0; 432a3890ad9Smacallan pGlint->mskformat = 0; 433a3890ad9Smacallan } 434a3890ad9Smacallan if (pSrc != NULL) { 435a3890ad9Smacallan pGlint->source_is_solid = 436a3890ad9Smacallan ((pSrc->drawable.width == 1) && (pSrc->drawable.height == 1)); 437a3890ad9Smacallan pGlint->srcoff = exaGetPixmapOffset(pSrc); 438a3890ad9Smacallan pGlint->srcpitch = exaGetPixmapPitch(pSrc); 439a3890ad9Smacallan if (pGlint->source_is_solid) { 440a3890ad9Smacallan pGlint->fillcolour = exaGetPixmapFirstPixel(pSrc); 441a3890ad9Smacallan } 442a3890ad9Smacallan } 443a3890ad9Smacallan pGlint->srcformat = pSrcPicture->format; 444a3890ad9Smacallan pGlint->dstformat = pDstPicture->format; 445a3890ad9Smacallan 446a3890ad9Smacallan 447a3890ad9Smacallan pGlint->op = op; 448a3890ad9Smacallan /* first things first */ 449a3890ad9Smacallan if (pGlint->source_is_solid) 450a3890ad9Smacallan goto ok; 451a3890ad9Smacallan if (pGlint->mskpitch == 0) 452a3890ad9Smacallan goto ok; 453a3890ad9Smacallan DPRINTF(X_ERROR, "nope\n"); 454a3890ad9Smacallan return FALSE; 455a3890ad9Smacallanok: 456a3890ad9Smacallan GLINT_WAIT(10); 457a3890ad9Smacallan GLINT_WRITE_REG(UNIT_DISABLE, ColorDDAMode); 458a3890ad9Smacallan LOADROP(GXcopy); 459a3890ad9Smacallan GLINT_WRITE_REG(0, QStart); 460a3890ad9Smacallan GLINT_WRITE_REG(0, dQdx); 461a3890ad9Smacallan GLINT_WRITE_REG(0, dQdyDom); 462a3890ad9Smacallan GLINT_WRITE_REG(0x20, PMTextureDataFormat); 463a3890ad9Smacallan GLINT_WRITE_REG(1 << 20, dSdx); 464a3890ad9Smacallan GLINT_WRITE_REG(0, dSdyDom); 465a3890ad9Smacallan GLINT_WRITE_REG(0, dTdx); 466a3890ad9Smacallan GLINT_WRITE_REG(1 << 20, dTdyDom); 467a3890ad9Smacallan return TRUE; 468a3890ad9Smacallan} 469a3890ad9Smacallan 470a3890ad9Smacallanvoid 471a3890ad9SmacallanPm2Comp_Over32Solid(ScrnInfoPtr pScrn, int maskX, int maskY, 472a3890ad9Smacallan int dstX, int dstY, 473a3890ad9Smacallan int width, int height) 474a3890ad9Smacallan{ 475a3890ad9Smacallan GLINTPtr pGlint = GLINTPTR(pScrn); 476a3890ad9Smacallan unsigned long pp; 477a3890ad9Smacallan uint32_t *m; 478a3890ad9Smacallan int i, j; 479a3890ad9Smacallan 480a3890ad9Smacallan ENTER; 481a3890ad9Smacallan 482a3890ad9Smacallan /* first blit the source colour into the mask */ 483a3890ad9Smacallan GLINT_WAIT(8); 484a3890ad9Smacallan GLINT_WRITE_REG(UNIT_DISABLE, AlphaBlendMode); 485a3890ad9Smacallan GLINT_WRITE_REG(UNIT_DISABLE, DitherMode); 486a3890ad9Smacallan GLINT_WRITE_REG(CFBRM_Packed| CWM_Enable, Config); 487a3890ad9Smacallan GLINT_WRITE_REG(pGlint->fillcolour, FBBlockColor); 488a3890ad9Smacallan DO_PLANEMASK(0x00ffffff); /* preserve alpha */ 489a3890ad9Smacallan Permedia2LoadCoord(pScrn, maskX, maskY + pGlint->mskoff / pGlint->mskpitch, width, height); 490a3890ad9Smacallan GLINT_WRITE_REG( 491a3890ad9Smacallan PrimitiveRectangle | XPositive | YPositive | FastFillEnable, 492a3890ad9Smacallan Render); 493a3890ad9Smacallan 494a3890ad9Smacallan /* now do the actual rendering */ 495a3890ad9Smacallan GLINT_WAIT(15); 496a3890ad9Smacallan 497a3890ad9Smacallan /* enable alpha blending */ 498a3890ad9Smacallan GLINT_WRITE_REG( 499a3890ad9Smacallan ABM_SrcSRC_ALPHA | ABM_DstONE_MINUS_SRC_ALPHA | 500a3890ad9Smacallan ABM_ColorOrderRGB | UNIT_ENABLE, AlphaBlendMode); 501a3890ad9Smacallan 502a3890ad9Smacallan /* not sure if we need this, everything is in ARGB anyway */ 503a3890ad9Smacallan GLINT_WRITE_REG(UNIT_ENABLE | DTM_ColorOrderRGB, DitherMode); 504a3890ad9Smacallan 505a3890ad9Smacallan /* setup for drawing the dst rectangle... */ 506a3890ad9Smacallan GLINT_WRITE_REG(CFBRM_DstEnable | /*CFBRM_Packed|*/ CWM_Enable, Config); 507a3890ad9Smacallan Permedia2LoadCoord(pScrn, dstX, dstY, width, height); 508a3890ad9Smacallan /* point at the texture, 1:1 mapping etc. */ 509a3890ad9Smacallan GLINT_WRITE_REG(pGlint->mskoff >> 2, PMTextureBaseAddress); 510a3890ad9Smacallan GLINT_WRITE_REG(1 | 0xb << 9 | 0xb << 13 | 1 << 1 | 1 << 3, PMTextureReadMode); 511a3890ad9Smacallan GLINT_WRITE_REG(1 | TextureModeCopy, TextureColorMode); 512a3890ad9Smacallan GLINT_WRITE_REG(1, TextureAddressMode); 513a3890ad9Smacallan GLINT_WRITE_REG(maskX << 20, SStart); 514a3890ad9Smacallan GLINT_WRITE_REG(maskY << 20, TStart); 515a3890ad9Smacallan GLINT_WRITE_REG(PrimitiveRectangle | XPositive | YPositive | TextureEnable, 516a3890ad9Smacallan Render); 517a3890ad9Smacallan} 518a3890ad9Smacallan 519a3890ad9Smacallanvoid 520a3890ad9SmacallanPm2Comp_Op32(ScrnInfoPtr pScrn, int op, int srcX, int srcY, 521a3890ad9Smacallan int dstX, int dstY, 522a3890ad9Smacallan int width, int height) 523a3890ad9Smacallan{ 524a3890ad9Smacallan GLINTPtr pGlint = GLINTPTR(pScrn); 525a3890ad9Smacallan 526a3890ad9Smacallan ENTER; 527a3890ad9Smacallan 528a3890ad9Smacallan GLINT_WAIT(8); 529a3890ad9Smacallan DO_PLANEMASK(0xffffffff); 530a3890ad9Smacallan 531a3890ad9Smacallan GLINT_WRITE_REG( 532a3890ad9Smacallan Pm2BlendOps[op] | 533a3890ad9Smacallan ABM_ColorOrderRGB | UNIT_ENABLE, AlphaBlendMode); 534a3890ad9Smacallan GLINT_WRITE_REG(UNIT_ENABLE | DTM_ColorOrderRGB, DitherMode); 535a3890ad9Smacallan GLINT_WRITE_REG(CFBRM_DstEnable | /*CFBRM_Packed|*/ CWM_Enable, Config); 536a3890ad9Smacallan Permedia2LoadCoord(pScrn, dstX, dstY, width, height); 537a3890ad9Smacallan GLINT_WRITE_REG(pGlint->srcoff >> 2, PMTextureBaseAddress); 538a3890ad9Smacallan GLINT_WRITE_REG(1 | 0xb << 9 | 0xb << 13 | 1 << 1 | 1 << 3, PMTextureReadMode); 539a3890ad9Smacallan GLINT_WRITE_REG(1 | TextureModeCopy, TextureColorMode); 540a3890ad9Smacallan GLINT_WRITE_REG(1, TextureAddressMode); 541a3890ad9Smacallan GLINT_WRITE_REG(srcX << 20, SStart); 542a3890ad9Smacallan GLINT_WRITE_REG(srcY << 20, TStart); 543a3890ad9Smacallan GLINT_WRITE_REG(PrimitiveRectangle | XPositive | YPositive | TextureEnable, 544a3890ad9Smacallan Render); 545a3890ad9Smacallan} 546a3890ad9Smacallan 547a3890ad9Smacallanvoid 548a3890ad9SmacallanPm2Composite(PixmapPtr pDst, int srcX, int srcY, 549a3890ad9Smacallan int maskX, int maskY, 550a3890ad9Smacallan int dstX, int dstY, 551a3890ad9Smacallan int width, int height) 552a3890ad9Smacallan{ 553a3890ad9Smacallan ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum]; 554a3890ad9Smacallan GLINTPtr pGlint = GLINTPTR(pScrn); 555a3890ad9Smacallan uint32_t dstoff, dstpitch; 556a3890ad9Smacallan 557a3890ad9Smacallan ENTER; 558a3890ad9Smacallan dstoff = exaGetPixmapOffset(pDst); 559a3890ad9Smacallan dstpitch = exaGetPixmapPitch(pDst); 560a3890ad9Smacallan dstY += dstoff / dstpitch; 561a3890ad9Smacallan if (pGlint->source_is_solid) { 562a3890ad9Smacallan switch (pGlint->op) { 563a3890ad9Smacallan case PictOpOver: 564a3890ad9Smacallan DPRINTF(X_ERROR, "Over %08x %08x, %d %d\n", 565a3890ad9Smacallan pGlint->mskformat, pGlint->dstformat, dstX, dstY); 566a3890ad9Smacallan switch (pGlint->mskformat) { 567a3890ad9Smacallan case PICT_a8r8g8b8: 568a3890ad9Smacallan case PICT_a8b8g8r8: 569a3890ad9Smacallan Pm2Comp_Over32Solid(pScrn, 570a3890ad9Smacallan maskX, maskY, 571a3890ad9Smacallan dstX, dstY, 572a3890ad9Smacallan width, height); 573a3890ad9Smacallan break; 574a3890ad9Smacallan default: 575a3890ad9Smacallan xf86Msg(X_ERROR, 576a3890ad9Smacallan "unsupported mask format\n"); 577a3890ad9Smacallan } 578a3890ad9Smacallan break; 579a3890ad9Smacallan default: 580a3890ad9Smacallan xf86Msg(X_ERROR, "unsupported op %d\n", pGlint->op); 581a3890ad9Smacallan } 582a3890ad9Smacallan } else { 583a3890ad9Smacallan Pm2Comp_Op32(pScrn, pGlint->op, srcX, srcY, dstX, dstY, width, height); 584a3890ad9Smacallan } 585a3890ad9Smacallan} 586a3890ad9Smacallan 587b3d5324cSmacallanBool 588b3d5324cSmacallanPm2InitEXA(ScreenPtr pScreen) 589b3d5324cSmacallan{ 590b3d5324cSmacallan ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 591b3d5324cSmacallan GLINTPtr pGlint = GLINTPTR(pScrn); 592b3d5324cSmacallan ExaDriverPtr pExa; 593eaa0d4a1Smacallan int stride, lines; 594b3d5324cSmacallan 595b3d5324cSmacallan ENTER; 596b3d5324cSmacallan 597b3d5324cSmacallan pExa = exaDriverAlloc(); 598b3d5324cSmacallan if (!pExa) 599b3d5324cSmacallan return FALSE; 600b3d5324cSmacallan 601b3d5324cSmacallan pGlint->pExa = pExa; 602b3d5324cSmacallan 603b3d5324cSmacallan pExa->exa_major = EXA_VERSION_MAJOR; 604b3d5324cSmacallan pExa->exa_minor = EXA_VERSION_MINOR; 605b3d5324cSmacallan 606b3d5324cSmacallan pExa->memoryBase = pGlint->FbBase; 607b3d5324cSmacallan stride = pScrn->displayWidth * (pScrn->bitsPerPixel >> 3); 608eaa0d4a1Smacallan lines = min(pGlint->FbMapSize / stride, 2047); 609eaa0d4a1Smacallan pExa->memorySize = lines * stride; 610a3890ad9Smacallan pExa->offScreenBase = stride * pScrn->virtualY; 611b3d5324cSmacallan DPRINTF(X_ERROR, "stride: %d\n", stride); 612b3d5324cSmacallan DPRINTF(X_ERROR, "pprod: %08x\n", pGlint->pprod); 613b3d5324cSmacallan pExa->offScreenBase = stride * pScrn->virtualY; 614b3d5324cSmacallan 615b3d5324cSmacallan /* for now, until I figure out how to do variable stride */ 616b3d5324cSmacallan pExa->pixmapOffsetAlign = stride; 617b3d5324cSmacallan pExa->pixmapPitchAlign = stride; 618b3d5324cSmacallan 619eaa0d4a1Smacallan pExa->flags = EXA_OFFSCREEN_PIXMAPS; 620b3d5324cSmacallan 621a3890ad9Smacallan pExa->maxX = 2047; 622a3890ad9Smacallan pExa->maxY = 2047; 623b3d5324cSmacallan 624b3d5324cSmacallan pExa->WaitMarker = Pm2WaitMarker; 625b3d5324cSmacallan 626b3d5324cSmacallan pExa->PrepareSolid = Pm2PrepareSolid; 627b3d5324cSmacallan pExa->Solid = Pm2Solid; 628b3d5324cSmacallan pExa->DoneSolid = Pm2DoneCopy; 629b3d5324cSmacallan pExa->PrepareCopy = Pm2PrepareCopy; 630b3d5324cSmacallan pExa->Copy = Pm2Copy; 631b3d5324cSmacallan pExa->DoneCopy = Pm2DoneCopy; 632b3d5324cSmacallan 633a3890ad9Smacallan if (pGlint->render) { 634a3890ad9Smacallan pExa->CheckComposite = Pm2CheckComposite; 635a3890ad9Smacallan pExa->PrepareComposite = Pm2PrepareComposite; 636a3890ad9Smacallan pExa->Composite = Pm2Composite; 637a3890ad9Smacallan pExa->DoneComposite = Pm2DoneCopy; 638a3890ad9Smacallan } 639a3890ad9Smacallan 640a3890ad9Smacallanif (0) { 641b3d5324cSmacallan pExa->UploadToScreen = Pm2UploadToScreen; 642b3d5324cSmacallan pExa->DownloadFromScreen = Pm2DownloadFromScreen; 643a3890ad9Smacallan} 644b3d5324cSmacallan Permedia2InitializeEngine(pScrn); 645b3d5324cSmacallan 646b3d5324cSmacallan return exaDriverInit(pScreen, pExa); 647b3d5324cSmacallan} 648