crime_accel.c revision 93351543
193351543Smacallan/* $NetBSD: crime_accel.c,v 1.4 2009/03/18 23:24:51 macallan Exp $ */ 2e1ea03a3Smacallan/* 3e1ea03a3Smacallan * Copyright (c) 2008 Michael Lorenz 4e1ea03a3Smacallan * All rights reserved. 5e1ea03a3Smacallan * 6e1ea03a3Smacallan * Redistribution and use in source and binary forms, with or without 7e1ea03a3Smacallan * modification, are permitted provided that the following conditions 8e1ea03a3Smacallan * are met: 9e1ea03a3Smacallan * 10e1ea03a3Smacallan * - Redistributions of source code must retain the above copyright 11e1ea03a3Smacallan * notice, this list of conditions and the following disclaimer. 12e1ea03a3Smacallan * - Redistributions in binary form must reproduce the above 13e1ea03a3Smacallan * copyright notice, this list of conditions and the following 14e1ea03a3Smacallan * disclaimer in the documentation and/or other materials provided 15e1ea03a3Smacallan * with the distribution. 16e1ea03a3Smacallan * 17e1ea03a3Smacallan * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18e1ea03a3Smacallan * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19e1ea03a3Smacallan * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 20e1ea03a3Smacallan * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 21e1ea03a3Smacallan * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 22e1ea03a3Smacallan * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 23e1ea03a3Smacallan * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24e1ea03a3Smacallan * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25e1ea03a3Smacallan * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26e1ea03a3Smacallan * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 27e1ea03a3Smacallan * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28e1ea03a3Smacallan * POSSIBILITY OF SUCH DAMAGE. 29e1ea03a3Smacallan * 30e1ea03a3Smacallan */ 31e1ea03a3Smacallan 32e1ea03a3Smacallan/* a driver for the CRIME rendering engine foundin SGI O2 workstations */ 33e1ea03a3Smacallan 34e1ea03a3Smacallan#include "crime.h" 35e1ea03a3Smacallan#include "picturestr.h" 36e1ea03a3Smacallan#include "xaalocal.h" 37e1ea03a3Smacallan 38e1ea03a3Smacallanuint32_t regcache[0x1000]; 39e1ea03a3Smacallan 40e1ea03a3Smacallan#define CRIMEREG(p) (volatile uint32_t *)(fPtr->engine + p) 41e1ea03a3Smacallan/*#define WBFLUSH { volatile uint32_t boo = *CRIMEREG(0x4000); }*/ 42e1ea03a3Smacallan#define WBFLUSH __asm__ ("nop; sync;") 43e1ea03a3Smacallan#if 0 44e1ea03a3Smacallan#define WRITE4(r, v) {if (regcache[r >> 2] != v) { \ 45e1ea03a3Smacallan *CRIMEREG(r) = v; \ 46e1ea03a3Smacallan regcache[r >> 2] = v; } } 47e1ea03a3Smacallan#else 48e1ea03a3Smacallan#define WRITE4(r, v) { *CRIMEREG(r) = v; } 49e1ea03a3Smacallan#endif 50e1ea03a3Smacallan#define WRITE4ST(r, v) {WBFLUSH; *CRIMEREG(r + CRIME_DE_START) = v; WBFLUSH;} 51e1ea03a3Smacallan#ifdef DEBUG 52e1ea03a3Smacallan#define SYNC { int bail = 0; do {bail++; } \ 53e1ea03a3Smacallan while(((*CRIMEREG(0x4000) & CRIME_DE_IDLE) == 0) && (bail < 10000000)); \ 54e1ea03a3Smacallan if (bail == 10000000) { \ 55e1ea03a3Smacallan xf86Msg(X_ERROR, "sync timeout\n"); \ 56e1ea03a3Smacallan WRITE4ST(CRIME_MTE_FLUSH, 0); \ 57e1ea03a3Smacallan WRITE4ST(CRIME_DE_FLUSH, 0); \ 58e1ea03a3Smacallan } \ 59e1ea03a3Smacallan } 60e1ea03a3Smacallan#else 61e1ea03a3Smacallan#define SYNC do {} while ((*CRIMEREG(0x4000) & CRIME_DE_IDLE) == 0) 62e1ea03a3Smacallan#endif 63e1ea03a3Smacallan#define READY do {} while ((*CRIMEREG(0x4000) & 0x0e000000) != 0x0e000000) 64e1ea03a3Smacallan 65e1ea03a3SmacallanCARD32 CrimeAlphaTextureFormats[] = {PICT_a8, 0}; 66e1ea03a3SmacallanCARD32 CrimeTextureFormats[] = {PICT_a8b8g8r8, PICT_a8r8g8b8, 0}; 67e1ea03a3Smacallan 68e1ea03a3Smacallanvoid 69e1ea03a3SmacallanCrimeSync(ScrnInfoPtr pScrn) 70e1ea03a3Smacallan{ 71e1ea03a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 72e1ea03a3Smacallan#ifdef CRIME_DEBUG_LOUD 73e1ea03a3Smacallan volatile uint32_t *status = CRIMEREG(CRIME_DE_STATUS); 74e1ea03a3Smacallan 75e1ea03a3Smacallan xf86Msg(X_ERROR, "%s: %08x\n", __func__, *status); 76e1ea03a3Smacallan#endif 77e1ea03a3Smacallan LOG(CRIME_DEBUG_SYNC); 78e1ea03a3Smacallan SYNC; 79e1ea03a3Smacallan} 80e1ea03a3Smacallan 81e1ea03a3Smacallanstatic void 82e1ea03a3SmacallanCrimeSetupForScreenToScreenCopy( 83e1ea03a3Smacallan ScrnInfoPtr pScrn, 84e1ea03a3Smacallan int xdir, 85e1ea03a3Smacallan int ydir, 86e1ea03a3Smacallan int rop, 87e1ea03a3Smacallan unsigned int planemask, 88e1ea03a3Smacallan int TransparencyColour 89e1ea03a3Smacallan) 90e1ea03a3Smacallan{ 91e1ea03a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 92e1ea03a3Smacallan 93e1ea03a3Smacallan LOG(CRIME_DEBUG_BITBLT); 94e1ea03a3Smacallan SYNC; 95e1ea03a3Smacallan#if 0 96e1ea03a3Smacallan if ((rop == GXcopy) && (planemask == 0xffffffff) && (xdir > 0)) { 97e1ea03a3Smacallan /* use the MTE */ 98e1ea03a3Smacallan WRITE4(CRIME_MTE_MODE, MTE_MODE_DST_ECC | 99e1ea03a3Smacallan MTE_TLB_A << MTE_DST_TLB_SHIFT | 100e1ea03a3Smacallan MTE_TLB_A << MTE_SRC_TLB_SHIFT | 101e1ea03a3Smacallan MTE_DEPTH_32 << MTE_DEPTH_SHIFT | 102e1ea03a3Smacallan MTE_MODE_COPY); 103e1ea03a3Smacallan fPtr->use_mte = 1; 104e1ea03a3Smacallan if (ydir > 0) { 105e1ea03a3Smacallan WRITE4(CRIME_MTE_DST_Y_STEP, 1); 106e1ea03a3Smacallan WRITE4(CRIME_MTE_SRC_Y_STEP, 1); 107e1ea03a3Smacallan } else { 108e1ea03a3Smacallan WRITE4(CRIME_MTE_DST_Y_STEP, -1); 109e1ea03a3Smacallan WRITE4(CRIME_MTE_SRC_Y_STEP, -1); 110e1ea03a3Smacallan } 111e1ea03a3Smacallan } else 112e1ea03a3Smacallan#endif 113e1ea03a3Smacallan fPtr->use_mte = 0; 114e1ea03a3Smacallan 115e1ea03a3Smacallan SYNC; 116e1ea03a3Smacallan WRITE4(CRIME_DE_XFER_STEP_X, 1); 117e1ea03a3Smacallan WRITE4(CRIME_DE_PLANEMASK, planemask); 118e1ea03a3Smacallan WRITE4(CRIME_DE_ROP, rop); 119e1ea03a3Smacallan WRITE4(CRIME_DE_DRAWMODE, 120e1ea03a3Smacallan DE_DRAWMODE_PLANEMASK | DE_DRAWMODE_BYTEMASK | 121e1ea03a3Smacallan DE_DRAWMODE_ROP | DE_DRAWMODE_XFER_EN); 122e1ea03a3Smacallan WRITE4(CRIME_DE_MODE_SRC, DE_MODE_TLB_A | DE_MODE_BUFDEPTH_32 | 123e1ea03a3Smacallan DE_MODE_TYPE_RGBA | DE_MODE_PIXDEPTH_32); 124e1ea03a3Smacallan fPtr->xdir = xdir; 125e1ea03a3Smacallan fPtr->ydir = ydir; 126e1ea03a3Smacallan DONE(CRIME_DEBUG_BITBLT); 127e1ea03a3Smacallan} 128e1ea03a3Smacallan 129e1ea03a3Smacallanstatic void 130e1ea03a3SmacallanCrimeSubsequentScreenToScreenCopy 131e1ea03a3Smacallan( 132e1ea03a3Smacallan ScrnInfoPtr pScrn, 133e1ea03a3Smacallan int xSrc, 134e1ea03a3Smacallan int ySrc, 135e1ea03a3Smacallan int xDst, 136e1ea03a3Smacallan int yDst, 137e1ea03a3Smacallan int w, 138e1ea03a3Smacallan int h 139e1ea03a3Smacallan) 140e1ea03a3Smacallan{ 141e1ea03a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 142e1ea03a3Smacallan uint32_t prim = DE_PRIM_RECTANGLE; 143e1ea03a3Smacallan volatile uint32_t reg, oreg; 144e1ea03a3Smacallan uint32_t rxa, rya, rxe, rye, rxs, rys, rxd, ryd, rxde, ryde; 145e1ea03a3Smacallan 146e1ea03a3Smacallan LOG(CRIME_DEBUG_BITBLT); 147e1ea03a3Smacallan#ifdef CRIME_DEBUG_LOUD 148e1ea03a3Smacallan xf86Msg(X_ERROR, "%s: %d, %d; %d x %d -> %d %d\n", __func__, 149e1ea03a3Smacallan xSrc, ySrc, w, h, xDst, yDst); 150e1ea03a3Smacallan#endif 151e1ea03a3Smacallan 152e1ea03a3Smacallan if ((fPtr->use_mte) && (w > 64) && ((w & 3) == 0) && ((xSrc & 3) == 0) && ((xDst & 3) == 0)) { 153e1ea03a3Smacallan if (fPtr->ydir == -1) { 154e1ea03a3Smacallan /* bottom to top */ 155e1ea03a3Smacallan rye = ySrc; 156e1ea03a3Smacallan rya = ySrc + h - 1; 157e1ea03a3Smacallan ryd = yDst + h - 1; 158e1ea03a3Smacallan ryde = yDst; 159e1ea03a3Smacallan } else { 160e1ea03a3Smacallan /* top to bottom */ 161e1ea03a3Smacallan rye = ySrc + h - 1; 162e1ea03a3Smacallan rya = ySrc; 163e1ea03a3Smacallan ryd = yDst; 164e1ea03a3Smacallan ryde = yDst + h - 1; 165e1ea03a3Smacallan } 166e1ea03a3Smacallan rxa = xSrc << 2; 167e1ea03a3Smacallan rxe = ((xSrc + w) << 2) - 1; 168e1ea03a3Smacallan rxd = xDst << 2; 169e1ea03a3Smacallan rxde = ((xDst + w) << 2) - 1; 170e1ea03a3Smacallan oreg = *CRIMEREG(0x4000); 171e1ea03a3Smacallan READY; 172e1ea03a3Smacallan WRITE4(CRIME_MTE_SRC0, (rxa << 16) | rya); 173e1ea03a3Smacallan WRITE4(CRIME_MTE_SRC1, (rxe << 16) | rye); 174e1ea03a3Smacallan WRITE4(CRIME_MTE_DST0, (rxd << 16) | ryd); 175e1ea03a3Smacallan WBFLUSH; 176e1ea03a3Smacallan WRITE4ST(CRIME_MTE_DST1, (rxde << 16) | ryde); 177e1ea03a3Smacallan reg = *CRIMEREG(0x4000); 178e1ea03a3Smacallan 179e1ea03a3Smacallan#ifdef CRIME_DEBUG_LOUD 180e1ea03a3Smacallan xf86Msg(X_ERROR, "reg: %08x %08x\n", oreg, reg); 181e1ea03a3Smacallan#endif 182e1ea03a3Smacallan } else { 183e1ea03a3Smacallan if (fPtr->xdir == -1) { 184e1ea03a3Smacallan prim |= DE_PRIM_RL; 185e1ea03a3Smacallan rxe = xDst; 186e1ea03a3Smacallan rxa = xDst + w - 1; 187e1ea03a3Smacallan rxs = xSrc + w - 1; 188e1ea03a3Smacallan } else { 189e1ea03a3Smacallan prim |= DE_PRIM_LR; 190e1ea03a3Smacallan rxe = xDst + w - 1; 191e1ea03a3Smacallan rxa = xDst; 192e1ea03a3Smacallan rxs = xSrc; 193e1ea03a3Smacallan } 194e1ea03a3Smacallan if (fPtr->ydir == -1) { 195e1ea03a3Smacallan prim |= DE_PRIM_BT; 196e1ea03a3Smacallan rye = yDst; 197e1ea03a3Smacallan rya = yDst + h - 1; 198e1ea03a3Smacallan rys = ySrc + h - 1; 199e1ea03a3Smacallan } else { 200e1ea03a3Smacallan prim |= DE_PRIM_TB; 201e1ea03a3Smacallan rye = yDst + h - 1; 202e1ea03a3Smacallan rya = yDst; 203e1ea03a3Smacallan rys = ySrc; 204e1ea03a3Smacallan } 205e1ea03a3Smacallan 206e1ea03a3Smacallan READY; 207e1ea03a3Smacallan WRITE4(CRIME_DE_PRIMITIVE, prim); 208e1ea03a3Smacallan WRITE4(CRIME_DE_XFER_ADDR_SRC,(rxs << 16) | (rys & 0xffff)); 209e1ea03a3Smacallan WRITE4(CRIME_DE_X_VERTEX_0, (rxa << 16) | (rya & 0xffff)); 210e1ea03a3Smacallan WBFLUSH; 211e1ea03a3Smacallan WRITE4ST(CRIME_DE_X_VERTEX_1, (rxe << 16) | (rye & 0xffff)); 212e1ea03a3Smacallan } 213e1ea03a3Smacallan DONE(CRIME_DEBUG_BITBLT); 214e1ea03a3Smacallan} 215e1ea03a3Smacallan 216e1ea03a3Smacallanstatic void 217e1ea03a3SmacallanCrimeSetupForSolidFill 218e1ea03a3Smacallan( 219e1ea03a3Smacallan ScrnInfoPtr pScrn, 220e1ea03a3Smacallan int colour, 221e1ea03a3Smacallan int rop, 222e1ea03a3Smacallan unsigned int planemask 223e1ea03a3Smacallan) 224e1ea03a3Smacallan{ 225e1ea03a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 226e1ea03a3Smacallan int i; 227e1ea03a3Smacallan 228e1ea03a3Smacallan SYNC; 229e1ea03a3Smacallan LOG(CRIME_DEBUG_RECTFILL); 230e1ea03a3Smacallan WRITE4(CRIME_DE_PLANEMASK, planemask); 231e1ea03a3Smacallan WRITE4(CRIME_DE_ROP, rop); 232e1ea03a3Smacallan WRITE4(CRIME_DE_FG, colour << 8); 233e1ea03a3Smacallan WRITE4(CRIME_DE_DRAWMODE, 23493351543Smacallan DE_DRAWMODE_PLANEMASK | DE_DRAWMODE_BYTEMASK | DE_DRAWMODE_ROP | 23593351543Smacallan DE_DRAWMODE_SCISSOR_EN); 236e1ea03a3Smacallan WRITE4(CRIME_DE_PRIMITIVE, 237e1ea03a3Smacallan DE_PRIM_RECTANGLE | DE_PRIM_LR | DE_PRIM_TB); 238e1ea03a3Smacallan WRITE4(CRIME_DE_MODE_SRC, DE_MODE_TLB_A | DE_MODE_BUFDEPTH_32 | 239e1ea03a3Smacallan DE_MODE_TYPE_RGBA | DE_MODE_PIXDEPTH_32); 240e1ea03a3Smacallan DONE(CRIME_DEBUG_RECTFILL); 241e1ea03a3Smacallan} 242e1ea03a3Smacallan 243e1ea03a3Smacallanstatic void 244e1ea03a3SmacallanCrimeSubsequentSolidFillRect 245e1ea03a3Smacallan( 246e1ea03a3Smacallan ScrnInfoPtr pScrn, 247e1ea03a3Smacallan int x, 248e1ea03a3Smacallan int y, 249e1ea03a3Smacallan int w, 250e1ea03a3Smacallan int h 251e1ea03a3Smacallan) 252e1ea03a3Smacallan{ 253e1ea03a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 254e1ea03a3Smacallan 255e1ea03a3Smacallan LOG(CRIME_DEBUG_RECTFILL); 256e1ea03a3Smacallan READY; 257e1ea03a3Smacallan WRITE4(CRIME_DE_X_VERTEX_0, (x << 16) | (y & 0xffff)); 258e1ea03a3Smacallan WBFLUSH; 259e1ea03a3Smacallan WRITE4ST(CRIME_DE_X_VERTEX_1, 260e1ea03a3Smacallan ((x + w - 1) << 16) | ((y + h - 1) & 0xffff)); 261e1ea03a3Smacallan DONE(CRIME_DEBUG_RECTFILL); 262e1ea03a3Smacallan} 263e1ea03a3Smacallan 264e1ea03a3Smacallanvoid 265e1ea03a3SmacallanCrimeSetupForScanlineImageWrite(ScrnInfoPtr pScrn, int rop, 266e1ea03a3Smacallan unsigned int planemask, int trans_color, 267e1ea03a3Smacallan int bpp, int depth) 268e1ea03a3Smacallan{ 269e1ea03a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 270e1ea03a3Smacallan 271e1ea03a3Smacallan LOG(CRIME_DEBUG_IMAGEWRITE); 272e1ea03a3Smacallan SYNC; 273e1ea03a3Smacallan#ifdef CRIME_DEBUG_LOUD 274e1ea03a3Smacallan if ((bpp == 24) || (depth == 24)) 275e1ea03a3Smacallan xf86Msg(X_ERROR, "%s: %d %d \n", __func__, bpp, depth); 276e1ea03a3Smacallan#endif 277e1ea03a3Smacallan WRITE4(CRIME_DE_MODE_SRC, DE_MODE_LIN_A | DE_MODE_BUFDEPTH_32 | 278e1ea03a3Smacallan DE_MODE_TYPE_RGB | DE_MODE_PIXDEPTH_32); 279e1ea03a3Smacallan WRITE4(CRIME_DE_PLANEMASK, planemask); 280e1ea03a3Smacallan WRITE4(CRIME_DE_XFER_STEP_X, 4); 281e1ea03a3Smacallan WRITE4(CRIME_DE_ROP, rop); 282e1ea03a3Smacallan WRITE4(CRIME_DE_DRAWMODE, 283e1ea03a3Smacallan DE_DRAWMODE_PLANEMASK | DE_DRAWMODE_BYTEMASK | DE_DRAWMODE_ROP | 284e1ea03a3Smacallan DE_DRAWMODE_XFER_EN); 285e1ea03a3Smacallan WRITE4(CRIME_DE_PRIMITIVE, 286e1ea03a3Smacallan DE_PRIM_RECTANGLE | DE_PRIM_LR | DE_PRIM_TB); 287e1ea03a3Smacallan DONE(CRIME_DEBUG_IMAGEWRITE); 288e1ea03a3Smacallan} 289e1ea03a3Smacallan 290e1ea03a3Smacallanvoid 291e1ea03a3SmacallanCrimeSubsequentImageWriteRect(ScrnInfoPtr pScrn, 292e1ea03a3Smacallan int x, int y, int w, int h, int skipleft) 293e1ea03a3Smacallan{ 294e1ea03a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 295e1ea03a3Smacallan 296e1ea03a3Smacallan LOG(CRIME_DEBUG_IMAGEWRITE); 297e1ea03a3Smacallan 298e1ea03a3Smacallan#ifdef CRIME_DEBUG_LOUD 299e1ea03a3Smacallan xf86Msg(X_ERROR, "%s: %d %d %d %d\n", __func__, x, y, w, h); 300e1ea03a3Smacallan#endif 301e1ea03a3Smacallan 302e1ea03a3Smacallan fPtr->start = skipleft; 303e1ea03a3Smacallan x += skipleft; 304e1ea03a3Smacallan w -= skipleft; 305e1ea03a3Smacallan if (x < 0) { 306e1ea03a3Smacallan fPtr->ux = 0; 307e1ea03a3Smacallan w += x; 308e1ea03a3Smacallan fPtr->start -= x; 309e1ea03a3Smacallan } else { 310e1ea03a3Smacallan fPtr->ux = x; 311e1ea03a3Smacallan } 312e1ea03a3Smacallan fPtr->uy = y; 313e1ea03a3Smacallan fPtr->uw = w; 314e1ea03a3Smacallan fPtr->uh = h; 315e1ea03a3Smacallan DONE(CRIME_DEBUG_IMAGEWRITE); 316e1ea03a3Smacallan} 317e1ea03a3Smacallan 318e1ea03a3Smacallanvoid 319e1ea03a3SmacallanCrimeSubsequentImageWriteScanline(ScrnInfoPtr pScrn, int bufno) 320e1ea03a3Smacallan{ 321e1ea03a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 322e1ea03a3Smacallan 323e1ea03a3Smacallan LOG(CRIME_DEBUG_IMAGEWRITE); 32434c4e112Smacallan SYNC; 325e1ea03a3Smacallan 326e1ea03a3Smacallan WRITE4(CRIME_DE_XFER_ADDR_SRC, (bufno << 13) + (fPtr->start << 2)); 327e1ea03a3Smacallan WRITE4(CRIME_DE_X_VERTEX_0, (fPtr->ux << 16) | fPtr->uy); 328e1ea03a3Smacallan WBFLUSH; 329e1ea03a3Smacallan WRITE4ST(CRIME_DE_X_VERTEX_1, 330e1ea03a3Smacallan ((fPtr->ux + fPtr->uw - 1) << 16) | (fPtr->uy)); 331e1ea03a3Smacallan fPtr->uy++; 332e1ea03a3Smacallan DONE(CRIME_DEBUG_IMAGEWRITE); 333e1ea03a3Smacallan} 334e1ea03a3Smacallan 335e1ea03a3Smacallanstatic void 336e1ea03a3SmacallanCrimeSetupForCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, 337e1ea03a3Smacallan int fg, int bg, 338e1ea03a3Smacallan int rop, 339e1ea03a3Smacallan unsigned int planemask) 340e1ea03a3Smacallan{ 341e1ea03a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 342e1ea03a3Smacallan 343e1ea03a3Smacallan LOG(CRIME_DEBUG_COLOUREXPAND); 344e1ea03a3Smacallan SYNC; 345e1ea03a3Smacallan WRITE4(CRIME_DE_PLANEMASK, planemask); 346e1ea03a3Smacallan WRITE4(CRIME_DE_ROP, rop); 347e1ea03a3Smacallan WRITE4(CRIME_DE_FG, fg << 8); 348e1ea03a3Smacallan if (bg == -1) { 349e1ea03a3Smacallan /* transparent */ 350e1ea03a3Smacallan WRITE4(CRIME_DE_DRAWMODE, 351e1ea03a3Smacallan DE_DRAWMODE_PLANEMASK | DE_DRAWMODE_BYTEMASK | 352e1ea03a3Smacallan DE_DRAWMODE_ROP | DE_DRAWMODE_POLY_STIP); 353e1ea03a3Smacallan } else { 354e1ea03a3Smacallan WRITE4(CRIME_DE_BG, bg << 8); 355e1ea03a3Smacallan WRITE4(CRIME_DE_DRAWMODE, 356e1ea03a3Smacallan DE_DRAWMODE_PLANEMASK | DE_DRAWMODE_BYTEMASK | 357e1ea03a3Smacallan DE_DRAWMODE_ROP | 358e1ea03a3Smacallan DE_DRAWMODE_OPAQUE_STIP | DE_DRAWMODE_POLY_STIP); 359e1ea03a3Smacallan } 360e1ea03a3Smacallan WRITE4(CRIME_DE_PRIMITIVE, 361e1ea03a3Smacallan DE_PRIM_RECTANGLE | DE_PRIM_LR | DE_PRIM_TB); 362e1ea03a3Smacallan DONE(CRIME_DEBUG_COLOUREXPAND); 363e1ea03a3Smacallan} 364e1ea03a3Smacallan 365e1ea03a3Smacallanstatic void 366e1ea03a3SmacallanCrimeSubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, 367e1ea03a3Smacallan int x, int y, int w, int h, 368e1ea03a3Smacallan int skipleft ) 369e1ea03a3Smacallan{ 370e1ea03a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 371e1ea03a3Smacallan 372e1ea03a3Smacallan LOG(CRIME_DEBUG_COLOUREXPAND); 373e1ea03a3Smacallan 374e1ea03a3Smacallan fPtr->start = skipleft; 375e1ea03a3Smacallan fPtr->ux = x; 376e1ea03a3Smacallan fPtr->uy = y; 377e1ea03a3Smacallan fPtr->uw = w; 378e1ea03a3Smacallan fPtr->uh = h; 379e1ea03a3Smacallan DONE(CRIME_DEBUG_COLOUREXPAND); 380e1ea03a3Smacallan} 381e1ea03a3Smacallan 382e1ea03a3Smacallanstatic void 383e1ea03a3SmacallanCrimeSubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno) 384e1ea03a3Smacallan{ 385e1ea03a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 386e1ea03a3Smacallan uint32_t *boo = (uint32_t *)fPtr->expandbuffers[bufno]; 387e1ea03a3Smacallan int idx = fPtr->uw, x = fPtr->ux; 388e1ea03a3Smacallan 389e1ea03a3Smacallan LOG(CRIME_DEBUG_COLOUREXPAND); 390e1ea03a3Smacallan READY; 391e1ea03a3Smacallan 392e1ea03a3Smacallan WRITE4(CRIME_DE_STIPPLE_MODE, 0x001f0000 | (fPtr->start << 24)); 393e1ea03a3Smacallan WRITE4(CRIME_DE_STIPPLE_PAT, *boo); 394e1ea03a3Smacallan boo++; 395e1ea03a3Smacallan WRITE4(CRIME_DE_X_VERTEX_0, (x + fPtr->start << 16) | fPtr->uy); 396e1ea03a3Smacallan WBFLUSH; 397e1ea03a3Smacallan WRITE4ST(CRIME_DE_X_VERTEX_1, 398e1ea03a3Smacallan ((x + min(idx, 32) - 1) << 16) | (fPtr->uy)); 399e1ea03a3Smacallan idx -= 32; 400e1ea03a3Smacallan x += 32; 401e1ea03a3Smacallan WRITE4(CRIME_DE_STIPPLE_MODE, 0x001f0000); 402e1ea03a3Smacallan 403e1ea03a3Smacallan while (idx > 0) { 404e1ea03a3Smacallan WRITE4(CRIME_DE_STIPPLE_PAT, *boo); 405e1ea03a3Smacallan boo++; 406e1ea03a3Smacallan WRITE4(CRIME_DE_X_VERTEX_0, (x << 16) | fPtr->uy); 407e1ea03a3Smacallan WBFLUSH; 408e1ea03a3Smacallan WRITE4ST(CRIME_DE_X_VERTEX_1, 409e1ea03a3Smacallan ((x + min(idx, 32) - 1) << 16) | (fPtr->uy)); 410e1ea03a3Smacallan idx -= 32; 411e1ea03a3Smacallan x += 32; 412e1ea03a3Smacallan } 413e1ea03a3Smacallan fPtr->uy++; 414e1ea03a3Smacallan DONE(CRIME_DEBUG_COLOUREXPAND); 415e1ea03a3Smacallan} 416e1ea03a3Smacallan 417e1ea03a3Smacallanstatic void 418e1ea03a3SmacallanCrimeSetupForSolidLine(ScrnInfoPtr pScrn, int color, int rop, 419e1ea03a3Smacallan unsigned int planemask) 420e1ea03a3Smacallan{ 421e1ea03a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 422e1ea03a3Smacallan 423e1ea03a3Smacallan LOG(CRIME_DEBUG_LINES); 424e1ea03a3Smacallan 425e1ea03a3Smacallan SYNC; 426e1ea03a3Smacallan WRITE4(CRIME_DE_PLANEMASK, planemask); 427e1ea03a3Smacallan WRITE4(CRIME_DE_ROP, rop); 428e1ea03a3Smacallan WRITE4(CRIME_DE_FG, color << 8); 429e1ea03a3Smacallan WRITE4(CRIME_DE_DRAWMODE, 430e1ea03a3Smacallan DE_DRAWMODE_PLANEMASK | DE_DRAWMODE_BYTEMASK | 43193351543Smacallan DE_DRAWMODE_ROP | DE_DRAWMODE_SCISSOR_EN); 432e1ea03a3Smacallan DONE(CRIME_DEBUG_LINES); 433e1ea03a3Smacallan} 434e1ea03a3Smacallan 435e1ea03a3Smacallanstatic void 436e1ea03a3SmacallanCrimeSubsequentSolidTwoPointLine(ScrnInfoPtr pScrn, int x1, int y1, int x2, 437e1ea03a3Smacallan int y2, int flags) 438e1ea03a3Smacallan{ 439e1ea03a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 440e1ea03a3Smacallan 441e1ea03a3Smacallan LOG(CRIME_DEBUG_LINES); 442e1ea03a3Smacallan READY; 443e1ea03a3Smacallan if (flags & OMIT_LAST) { 444e1ea03a3Smacallan WRITE4(CRIME_DE_PRIMITIVE, 445e1ea03a3Smacallan DE_PRIM_LINE | DE_PRIM_LINE_SKIP_END | 2); 446e1ea03a3Smacallan } else { 447e1ea03a3Smacallan WRITE4(CRIME_DE_PRIMITIVE, 448e1ea03a3Smacallan DE_PRIM_LINE | 2); 449e1ea03a3Smacallan } 450e1ea03a3Smacallan WRITE4(CRIME_DE_X_VERTEX_0, (x1 << 16) | y1); 451e1ea03a3Smacallan WBFLUSH; 452e1ea03a3Smacallan WRITE4ST(CRIME_DE_X_VERTEX_1, (x2 << 16) | y2); 453e1ea03a3Smacallan DONE(CRIME_DEBUG_LINES); 454e1ea03a3Smacallan} 455e1ea03a3Smacallan 456e1ea03a3Smacallanvoid 457e1ea03a3SmacallanCrimeSetupForDashedLine(ScrnInfoPtr pScrn, 458e1ea03a3Smacallan int fg, int bg, int rop, unsigned int planemask, 459e1ea03a3Smacallan int length, unsigned char *pattern) 460e1ea03a3Smacallan{ 461e1ea03a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 462e1ea03a3Smacallan uint32_t pat; 463e1ea03a3Smacallan 464e1ea03a3Smacallan LOG(CRIME_DEBUG_LINES); 465e1ea03a3Smacallan SYNC; 466e1ea03a3Smacallan 467e1ea03a3Smacallan fPtr->uw = length; 468e1ea03a3Smacallan WRITE4(CRIME_DE_PLANEMASK, planemask); 469e1ea03a3Smacallan WRITE4(CRIME_DE_ROP, rop); 470e1ea03a3Smacallan WRITE4(CRIME_DE_FG, fg << 8); 471e1ea03a3Smacallan if (bg == -1) { 472e1ea03a3Smacallan /* transparent */ 473e1ea03a3Smacallan WRITE4(CRIME_DE_DRAWMODE, 474e1ea03a3Smacallan DE_DRAWMODE_PLANEMASK | DE_DRAWMODE_BYTEMASK | 47593351543Smacallan DE_DRAWMODE_ROP | DE_DRAWMODE_LINE_STIP | 47693351543Smacallan DE_DRAWMODE_SCISSOR_EN); 477e1ea03a3Smacallan } else { 478e1ea03a3Smacallan WRITE4(CRIME_DE_BG, bg << 8); 479e1ea03a3Smacallan WRITE4(CRIME_DE_DRAWMODE, 480e1ea03a3Smacallan DE_DRAWMODE_PLANEMASK | DE_DRAWMODE_BYTEMASK | 48193351543Smacallan DE_DRAWMODE_ROP | DE_DRAWMODE_SCISSOR_EN | 482e1ea03a3Smacallan DE_DRAWMODE_OPAQUE_STIP | DE_DRAWMODE_LINE_STIP); 483e1ea03a3Smacallan } 484e1ea03a3Smacallan /* 485e1ea03a3Smacallan * can we trust the Xserver to always hand us a 32bit aligned 486e1ea03a3Smacallan * pattern buffer? 487e1ea03a3Smacallan */ 488e1ea03a3Smacallan memcpy(&pat, pattern, 4); 489e1ea03a3Smacallan WRITE4(CRIME_DE_STIPPLE_PAT, pat); 490e1ea03a3Smacallan DONE(CRIME_DEBUG_LINES); 491e1ea03a3Smacallan} 492e1ea03a3Smacallan 493e1ea03a3Smacallanvoid 494e1ea03a3SmacallanCrimeSubsequentDashedTwoPointLine( ScrnInfoPtr pScrn, 495e1ea03a3Smacallan int x1, int y1, int x2, int y2, int flags, int phase) 496e1ea03a3Smacallan{ 497e1ea03a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 498e1ea03a3Smacallan uint32_t stipmode; 499e1ea03a3Smacallan 500e1ea03a3Smacallan LOG(CRIME_DEBUG_LINES); 501e1ea03a3Smacallan READY; 502e1ea03a3Smacallan 503e1ea03a3Smacallan if (flags & OMIT_LAST) { 504e1ea03a3Smacallan WRITE4(CRIME_DE_PRIMITIVE, 505e1ea03a3Smacallan DE_PRIM_LINE | DE_PRIM_LINE_SKIP_END | 2); 506e1ea03a3Smacallan } else { 507e1ea03a3Smacallan WRITE4(CRIME_DE_PRIMITIVE, 508e1ea03a3Smacallan DE_PRIM_LINE | 2); 509e1ea03a3Smacallan } 510e1ea03a3Smacallan 511e1ea03a3Smacallan stipmode = ((fPtr->uw - 1) << 16) | (phase << 24); 512e1ea03a3Smacallan WRITE4(CRIME_DE_STIPPLE_MODE, stipmode); 513e1ea03a3Smacallan WRITE4(CRIME_DE_X_VERTEX_0, (x1 << 16) | y1); 514e1ea03a3Smacallan WBFLUSH; 515e1ea03a3Smacallan WRITE4ST(CRIME_DE_X_VERTEX_1, (x2 << 16) | y2); 516e1ea03a3Smacallan DONE(CRIME_DEBUG_LINES); 517e1ea03a3Smacallan} 518e1ea03a3Smacallan 519e1ea03a3Smacallanvoid 520e1ea03a3SmacallanCrimeSetClippingRectangle ( ScrnInfoPtr pScrn, 521e1ea03a3Smacallan int left, int top, int right, int bottom) 522e1ea03a3Smacallan{ 523e1ea03a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 524e1ea03a3Smacallan 525e1ea03a3Smacallan LOG(CRIME_DEBUG_CLIPPING); 52693351543Smacallan WRITE4(CRIME_DE_SCISSOR, (left << 16) | top); 52793351543Smacallan WRITE4(CRIME_DE_SCISSOR + 4, ((right + 1) << 16) | (bottom + 1)); 52893351543Smacallan 529e1ea03a3Smacallan DONE(CRIME_DEBUG_CLIPPING); 530e1ea03a3Smacallan} 531e1ea03a3Smacallan 532e1ea03a3Smacallanvoid 533e1ea03a3SmacallanCrimeDisableClipping (ScrnInfoPtr pScrn) 534e1ea03a3Smacallan{ 535e1ea03a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 536e1ea03a3Smacallan 537e1ea03a3Smacallan LOG(CRIME_DEBUG_CLIPPING); 538e1ea03a3Smacallan SYNC; 539e1ea03a3Smacallan 54093351543Smacallan WRITE4(CRIME_DE_SCISSOR, 0); 54193351543Smacallan WRITE4(CRIME_DE_SCISSOR + 4, 0x3fff3fff); 542e1ea03a3Smacallan DONE(CRIME_DEBUG_CLIPPING); 543e1ea03a3Smacallan} 544e1ea03a3Smacallan 545e1ea03a3Smacallanstatic Bool 546e1ea03a3SmacallanCrimeSetupForCPUToScreenAlphaTexture ( 547e1ea03a3Smacallan ScrnInfoPtr pScrn, 548e1ea03a3Smacallan int op, 549e1ea03a3Smacallan CARD16 red, 550e1ea03a3Smacallan CARD16 green, 551e1ea03a3Smacallan CARD16 blue, 552e1ea03a3Smacallan CARD16 alpha, 553e1ea03a3Smacallan int alphaType, 554e1ea03a3Smacallan CARD8 *alphaPtr, 555e1ea03a3Smacallan int alphaPitch, 556e1ea03a3Smacallan int width, 557e1ea03a3Smacallan int height, 558e1ea03a3Smacallan int flags 559e1ea03a3Smacallan) 560e1ea03a3Smacallan{ 561e1ea03a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 562e1ea03a3Smacallan 563e1ea03a3Smacallan if (op != PictOpOver) { 564e1ea03a3Smacallan xf86Msg(X_ERROR, "%s: op %d\n", __func__, op); 565e1ea03a3Smacallan op = PictOpOver; 566e1ea03a3Smacallan } 567e1ea03a3Smacallan 568e1ea03a3Smacallan LOG(CRIME_DEBUG_XRENDER); 569e1ea03a3Smacallan 570e1ea03a3Smacallan fPtr->alpha_color = ((red & 0xff00) << 16) | 571e1ea03a3Smacallan ((green & 0xff00) << 8) | 57209f0d67cSmacallan (blue & 0xff00); 573e1ea03a3Smacallan fPtr->uw = width; 574e1ea03a3Smacallan fPtr->uh = height; 575e1ea03a3Smacallan fPtr->us = alphaPitch; 576e1ea03a3Smacallan fPtr->alpha_texture = alphaPtr; 57709f0d67cSmacallan fPtr->format = alphaType; 57809f0d67cSmacallan if (alphaType != PICT_a8) { 57909f0d67cSmacallan xf86Msg(X_ERROR, "ARGB mask %08x %d\n", (uint32_t)alphaPtr, 58009f0d67cSmacallan alphaPitch); 58109f0d67cSmacallan 58209f0d67cSmacallan } 583e1ea03a3Smacallan SYNC; 584e1ea03a3Smacallan /* XXX this register is not where it's supposed to be */ 585e1ea03a3Smacallan WRITE4(CRIME_DE_ALPHA_COLOR, fPtr->alpha_color); 58609f0d67cSmacallan if (alphaType == PICT_a8) { 58709f0d67cSmacallan if (fPtr->alpha_color == 0) { 58809f0d67cSmacallan WRITE4(CRIME_DE_MODE_SRC, DE_MODE_LIN_A | DE_MODE_BUFDEPTH_8 | 589e1ea03a3Smacallan DE_MODE_TYPE_RGBA | DE_MODE_PIXDEPTH_32); 59009f0d67cSmacallan WRITE4(CRIME_DE_XFER_STEP_X, 1); 59109f0d67cSmacallan WRITE4(CRIME_DE_ALPHA_FUNC, 59209f0d67cSmacallan DE_ALPHA_ADD | 59309f0d67cSmacallan (DE_ALPHA_OP_ZERO << DE_ALPHA_OP_SRC_SHIFT) | 59409f0d67cSmacallan (DE_ALPHA_OP_1_MINUS_SRC_ALPHA << DE_ALPHA_OP_DST_SHIFT)); 59509f0d67cSmacallan } else { 59609f0d67cSmacallan WRITE4(CRIME_DE_MODE_SRC, DE_MODE_LIN_A | DE_MODE_BUFDEPTH_32 | 59709f0d67cSmacallan DE_MODE_TYPE_RGBA | DE_MODE_PIXDEPTH_32); 59809f0d67cSmacallan WRITE4(CRIME_DE_XFER_STEP_X, 4); 59909f0d67cSmacallan WRITE4(CRIME_DE_ALPHA_FUNC, 60009f0d67cSmacallan DE_ALPHA_ADD | 60109f0d67cSmacallan (DE_ALPHA_OP_SRC_ALPHA << DE_ALPHA_OP_SRC_SHIFT) | 60209f0d67cSmacallan (DE_ALPHA_OP_1_MINUS_SRC_ALPHA << DE_ALPHA_OP_DST_SHIFT)); 60309f0d67cSmacallan } 604e1ea03a3Smacallan } else { 605e1ea03a3Smacallan WRITE4(CRIME_DE_MODE_SRC, DE_MODE_LIN_A | DE_MODE_BUFDEPTH_32 | 606e1ea03a3Smacallan DE_MODE_TYPE_RGBA | DE_MODE_PIXDEPTH_32); 607e1ea03a3Smacallan WRITE4(CRIME_DE_XFER_STEP_X, 4); 608e1ea03a3Smacallan WRITE4(CRIME_DE_ALPHA_FUNC, 609e1ea03a3Smacallan DE_ALPHA_ADD | 610e1ea03a3Smacallan (DE_ALPHA_OP_SRC_ALPHA << DE_ALPHA_OP_SRC_SHIFT) | 611e1ea03a3Smacallan (DE_ALPHA_OP_1_MINUS_SRC_ALPHA << DE_ALPHA_OP_DST_SHIFT)); 61209f0d67cSmacallan } 613e1ea03a3Smacallan WRITE4(CRIME_DE_DRAWMODE, 614e1ea03a3Smacallan DE_DRAWMODE_BYTEMASK | DE_DRAWMODE_ALPHA_BLEND | 615e1ea03a3Smacallan DE_DRAWMODE_XFER_EN); 616e1ea03a3Smacallan WRITE4(CRIME_DE_PRIMITIVE, 617e1ea03a3Smacallan DE_PRIM_RECTANGLE | DE_PRIM_LR | DE_PRIM_TB); 618e1ea03a3Smacallan DONE(CRIME_DEBUG_XRENDER); 619e1ea03a3Smacallan return TRUE; 620e1ea03a3Smacallan} 621e1ea03a3Smacallan 622e1ea03a3Smacallanvoid 623e1ea03a3SmacallanCrimeSubsequentCPUToScreenAlphaTexture ( 624e1ea03a3Smacallan ScrnInfoPtr pScrn, 625e1ea03a3Smacallan int dstx, 626e1ea03a3Smacallan int dsty, 627e1ea03a3Smacallan int srcx, 628e1ea03a3Smacallan int srcy, 629e1ea03a3Smacallan int width, 630e1ea03a3Smacallan int height 631e1ea03a3Smacallan) 632e1ea03a3Smacallan{ 633e1ea03a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 634e1ea03a3Smacallan unsigned char *aptr; 635e1ea03a3Smacallan uint32_t *dptr, aval; 636e1ea03a3Smacallan int i, j; 637e1ea03a3Smacallan int bufnum = 0; 638e1ea03a3Smacallan 639e1ea03a3Smacallan LOG(CRIME_DEBUG_XRENDER); 640e1ea03a3Smacallan#ifdef CRIME_DEBUG_LOUD 641e1ea03a3Smacallan xf86Msg(X_ERROR, "%d %d %d %d %d %d\n",srcx, srcy, dstx, dsty, width, 642e1ea03a3Smacallan height); 643e1ea03a3Smacallan#endif 644e1ea03a3Smacallan aptr = fPtr->alpha_texture + (fPtr->us * srcy) + srcx; 645e1ea03a3Smacallan for (i = 0; i < height; i++) { 646e1ea03a3Smacallan dptr = (uint32_t *)fPtr->buffers[bufnum]; 647e1ea03a3Smacallan if (fPtr->alpha_color == 0) { 648e1ea03a3Smacallan memcpy(dptr, aptr, width); 649e1ea03a3Smacallan } else { 650e1ea03a3Smacallan for (j = 0; j < width; j++) { 651e1ea03a3Smacallan aval = aptr[j]; 652e1ea03a3Smacallan *dptr = aval | fPtr->alpha_color; 653e1ea03a3Smacallan dptr++; 654e1ea03a3Smacallan } 655e1ea03a3Smacallan } 656e1ea03a3Smacallan READY; 657e1ea03a3Smacallan WRITE4(CRIME_DE_XFER_ADDR_SRC, bufnum * 8192); 658e1ea03a3Smacallan WRITE4(CRIME_DE_X_VERTEX_0, dstx << 16 | (dsty + i)); 659e1ea03a3Smacallan WBFLUSH; 660e1ea03a3Smacallan WRITE4ST(CRIME_DE_X_VERTEX_1, 661e1ea03a3Smacallan ((dstx + width - 1) << 16) | (dsty + i)); 662e1ea03a3Smacallan bufnum++; 663e1ea03a3Smacallan if (bufnum == 8) bufnum = 0; 664e1ea03a3Smacallan aptr += fPtr->us; 665e1ea03a3Smacallan } 666e1ea03a3Smacallan DONE(CRIME_DEBUG_XRENDER); 667e1ea03a3Smacallan} 668e1ea03a3Smacallan 66909f0d67cSmacallanvoid 67009f0d67cSmacallanCrimeSubsequentCPUToScreenAlphaTexture32 ( 67109f0d67cSmacallan ScrnInfoPtr pScrn, 67209f0d67cSmacallan int dstx, 67309f0d67cSmacallan int dsty, 67409f0d67cSmacallan int srcx, 67509f0d67cSmacallan int srcy, 67609f0d67cSmacallan int width, 67709f0d67cSmacallan int height 67809f0d67cSmacallan) 67909f0d67cSmacallan{ 68009f0d67cSmacallan CrimePtr fPtr = CRIMEPTR(pScrn); 68109f0d67cSmacallan uint8_t *aptr; 68209f0d67cSmacallan uint32_t *dptr, *sptr; 68309f0d67cSmacallan int i, j; 68409f0d67cSmacallan int bufnum = 0; 68509f0d67cSmacallan 68609f0d67cSmacallan LOG(CRIME_DEBUG_XRENDER); 68709f0d67cSmacallan#ifndef CRIME_DEBUG_LOUD 68809f0d67cSmacallan xf86Msg(X_ERROR, "%d %d %d %d %d %d\n",srcx, srcy, dstx, dsty, width, 68909f0d67cSmacallan height); 69009f0d67cSmacallan#endif 69109f0d67cSmacallan aptr = fPtr->alpha_texture + (fPtr->us * srcy) + (srcx << 2); 69209f0d67cSmacallan for (i = 0; i < height; i++) { 69309f0d67cSmacallan dptr = (uint32_t *)fPtr->buffers[bufnum]; 69409f0d67cSmacallan sptr = (uint32_t *)aptr; 69509f0d67cSmacallan for (j = 0; j < width; j++) { 69609f0d67cSmacallan *dptr = (*sptr >> 24) | fPtr->alpha_color; 69709f0d67cSmacallan#ifdef CRIME_DEBUG_LOUD 69809f0d67cSmacallan xf86Msg(X_ERROR, "%08x %08x\n", *sptr, *dptr); 69909f0d67cSmacallan#endif 70009f0d67cSmacallan sptr++; 70109f0d67cSmacallan dptr++; 70209f0d67cSmacallan } 70309f0d67cSmacallan READY; 70409f0d67cSmacallan WRITE4(CRIME_DE_XFER_ADDR_SRC, bufnum * 8192); 70509f0d67cSmacallan WRITE4(CRIME_DE_X_VERTEX_0, dstx << 16 | (dsty + i)); 70609f0d67cSmacallan WBFLUSH; 70709f0d67cSmacallan WRITE4ST(CRIME_DE_X_VERTEX_1, 70809f0d67cSmacallan ((dstx + width - 1) << 16) | (dsty + i)); 70909f0d67cSmacallan bufnum++; 71009f0d67cSmacallan if (bufnum == 8) bufnum = 0; 71109f0d67cSmacallan aptr += fPtr->us; 71209f0d67cSmacallan } 71309f0d67cSmacallan DONE(CRIME_DEBUG_XRENDER); 71409f0d67cSmacallan} 71509f0d67cSmacallan 716e1ea03a3Smacallanstatic Bool 717e1ea03a3SmacallanCrimeSetupForCPUToScreenTexture ( 718e1ea03a3Smacallan ScrnInfoPtr pScrn, 719e1ea03a3Smacallan int op, 720e1ea03a3Smacallan int texType, 721e1ea03a3Smacallan CARD8 *texPtr, 722e1ea03a3Smacallan int texPitch, 723e1ea03a3Smacallan int width, 724e1ea03a3Smacallan int height, 725e1ea03a3Smacallan int flags 726e1ea03a3Smacallan) 727e1ea03a3Smacallan{ 728e1ea03a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 729e1ea03a3Smacallan 730e1ea03a3Smacallan if (op != PictOpOver) { 731e1ea03a3Smacallan xf86Msg(X_ERROR, "%s: op %d\n", __func__, op); 732e1ea03a3Smacallan op = PictOpOver; 733e1ea03a3Smacallan } 734e1ea03a3Smacallan 735e1ea03a3Smacallan LOG(CRIME_DEBUG_XRENDER); 736e1ea03a3Smacallan 737e1ea03a3Smacallan fPtr->uw = width; 738e1ea03a3Smacallan fPtr->uh = height; 739e1ea03a3Smacallan fPtr->us = texPitch; 740e1ea03a3Smacallan fPtr->alpha_texture = texPtr; 741e1ea03a3Smacallan SYNC; 742e1ea03a3Smacallan if (texType == PICT_a8b8g8r8) { 743e1ea03a3Smacallan WRITE4(CRIME_DE_MODE_SRC, DE_MODE_LIN_A | DE_MODE_BUFDEPTH_32 | 744e1ea03a3Smacallan DE_MODE_TYPE_ABGR | DE_MODE_PIXDEPTH_32); 745e1ea03a3Smacallan } else { 746e1ea03a3Smacallan WRITE4(CRIME_DE_MODE_SRC, DE_MODE_LIN_A | DE_MODE_BUFDEPTH_32 | 747e1ea03a3Smacallan DE_MODE_TYPE_RGBA | DE_MODE_PIXDEPTH_32); 748e1ea03a3Smacallan } 749e1ea03a3Smacallan fPtr->format = texType; 750e1ea03a3Smacallan WRITE4(CRIME_DE_XFER_STEP_X, 4); 751e1ea03a3Smacallan WRITE4(CRIME_DE_ALPHA_FUNC, 752e1ea03a3Smacallan DE_ALPHA_ADD | 753e1ea03a3Smacallan (DE_ALPHA_OP_ONE/*SRC_ALPHA*/ << DE_ALPHA_OP_SRC_SHIFT) | 754e1ea03a3Smacallan (DE_ALPHA_OP_1_MINUS_SRC_ALPHA << DE_ALPHA_OP_DST_SHIFT)); 755e1ea03a3Smacallan WRITE4(CRIME_DE_DRAWMODE, 756e1ea03a3Smacallan DE_DRAWMODE_BYTEMASK | DE_DRAWMODE_ALPHA_BLEND | 757e1ea03a3Smacallan DE_DRAWMODE_XFER_EN); 758e1ea03a3Smacallan WRITE4(CRIME_DE_PRIMITIVE, 759e1ea03a3Smacallan DE_PRIM_RECTANGLE | DE_PRIM_LR | DE_PRIM_TB); 760e1ea03a3Smacallan DONE(CRIME_DEBUG_XRENDER); 761e1ea03a3Smacallan return TRUE; 762e1ea03a3Smacallan} 763e1ea03a3Smacallan 764e1ea03a3Smacallanvoid 765e1ea03a3SmacallanCrimeSubsequentCPUToScreenTexture ( 766e1ea03a3Smacallan ScrnInfoPtr pScrn, 767e1ea03a3Smacallan int dstx, 768e1ea03a3Smacallan int dsty, 769e1ea03a3Smacallan int srcx, 770e1ea03a3Smacallan int srcy, 771e1ea03a3Smacallan int width, 772e1ea03a3Smacallan int height 773e1ea03a3Smacallan) 774e1ea03a3Smacallan{ 775e1ea03a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 776e1ea03a3Smacallan unsigned char *aptr, *lptr; 777e1ea03a3Smacallan uint32_t *dptr, *sptr, aval, pixel; 778e1ea03a3Smacallan int i, j, k, l, rep = 1, period = fPtr->uw, xoff, lcnt, xa, xe; 779e1ea03a3Smacallan int bufnum = 0; 780e1ea03a3Smacallan 781e1ea03a3Smacallan LOG(CRIME_DEBUG_XRENDER); 782e1ea03a3Smacallan#ifdef CRIME_DEBUG_LOUD 783e1ea03a3Smacallan xf86Msg(X_ERROR, "%s: %d %d %d %d %d %d\n", __func__, 784e1ea03a3Smacallan srcx, srcy, dstx, dsty, width, height); 785e1ea03a3Smacallan#endif 786e1ea03a3Smacallan if ((width == 1) || (fPtr->format != PICT_a8r8g8b8)) { 787e1ea03a3Smacallan xf86Msg(X_ERROR, "%s: %d %d %d %d %d %d %d %d\n", __func__, 788e1ea03a3Smacallan srcx, srcy, dstx, dsty, width, height, fPtr->uw, fPtr->us); 789e1ea03a3Smacallan return; 790e1ea03a3Smacallan } 791e1ea03a3Smacallan 792e1ea03a3Smacallan aptr = fPtr->alpha_texture + (srcx << 2); 793e1ea03a3Smacallan lptr = aptr + (fPtr->us * srcy); 794e1ea03a3Smacallan if ((fPtr->uw < 128) && (fPtr->uw < width)) { 795e1ea03a3Smacallan rep = 128 / fPtr->uw; 796e1ea03a3Smacallan period = rep * fPtr->uw; 797e1ea03a3Smacallan } 798e1ea03a3Smacallan 799e1ea03a3Smacallan if (fPtr->format == PICT_a8b8g8r8) { 800e1ea03a3Smacallan#ifdef CRIME_DEBUG_LOUD 801e1ea03a3Smacallan xf86Msg(X_ERROR, "ABGR\n"); 802e1ea03a3Smacallan#endif 803e1ea03a3Smacallan for (i = 0; i < height; i++) { 804e1ea03a3Smacallan dptr = (uint32_t *)fPtr->buffers[bufnum]; 805e1ea03a3Smacallan memcpy(dptr, aptr, fPtr->us); 806e1ea03a3Smacallan READY; 807e1ea03a3Smacallan WRITE4(CRIME_DE_XFER_ADDR_SRC, bufnum * 8192); 808e1ea03a3Smacallan WRITE4(CRIME_DE_X_VERTEX_0, dstx << 16 | (dsty + i)); 809e1ea03a3Smacallan WBFLUSH; 810e1ea03a3Smacallan WRITE4ST(CRIME_DE_X_VERTEX_1, 811e1ea03a3Smacallan ((dstx + width - 1) << 16) | (dsty + i)); 812e1ea03a3Smacallan bufnum++; 813e1ea03a3Smacallan if (bufnum == 8) bufnum = 0; 814e1ea03a3Smacallan aptr += fPtr->us; 815e1ea03a3Smacallan } 816e1ea03a3Smacallan } else { 817e1ea03a3Smacallan#ifdef CRIME_DEBUG_LOUD 818e1ea03a3Smacallan xf86Msg(X_ERROR, "ARGB %08x %d\n", (uint32_t)aptr, fPtr->uw); 819e1ea03a3Smacallan#endif 820e1ea03a3Smacallan lcnt = fPtr->uh - srcy; 821e1ea03a3Smacallan for (i = 0; i < height; i++) { 822e1ea03a3Smacallan dptr = (uint32_t *)fPtr->buffers[bufnum]; 823e1ea03a3Smacallan for (k = 0; k < rep; k++) { 824e1ea03a3Smacallan sptr = (uint32_t *)aptr; 825e1ea03a3Smacallan for (j = 0; j < fPtr->uw; j++) { 826e1ea03a3Smacallan pixel = *sptr; 827e1ea03a3Smacallan *dptr = (pixel << 8) | (pixel >> 24); 828e1ea03a3Smacallan dptr++; 829e1ea03a3Smacallan sptr++; 830e1ea03a3Smacallan } 831e1ea03a3Smacallan } 832e1ea03a3Smacallan xoff = 0; 833e1ea03a3Smacallan READY; 834e1ea03a3Smacallan WRITE4(CRIME_DE_XFER_ADDR_SRC, bufnum * 8192); 835e1ea03a3Smacallan while (xoff < width) { 836e1ea03a3Smacallan xa = dstx + xoff; 837e1ea03a3Smacallan xe = dstx + min(xoff + period, width) - 1; 838e1ea03a3Smacallan READY; 839e1ea03a3Smacallan WRITE4(CRIME_DE_X_VERTEX_0, 840e1ea03a3Smacallan xa << 16 | (dsty + i)); 841e1ea03a3Smacallan WBFLUSH; 842e1ea03a3Smacallan WRITE4ST(CRIME_DE_X_VERTEX_1, 843e1ea03a3Smacallan (xe << 16) | (dsty + i)); 844e1ea03a3Smacallan xoff += period; 845e1ea03a3Smacallan } 846e1ea03a3Smacallan bufnum++; 847e1ea03a3Smacallan if (bufnum == 8) bufnum = 0; 848e1ea03a3Smacallan lcnt--; 849e1ea03a3Smacallan if (lcnt == 0) { 850e1ea03a3Smacallan aptr = lptr; 851e1ea03a3Smacallan lcnt = fPtr->uh; 852e1ea03a3Smacallan } else 853e1ea03a3Smacallan aptr += fPtr->us; 854e1ea03a3Smacallan } 855e1ea03a3Smacallan } 856e1ea03a3Smacallan DONE(CRIME_DEBUG_XRENDER); 857e1ea03a3Smacallan} 858e1ea03a3Smacallan 859e1ea03a3Smacallanstatic Bool 860e1ea03a3SmacallanCrimeSetupForCPUToScreenTextureMask( 861e1ea03a3Smacallan ScrnInfoPtr pScrn, 862e1ea03a3Smacallan int op, 863e1ea03a3Smacallan int texType, 864e1ea03a3Smacallan CARD8 *srcPtr, 865e1ea03a3Smacallan int srcPitch, 866e1ea03a3Smacallan CARD8 *mskPtr, 867e1ea03a3Smacallan int mskPitch, 868e1ea03a3Smacallan int width, 869e1ea03a3Smacallan int height, 870e1ea03a3Smacallan int flags 871e1ea03a3Smacallan) 872e1ea03a3Smacallan{ 873e1ea03a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 874e1ea03a3Smacallan 875e1ea03a3Smacallan if (op != PictOpOver) { 876e1ea03a3Smacallan xf86Msg(X_ERROR, "%s: op %d\n", __func__, op); 877e1ea03a3Smacallan op = PictOpOver; 878e1ea03a3Smacallan } 879e1ea03a3Smacallan 880e1ea03a3Smacallan LOG(CRIME_DEBUG_XRENDER); 881e1ea03a3Smacallan 882e1ea03a3Smacallan fPtr->uw = width; 883e1ea03a3Smacallan fPtr->uh = height; 884e1ea03a3Smacallan fPtr->us = srcPitch >> 2; 885e1ea03a3Smacallan if (PICT_FORMAT_BPP(texType) == 32) { 886e1ea03a3Smacallan fPtr->um = mskPitch >> 2; 887e1ea03a3Smacallan } else 888e1ea03a3Smacallan fPtr->um = mskPitch; 889e1ea03a3Smacallan fPtr->msk = (uint8_t *)mskPtr; 890e1ea03a3Smacallan fPtr->src = (uint8_t *)srcPtr; 891e1ea03a3Smacallan fPtr->texture_depth = PICT_FORMAT_BPP(texType); 892e1ea03a3Smacallan 893e1ea03a3Smacallan SYNC; 894e1ea03a3Smacallan /* always expect ARGB for now */ 895e1ea03a3Smacallan WRITE4(CRIME_DE_MODE_SRC, DE_MODE_LIN_A | DE_MODE_BUFDEPTH_32 | 896e1ea03a3Smacallan DE_MODE_TYPE_RGBA | DE_MODE_PIXDEPTH_32); 897e1ea03a3Smacallan fPtr->format = texType; 898e1ea03a3Smacallan WRITE4(CRIME_DE_ALPHA_FUNC, 899e1ea03a3Smacallan DE_ALPHA_ADD | 900e1ea03a3Smacallan (DE_ALPHA_OP_SRC_ALPHA << DE_ALPHA_OP_SRC_SHIFT) | 901e1ea03a3Smacallan (DE_ALPHA_OP_1_MINUS_SRC_ALPHA << DE_ALPHA_OP_DST_SHIFT)); 902e1ea03a3Smacallan WRITE4(CRIME_DE_XFER_STEP_X, 4); 903e1ea03a3Smacallan WRITE4(CRIME_DE_DRAWMODE, 904e1ea03a3Smacallan DE_DRAWMODE_BYTEMASK | DE_DRAWMODE_ALPHA_BLEND | 905e1ea03a3Smacallan DE_DRAWMODE_XFER_EN); 906e1ea03a3Smacallan WRITE4(CRIME_DE_PRIMITIVE, 907e1ea03a3Smacallan DE_PRIM_RECTANGLE | DE_PRIM_LR | DE_PRIM_TB); 908e1ea03a3Smacallan DONE(CRIME_DEBUG_XRENDER); 909e1ea03a3Smacallan return TRUE; 910e1ea03a3Smacallan} 911e1ea03a3Smacallan 912e1ea03a3Smacallanvoid 913e1ea03a3SmacallanCrimeSubsequentCPUToScreenTextureMask32( 914e1ea03a3Smacallan ScrnInfoPtr pScrn, 915e1ea03a3Smacallan int dstx, 916e1ea03a3Smacallan int dsty, 917e1ea03a3Smacallan int srcx, 918e1ea03a3Smacallan int srcy, 919e1ea03a3Smacallan int maskx, 920e1ea03a3Smacallan int masky, 921e1ea03a3Smacallan int width, 922e1ea03a3Smacallan int height 923e1ea03a3Smacallan) 924e1ea03a3Smacallan{ 925e1ea03a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 926e1ea03a3Smacallan uint32_t *lsptr, *lmptr, *asptr, *amptr; 927e1ea03a3Smacallan uint32_t *dptr, *sptr, *mptr, aval, pixel, mask; 928e1ea03a3Smacallan int i, j, k, l, rep = 1, period = fPtr->uw, xoff, lcnt, xa, xe; 929e1ea03a3Smacallan int bufnum = 0; 930e1ea03a3Smacallan int sr, sg, sb, sa, mr, mg, mb, ma, rr, gg, bb, aa; 931e1ea03a3Smacallan 932e1ea03a3Smacallan LOG(CRIME_DEBUG_XRENDER); 933e1ea03a3Smacallan#ifdef CRIME_DEBUG_LOUD 934e1ea03a3Smacallan xf86Msg(X_ERROR, "%s: %d %d %d %d %d %d; %d %d %d\n", __func__, 935e1ea03a3Smacallan srcx, srcy, dstx, dsty, width, height, maskx, masky, fPtr->um); 936e1ea03a3Smacallan#endif 937e1ea03a3Smacallan sptr = fPtr->src + (srcx << 2); 938e1ea03a3Smacallan mptr = fPtr->msk + (srcx << 2); 939e1ea03a3Smacallan lsptr = sptr + (fPtr->us * srcy); 940e1ea03a3Smacallan lmptr = mptr + (fPtr->um * srcy); 941e1ea03a3Smacallan if ((fPtr->uw < 128) && (fPtr->uw < width)) { 942e1ea03a3Smacallan rep = 128 / fPtr->uw; 943e1ea03a3Smacallan period = rep * fPtr->uw; 944e1ea03a3Smacallan } 945e1ea03a3Smacallan 946e1ea03a3Smacallan#ifdef CRIME_DEBUG_LOUD 947e1ea03a3Smacallan xf86Msg(X_ERROR, "ARGB %08x %d\n", (uint32_t)aptr, fPtr->uw); 948e1ea03a3Smacallan#endif 949e1ea03a3Smacallan lcnt = fPtr->uh - srcy; 950e1ea03a3Smacallan for (i = 0; i < height; i++) { 951e1ea03a3Smacallan dptr = (uint32_t *)fPtr->buffers[bufnum]; 952e1ea03a3Smacallan for (k = 0; k < rep; k++) { 953e1ea03a3Smacallan asptr = lsptr; 954e1ea03a3Smacallan amptr = lmptr; 955e1ea03a3Smacallan for (j = 0; j < fPtr->uw; j++) { 956e1ea03a3Smacallan pixel = *asptr; 957e1ea03a3Smacallan mask = *amptr; 958e1ea03a3Smacallan if (mask == 0xffffffff) { 959e1ea03a3Smacallan *dptr = (pixel >> 24) | (pixel << 8); 960e1ea03a3Smacallan } else if (mask == 0x00000000) { 961e1ea03a3Smacallan *dptr = 0; 962e1ea03a3Smacallan } else { 963e1ea03a3Smacallan /* input is ARGB */ 964e1ea03a3Smacallan sb = pixel & 0xff; 965e1ea03a3Smacallan sg = (pixel >> 8) & 0xff; 966e1ea03a3Smacallan sr = (pixel >> 16) & 0xff; 967e1ea03a3Smacallan sa = (pixel >> 24) & 0xff; 968e1ea03a3Smacallan mb = mask & 0xff; 969e1ea03a3Smacallan mg = (mask >> 8) & 0xff; 970e1ea03a3Smacallan mr = (mask >> 16) & 0xff; 971e1ea03a3Smacallan ma = (mask >> 24) & 0xff; 972e1ea03a3Smacallan 973e1ea03a3Smacallan /* and here we need an RGBA pixel */ 974e1ea03a3Smacallan bb = (((sb * mb) + 0x80) & 0xff00); 975e1ea03a3Smacallan gg = (((sg * mg) + 0x80) & 0xff00) << 8; 976e1ea03a3Smacallan rr = (((sr * mr) + 0x80) & 0xff00) << 16; 977e1ea03a3Smacallan aa = (((sa * ma) + 0x80) & 0xff00) >> 8; 978e1ea03a3Smacallan /* 979e1ea03a3Smacallan * actually we could let the HW do this stuff 980e1ea03a3Smacallan */ 981e1ea03a3Smacallan *dptr = aa | rr | gg | bb; 982e1ea03a3Smacallan } 983e1ea03a3Smacallan dptr++; 984e1ea03a3Smacallan asptr++; 985e1ea03a3Smacallan amptr++; 986e1ea03a3Smacallan } 987e1ea03a3Smacallan } 988e1ea03a3Smacallan xoff = 0; 989e1ea03a3Smacallan READY; 990e1ea03a3Smacallan WRITE4(CRIME_DE_XFER_ADDR_SRC, bufnum * 8192); 991e1ea03a3Smacallan while (xoff < width) { 992e1ea03a3Smacallan xa = dstx + xoff; 993e1ea03a3Smacallan xe = dstx + min(xoff + period, width) - 1; 994e1ea03a3Smacallan READY; 995e1ea03a3Smacallan WRITE4(CRIME_DE_X_VERTEX_0, 996e1ea03a3Smacallan xa << 16 | (dsty + i)); 997e1ea03a3Smacallan WBFLUSH; 998e1ea03a3Smacallan WRITE4ST(CRIME_DE_X_VERTEX_1, 999e1ea03a3Smacallan (xe << 16) | (dsty + i)); 1000e1ea03a3Smacallan xoff += period; 1001e1ea03a3Smacallan } 1002e1ea03a3Smacallan bufnum++; 1003e1ea03a3Smacallan if (bufnum == 8) bufnum = 0; 1004e1ea03a3Smacallan lcnt--; 1005e1ea03a3Smacallan if (lcnt == 0) { 1006e1ea03a3Smacallan /* back to the beginning */ 1007e1ea03a3Smacallan lsptr = sptr; 1008e1ea03a3Smacallan lmptr = mptr; 1009e1ea03a3Smacallan lcnt = fPtr->uh; 1010e1ea03a3Smacallan } else 1011e1ea03a3Smacallan /* next line */ 1012e1ea03a3Smacallan lsptr += fPtr->us; 1013e1ea03a3Smacallan lmptr += fPtr->um; 1014e1ea03a3Smacallan } 1015e1ea03a3Smacallan DONE(CRIME_DEBUG_XRENDER); 1016e1ea03a3Smacallan} 1017e1ea03a3Smacallan 1018e1ea03a3Smacallanvoid 1019e1ea03a3SmacallanCrimeSubsequentCPUToScreenTextureMask8( 1020e1ea03a3Smacallan ScrnInfoPtr pScrn, 1021e1ea03a3Smacallan int dstx, 1022e1ea03a3Smacallan int dsty, 1023e1ea03a3Smacallan int srcx, 1024e1ea03a3Smacallan int srcy, 1025e1ea03a3Smacallan int maskx, 1026e1ea03a3Smacallan int masky, 1027e1ea03a3Smacallan int width, 1028e1ea03a3Smacallan int height 1029e1ea03a3Smacallan) 1030e1ea03a3Smacallan{ 1031e1ea03a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 1032e1ea03a3Smacallan uint32_t *lsptr, *asptr; 1033e1ea03a3Smacallan uint32_t *dptr, *sptr, aval, pixel, mask; 1034e1ea03a3Smacallan uint8_t *lmptr, *amptr, *mptr; 1035e1ea03a3Smacallan int i, j, k, l, rep = 1, period = fPtr->uw, xoff, lcnt, xa, xe; 1036e1ea03a3Smacallan int bufnum = 0; 1037e1ea03a3Smacallan int sr, sg, sb, sa, rr, gg, bb, aa; 1038e1ea03a3Smacallan 1039e1ea03a3Smacallan LOG(CRIME_DEBUG_XRENDER); 1040e1ea03a3Smacallan#ifndef CRIME_DEBUG_LOUD 1041e1ea03a3Smacallan xf86Msg(X_ERROR, "%s: %d %d %d %d %d %d\n", __func__, 1042e1ea03a3Smacallan srcx, srcy, dstx, dsty, width, height); 1043e1ea03a3Smacallan#endif 1044e1ea03a3Smacallan sptr = (uint32_t *)fPtr->src + (fPtr->us * srcy) + (srcx << 2); 1045e1ea03a3Smacallan mptr = (uint8_t *)fPtr->msk + (fPtr->um * srcy) + srcx; 1046e1ea03a3Smacallan lsptr = sptr; 1047e1ea03a3Smacallan lmptr = mptr; 1048e1ea03a3Smacallan if ((fPtr->uw < 128) && (fPtr->uw < width)) { 1049e1ea03a3Smacallan rep = 128 / fPtr->uw; 1050e1ea03a3Smacallan period = rep * fPtr->uw; 1051e1ea03a3Smacallan } 1052e1ea03a3Smacallan 1053e1ea03a3Smacallan#ifdef CRIME_DEBUG_LOUD 1054e1ea03a3Smacallan xf86Msg(X_ERROR, "ARGB %08x %d\n", (uint32_t)aptr, fPtr->uw); 1055e1ea03a3Smacallan#endif 1056e1ea03a3Smacallan lcnt = fPtr->uh; 1057e1ea03a3Smacallan for (i = 0; i < height; i++) { 1058e1ea03a3Smacallan dptr = (uint32_t *)fPtr->buffers[bufnum]; 1059e1ea03a3Smacallan for (k = 0; k < rep; k++) { 1060e1ea03a3Smacallan asptr = lsptr; 1061e1ea03a3Smacallan amptr = lmptr; 1062e1ea03a3Smacallan for (j = 0; j < fPtr->uw; j++) { 1063e1ea03a3Smacallan pixel = *asptr; 1064e1ea03a3Smacallan mask = *amptr; 1065e1ea03a3Smacallan if (mask == 0xff) { 1066e1ea03a3Smacallan *dptr = (pixel >> 24) | (pixel << 8); 1067e1ea03a3Smacallan } else if (mask == 0x00) { 1068e1ea03a3Smacallan *dptr = 0; 1069e1ea03a3Smacallan } else { 1070e1ea03a3Smacallan /* input is ARGB */ 1071e1ea03a3Smacallan sb = pixel & 0xff; 1072e1ea03a3Smacallan sg = (pixel >> 8) & 0xff; 1073e1ea03a3Smacallan sr = (pixel >> 16) & 0xff; 1074e1ea03a3Smacallan sa = (pixel >> 24) & 0xff; 1075e1ea03a3Smacallan 1076e1ea03a3Smacallan /* and here we need an RGBA pixel */ 1077e1ea03a3Smacallan bb = (((sb * mask) + 0x80) & 0xff00); 1078e1ea03a3Smacallan gg = (((sg * mask) + 0x80) & 0xff00) 1079e1ea03a3Smacallan << 8; 1080e1ea03a3Smacallan rr = (((sr * mask) + 0x80) & 0xff00) 1081e1ea03a3Smacallan << 16; 1082e1ea03a3Smacallan aa = (((sa * mask) + 0x80) & 0xff00) 1083e1ea03a3Smacallan >> 8; 1084e1ea03a3Smacallan /* 1085e1ea03a3Smacallan * actually we could let the HW do this 1086e1ea03a3Smacallan * stuff 1087e1ea03a3Smacallan */ 1088e1ea03a3Smacallan *dptr = aa | rr | gg | bb; 1089e1ea03a3Smacallan } 1090e1ea03a3Smacallan dptr++; 1091e1ea03a3Smacallan asptr++; 1092e1ea03a3Smacallan amptr++; 1093e1ea03a3Smacallan } 1094e1ea03a3Smacallan } 1095e1ea03a3Smacallan xoff = 0; 1096e1ea03a3Smacallan SYNC; 1097e1ea03a3Smacallan WRITE4(CRIME_DE_XFER_ADDR_SRC, bufnum * 8192); 1098e1ea03a3Smacallan while (xoff < width) { 1099e1ea03a3Smacallan xa = dstx + xoff; 1100e1ea03a3Smacallan xe = dstx + min(xoff + period, width) - 1; 1101e1ea03a3Smacallan READY; 1102e1ea03a3Smacallan WRITE4(CRIME_DE_X_VERTEX_0, 1103e1ea03a3Smacallan xa << 16 | (dsty + i)); 1104e1ea03a3Smacallan WBFLUSH; 1105e1ea03a3Smacallan WRITE4ST(CRIME_DE_X_VERTEX_1, 1106e1ea03a3Smacallan (xe << 16) | (dsty + i)); 1107e1ea03a3Smacallan xoff += period; 1108e1ea03a3Smacallan } 1109e1ea03a3Smacallan bufnum++; 1110e1ea03a3Smacallan if (bufnum == 8) bufnum = 0; 1111e1ea03a3Smacallan lcnt--; 1112e1ea03a3Smacallan if (lcnt == 0) { 1113e1ea03a3Smacallan /* back to the beginning */ 1114e1ea03a3Smacallan lsptr = sptr; 1115e1ea03a3Smacallan lmptr = mptr; 1116e1ea03a3Smacallan lcnt = fPtr->uh; 1117e1ea03a3Smacallan } else 1118e1ea03a3Smacallan /* next line */ 1119e1ea03a3Smacallan lsptr += fPtr->us; 1120e1ea03a3Smacallan lmptr += fPtr->um; 1121e1ea03a3Smacallan } 1122e1ea03a3Smacallan DONE(CRIME_DEBUG_XRENDER); 1123e1ea03a3Smacallan} 1124e1ea03a3Smacallan 1125e1ea03a3Smacallanstatic void 1126e1ea03a3SmacallanCrimeDoCPUToScreenComposite( 1127e1ea03a3Smacallan CARD8 op, 1128e1ea03a3Smacallan PicturePtr pSrc, 1129e1ea03a3Smacallan PicturePtr pMask, 1130e1ea03a3Smacallan PicturePtr pDst, 1131e1ea03a3Smacallan INT16 xSrc, 1132e1ea03a3Smacallan INT16 ySrc, 1133e1ea03a3Smacallan INT16 xMask, 1134e1ea03a3Smacallan INT16 yMask, 1135e1ea03a3Smacallan INT16 xDst, 1136e1ea03a3Smacallan INT16 yDst, 1137e1ea03a3Smacallan CARD16 width, 1138e1ea03a3Smacallan CARD16 height 1139e1ea03a3Smacallan) 1140e1ea03a3Smacallan{ 1141e1ea03a3Smacallan ScreenPtr pScreen = pDst->pDrawable->pScreen; 1142e1ea03a3Smacallan XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen); 1143e1ea03a3Smacallan RegionRec region; 1144e1ea03a3Smacallan CARD32 *formats; 1145e1ea03a3Smacallan int flags = 0; 1146e1ea03a3Smacallan BoxPtr pbox; 1147e1ea03a3Smacallan int nbox, w, h; 1148e1ea03a3Smacallan 1149e1ea03a3Smacallan LOG(CRIME_DEBUG_XRENDER); 1150e1ea03a3Smacallan if (pSrc->transform || (pMask && pMask->transform)) { 1151e1ea03a3Smacallan xf86Msg(X_ERROR, "%s: transform?!\n", __func__); 1152e1ea03a3Smacallan return; 1153e1ea03a3Smacallan } 1154e1ea03a3Smacallan 1155e1ea03a3Smacallan if (pDst->alphaMap || pSrc->alphaMap || (pMask && pMask->alphaMap)) { 1156e1ea03a3Smacallan xf86Msg(X_ERROR, "%s: alpha-map?!\n", __func__); 1157e1ea03a3Smacallan return; 1158e1ea03a3Smacallan } 1159e1ea03a3Smacallan 1160e1ea03a3Smacallan xDst += pDst->pDrawable->x; 1161e1ea03a3Smacallan yDst += pDst->pDrawable->y; 1162e1ea03a3Smacallan xSrc += pSrc->pDrawable->x; 1163e1ea03a3Smacallan ySrc += pSrc->pDrawable->y; 1164e1ea03a3Smacallan 1165e1ea03a3Smacallan if(pMask) { 1166e1ea03a3Smacallan CARD16 red, green, blue, alpha; 1167e1ea03a3Smacallan CARD32 pixel = 1168e1ea03a3Smacallan *((CARD32*)(((PixmapPtr)(pSrc->pDrawable))->devPrivate.ptr)); 116909f0d67cSmacallan#ifdef CRIME_DEBUG_LOUD 1170e1ea03a3Smacallan if(pMask->componentAlpha) { 1171e1ea03a3Smacallan xf86Msg(X_ERROR, "%s: alpha component mask\n", 1172e1ea03a3Smacallan __func__); 117309f0d67cSmacallan xf86Msg(X_ERROR, "src: %d x %d\n", pSrc->pDrawable->width, 117409f0d67cSmacallan pSrc->pDrawable->height); 1175e1ea03a3Smacallan } 117609f0d67cSmacallan#endif 1177e1ea03a3Smacallan if ((pSrc->pDrawable->width == 1) && 1178e1ea03a3Smacallan (pSrc->pDrawable->height == 1)) { 1179e1ea03a3Smacallan 1180e1ea03a3Smacallan if(!XAAGetRGBAFromPixel(pixel, &red, &green, &blue, 1181e1ea03a3Smacallan &alpha, pSrc->format)) { 1182e1ea03a3Smacallan xf86Msg(X_ERROR, "%s: can't read pixel\n", __func__); 1183e1ea03a3Smacallan return; 1184e1ea03a3Smacallan } 1185e1ea03a3Smacallan xMask += pMask->pDrawable->x; 1186e1ea03a3Smacallan yMask += pMask->pDrawable->y; 1187e1ea03a3Smacallan 1188e1ea03a3Smacallan /* pull out color expandable operations here */ 1189e1ea03a3Smacallan if(pMask->format == PICT_a1) { 1190e1ea03a3Smacallan PixmapPtr pPix = (PixmapPtr)(pMask->pDrawable); 1191e1ea03a3Smacallan int skipleft; 1192e1ea03a3Smacallan 1193e1ea03a3Smacallan if (alpha == 0xffff) { 1194e1ea03a3Smacallan /* actually we can but for now we don't care */ 1195e1ea03a3Smacallan xf86Msg(X_ERROR, 1196e1ea03a3Smacallan "can't colour expand with alpha\n"); 1197e1ea03a3Smacallan return; 1198e1ea03a3Smacallan } 1199e1ea03a3Smacallan if (op != PictOpOver) { 1200e1ea03a3Smacallan xf86Msg(X_ERROR, "!over\n"); 1201e1ea03a3Smacallan return; 1202e1ea03a3Smacallan } 1203e1ea03a3Smacallan if (pMask->repeat) { 1204e1ea03a3Smacallan xf86Msg(X_ERROR, "mono repeat\n"); 1205e1ea03a3Smacallan return; 1206e1ea03a3Smacallan } 1207e1ea03a3Smacallan if (!miComputeCompositeRegion (®ion, pSrc, 1208e1ea03a3Smacallan pMask, pDst, xSrc, ySrc, xMask, yMask, xDst, 1209e1ea03a3Smacallan yDst, width, height)) { 1210e1ea03a3Smacallan return; 1211e1ea03a3Smacallan } 1212e1ea03a3Smacallan 1213e1ea03a3Smacallan nbox = REGION_NUM_RECTS(®ion); 1214e1ea03a3Smacallan pbox = REGION_RECTS(®ion); 1215e1ea03a3Smacallan 1216e1ea03a3Smacallan if(!nbox) { 1217e1ea03a3Smacallan return; 1218e1ea03a3Smacallan } 1219e1ea03a3Smacallan 1220e1ea03a3Smacallan XAAGetPixelFromRGBA(&pixel, red, green, blue, 0, 1221e1ea03a3Smacallan pDst->format); 1222e1ea03a3Smacallan 1223e1ea03a3Smacallan xMask -= xDst; 1224e1ea03a3Smacallan yMask -= yDst; 1225e1ea03a3Smacallan 1226e1ea03a3Smacallan while(nbox--) { 1227e1ea03a3Smacallan skipleft = pbox->x1 + xMask; 1228e1ea03a3Smacallan 1229e1ea03a3Smacallan (*infoRec->WriteBitmap)(infoRec->pScrn, pbox->x1, pbox->y1, 1230e1ea03a3Smacallan pbox->x2 - pbox->x1, 1231e1ea03a3Smacallan pbox->y2 - pbox->y1, 1232e1ea03a3Smacallan (unsigned char*)(pPix->devPrivate.ptr) + (pPix->devKind * 1233e1ea03a3Smacallan (pbox->y1 + yMask)) + ((skipleft >> 3) & ~3), 1234e1ea03a3Smacallan pPix->devKind, skipleft & 31, pixel, -1, 1235e1ea03a3Smacallan GXcopy, ~0); 1236e1ea03a3Smacallan pbox++; 1237e1ea03a3Smacallan } 1238e1ea03a3Smacallan 1239e1ea03a3Smacallan /* WriteBitmap sets the Sync flag */ 1240e1ea03a3Smacallan REGION_UNINIT(pScreen, ®ion); 1241e1ea03a3Smacallan DONE(CRIME_DEBUG_XRENDER); 1242e1ea03a3Smacallan return; 1243e1ea03a3Smacallan } 124409f0d67cSmacallan if((pMask->format == PICT_a8) || 124509f0d67cSmacallan (pMask->format == PICT_a8r8g8b8)) { 1246e1ea03a3Smacallan 1247e1ea03a3Smacallan w = pMask->pDrawable->width; 1248e1ea03a3Smacallan h = pMask->pDrawable->height; 1249e1ea03a3Smacallan 1250e1ea03a3Smacallan if(pMask->repeat) { 1251e1ea03a3Smacallan flags |= XAA_RENDER_REPEAT; 1252e1ea03a3Smacallan } 1253e1ea03a3Smacallan 1254e1ea03a3Smacallan if (!miComputeCompositeRegion (®ion, pSrc, pMask, 1255e1ea03a3Smacallan pDst, xSrc, ySrc, xMask, yMask, xDst, yDst, 1256e1ea03a3Smacallan width, height)) { 1257e1ea03a3Smacallan return; 1258e1ea03a3Smacallan } 1259e1ea03a3Smacallan 1260e1ea03a3Smacallan nbox = REGION_NUM_RECTS(®ion); 1261e1ea03a3Smacallan pbox = REGION_RECTS(®ion); 1262e1ea03a3Smacallan 1263e1ea03a3Smacallan if(!nbox) { 1264e1ea03a3Smacallan REGION_UNINIT(pScreen, ®ion); 1265e1ea03a3Smacallan return; 1266e1ea03a3Smacallan } 1267e1ea03a3Smacallan 1268e1ea03a3Smacallan CrimeSetupForCPUToScreenAlphaTexture(infoRec->pScrn, 1269e1ea03a3Smacallan op, red, green, blue, alpha, pMask->format, 1270e1ea03a3Smacallan ((PixmapPtr)(pMask->pDrawable))->devPrivate.ptr, 1271e1ea03a3Smacallan ((PixmapPtr)(pMask->pDrawable))->devKind, 1272e1ea03a3Smacallan w, h, flags); 1273e1ea03a3Smacallan 1274e1ea03a3Smacallan xMask -= xDst; 1275e1ea03a3Smacallan yMask -= yDst; 1276e1ea03a3Smacallan 127709f0d67cSmacallan if (pMask->format != PICT_a8) { 127809f0d67cSmacallan while(nbox--) { 127909f0d67cSmacallan CrimeSubsequentCPUToScreenAlphaTexture32( 128009f0d67cSmacallan infoRec->pScrn, 128109f0d67cSmacallan pbox->x1, pbox->y1, pbox->x1 + xMask, 128209f0d67cSmacallan pbox->y1 + yMask, pbox->x2 - pbox->x1, 128309f0d67cSmacallan pbox->y2 - pbox->y1); 128409f0d67cSmacallan pbox++; 128509f0d67cSmacallan } 128609f0d67cSmacallan } else { 128709f0d67cSmacallan while(nbox--) { 128809f0d67cSmacallan CrimeSubsequentCPUToScreenAlphaTexture( 128909f0d67cSmacallan infoRec->pScrn, 129009f0d67cSmacallan pbox->x1, pbox->y1, pbox->x1 + xMask, 129109f0d67cSmacallan pbox->y1 + yMask, pbox->x2 - pbox->x1, 129209f0d67cSmacallan pbox->y2 - pbox->y1); 129309f0d67cSmacallan pbox++; 129409f0d67cSmacallan } 1295e1ea03a3Smacallan } 1296e1ea03a3Smacallan SET_SYNC_FLAG(infoRec); 1297e1ea03a3Smacallan REGION_UNINIT(pScreen, ®ion); 1298e1ea03a3Smacallan DONE(CRIME_DEBUG_XRENDER); 1299e1ea03a3Smacallan return; 1300e1ea03a3Smacallan } else { 1301e1ea03a3Smacallan xf86Msg(X_ERROR, "unknown mask %x\n", pMask->format); 1302e1ea03a3Smacallan } 1303e1ea03a3Smacallan REGION_UNINIT(pScreen, ®ion); 1304e1ea03a3Smacallan DONE(CRIME_DEBUG_XRENDER); 1305e1ea03a3Smacallan return; 1306e1ea03a3Smacallan } else { 1307e1ea03a3Smacallan /* source isn't solid */ 1308e1ea03a3Smacallan 1309e1ea03a3Smacallan w = pSrc->pDrawable->width; 1310e1ea03a3Smacallan h = pSrc->pDrawable->height; 1311e1ea03a3Smacallan 1312e1ea03a3Smacallan if(pSrc->repeat) 1313e1ea03a3Smacallan flags |= XAA_RENDER_REPEAT; 1314e1ea03a3Smacallan 1315e1ea03a3Smacallan if (!miComputeCompositeRegion (®ion, pSrc, pMask, 1316e1ea03a3Smacallan pDst, xSrc, ySrc, xMask, yMask, xDst, yDst, 1317e1ea03a3Smacallan width, height)) { 1318e1ea03a3Smacallan return; 1319e1ea03a3Smacallan } 1320e1ea03a3Smacallan 1321e1ea03a3Smacallan nbox = REGION_NUM_RECTS(®ion); 1322e1ea03a3Smacallan pbox = REGION_RECTS(®ion); 1323e1ea03a3Smacallan 1324e1ea03a3Smacallan if(!nbox) { 1325e1ea03a3Smacallan REGION_UNINIT(pScreen, ®ion); 1326e1ea03a3Smacallan return; 1327e1ea03a3Smacallan } 1328e1ea03a3Smacallan CrimeSetupForCPUToScreenTextureMask( 1329e1ea03a3Smacallan infoRec->pScrn, op, pMask->format, 1330e1ea03a3Smacallan ((PixmapPtr)(pSrc->pDrawable))->devPrivate.ptr, 1331e1ea03a3Smacallan ((PixmapPtr)(pSrc->pDrawable))->devKind, 1332e1ea03a3Smacallan ((PixmapPtr)(pMask->pDrawable))->devPrivate.ptr, 1333e1ea03a3Smacallan ((PixmapPtr)(pMask->pDrawable))->devKind, 1334e1ea03a3Smacallan w, h, flags); 1335e1ea03a3Smacallan 1336e1ea03a3Smacallan xSrc -= xDst; 1337e1ea03a3Smacallan ySrc -= yDst; 1338e1ea03a3Smacallan 1339e1ea03a3Smacallan if (PICT_FORMAT_BPP(pMask->format) == 32) { 1340e1ea03a3Smacallan while(nbox--) { 1341e1ea03a3Smacallan CrimeSubsequentCPUToScreenTextureMask32( 1342e1ea03a3Smacallan infoRec->pScrn, 1343e1ea03a3Smacallan pbox->x1, pbox->y1, 1344e1ea03a3Smacallan pbox->x1 + xSrc, pbox->y1 + ySrc, 1345e1ea03a3Smacallan xMask, yMask, 1346e1ea03a3Smacallan pbox->x2 - pbox->x1, pbox->y2 - pbox->y1); 1347e1ea03a3Smacallan pbox++; 1348e1ea03a3Smacallan } 1349e1ea03a3Smacallan } else { 1350e1ea03a3Smacallan while(nbox--) { 1351e1ea03a3Smacallan CrimeSubsequentCPUToScreenTextureMask8( 1352e1ea03a3Smacallan infoRec->pScrn, 1353e1ea03a3Smacallan pbox->x1, pbox->y1, pbox->x1 + xSrc, 1354e1ea03a3Smacallan pbox->y1 + ySrc, 1355e1ea03a3Smacallan xMask, yMask, 1356e1ea03a3Smacallan pbox->x2 - pbox->x1, 1357e1ea03a3Smacallan pbox->y2 - pbox->y1); 1358e1ea03a3Smacallan pbox++; 1359e1ea03a3Smacallan } 1360e1ea03a3Smacallan } 1361e1ea03a3Smacallan 1362e1ea03a3Smacallan SET_SYNC_FLAG(infoRec); 1363e1ea03a3Smacallan REGION_UNINIT(pScreen, ®ion); 1364e1ea03a3Smacallan DONE(CRIME_DEBUG_XRENDER); 1365e1ea03a3Smacallan return; 1366e1ea03a3Smacallan } 1367e1ea03a3Smacallan } else { /* no mask */ 1368e1ea03a3Smacallan formats = infoRec->CPUToScreenTextureFormats; 1369e1ea03a3Smacallan 1370e1ea03a3Smacallan w = pSrc->pDrawable->width; 1371e1ea03a3Smacallan h = pSrc->pDrawable->height; 1372e1ea03a3Smacallan 1373e1ea03a3Smacallan if(pSrc->repeat) 1374e1ea03a3Smacallan flags |= XAA_RENDER_REPEAT; 1375e1ea03a3Smacallan 1376e1ea03a3Smacallan while(*formats != pSrc->format) { 1377e1ea03a3Smacallan if(!(*formats)) { 1378e1ea03a3Smacallan xf86Msg(X_ERROR, 1379e1ea03a3Smacallan "%s: format %x not found\n", 1380e1ea03a3Smacallan __func__, pSrc->format); 1381e1ea03a3Smacallan return; 1382e1ea03a3Smacallan } 1383e1ea03a3Smacallan formats++; 1384e1ea03a3Smacallan } 1385e1ea03a3Smacallan 1386e1ea03a3Smacallan if (!miComputeCompositeRegion (®ion, pSrc, pMask, pDst, 1387e1ea03a3Smacallan xSrc, ySrc, xMask, yMask, xDst, yDst, 1388e1ea03a3Smacallan width, height)) { 1389e1ea03a3Smacallan return; 1390e1ea03a3Smacallan } 1391e1ea03a3Smacallan 1392e1ea03a3Smacallan nbox = REGION_NUM_RECTS(®ion); 1393e1ea03a3Smacallan pbox = REGION_RECTS(®ion); 1394e1ea03a3Smacallan 1395e1ea03a3Smacallan if(!nbox) { 1396e1ea03a3Smacallan REGION_UNINIT(pScreen, ®ion); 1397e1ea03a3Smacallan return; 1398e1ea03a3Smacallan } 1399e1ea03a3Smacallan 1400e1ea03a3Smacallan CrimeSetupForCPUToScreenTexture(infoRec->pScrn, 1401e1ea03a3Smacallan op, pSrc->format, 1402e1ea03a3Smacallan ((PixmapPtr)(pSrc->pDrawable))->devPrivate.ptr, 1403e1ea03a3Smacallan ((PixmapPtr)(pSrc->pDrawable))->devKind, 1404e1ea03a3Smacallan w, h, flags); 1405e1ea03a3Smacallan 1406e1ea03a3Smacallan xSrc -= xDst; 1407e1ea03a3Smacallan ySrc -= yDst; 1408e1ea03a3Smacallan 1409e1ea03a3Smacallan while(nbox--) { 1410e1ea03a3Smacallan CrimeSubsequentCPUToScreenTexture(infoRec->pScrn, 1411e1ea03a3Smacallan pbox->x1, pbox->y1, pbox->x1 + xSrc, 1412e1ea03a3Smacallan pbox->y1 + ySrc, pbox->x2 - pbox->x1, 1413e1ea03a3Smacallan pbox->y2 - pbox->y1); 1414e1ea03a3Smacallan pbox++; 1415e1ea03a3Smacallan } 1416e1ea03a3Smacallan 1417e1ea03a3Smacallan SET_SYNC_FLAG(infoRec); 1418e1ea03a3Smacallan REGION_UNINIT(pScreen, ®ion); 1419e1ea03a3Smacallan DONE(CRIME_DEBUG_XRENDER); 1420e1ea03a3Smacallan return; 1421e1ea03a3Smacallan } 1422e1ea03a3Smacallan xf86Msg(X_ERROR, "%s: shouldn't be here\n", __func__); 1423e1ea03a3Smacallan} 1424e1ea03a3Smacallan 1425e1ea03a3Smacallanstatic void 1426e1ea03a3SmacallanCrimeDoScreenToScreenComposite( 1427e1ea03a3Smacallan CARD8 op, 1428e1ea03a3Smacallan PicturePtr pSrc, 1429e1ea03a3Smacallan PicturePtr pMask, 1430e1ea03a3Smacallan PicturePtr pDst, 1431e1ea03a3Smacallan INT16 xSrc, 1432e1ea03a3Smacallan INT16 ySrc, 1433e1ea03a3Smacallan INT16 xMask, 1434e1ea03a3Smacallan INT16 yMask, 1435e1ea03a3Smacallan INT16 xDst, 1436e1ea03a3Smacallan INT16 yDst, 1437e1ea03a3Smacallan CARD16 width, 1438e1ea03a3Smacallan CARD16 height 1439e1ea03a3Smacallan) 1440e1ea03a3Smacallan{ 1441e1ea03a3Smacallan ScreenPtr pScreen = pDst->pDrawable->pScreen; 1442e1ea03a3Smacallan XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen); 1443e1ea03a3Smacallan ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 1444e1ea03a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 1445e1ea03a3Smacallan RegionRec region; 1446e1ea03a3Smacallan CARD32 *formats; 1447e1ea03a3Smacallan int flags = 0; 1448e1ea03a3Smacallan BoxPtr pbox; 1449e1ea03a3Smacallan int nbox; 1450e1ea03a3Smacallan int xs, ys, xd, yd, w, h; 1451e1ea03a3Smacallan 1452e1ea03a3Smacallan LOG(CRIME_DEBUG_XRENDER); 1453e1ea03a3Smacallan if (pSrc->transform || (pMask && pMask->transform)) { 1454e1ea03a3Smacallan xf86Msg(X_ERROR, "%s: mask?!\n", __func__); 1455e1ea03a3Smacallan return; 1456e1ea03a3Smacallan } 1457e1ea03a3Smacallan xf86Msg(X_ERROR, "%s: %d\n", __func__, op); 1458e1ea03a3Smacallan if (pDst->alphaMap || pSrc->alphaMap || (pMask && pMask->alphaMap)) { 1459e1ea03a3Smacallan xf86Msg(X_ERROR, "%s: alpha-map\n", __func__); 1460e1ea03a3Smacallan return; 1461e1ea03a3Smacallan } 1462e1ea03a3Smacallan 1463e1ea03a3Smacallan xDst += pDst->pDrawable->x; 1464e1ea03a3Smacallan yDst += pDst->pDrawable->y; 1465e1ea03a3Smacallan xSrc += pSrc->pDrawable->x; 1466e1ea03a3Smacallan ySrc += pSrc->pDrawable->y; 1467e1ea03a3Smacallan 1468e1ea03a3Smacallan formats = infoRec->CPUToScreenTextureFormats; 1469e1ea03a3Smacallan 1470e1ea03a3Smacallan w = pSrc->pDrawable->width; 1471e1ea03a3Smacallan h = pSrc->pDrawable->height; 1472e1ea03a3Smacallan 1473e1ea03a3Smacallan if(pSrc->repeat) 1474e1ea03a3Smacallan flags |= XAA_RENDER_REPEAT; 1475e1ea03a3Smacallan 1476e1ea03a3Smacallan while(*formats != pSrc->format) { 1477e1ea03a3Smacallan if(!(*formats)) return; 1478e1ea03a3Smacallan formats++; 1479e1ea03a3Smacallan } 1480e1ea03a3Smacallan 1481e1ea03a3Smacallan if (!miComputeCompositeRegion (®ion, pSrc, pMask, pDst, 1482e1ea03a3Smacallan xSrc, ySrc, xMask, yMask, xDst, yDst, width, height)) 1483e1ea03a3Smacallan return; 1484e1ea03a3Smacallan 1485e1ea03a3Smacallan nbox = REGION_NUM_RECTS(®ion); 1486e1ea03a3Smacallan pbox = REGION_RECTS(®ion); 1487e1ea03a3Smacallan 1488e1ea03a3Smacallan if(!nbox) { 1489e1ea03a3Smacallan REGION_UNINIT(pScreen, ®ion); 1490e1ea03a3Smacallan return; 1491e1ea03a3Smacallan } 1492e1ea03a3Smacallan 1493e1ea03a3Smacallan SYNC; 1494e1ea03a3Smacallan WRITE4(CRIME_DE_MODE_SRC, DE_MODE_TLB_A | DE_MODE_BUFDEPTH_32 | 1495e1ea03a3Smacallan DE_MODE_TYPE_RGBA | DE_MODE_PIXDEPTH_32); 1496e1ea03a3Smacallan WRITE4(CRIME_DE_XFER_STEP_X, 1); 1497e1ea03a3Smacallan WRITE4(CRIME_DE_ALPHA_FUNC, 1498e1ea03a3Smacallan DE_ALPHA_ADD | 1499e1ea03a3Smacallan (DE_ALPHA_OP_SRC_ALPHA << DE_ALPHA_OP_SRC_SHIFT) | 1500e1ea03a3Smacallan (DE_ALPHA_OP_1_MINUS_SRC_ALPHA << DE_ALPHA_OP_DST_SHIFT)); 1501e1ea03a3Smacallan WRITE4(CRIME_DE_DRAWMODE, 1502e1ea03a3Smacallan DE_DRAWMODE_BYTEMASK | DE_DRAWMODE_ALPHA_BLEND | 1503e1ea03a3Smacallan DE_DRAWMODE_XFER_EN); 1504e1ea03a3Smacallan WRITE4(CRIME_DE_PRIMITIVE, 1505e1ea03a3Smacallan DE_PRIM_RECTANGLE | DE_PRIM_LR | DE_PRIM_TB); 1506e1ea03a3Smacallan 1507e1ea03a3Smacallan xSrc -= xDst; 1508e1ea03a3Smacallan ySrc -= yDst; 1509e1ea03a3Smacallan 1510e1ea03a3Smacallan /* assume no overlap - might bite us in the arse at some point */ 1511e1ea03a3Smacallan while(nbox--) { 1512e1ea03a3Smacallan xs = pbox->x1 + xSrc; 1513e1ea03a3Smacallan ys = pbox->y1 + ySrc; 1514e1ea03a3Smacallan xd = pbox->x1; 1515e1ea03a3Smacallan yd = pbox->y1; 1516e1ea03a3Smacallan w = pbox->x2 - pbox->x1; 1517e1ea03a3Smacallan h = pbox->y2 - pbox->y1; 1518e1ea03a3Smacallan READY; 1519e1ea03a3Smacallan WRITE4(CRIME_DE_XFER_ADDR_SRC,(xs << 16) | (ys & 0xffff)); 1520e1ea03a3Smacallan WRITE4(CRIME_DE_X_VERTEX_0, (xd << 16) | (yd & 0xffff)); 1521e1ea03a3Smacallan WBFLUSH; 1522e1ea03a3Smacallan WRITE4ST(CRIME_DE_X_VERTEX_1, 1523e1ea03a3Smacallan ((xd + w - 1) << 16) | ((yd + h - 1) & 0xffff)); 1524e1ea03a3Smacallan pbox++; 1525e1ea03a3Smacallan } 1526e1ea03a3Smacallan 1527e1ea03a3Smacallan SET_SYNC_FLAG(infoRec); 1528e1ea03a3Smacallan REGION_UNINIT(pScreen, ®ion); 1529e1ea03a3Smacallan return; 1530e1ea03a3Smacallan} 1531e1ea03a3Smacallan 1532e1ea03a3Smacallanstatic Bool 1533e1ea03a3SmacallanCrimeComposite( 1534e1ea03a3Smacallan CARD8 op, 1535e1ea03a3Smacallan PicturePtr pSrc, 1536e1ea03a3Smacallan PicturePtr pMask, 1537e1ea03a3Smacallan PicturePtr pDst, 1538e1ea03a3Smacallan INT16 xSrc, 1539e1ea03a3Smacallan INT16 ySrc, 1540e1ea03a3Smacallan INT16 xMask, 1541e1ea03a3Smacallan INT16 yMask, 1542e1ea03a3Smacallan INT16 xDst, 1543e1ea03a3Smacallan INT16 yDst, 1544e1ea03a3Smacallan CARD16 width, 1545e1ea03a3Smacallan CARD16 height 1546e1ea03a3Smacallan) 1547e1ea03a3Smacallan{ 1548e1ea03a3Smacallan ScreenPtr pScreen = pDst->pDrawable->pScreen; 1549e1ea03a3Smacallan XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen); 1550e1ea03a3Smacallan 1551e1ea03a3Smacallan LOG(CRIME_DEBUG_XRENDER); 1552e1ea03a3Smacallan 1553e1ea03a3Smacallan if(!REGION_NUM_RECTS(pDst->pCompositeClip)) 1554e1ea03a3Smacallan return TRUE; 1555e1ea03a3Smacallan 1556e1ea03a3Smacallan if(!infoRec->pScrn->vtSema) 1557e1ea03a3Smacallan return FALSE; 1558e1ea03a3Smacallan 1559e1ea03a3Smacallan if((pDst->pDrawable->type == DRAWABLE_WINDOW) || 1560e1ea03a3Smacallan IS_OFFSCREEN_PIXMAP(pDst->pDrawable)) { 1561e1ea03a3Smacallan if ((pSrc->pDrawable->type == DRAWABLE_WINDOW) || 1562e1ea03a3Smacallan IS_OFFSCREEN_PIXMAP(pSrc->pDrawable)) { 1563e1ea03a3Smacallan /* screen-to-screen */ 1564e1ea03a3Smacallan CrimeDoScreenToScreenComposite(op, pSrc, pMask, pDst, 1565e1ea03a3Smacallan xSrc, ySrc, xMask, yMask, 1566e1ea03a3Smacallan xDst, yDst, width, height); 1567e1ea03a3Smacallan return TRUE; 1568e1ea03a3Smacallan } else { 1569e1ea03a3Smacallan /* CPU-to-screen composite */ 1570e1ea03a3Smacallan if (op != PictOpOver) 1571e1ea03a3Smacallan xf86Msg(X_ERROR, "%s: op %d\n", __func__, op); 1572e1ea03a3Smacallan CrimeDoCPUToScreenComposite(op, pSrc, pMask, pDst, 1573e1ea03a3Smacallan xSrc, ySrc, xMask, yMask, 1574e1ea03a3Smacallan xDst, yDst, width, height); 1575e1ea03a3Smacallan return TRUE; 1576e1ea03a3Smacallan } 1577e1ea03a3Smacallan } else { 1578e1ea03a3Smacallan if ((pSrc->pDrawable->type == DRAWABLE_WINDOW) || 1579e1ea03a3Smacallan IS_OFFSCREEN_PIXMAP(pSrc->pDrawable)) { 1580e1ea03a3Smacallan /* screen-to-RAM */ 1581e1ea03a3Smacallan xf86Msg(X_ERROR, "%s: screen-to-RAM composite\n", 1582e1ea03a3Smacallan __func__); 1583e1ea03a3Smacallan return TRUE; 1584e1ea03a3Smacallan } else { 1585e1ea03a3Smacallan /* RAM-to-RAM */ 1586e1ea03a3Smacallan return FALSE; 1587e1ea03a3Smacallan } 1588e1ea03a3Smacallan } 1589e1ea03a3Smacallan xf86Msg(X_ERROR, "composite fucked\n"); 1590e1ea03a3Smacallan} 1591e1ea03a3Smacallan 1592e1ea03a3Smacallanstatic void 1593e1ea03a3SmacallanCrimePolyPoint( 1594e1ea03a3Smacallan DrawablePtr pDraw, 1595e1ea03a3Smacallan GCPtr pGC, 1596e1ea03a3Smacallan int mode, 1597e1ea03a3Smacallan int npt, 1598e1ea03a3Smacallan xPoint *pptInit 1599e1ea03a3Smacallan) 1600e1ea03a3Smacallan{ 1601e1ea03a3Smacallan ScreenPtr pScreen = pDraw->pScreen; 1602e1ea03a3Smacallan ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 1603e1ea03a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 1604e1ea03a3Smacallan BoxPtr pBox; 1605e1ea03a3Smacallan xPoint *ppt, *pts; 1606e1ea03a3Smacallan int x1, x2, y1, y2, x, y, i, nBox; 1607e1ea03a3Smacallan 1608e1ea03a3Smacallan /* make pointlist origin relative */ 1609e1ea03a3Smacallan ppt = pptInit; 1610e1ea03a3Smacallan if (mode == CoordModePrevious) { 1611e1ea03a3Smacallan for (i = 0; i < npt; i++) { 1612e1ea03a3Smacallan ppt++; 1613e1ea03a3Smacallan ppt->x += (ppt-1)->x; 1614e1ea03a3Smacallan ppt->y += (ppt-1)->y; 1615e1ea03a3Smacallan } 1616e1ea03a3Smacallan } 1617e1ea03a3Smacallan SYNC; 1618e1ea03a3Smacallan WRITE4(CRIME_DE_FG, pGC->fgPixel << 8); 1619e1ea03a3Smacallan WRITE4(CRIME_DE_ROP, pGC->alu); 1620e1ea03a3Smacallan WRITE4(CRIME_DE_PLANEMASK, pGC->planemask); 1621e1ea03a3Smacallan WRITE4(CRIME_DE_DRAWMODE, 1622e1ea03a3Smacallan DE_DRAWMODE_PLANEMASK | DE_DRAWMODE_BYTEMASK | DE_DRAWMODE_ROP); 1623e1ea03a3Smacallan WRITE4(CRIME_DE_PRIMITIVE, DE_PRIM_POINT); 1624e1ea03a3Smacallan for (nBox = REGION_NUM_RECTS (pGC->pCompositeClip), 1625e1ea03a3Smacallan pBox = REGION_RECTS (pGC->pCompositeClip); 1626e1ea03a3Smacallan nBox--; pBox++) { 1627e1ea03a3Smacallan 1628e1ea03a3Smacallan pts = pptInit; 1629e1ea03a3Smacallan for (i = 0; i < npt; i++) { 1630e1ea03a3Smacallan x1 = pBox->x1; 1631e1ea03a3Smacallan y1 = pBox->y1; 1632e1ea03a3Smacallan x2 = pBox->x2; 1633e1ea03a3Smacallan y2 = pBox->y2; 1634e1ea03a3Smacallan x = pts->x + pDraw->x; 1635e1ea03a3Smacallan y = pts->y + pDraw->y; 1636e1ea03a3Smacallan if (x1 <= x && x < x2 && y1 <= y && y < y2) { 1637e1ea03a3Smacallan 1638e1ea03a3Smacallan READY; 1639e1ea03a3Smacallan WRITE4ST(CRIME_DE_X_VERTEX_0, 1640e1ea03a3Smacallan (x << 16) | y); 1641e1ea03a3Smacallan } 1642e1ea03a3Smacallan pts++; 1643e1ea03a3Smacallan } 1644e1ea03a3Smacallan } 1645e1ea03a3Smacallan} 1646e1ea03a3Smacallan 1647e1ea03a3Smacallanstatic void 1648e1ea03a3SmacallanCrimeValidatePolyPoint( 1649e1ea03a3Smacallan GCPtr pGC, 1650e1ea03a3Smacallan unsigned long changes, 1651e1ea03a3Smacallan DrawablePtr pDraw ) 1652e1ea03a3Smacallan{ 1653e1ea03a3Smacallan 1654e1ea03a3Smacallan if ((pDraw->type == DRAWABLE_WINDOW) || 1655e1ea03a3Smacallan IS_OFFSCREEN_PIXMAP(pDraw)) { 1656e1ea03a3Smacallan pGC->ops->PolyPoint = CrimePolyPoint; 1657e1ea03a3Smacallan } else 1658e1ea03a3Smacallan xf86Msg(X_ERROR, "boo\n"); 1659e1ea03a3Smacallan} 166034c4e112Smacallanstatic void 166134c4e112SmacallanCrimePolyArc(DrawablePtr pDraw, 166234c4e112Smacallan GCPtr pGC, 166334c4e112Smacallan int narcs, 166434c4e112Smacallan xArc *parcs) 166534c4e112Smacallan{ 166634c4e112Smacallan xArc *arc; 166734c4e112Smacallan BoxRec box; 166834c4e112Smacallan int i, x2, y2; 166934c4e112Smacallan RegionPtr cclip; 167034c4e112Smacallan 167134c4e112Smacallan cclip = pGC->pCompositeClip; 167234c4e112Smacallan 167334c4e112Smacallan if(!REGION_NUM_RECTS(cclip)) 167434c4e112Smacallan return; 167534c4e112Smacallan 167634c4e112Smacallan for (arc = parcs, i = narcs; --i >= 0; arc++) { 167734c4e112Smacallan if (miCanZeroArc(arc)) { 167834c4e112Smacallan box.x1 = arc->x + pDraw->x; 167934c4e112Smacallan box.y1 = arc->y + pDraw->y; 168034c4e112Smacallan x2 = box.x1 + (int)arc->width + 1; 168134c4e112Smacallan box.x2 = x2; 168234c4e112Smacallan y2 = box.y1 + (int)arc->height + 1; 168334c4e112Smacallan box.y2 = y2; 168434c4e112Smacallan if ( (x2 <= SHRT_MAX) && (y2 <= SHRT_MAX) && 168534c4e112Smacallan (RECT_IN_REGION(pDraw->pScreen, cclip, &box) == rgnIN) ) 168634c4e112Smacallan miZeroPolyArc(pDraw, pGC, 1, arc); 168734c4e112Smacallan } 168834c4e112Smacallan else 168934c4e112Smacallan miPolyArc(pDraw, pGC, 1, arc); 169034c4e112Smacallan } 169134c4e112Smacallan} 169234c4e112Smacallan 169334c4e112Smacallanstatic void 169434c4e112SmacallanCrimeValidatePolyArc(GCPtr pGC, 169534c4e112Smacallan unsigned long changes, 169634c4e112Smacallan DrawablePtr pDraw) 169734c4e112Smacallan{ 169834c4e112Smacallan if ((pDraw->type == DRAWABLE_WINDOW) || 169934c4e112Smacallan IS_OFFSCREEN_PIXMAP(pDraw)) { 170034c4e112Smacallan pGC->ops->PolyPoint = CrimePolyPoint; 170134c4e112Smacallan /*pGC->ops->PolyArc = miPolyArc;*/ 170234c4e112Smacallan pGC->ops->PolyArc = CrimePolyArc; 170334c4e112Smacallan } else 170434c4e112Smacallan { 170534c4e112Smacallan pGC->ops->PolyPoint = XAAGetFallbackOps()->PolyPoint; 170634c4e112Smacallan pGC->ops->PolyArc = XAAGetFallbackOps()->PolyArc; 170734c4e112Smacallan } 170834c4e112Smacallan} 1709e1ea03a3Smacallan 171034c4e112Smacallanstatic void 171134c4e112SmacallanCrimeReadPixmap(ScrnInfoPtr pScrn, 171234c4e112Smacallan int x, 171334c4e112Smacallan int y, 171434c4e112Smacallan int w, 171534c4e112Smacallan int h, 171634c4e112Smacallan unsigned char *dst, 171734c4e112Smacallan int dstwidth, 171834c4e112Smacallan int bpp, 171934c4e112Smacallan int depth) 172034c4e112Smacallan{ 172134c4e112Smacallan /* dummy for now */ 172234c4e112Smacallan LOG(CRIME_DEBUG_IMAGEWRITE); 172334c4e112Smacallan} 1724e1ea03a3Smacallanint 1725e1ea03a3SmacallanCrimeAccelInit(ScrnInfoPtr pScrn) 1726e1ea03a3Smacallan{ 1727e1ea03a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 1728e1ea03a3Smacallan XAAInfoRecPtr pXAAInfo = fPtr->pXAA; 1729e1ea03a3Smacallan int i; 1730e1ea03a3Smacallan 1731e1ea03a3Smacallan for (i = 0; i < 0x1000; i++) regcache[i] = 0x12345678; 1732e1ea03a3Smacallan LOG(CRIME_DEBUG_ALL); 1733e1ea03a3Smacallan SYNC; 1734e1ea03a3Smacallan WRITE4(CRIME_DE_MODE_DST, DE_MODE_TLB_A | DE_MODE_BUFDEPTH_32 | 1735e1ea03a3Smacallan DE_MODE_TYPE_RGBA | DE_MODE_PIXDEPTH_32); 1736e1ea03a3Smacallan 1737e1ea03a3Smacallan WRITE4(CRIME_DE_XFER_STEP_Y, 1); 1738e1ea03a3Smacallan WRITE4(CRIME_DE_XFER_STRD_DST, 0); 1739e1ea03a3Smacallan WRITE4(CRIME_DE_XFER_STRD_SRC, 1); 1740e1ea03a3Smacallan 1741e1ea03a3Smacallan WRITE4(CRIME_MTE_BYTEMASK, 0xffffffff); 1742e1ea03a3Smacallan WRITE4(CRIME_MTE_SRC_Y_STEP, 4); 1743e1ea03a3Smacallan WRITE4(CRIME_MTE_DST_Y_STEP, 4); 1744e1ea03a3Smacallan 1745e1ea03a3Smacallan /* blit the screen black */ 1746e1ea03a3Smacallan WRITE4(CRIME_DE_DRAWMODE, 1747e1ea03a3Smacallan DE_DRAWMODE_PLANEMASK | DE_DRAWMODE_BYTEMASK | DE_DRAWMODE_ROP); 1748e1ea03a3Smacallan WRITE4(CRIME_DE_ROP, 3); 1749e1ea03a3Smacallan WRITE4(CRIME_DE_PRIMITIVE, DE_PRIM_RECTANGLE | DE_PRIM_LR | DE_PRIM_TB); 1750e1ea03a3Smacallan WRITE4(CRIME_DE_FG, 0); 1751e1ea03a3Smacallan WRITE4(CRIME_DE_X_VERTEX_0, 0); 1752e1ea03a3Smacallan WRITE4ST(CRIME_DE_X_VERTEX_1, 1753e1ea03a3Smacallan fPtr->info.width << 16 | fPtr->info.height); 1754e1ea03a3Smacallan SYNC; 1755e1ea03a3Smacallan 175634c4e112Smacallan pXAAInfo->Flags = /*LINEAR_FRAMEBUFFER |*/ PIXMAP_CACHE | OFFSCREEN_PIXMAPS; 1757e1ea03a3Smacallan pXAAInfo->maxOffPixWidth = fPtr->info.width; 1758e1ea03a3Smacallan pXAAInfo->maxOffPixHeight = 2048; 1759e1ea03a3Smacallan 1760e1ea03a3Smacallan /* Sync */ 1761e1ea03a3Smacallan pXAAInfo->Sync = CrimeSync; 1762e1ea03a3Smacallan 1763e1ea03a3Smacallan /* Screen-to-screen copy */ 1764e1ea03a3Smacallan pXAAInfo->ScreenToScreenCopyFlags = NO_TRANSPARENCY; 1765e1ea03a3Smacallan pXAAInfo->SetupForScreenToScreenCopy = CrimeSetupForScreenToScreenCopy; 1766e1ea03a3Smacallan pXAAInfo->SubsequentScreenToScreenCopy = 1767e1ea03a3Smacallan CrimeSubsequentScreenToScreenCopy; 1768e1ea03a3Smacallan 1769e1ea03a3Smacallan /* rectangle fills */ 1770e1ea03a3Smacallan pXAAInfo->SetupForSolidFill = CrimeSetupForSolidFill; 1771e1ea03a3Smacallan pXAAInfo->SubsequentSolidFillRect = CrimeSubsequentSolidFillRect; 1772e1ea03a3Smacallan 1773e1ea03a3Smacallan /* image writes */ 1774e1ea03a3Smacallan pXAAInfo->ScanlineImageWriteFlags = 1775e1ea03a3Smacallan NO_TRANSPARENCY | LEFT_EDGE_CLIPPING | 1776e1ea03a3Smacallan LEFT_EDGE_CLIPPING_NEGATIVE_X | 1777e1ea03a3Smacallan CPU_TRANSFER_PAD_DWORD | SCANLINE_PAD_DWORD; 1778e1ea03a3Smacallan pXAAInfo->NumScanlineImageWriteBuffers = 8; 1779e1ea03a3Smacallan for (i = 0; i < 8; i++) 1780e1ea03a3Smacallan fPtr->buffers[i] = fPtr->linear + (i * 8192); 1781e1ea03a3Smacallan pXAAInfo->ScanlineImageWriteBuffers = fPtr->buffers; 1782e1ea03a3Smacallan pXAAInfo->SetupForScanlineImageWrite = 1783e1ea03a3Smacallan CrimeSetupForScanlineImageWrite; 1784e1ea03a3Smacallan pXAAInfo->SubsequentScanlineImageWriteRect = 1785e1ea03a3Smacallan CrimeSubsequentImageWriteRect; 1786e1ea03a3Smacallan pXAAInfo->SubsequentImageWriteScanline = 1787e1ea03a3Smacallan CrimeSubsequentImageWriteScanline; 1788e1ea03a3Smacallan 178934c4e112Smacallan /* read pixmap */ 179034c4e112Smacallan pXAAInfo->ReadPixmapFlags = 0 179134c4e112Smacallan | CPU_TRANSFER_PAD_DWORD 179234c4e112Smacallan ; 179334c4e112Smacallan pXAAInfo->ReadPixmap = CrimeReadPixmap; 179434c4e112Smacallan 1795e1ea03a3Smacallan /* colour expansion */ 1796e1ea03a3Smacallan pXAAInfo->ScanlineCPUToScreenColorExpandFillFlags = 1797e1ea03a3Smacallan LEFT_EDGE_CLIPPING; 1798e1ea03a3Smacallan pXAAInfo->NumScanlineColorExpandBuffers = 1; 1799e1ea03a3Smacallan fPtr->expandbuffers[0] = (uint8_t *)fPtr->expand; 1800e1ea03a3Smacallan pXAAInfo->ScanlineColorExpandBuffers = (void *)&fPtr->expandbuffers; 1801e1ea03a3Smacallan pXAAInfo->SetupForScanlineCPUToScreenColorExpandFill = 1802e1ea03a3Smacallan CrimeSetupForCPUToScreenColorExpandFill; 1803e1ea03a3Smacallan pXAAInfo->SubsequentScanlineCPUToScreenColorExpandFill = 1804e1ea03a3Smacallan CrimeSubsequentScanlineCPUToScreenColorExpandFill; 1805e1ea03a3Smacallan pXAAInfo->SubsequentColorExpandScanline = 1806e1ea03a3Smacallan CrimeSubsequentColorExpandScanline; 1807e1ea03a3Smacallan 1808e1ea03a3Smacallan /* clipping */ 1809e1ea03a3Smacallan pXAAInfo->ClippingFlags = HARDWARE_CLIP_SCREEN_TO_SCREEN_COPY | 1810e1ea03a3Smacallan HARDWARE_CLIP_SOLID_FILL | HARDWARE_CLIP_SOLID_LINE; 1811e1ea03a3Smacallan pXAAInfo->SetClippingRectangle = CrimeSetClippingRectangle; 1812e1ea03a3Smacallan pXAAInfo->DisableClipping = CrimeDisableClipping; 1813e1ea03a3Smacallan 1814e1ea03a3Smacallan /* solid line drawing */ 1815e1ea03a3Smacallan pXAAInfo->SetupForSolidLine = CrimeSetupForSolidLine; 1816e1ea03a3Smacallan pXAAInfo->SubsequentSolidTwoPointLine = 1817e1ea03a3Smacallan CrimeSubsequentSolidTwoPointLine; 1818e1ea03a3Smacallan pXAAInfo->SolidLineFlags = BIT_ORDER_IN_BYTE_MSBFIRST; 1819e1ea03a3Smacallan 1820e1ea03a3Smacallan /* dashed line drawing */ 1821e1ea03a3Smacallan pXAAInfo->SetupForDashedLine = CrimeSetupForDashedLine; 1822e1ea03a3Smacallan pXAAInfo->SubsequentDashedTwoPointLine = 1823e1ea03a3Smacallan CrimeSubsequentDashedTwoPointLine; 1824e1ea03a3Smacallan pXAAInfo->DashedLineFlags = LINE_PATTERN_MSBFIRST_MSBJUSTIFIED; 1825e1ea03a3Smacallan pXAAInfo->DashPatternMaxLength = 32; 1826e1ea03a3Smacallan 1827e1ea03a3Smacallan /* XRender acceleration */ 1828e1ea03a3Smacallan#ifdef RENDER 1829e1ea03a3Smacallan pXAAInfo->CPUToScreenAlphaTextureFlags = 0; 1830e1ea03a3Smacallan pXAAInfo->SetupForCPUToScreenAlphaTexture = 1831e1ea03a3Smacallan CrimeSetupForCPUToScreenAlphaTexture; 1832e1ea03a3Smacallan pXAAInfo->SubsequentCPUToScreenAlphaTexture = 1833e1ea03a3Smacallan CrimeSubsequentCPUToScreenAlphaTexture; 1834e1ea03a3Smacallan pXAAInfo->CPUToScreenAlphaTextureFormats = CrimeAlphaTextureFormats; 1835e1ea03a3Smacallan 1836e1ea03a3Smacallan pXAAInfo->SetupForCPUToScreenTexture = CrimeSetupForCPUToScreenTexture; 1837e1ea03a3Smacallan pXAAInfo->SubsequentCPUToScreenTexture = 1838e1ea03a3Smacallan CrimeSubsequentCPUToScreenTexture; 1839e1ea03a3Smacallan pXAAInfo->CPUToScreenTextureFlags = 0; 1840e1ea03a3Smacallan pXAAInfo->CPUToScreenTextureFormats = CrimeTextureFormats; 1841e1ea03a3Smacallan pXAAInfo->Composite = CrimeComposite; 1842e1ea03a3Smacallan#endif 1843e1ea03a3Smacallan pXAAInfo->ValidatePolyPoint = CrimeValidatePolyPoint; 1844e1ea03a3Smacallan pXAAInfo->PolyPointMask = GCFunction; 184534c4e112Smacallan pXAAInfo->ValidatePolyArc = CrimeValidatePolyArc; 184634c4e112Smacallan pXAAInfo->PolyArcMask = GCFunction | GCLineWidth; 1847e1ea03a3Smacallan 1848e1ea03a3Smacallan return -1; 1849e1ea03a3Smacallan} 1850