crime_accel.c revision 850ab569
1850ab569Smacallan/* $NetBSD: crime_accel.c,v 1.11 2009/09/29 20:41:22 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" 37850ab569Smacallan#include "xaa.h" 38e1ea03a3Smacallan 39e1ea03a3Smacallanuint32_t regcache[0x1000]; 40e1ea03a3Smacallan 41e1ea03a3Smacallan#define CRIMEREG(p) (volatile uint32_t *)(fPtr->engine + p) 42e1ea03a3Smacallan/*#define WBFLUSH { volatile uint32_t boo = *CRIMEREG(0x4000); }*/ 43e1ea03a3Smacallan#define WBFLUSH __asm__ ("nop; sync;") 44e1ea03a3Smacallan#if 0 45e1ea03a3Smacallan#define WRITE4(r, v) {if (regcache[r >> 2] != v) { \ 46e1ea03a3Smacallan *CRIMEREG(r) = v; \ 47e1ea03a3Smacallan regcache[r >> 2] = v; } } 48e1ea03a3Smacallan#else 49e1ea03a3Smacallan#define WRITE4(r, v) { *CRIMEREG(r) = v; } 50e1ea03a3Smacallan#endif 51e1ea03a3Smacallan#define WRITE4ST(r, v) {WBFLUSH; *CRIMEREG(r + CRIME_DE_START) = v; WBFLUSH;} 52850ab569Smacallan#ifdef CRIME_DEBUG 53e1ea03a3Smacallan#define SYNC { int bail = 0; do {bail++; } \ 54e1ea03a3Smacallan while(((*CRIMEREG(0x4000) & CRIME_DE_IDLE) == 0) && (bail < 10000000)); \ 55e1ea03a3Smacallan if (bail == 10000000) { \ 56e1ea03a3Smacallan xf86Msg(X_ERROR, "sync timeout\n"); \ 57e1ea03a3Smacallan WRITE4ST(CRIME_MTE_FLUSH, 0); \ 58e1ea03a3Smacallan WRITE4ST(CRIME_DE_FLUSH, 0); \ 59e1ea03a3Smacallan } \ 60e1ea03a3Smacallan } 61e1ea03a3Smacallan#else 62e1ea03a3Smacallan#define SYNC do {} while ((*CRIMEREG(0x4000) & CRIME_DE_IDLE) == 0) 6326dcc2a3Smacallan#define SYNCMTE do {} while ((*CRIMEREG(0x4000) & CRIME_DE_MTE_IDLE) == 0) 64e1ea03a3Smacallan#endif 6526dcc2a3Smacallan#define MAKE_ROOM(x) do {} while ((16 - \ 6626dcc2a3Smacallan CRIME_PIPE_LEVEL(*CRIMEREG(0x4000))) < x); 67e1ea03a3Smacallan 687a6652bbSmacallan#define MAX(a, b) (a > b ? a : b) 697a6652bbSmacallan#define MIN(a, b) (a < b ? a : b) 707a6652bbSmacallan 71e1ea03a3SmacallanCARD32 CrimeAlphaTextureFormats[] = {PICT_a8, 0}; 72e1ea03a3SmacallanCARD32 CrimeTextureFormats[] = {PICT_a8b8g8r8, PICT_a8r8g8b8, 0}; 73e1ea03a3Smacallan 74e1ea03a3Smacallanvoid 75e1ea03a3SmacallanCrimeSync(ScrnInfoPtr pScrn) 76e1ea03a3Smacallan{ 77e1ea03a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 78e1ea03a3Smacallan#ifdef CRIME_DEBUG_LOUD 79e1ea03a3Smacallan volatile uint32_t *status = CRIMEREG(CRIME_DE_STATUS); 80e1ea03a3Smacallan 81e1ea03a3Smacallan xf86Msg(X_ERROR, "%s: %08x\n", __func__, *status); 82e1ea03a3Smacallan#endif 83e1ea03a3Smacallan LOG(CRIME_DEBUG_SYNC); 84e1ea03a3Smacallan SYNC; 85e1ea03a3Smacallan} 86e1ea03a3Smacallan 87e1ea03a3Smacallanstatic void 88e1ea03a3SmacallanCrimeSetupForScreenToScreenCopy( 89e1ea03a3Smacallan ScrnInfoPtr pScrn, 90e1ea03a3Smacallan int xdir, 91e1ea03a3Smacallan int ydir, 92e1ea03a3Smacallan int rop, 93e1ea03a3Smacallan unsigned int planemask, 94e1ea03a3Smacallan int TransparencyColour 95e1ea03a3Smacallan) 96e1ea03a3Smacallan{ 97e1ea03a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 98e1ea03a3Smacallan 99e1ea03a3Smacallan LOG(CRIME_DEBUG_BITBLT); 10026dcc2a3Smacallan MAKE_ROOM(9); 101e1ea03a3Smacallan if ((rop == GXcopy) && (planemask == 0xffffffff) && (xdir > 0)) { 102e1ea03a3Smacallan /* use the MTE */ 103e1ea03a3Smacallan WRITE4(CRIME_MTE_MODE, MTE_MODE_DST_ECC | 104e1ea03a3Smacallan MTE_TLB_A << MTE_DST_TLB_SHIFT | 105e1ea03a3Smacallan MTE_TLB_A << MTE_SRC_TLB_SHIFT | 106e1ea03a3Smacallan MTE_DEPTH_32 << MTE_DEPTH_SHIFT | 107e1ea03a3Smacallan MTE_MODE_COPY); 108e1ea03a3Smacallan fPtr->use_mte = 1; 109e1ea03a3Smacallan if (ydir > 0) { 110e1ea03a3Smacallan WRITE4(CRIME_MTE_DST_Y_STEP, 1); 111e1ea03a3Smacallan WRITE4(CRIME_MTE_SRC_Y_STEP, 1); 112e1ea03a3Smacallan } else { 113e1ea03a3Smacallan WRITE4(CRIME_MTE_DST_Y_STEP, -1); 114e1ea03a3Smacallan WRITE4(CRIME_MTE_SRC_Y_STEP, -1); 115e1ea03a3Smacallan } 116e1ea03a3Smacallan } else 117e1ea03a3Smacallan fPtr->use_mte = 0; 118e1ea03a3Smacallan 119e1ea03a3Smacallan WRITE4(CRIME_DE_XFER_STEP_X, 1); 120e1ea03a3Smacallan WRITE4(CRIME_DE_PLANEMASK, planemask); 121e1ea03a3Smacallan WRITE4(CRIME_DE_ROP, rop); 122e1ea03a3Smacallan WRITE4(CRIME_DE_DRAWMODE, 123e1ea03a3Smacallan DE_DRAWMODE_PLANEMASK | DE_DRAWMODE_BYTEMASK | 124e1ea03a3Smacallan DE_DRAWMODE_ROP | DE_DRAWMODE_XFER_EN); 125e1ea03a3Smacallan WRITE4(CRIME_DE_MODE_SRC, DE_MODE_TLB_A | DE_MODE_BUFDEPTH_32 | 126e1ea03a3Smacallan DE_MODE_TYPE_RGBA | DE_MODE_PIXDEPTH_32); 12726dcc2a3Smacallan WRITE4(CRIME_DE_MODE_DST, DE_MODE_TLB_A | DE_MODE_BUFDEPTH_32 | 12826dcc2a3Smacallan DE_MODE_TYPE_RGBA | DE_MODE_PIXDEPTH_32); 129e1ea03a3Smacallan fPtr->xdir = xdir; 130e1ea03a3Smacallan fPtr->ydir = ydir; 13126dcc2a3Smacallan SYNC; 132e1ea03a3Smacallan DONE(CRIME_DEBUG_BITBLT); 133e1ea03a3Smacallan} 134e1ea03a3Smacallan 135e1ea03a3Smacallanstatic void 136e1ea03a3SmacallanCrimeSubsequentScreenToScreenCopy 137e1ea03a3Smacallan( 138e1ea03a3Smacallan ScrnInfoPtr pScrn, 139e1ea03a3Smacallan int xSrc, 140e1ea03a3Smacallan int ySrc, 141e1ea03a3Smacallan int xDst, 142e1ea03a3Smacallan int yDst, 143e1ea03a3Smacallan int w, 144e1ea03a3Smacallan int h 145e1ea03a3Smacallan) 146e1ea03a3Smacallan{ 147e1ea03a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 148e1ea03a3Smacallan uint32_t prim = DE_PRIM_RECTANGLE; 149e1ea03a3Smacallan uint32_t rxa, rya, rxe, rye, rxs, rys, rxd, ryd, rxde, ryde; 150e1ea03a3Smacallan 151e1ea03a3Smacallan LOG(CRIME_DEBUG_BITBLT); 152e1ea03a3Smacallan#ifdef CRIME_DEBUG_LOUD 153e1ea03a3Smacallan xf86Msg(X_ERROR, "%s: %d, %d; %d x %d -> %d %d\n", __func__, 154e1ea03a3Smacallan xSrc, ySrc, w, h, xDst, yDst); 155e1ea03a3Smacallan#endif 156231734e4Smacallan if ((fPtr->use_mte) && (w > 64) && /*((w & 3) == 0) &&*/ 157231734e4Smacallan ((xSrc & 15) == (xDst & 15))) { 158e1ea03a3Smacallan if (fPtr->ydir == -1) { 159e1ea03a3Smacallan /* bottom to top */ 160e1ea03a3Smacallan rye = ySrc; 161e1ea03a3Smacallan rya = ySrc + h - 1; 162e1ea03a3Smacallan ryd = yDst + h - 1; 163e1ea03a3Smacallan ryde = yDst; 164e1ea03a3Smacallan } else { 165e1ea03a3Smacallan /* top to bottom */ 166e1ea03a3Smacallan rye = ySrc + h - 1; 167e1ea03a3Smacallan rya = ySrc; 168e1ea03a3Smacallan ryd = yDst; 169e1ea03a3Smacallan ryde = yDst + h - 1; 170e1ea03a3Smacallan } 171e1ea03a3Smacallan rxa = xSrc << 2; 172e1ea03a3Smacallan rxe = ((xSrc + w) << 2) - 1; 173e1ea03a3Smacallan rxd = xDst << 2; 174e1ea03a3Smacallan rxde = ((xDst + w) << 2) - 1; 17526dcc2a3Smacallan MAKE_ROOM(4); 176e1ea03a3Smacallan WRITE4(CRIME_MTE_SRC0, (rxa << 16) | rya); 177e1ea03a3Smacallan WRITE4(CRIME_MTE_SRC1, (rxe << 16) | rye); 178e1ea03a3Smacallan WRITE4(CRIME_MTE_DST0, (rxd << 16) | ryd); 179e1ea03a3Smacallan WRITE4ST(CRIME_MTE_DST1, (rxde << 16) | ryde); 180e1ea03a3Smacallan 181e1ea03a3Smacallan#ifdef CRIME_DEBUG_LOUD 182e1ea03a3Smacallan xf86Msg(X_ERROR, "reg: %08x %08x\n", oreg, reg); 183e1ea03a3Smacallan#endif 184e1ea03a3Smacallan } else { 185e1ea03a3Smacallan if (fPtr->xdir == -1) { 186e1ea03a3Smacallan prim |= DE_PRIM_RL; 187e1ea03a3Smacallan rxe = xDst; 188e1ea03a3Smacallan rxa = xDst + w - 1; 189e1ea03a3Smacallan rxs = xSrc + w - 1; 190e1ea03a3Smacallan } else { 191e1ea03a3Smacallan prim |= DE_PRIM_LR; 192e1ea03a3Smacallan rxe = xDst + w - 1; 193e1ea03a3Smacallan rxa = xDst; 194e1ea03a3Smacallan rxs = xSrc; 195e1ea03a3Smacallan } 196e1ea03a3Smacallan if (fPtr->ydir == -1) { 197e1ea03a3Smacallan prim |= DE_PRIM_BT; 198e1ea03a3Smacallan rye = yDst; 199e1ea03a3Smacallan rya = yDst + h - 1; 200e1ea03a3Smacallan rys = ySrc + h - 1; 201e1ea03a3Smacallan } else { 202e1ea03a3Smacallan prim |= DE_PRIM_TB; 203e1ea03a3Smacallan rye = yDst + h - 1; 204e1ea03a3Smacallan rya = yDst; 205e1ea03a3Smacallan rys = ySrc; 206e1ea03a3Smacallan } 207e1ea03a3Smacallan 20826dcc2a3Smacallan MAKE_ROOM(4); 209e1ea03a3Smacallan WRITE4(CRIME_DE_PRIMITIVE, prim); 210e1ea03a3Smacallan WRITE4(CRIME_DE_XFER_ADDR_SRC,(rxs << 16) | (rys & 0xffff)); 211e1ea03a3Smacallan WRITE4(CRIME_DE_X_VERTEX_0, (rxa << 16) | (rya & 0xffff)); 212e1ea03a3Smacallan WRITE4ST(CRIME_DE_X_VERTEX_1, (rxe << 16) | (rye & 0xffff)); 213e1ea03a3Smacallan } 214e1ea03a3Smacallan DONE(CRIME_DEBUG_BITBLT); 215e1ea03a3Smacallan} 216e1ea03a3Smacallan 217e1ea03a3Smacallanstatic void 218e1ea03a3SmacallanCrimeSetupForSolidFill 219e1ea03a3Smacallan( 220e1ea03a3Smacallan ScrnInfoPtr pScrn, 221e1ea03a3Smacallan int colour, 222e1ea03a3Smacallan int rop, 223e1ea03a3Smacallan unsigned int planemask 224e1ea03a3Smacallan) 225e1ea03a3Smacallan{ 226e1ea03a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 227e1ea03a3Smacallan int i; 228e1ea03a3Smacallan 229e1ea03a3Smacallan LOG(CRIME_DEBUG_RECTFILL); 230850ab569Smacallan#ifdef MTE_DRAW_RECT 231231734e4Smacallan if (rop == GXcopy) { 232231734e4Smacallan fPtr->use_mte = 1; 233231734e4Smacallan MAKE_ROOM(3); 234231734e4Smacallan WRITE4(CRIME_MTE_MODE, MTE_MODE_DST_ECC | 235231734e4Smacallan MTE_TLB_A << MTE_DST_TLB_SHIFT | 236231734e4Smacallan MTE_TLB_A << MTE_SRC_TLB_SHIFT | 237231734e4Smacallan MTE_DEPTH_32 << MTE_DEPTH_SHIFT); 238231734e4Smacallan WRITE4(CRIME_MTE_DST_Y_STEP, 1); 239231734e4Smacallan WRITE4(CRIME_MTE_BG, colour << 8); 240231734e4Smacallan SYNCMTE; 241850ab569Smacallan } else 242850ab569Smacallan#endif 243850ab569Smacallan { 244231734e4Smacallan fPtr->use_mte = 0; 245231734e4Smacallan MAKE_ROOM(7); 246231734e4Smacallan WRITE4(CRIME_DE_PLANEMASK, planemask); 247231734e4Smacallan WRITE4(CRIME_DE_ROP, rop); 248231734e4Smacallan WRITE4(CRIME_DE_FG, colour << 8); 249231734e4Smacallan WRITE4(CRIME_DE_DRAWMODE, 250231734e4Smacallan DE_DRAWMODE_PLANEMASK | DE_DRAWMODE_BYTEMASK | 251231734e4Smacallan DE_DRAWMODE_ROP |\ 252231734e4Smacallan DE_DRAWMODE_SCISSOR_EN); 253231734e4Smacallan WRITE4(CRIME_DE_PRIMITIVE, 254231734e4Smacallan DE_PRIM_RECTANGLE | DE_PRIM_LR | DE_PRIM_TB); 255231734e4Smacallan WRITE4(CRIME_DE_MODE_DST, DE_MODE_TLB_A | DE_MODE_BUFDEPTH_32 | 256231734e4Smacallan DE_MODE_TYPE_RGBA | DE_MODE_PIXDEPTH_32); 257231734e4Smacallan SYNC; 258231734e4Smacallan } 259e1ea03a3Smacallan DONE(CRIME_DEBUG_RECTFILL); 260e1ea03a3Smacallan} 261e1ea03a3Smacallan 262e1ea03a3Smacallanstatic void 263e1ea03a3SmacallanCrimeSubsequentSolidFillRect 264e1ea03a3Smacallan( 265e1ea03a3Smacallan ScrnInfoPtr pScrn, 266e1ea03a3Smacallan int x, 267e1ea03a3Smacallan int y, 268e1ea03a3Smacallan int w, 269e1ea03a3Smacallan int h 270e1ea03a3Smacallan) 271e1ea03a3Smacallan{ 272e1ea03a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 2737a6652bbSmacallan int xa, xe, ya, ye; 274e1ea03a3Smacallan 275e1ea03a3Smacallan LOG(CRIME_DEBUG_RECTFILL); 276850ab569Smacallan#ifdef MTE_DRAW_RECT 277231734e4Smacallan if (fPtr->use_mte) { 2787a6652bbSmacallan 2797a6652bbSmacallan /* 2807a6652bbSmacallan * the MTE doesn't support clipping so we have to do it 2817a6652bbSmacallan * ourselves - luckily it's trivial with rectangles 2827a6652bbSmacallan */ 2837a6652bbSmacallan xa = MAX(fPtr->cxa, x); 2847a6652bbSmacallan ya = MAX(fPtr->cya, y); 2857a6652bbSmacallan xe = MIN(fPtr->cxe, x + w); 2867a6652bbSmacallan ye = MIN(fPtr->cye, y + h); 2877a6652bbSmacallan if ((xa < xe) && (ya < ye)) { 2887a6652bbSmacallan MAKE_ROOM(2); 2897a6652bbSmacallan WRITE4(CRIME_MTE_DST0, (xa << 18) | (ya & 0xffff)); 2907a6652bbSmacallan WRITE4ST(CRIME_MTE_DST1, 2917a6652bbSmacallan (((xe << 2) - 1 ) << 16) | ((ye - 1) & 0xffff)); 2927a6652bbSmacallan } 293850ab569Smacallan } else 294850ab569Smacallan#endif 295850ab569Smacallan { 296231734e4Smacallan MAKE_ROOM(2); 297231734e4Smacallan WRITE4(CRIME_DE_X_VERTEX_0, (x << 16) | (y & 0xffff)); 298231734e4Smacallan WRITE4ST(CRIME_DE_X_VERTEX_1, 299231734e4Smacallan ((x + w - 1) << 16) | ((y + h - 1) & 0xffff)); 300231734e4Smacallan } 301e1ea03a3Smacallan DONE(CRIME_DEBUG_RECTFILL); 302e1ea03a3Smacallan} 303e1ea03a3Smacallan 3045b2650b9Smacallanstatic void 3055b2650b9SmacallanCrimeSetupForMono8x8PatternFill(ScrnInfoPtr pScrn, int patx, int paty, 3065b2650b9Smacallan int fg, int bg, int rop, unsigned int planemask) 3075b2650b9Smacallan{ 3085b2650b9Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 3095b2650b9Smacallan uint32_t pat; 3105b2650b9Smacallan 3115b2650b9Smacallan LOG(CRIME_DEBUG_RECTFILL); 3125b2650b9Smacallan MAKE_ROOM(7); 3135b2650b9Smacallan WRITE4(CRIME_DE_PLANEMASK, planemask); 3145b2650b9Smacallan WRITE4(CRIME_DE_ROP, rop); 3155b2650b9Smacallan WRITE4(CRIME_DE_FG, fg << 8); 3165b2650b9Smacallan if (bg == -1) { 3175b2650b9Smacallan WRITE4(CRIME_DE_DRAWMODE, 3185b2650b9Smacallan DE_DRAWMODE_PLANEMASK | DE_DRAWMODE_BYTEMASK | 3195b2650b9Smacallan DE_DRAWMODE_ROP | DE_DRAWMODE_POLY_STIP | 3205b2650b9Smacallan DE_DRAWMODE_SCISSOR_EN); 3215b2650b9Smacallan } else { 3225b2650b9Smacallan WRITE4(CRIME_DE_BG, bg << 8); 3235b2650b9Smacallan WRITE4(CRIME_DE_DRAWMODE, 3245b2650b9Smacallan DE_DRAWMODE_PLANEMASK | DE_DRAWMODE_BYTEMASK | 3255b2650b9Smacallan DE_DRAWMODE_ROP | DE_DRAWMODE_POLY_STIP | 3265b2650b9Smacallan DE_DRAWMODE_OPAQUE_STIP | DE_DRAWMODE_SCISSOR_EN); 3275b2650b9Smacallan } 3285b2650b9Smacallan WRITE4(CRIME_DE_PRIMITIVE, 3295b2650b9Smacallan DE_PRIM_RECTANGLE | DE_PRIM_LR | DE_PRIM_TB); 3305b2650b9Smacallan WRITE4(CRIME_DE_MODE_DST, DE_MODE_TLB_A | DE_MODE_BUFDEPTH_32 | 3315b2650b9Smacallan DE_MODE_TYPE_RGBA | DE_MODE_PIXDEPTH_32); 3325b2650b9Smacallan 3335b2650b9Smacallan /* 3345b2650b9Smacallan * we need to store the pattern so we can just hammer it into the 3355b2650b9Smacallan * stipple register later on 3365b2650b9Smacallan */ 3375b2650b9Smacallan pat = patx & 0xff000000; 3385b2650b9Smacallan pat |= pat >> 8; 3395b2650b9Smacallan fPtr->pattern[0] = pat | (pat >> 16); 3405b2650b9Smacallan pat = patx & 0x00ff0000; 3415b2650b9Smacallan pat |= pat << 8; 3425b2650b9Smacallan fPtr->pattern[1] = pat | (pat >> 16); 3435b2650b9Smacallan pat = patx & 0x0000ff00; 3445b2650b9Smacallan pat |= pat >> 8; 3455b2650b9Smacallan fPtr->pattern[2] = pat | (pat << 16); 3465b2650b9Smacallan pat = patx & 0x000000ff; 3475b2650b9Smacallan pat |= pat << 8; 3485b2650b9Smacallan fPtr->pattern[3] = pat | (pat << 16); 3495b2650b9Smacallan 3505b2650b9Smacallan pat = paty & 0xff000000; 3515b2650b9Smacallan pat |= pat >> 8; 3525b2650b9Smacallan fPtr->pattern[4] = pat | (pat >> 16); 3535b2650b9Smacallan pat = paty & 0x00ff0000; 3545b2650b9Smacallan pat |= pat << 8; 3555b2650b9Smacallan fPtr->pattern[5] = pat | (pat >> 16); 3565b2650b9Smacallan pat = paty & 0x0000ff00; 3575b2650b9Smacallan pat |= pat >> 8; 3585b2650b9Smacallan fPtr->pattern[6] = pat | (pat << 16); 3595b2650b9Smacallan pat = paty & 0x000000ff; 3605b2650b9Smacallan pat |= pat << 8; 3615b2650b9Smacallan fPtr->pattern[7] = pat | (pat << 16); 3625b2650b9Smacallan SYNC; 3635b2650b9Smacallan DONE(CRIME_DEBUG_RECTFILL); 3645b2650b9Smacallan} 3655b2650b9Smacallan 3665b2650b9Smacallanstatic void 3675b2650b9SmacallanCrimeSubsequentMono8x8PatternFillRect( ScrnInfoPtr pScrn, 3685b2650b9Smacallan int patx, int paty, int x, int y, int w, int h) 3695b2650b9Smacallan{ 3705b2650b9Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 3715b2650b9Smacallan int i, pat; 3725b2650b9Smacallan 3735b2650b9Smacallan LOG(CRIME_DEBUG_RECTFILL); 3745b2650b9Smacallan 3755b2650b9Smacallan /* first setup the stipple stuff */ 3765b2650b9Smacallan 3775b2650b9Smacallan MAKE_ROOM(1); 3785b2650b9Smacallan WRITE4(CRIME_DE_STIPPLE_MODE, 0x001f0000 | (patx << 24)); 3795b2650b9Smacallan pat = paty; 3805b2650b9Smacallan 3815b2650b9Smacallan for (i = 0; i < h; i++) { 3825b2650b9Smacallan MAKE_ROOM(3); 3835b2650b9Smacallan WRITE4(CRIME_DE_STIPPLE_PAT, fPtr->pattern[pat]); 3845b2650b9Smacallan WRITE4(CRIME_DE_X_VERTEX_0, (x << 16) | ((y + i) & 0xffff)); 3855b2650b9Smacallan WRITE4ST(CRIME_DE_X_VERTEX_1, 3865b2650b9Smacallan ((x + w - 1) << 16) | ((y + i) & 0xffff)); 3875b2650b9Smacallan pat = (pat + 1) & 7; 3885b2650b9Smacallan } 3895b2650b9Smacallan DONE(CRIME_DEBUG_RECTFILL); 3905b2650b9Smacallan} 3915b2650b9Smacallan 3925b2650b9Smacallanstatic void 393e1ea03a3SmacallanCrimeSetupForScanlineImageWrite(ScrnInfoPtr pScrn, int rop, 394e1ea03a3Smacallan unsigned int planemask, int trans_color, 395e1ea03a3Smacallan int bpp, int depth) 396e1ea03a3Smacallan{ 397e1ea03a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 398e1ea03a3Smacallan 399e1ea03a3Smacallan LOG(CRIME_DEBUG_IMAGEWRITE); 400e1ea03a3Smacallan#ifdef CRIME_DEBUG_LOUD 401e1ea03a3Smacallan if ((bpp == 24) || (depth == 24)) 402e1ea03a3Smacallan xf86Msg(X_ERROR, "%s: %d %d \n", __func__, bpp, depth); 403e1ea03a3Smacallan#endif 40426dcc2a3Smacallan MAKE_ROOM(7); 405e1ea03a3Smacallan WRITE4(CRIME_DE_MODE_SRC, DE_MODE_LIN_A | DE_MODE_BUFDEPTH_32 | 406e1ea03a3Smacallan DE_MODE_TYPE_RGB | DE_MODE_PIXDEPTH_32); 40726dcc2a3Smacallan WRITE4(CRIME_DE_MODE_DST, DE_MODE_TLB_A | DE_MODE_BUFDEPTH_32 | 40826dcc2a3Smacallan DE_MODE_TYPE_RGBA | DE_MODE_PIXDEPTH_32); 409e1ea03a3Smacallan WRITE4(CRIME_DE_PLANEMASK, planemask); 410e1ea03a3Smacallan WRITE4(CRIME_DE_XFER_STEP_X, 4); 411e1ea03a3Smacallan WRITE4(CRIME_DE_ROP, rop); 412e1ea03a3Smacallan WRITE4(CRIME_DE_DRAWMODE, 413e1ea03a3Smacallan DE_DRAWMODE_PLANEMASK | DE_DRAWMODE_BYTEMASK | DE_DRAWMODE_ROP | 414e1ea03a3Smacallan DE_DRAWMODE_XFER_EN); 415e1ea03a3Smacallan WRITE4(CRIME_DE_PRIMITIVE, 416e1ea03a3Smacallan DE_PRIM_RECTANGLE | DE_PRIM_LR | DE_PRIM_TB); 41726dcc2a3Smacallan SYNC; 418e1ea03a3Smacallan DONE(CRIME_DEBUG_IMAGEWRITE); 419e1ea03a3Smacallan} 420e1ea03a3Smacallan 4215b2650b9Smacallanstatic void 422e1ea03a3SmacallanCrimeSubsequentImageWriteRect(ScrnInfoPtr pScrn, 423e1ea03a3Smacallan int x, int y, int w, int h, int skipleft) 424e1ea03a3Smacallan{ 425e1ea03a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 426e1ea03a3Smacallan 427e1ea03a3Smacallan LOG(CRIME_DEBUG_IMAGEWRITE); 428e1ea03a3Smacallan 429e1ea03a3Smacallan#ifdef CRIME_DEBUG_LOUD 430e1ea03a3Smacallan xf86Msg(X_ERROR, "%s: %d %d %d %d\n", __func__, x, y, w, h); 431e1ea03a3Smacallan#endif 432e1ea03a3Smacallan 433e1ea03a3Smacallan fPtr->start = skipleft; 434e1ea03a3Smacallan x += skipleft; 435e1ea03a3Smacallan w -= skipleft; 436e1ea03a3Smacallan if (x < 0) { 437e1ea03a3Smacallan fPtr->ux = 0; 438e1ea03a3Smacallan w += x; 439e1ea03a3Smacallan fPtr->start -= x; 440e1ea03a3Smacallan } else { 441e1ea03a3Smacallan fPtr->ux = x; 442e1ea03a3Smacallan } 443e1ea03a3Smacallan fPtr->uy = y; 444e1ea03a3Smacallan fPtr->uw = w; 445e1ea03a3Smacallan fPtr->uh = h; 446e1ea03a3Smacallan DONE(CRIME_DEBUG_IMAGEWRITE); 447e1ea03a3Smacallan} 448e1ea03a3Smacallan 4495b2650b9Smacallanstatic void 450e1ea03a3SmacallanCrimeSubsequentImageWriteScanline(ScrnInfoPtr pScrn, int bufno) 451e1ea03a3Smacallan{ 452e1ea03a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 453e1ea03a3Smacallan 454e1ea03a3Smacallan LOG(CRIME_DEBUG_IMAGEWRITE); 45526dcc2a3Smacallan /* 45626dcc2a3Smacallan * we need to sync here, otherwise we might queue up more copy 45726dcc2a3Smacallan * commands than we have buffers 45826dcc2a3Smacallan */ 45934c4e112Smacallan SYNC; 460e1ea03a3Smacallan WRITE4(CRIME_DE_XFER_ADDR_SRC, (bufno << 13) + (fPtr->start << 2)); 461e1ea03a3Smacallan WRITE4(CRIME_DE_X_VERTEX_0, (fPtr->ux << 16) | fPtr->uy); 462e1ea03a3Smacallan WRITE4ST(CRIME_DE_X_VERTEX_1, 463e1ea03a3Smacallan ((fPtr->ux + fPtr->uw - 1) << 16) | (fPtr->uy)); 464e1ea03a3Smacallan fPtr->uy++; 465e1ea03a3Smacallan DONE(CRIME_DEBUG_IMAGEWRITE); 466e1ea03a3Smacallan} 467e1ea03a3Smacallan 468e1ea03a3Smacallanstatic void 469e1ea03a3SmacallanCrimeSetupForCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, 470e1ea03a3Smacallan int fg, int bg, 471e1ea03a3Smacallan int rop, 472e1ea03a3Smacallan unsigned int planemask) 473e1ea03a3Smacallan{ 474e1ea03a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 475e1ea03a3Smacallan 476e1ea03a3Smacallan LOG(CRIME_DEBUG_COLOUREXPAND); 47726dcc2a3Smacallan MAKE_ROOM(7); 47826dcc2a3Smacallan WRITE4(CRIME_DE_MODE_DST, DE_MODE_TLB_A | DE_MODE_BUFDEPTH_32 | 47926dcc2a3Smacallan DE_MODE_TYPE_RGBA | DE_MODE_PIXDEPTH_32); 480e1ea03a3Smacallan WRITE4(CRIME_DE_PLANEMASK, planemask); 481e1ea03a3Smacallan WRITE4(CRIME_DE_ROP, rop); 482e1ea03a3Smacallan WRITE4(CRIME_DE_FG, fg << 8); 483e1ea03a3Smacallan if (bg == -1) { 484e1ea03a3Smacallan /* transparent */ 485e1ea03a3Smacallan WRITE4(CRIME_DE_DRAWMODE, 486e1ea03a3Smacallan DE_DRAWMODE_PLANEMASK | DE_DRAWMODE_BYTEMASK | 487e1ea03a3Smacallan DE_DRAWMODE_ROP | DE_DRAWMODE_POLY_STIP); 488e1ea03a3Smacallan } else { 489e1ea03a3Smacallan WRITE4(CRIME_DE_BG, bg << 8); 490e1ea03a3Smacallan WRITE4(CRIME_DE_DRAWMODE, 491e1ea03a3Smacallan DE_DRAWMODE_PLANEMASK | DE_DRAWMODE_BYTEMASK | 492e1ea03a3Smacallan DE_DRAWMODE_ROP | 493e1ea03a3Smacallan DE_DRAWMODE_OPAQUE_STIP | DE_DRAWMODE_POLY_STIP); 494e1ea03a3Smacallan } 495e1ea03a3Smacallan WRITE4(CRIME_DE_PRIMITIVE, 496e1ea03a3Smacallan DE_PRIM_RECTANGLE | DE_PRIM_LR | DE_PRIM_TB); 49726dcc2a3Smacallan SYNC; 498e1ea03a3Smacallan DONE(CRIME_DEBUG_COLOUREXPAND); 499e1ea03a3Smacallan} 500e1ea03a3Smacallan 501e1ea03a3Smacallanstatic void 502e1ea03a3SmacallanCrimeSubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, 503e1ea03a3Smacallan int x, int y, int w, int h, 504e1ea03a3Smacallan int skipleft ) 505e1ea03a3Smacallan{ 506e1ea03a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 507e1ea03a3Smacallan 508e1ea03a3Smacallan LOG(CRIME_DEBUG_COLOUREXPAND); 509e1ea03a3Smacallan 510e1ea03a3Smacallan fPtr->start = skipleft; 511e1ea03a3Smacallan fPtr->ux = x; 512e1ea03a3Smacallan fPtr->uy = y; 513e1ea03a3Smacallan fPtr->uw = w; 514e1ea03a3Smacallan fPtr->uh = h; 515e1ea03a3Smacallan DONE(CRIME_DEBUG_COLOUREXPAND); 516e1ea03a3Smacallan} 517e1ea03a3Smacallan 518e1ea03a3Smacallanstatic void 519e1ea03a3SmacallanCrimeSubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno) 520e1ea03a3Smacallan{ 521e1ea03a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 522e1ea03a3Smacallan uint32_t *boo = (uint32_t *)fPtr->expandbuffers[bufno]; 523e1ea03a3Smacallan int idx = fPtr->uw, x = fPtr->ux; 524e1ea03a3Smacallan 525e1ea03a3Smacallan LOG(CRIME_DEBUG_COLOUREXPAND); 526e1ea03a3Smacallan 52726dcc2a3Smacallan MAKE_ROOM(5); 528e1ea03a3Smacallan WRITE4(CRIME_DE_STIPPLE_MODE, 0x001f0000 | (fPtr->start << 24)); 529e1ea03a3Smacallan WRITE4(CRIME_DE_STIPPLE_PAT, *boo); 530e1ea03a3Smacallan boo++; 531e1ea03a3Smacallan WRITE4(CRIME_DE_X_VERTEX_0, (x + fPtr->start << 16) | fPtr->uy); 532e1ea03a3Smacallan WRITE4ST(CRIME_DE_X_VERTEX_1, 533e1ea03a3Smacallan ((x + min(idx, 32) - 1) << 16) | (fPtr->uy)); 534e1ea03a3Smacallan idx -= 32; 535e1ea03a3Smacallan x += 32; 536e1ea03a3Smacallan WRITE4(CRIME_DE_STIPPLE_MODE, 0x001f0000); 537e1ea03a3Smacallan 538e1ea03a3Smacallan while (idx > 0) { 53926dcc2a3Smacallan MAKE_ROOM(3); 540e1ea03a3Smacallan WRITE4(CRIME_DE_STIPPLE_PAT, *boo); 541e1ea03a3Smacallan boo++; 542e1ea03a3Smacallan WRITE4(CRIME_DE_X_VERTEX_0, (x << 16) | fPtr->uy); 543e1ea03a3Smacallan WRITE4ST(CRIME_DE_X_VERTEX_1, 544e1ea03a3Smacallan ((x + min(idx, 32) - 1) << 16) | (fPtr->uy)); 545e1ea03a3Smacallan idx -= 32; 546e1ea03a3Smacallan x += 32; 547e1ea03a3Smacallan } 548e1ea03a3Smacallan fPtr->uy++; 549e1ea03a3Smacallan DONE(CRIME_DEBUG_COLOUREXPAND); 550e1ea03a3Smacallan} 551e1ea03a3Smacallan 552e1ea03a3Smacallanstatic void 553e1ea03a3SmacallanCrimeSetupForSolidLine(ScrnInfoPtr pScrn, int color, int rop, 554e1ea03a3Smacallan unsigned int planemask) 555e1ea03a3Smacallan{ 556e1ea03a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 557e1ea03a3Smacallan 558e1ea03a3Smacallan LOG(CRIME_DEBUG_LINES); 559e1ea03a3Smacallan 56026dcc2a3Smacallan MAKE_ROOM(5); 56126dcc2a3Smacallan WRITE4(CRIME_DE_MODE_DST, DE_MODE_TLB_A | DE_MODE_BUFDEPTH_32 | 56226dcc2a3Smacallan DE_MODE_TYPE_RGBA | DE_MODE_PIXDEPTH_32); 563e1ea03a3Smacallan WRITE4(CRIME_DE_PLANEMASK, planemask); 564e1ea03a3Smacallan WRITE4(CRIME_DE_ROP, rop); 565e1ea03a3Smacallan WRITE4(CRIME_DE_FG, color << 8); 566e1ea03a3Smacallan WRITE4(CRIME_DE_DRAWMODE, 567e1ea03a3Smacallan DE_DRAWMODE_PLANEMASK | DE_DRAWMODE_BYTEMASK | 56893351543Smacallan DE_DRAWMODE_ROP | DE_DRAWMODE_SCISSOR_EN); 56926dcc2a3Smacallan SYNC; 570e1ea03a3Smacallan DONE(CRIME_DEBUG_LINES); 571e1ea03a3Smacallan} 572e1ea03a3Smacallan 573e1ea03a3Smacallanstatic void 574e1ea03a3SmacallanCrimeSubsequentSolidTwoPointLine(ScrnInfoPtr pScrn, int x1, int y1, int x2, 575e1ea03a3Smacallan int y2, int flags) 576e1ea03a3Smacallan{ 577e1ea03a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 578e1ea03a3Smacallan 579e1ea03a3Smacallan LOG(CRIME_DEBUG_LINES); 58026dcc2a3Smacallan MAKE_ROOM(3); 581e1ea03a3Smacallan if (flags & OMIT_LAST) { 582e1ea03a3Smacallan WRITE4(CRIME_DE_PRIMITIVE, 583e1ea03a3Smacallan DE_PRIM_LINE | DE_PRIM_LINE_SKIP_END | 2); 584e1ea03a3Smacallan } else { 585e1ea03a3Smacallan WRITE4(CRIME_DE_PRIMITIVE, 586e1ea03a3Smacallan DE_PRIM_LINE | 2); 587e1ea03a3Smacallan } 588e1ea03a3Smacallan WRITE4(CRIME_DE_X_VERTEX_0, (x1 << 16) | y1); 589e1ea03a3Smacallan WRITE4ST(CRIME_DE_X_VERTEX_1, (x2 << 16) | y2); 590e1ea03a3Smacallan DONE(CRIME_DEBUG_LINES); 591850ab569Smacallan} 592e1ea03a3Smacallan 593e1ea03a3Smacallanvoid 594e1ea03a3SmacallanCrimeSetupForDashedLine(ScrnInfoPtr pScrn, 595e1ea03a3Smacallan int fg, int bg, int rop, unsigned int planemask, 596e1ea03a3Smacallan int length, unsigned char *pattern) 597e1ea03a3Smacallan{ 598e1ea03a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 599e1ea03a3Smacallan uint32_t pat; 600e1ea03a3Smacallan 601e1ea03a3Smacallan LOG(CRIME_DEBUG_LINES); 602e1ea03a3Smacallan 603e1ea03a3Smacallan fPtr->uw = length; 60426dcc2a3Smacallan MAKE_ROOM(7); 60526dcc2a3Smacallan WRITE4(CRIME_DE_MODE_DST, DE_MODE_TLB_A | DE_MODE_BUFDEPTH_32 | 60626dcc2a3Smacallan DE_MODE_TYPE_RGBA | DE_MODE_PIXDEPTH_32); 607e1ea03a3Smacallan WRITE4(CRIME_DE_PLANEMASK, planemask); 608e1ea03a3Smacallan WRITE4(CRIME_DE_ROP, rop); 609e1ea03a3Smacallan WRITE4(CRIME_DE_FG, fg << 8); 610e1ea03a3Smacallan if (bg == -1) { 611e1ea03a3Smacallan /* transparent */ 612e1ea03a3Smacallan WRITE4(CRIME_DE_DRAWMODE, 613e1ea03a3Smacallan DE_DRAWMODE_PLANEMASK | DE_DRAWMODE_BYTEMASK | 61493351543Smacallan DE_DRAWMODE_ROP | DE_DRAWMODE_LINE_STIP | 61593351543Smacallan DE_DRAWMODE_SCISSOR_EN); 616e1ea03a3Smacallan } else { 617e1ea03a3Smacallan WRITE4(CRIME_DE_BG, bg << 8); 618e1ea03a3Smacallan WRITE4(CRIME_DE_DRAWMODE, 619e1ea03a3Smacallan DE_DRAWMODE_PLANEMASK | DE_DRAWMODE_BYTEMASK | 62093351543Smacallan DE_DRAWMODE_ROP | DE_DRAWMODE_SCISSOR_EN | 621e1ea03a3Smacallan DE_DRAWMODE_OPAQUE_STIP | DE_DRAWMODE_LINE_STIP); 622e1ea03a3Smacallan } 623e1ea03a3Smacallan /* 624e1ea03a3Smacallan * can we trust the Xserver to always hand us a 32bit aligned 625e1ea03a3Smacallan * pattern buffer? 626e1ea03a3Smacallan */ 627e1ea03a3Smacallan memcpy(&pat, pattern, 4); 628e1ea03a3Smacallan WRITE4(CRIME_DE_STIPPLE_PAT, pat); 62926dcc2a3Smacallan SYNC; 630e1ea03a3Smacallan DONE(CRIME_DEBUG_LINES); 631e1ea03a3Smacallan} 632e1ea03a3Smacallan 633e1ea03a3Smacallanvoid 634e1ea03a3SmacallanCrimeSubsequentDashedTwoPointLine( ScrnInfoPtr pScrn, 635e1ea03a3Smacallan int x1, int y1, int x2, int y2, int flags, int phase) 636e1ea03a3Smacallan{ 637e1ea03a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 638e1ea03a3Smacallan uint32_t stipmode; 639e1ea03a3Smacallan 640e1ea03a3Smacallan LOG(CRIME_DEBUG_LINES); 64126dcc2a3Smacallan MAKE_ROOM(4); 642e1ea03a3Smacallan 643e1ea03a3Smacallan if (flags & OMIT_LAST) { 644e1ea03a3Smacallan WRITE4(CRIME_DE_PRIMITIVE, 645e1ea03a3Smacallan DE_PRIM_LINE | DE_PRIM_LINE_SKIP_END | 2); 646e1ea03a3Smacallan } else { 647e1ea03a3Smacallan WRITE4(CRIME_DE_PRIMITIVE, 648e1ea03a3Smacallan DE_PRIM_LINE | 2); 649e1ea03a3Smacallan } 650e1ea03a3Smacallan 651e1ea03a3Smacallan stipmode = ((fPtr->uw - 1) << 16) | (phase << 24); 652e1ea03a3Smacallan WRITE4(CRIME_DE_STIPPLE_MODE, stipmode); 653e1ea03a3Smacallan WRITE4(CRIME_DE_X_VERTEX_0, (x1 << 16) | y1); 654e1ea03a3Smacallan WRITE4ST(CRIME_DE_X_VERTEX_1, (x2 << 16) | y2); 655e1ea03a3Smacallan DONE(CRIME_DEBUG_LINES); 656e1ea03a3Smacallan} 657e1ea03a3Smacallan 658e1ea03a3Smacallanvoid 659e1ea03a3SmacallanCrimeSetClippingRectangle ( ScrnInfoPtr pScrn, 660e1ea03a3Smacallan int left, int top, int right, int bottom) 661e1ea03a3Smacallan{ 662e1ea03a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 663e1ea03a3Smacallan 664e1ea03a3Smacallan LOG(CRIME_DEBUG_CLIPPING); 66526dcc2a3Smacallan MAKE_ROOM(2); 66693351543Smacallan WRITE4(CRIME_DE_SCISSOR, (left << 16) | top); 66793351543Smacallan WRITE4(CRIME_DE_SCISSOR + 4, ((right + 1) << 16) | (bottom + 1)); 6687a6652bbSmacallan fPtr->cxa = left; 6697a6652bbSmacallan fPtr->cxe = right; 6707a6652bbSmacallan fPtr->cya = top; 6717a6652bbSmacallan fPtr->cye = bottom; 67226dcc2a3Smacallan SYNC; 673e1ea03a3Smacallan DONE(CRIME_DEBUG_CLIPPING); 674e1ea03a3Smacallan} 675e1ea03a3Smacallan 676e1ea03a3Smacallanvoid 677e1ea03a3SmacallanCrimeDisableClipping (ScrnInfoPtr pScrn) 678e1ea03a3Smacallan{ 679e1ea03a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 680e1ea03a3Smacallan 681e1ea03a3Smacallan LOG(CRIME_DEBUG_CLIPPING); 68226dcc2a3Smacallan MAKE_ROOM(2); 68393351543Smacallan WRITE4(CRIME_DE_SCISSOR, 0); 68493351543Smacallan WRITE4(CRIME_DE_SCISSOR + 4, 0x3fff3fff); 6857a6652bbSmacallan fPtr->cxa = 0; 6867a6652bbSmacallan fPtr->cxe = 2047; 6877a6652bbSmacallan fPtr->cya = 0; 6887a6652bbSmacallan fPtr->cye = 2047; 68926dcc2a3Smacallan SYNC; 690e1ea03a3Smacallan DONE(CRIME_DEBUG_CLIPPING); 691e1ea03a3Smacallan} 692e1ea03a3Smacallan 693e1ea03a3Smacallanstatic Bool 694e1ea03a3SmacallanCrimeSetupForCPUToScreenAlphaTexture ( 695e1ea03a3Smacallan ScrnInfoPtr pScrn, 696e1ea03a3Smacallan int op, 697e1ea03a3Smacallan CARD16 red, 698e1ea03a3Smacallan CARD16 green, 699e1ea03a3Smacallan CARD16 blue, 700e1ea03a3Smacallan CARD16 alpha, 701e1ea03a3Smacallan int alphaType, 702e1ea03a3Smacallan CARD8 *alphaPtr, 703e1ea03a3Smacallan int alphaPitch, 704e1ea03a3Smacallan int width, 705e1ea03a3Smacallan int height, 706e1ea03a3Smacallan int flags 707e1ea03a3Smacallan) 708e1ea03a3Smacallan{ 709e1ea03a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 710e1ea03a3Smacallan 711e1ea03a3Smacallan if (op != PictOpOver) { 712e1ea03a3Smacallan xf86Msg(X_ERROR, "%s: op %d\n", __func__, op); 713e1ea03a3Smacallan op = PictOpOver; 714e1ea03a3Smacallan } 715e1ea03a3Smacallan 716e1ea03a3Smacallan LOG(CRIME_DEBUG_XRENDER); 717e1ea03a3Smacallan 718e1ea03a3Smacallan fPtr->alpha_color = ((red & 0xff00) << 16) | 719e1ea03a3Smacallan ((green & 0xff00) << 8) | 72009f0d67cSmacallan (blue & 0xff00); 721e1ea03a3Smacallan fPtr->uw = width; 722e1ea03a3Smacallan fPtr->uh = height; 723e1ea03a3Smacallan fPtr->us = alphaPitch; 724e1ea03a3Smacallan fPtr->alpha_texture = alphaPtr; 72509f0d67cSmacallan fPtr->format = alphaType; 7265b2650b9Smacallan#ifdef CRIME_DEBUG_LOUD 72709f0d67cSmacallan if (alphaType != PICT_a8) { 72809f0d67cSmacallan xf86Msg(X_ERROR, "ARGB mask %08x %d\n", (uint32_t)alphaPtr, 72909f0d67cSmacallan alphaPitch); 73009f0d67cSmacallan } 7315b2650b9Smacallan#endif 73226dcc2a3Smacallan MAKE_ROOM(7); 73326dcc2a3Smacallan WRITE4(CRIME_DE_MODE_DST, DE_MODE_TLB_A | DE_MODE_BUFDEPTH_32 | 73426dcc2a3Smacallan DE_MODE_TYPE_RGBA | DE_MODE_PIXDEPTH_32); 735e1ea03a3Smacallan /* XXX this register is not where it's supposed to be */ 736e1ea03a3Smacallan WRITE4(CRIME_DE_ALPHA_COLOR, fPtr->alpha_color); 73709f0d67cSmacallan if (alphaType == PICT_a8) { 73809f0d67cSmacallan if (fPtr->alpha_color == 0) { 73909f0d67cSmacallan WRITE4(CRIME_DE_MODE_SRC, DE_MODE_LIN_A | DE_MODE_BUFDEPTH_8 | 740e1ea03a3Smacallan DE_MODE_TYPE_RGBA | DE_MODE_PIXDEPTH_32); 74109f0d67cSmacallan WRITE4(CRIME_DE_XFER_STEP_X, 1); 74209f0d67cSmacallan WRITE4(CRIME_DE_ALPHA_FUNC, 74309f0d67cSmacallan DE_ALPHA_ADD | 74409f0d67cSmacallan (DE_ALPHA_OP_ZERO << DE_ALPHA_OP_SRC_SHIFT) | 74509f0d67cSmacallan (DE_ALPHA_OP_1_MINUS_SRC_ALPHA << DE_ALPHA_OP_DST_SHIFT)); 74609f0d67cSmacallan } else { 74709f0d67cSmacallan WRITE4(CRIME_DE_MODE_SRC, DE_MODE_LIN_A | DE_MODE_BUFDEPTH_32 | 74809f0d67cSmacallan DE_MODE_TYPE_RGBA | DE_MODE_PIXDEPTH_32); 74909f0d67cSmacallan WRITE4(CRIME_DE_XFER_STEP_X, 4); 75009f0d67cSmacallan WRITE4(CRIME_DE_ALPHA_FUNC, 75109f0d67cSmacallan DE_ALPHA_ADD | 75209f0d67cSmacallan (DE_ALPHA_OP_SRC_ALPHA << DE_ALPHA_OP_SRC_SHIFT) | 75309f0d67cSmacallan (DE_ALPHA_OP_1_MINUS_SRC_ALPHA << DE_ALPHA_OP_DST_SHIFT)); 75409f0d67cSmacallan } 755e1ea03a3Smacallan } else { 756e1ea03a3Smacallan WRITE4(CRIME_DE_MODE_SRC, DE_MODE_LIN_A | DE_MODE_BUFDEPTH_32 | 757e1ea03a3Smacallan DE_MODE_TYPE_RGBA | DE_MODE_PIXDEPTH_32); 758e1ea03a3Smacallan WRITE4(CRIME_DE_XFER_STEP_X, 4); 759e1ea03a3Smacallan WRITE4(CRIME_DE_ALPHA_FUNC, 760e1ea03a3Smacallan DE_ALPHA_ADD | 761e1ea03a3Smacallan (DE_ALPHA_OP_SRC_ALPHA << DE_ALPHA_OP_SRC_SHIFT) | 762e1ea03a3Smacallan (DE_ALPHA_OP_1_MINUS_SRC_ALPHA << DE_ALPHA_OP_DST_SHIFT)); 76309f0d67cSmacallan } 764e1ea03a3Smacallan WRITE4(CRIME_DE_DRAWMODE, 765e1ea03a3Smacallan DE_DRAWMODE_BYTEMASK | DE_DRAWMODE_ALPHA_BLEND | 766e1ea03a3Smacallan DE_DRAWMODE_XFER_EN); 767e1ea03a3Smacallan WRITE4(CRIME_DE_PRIMITIVE, 768e1ea03a3Smacallan DE_PRIM_RECTANGLE | DE_PRIM_LR | DE_PRIM_TB); 76926dcc2a3Smacallan SYNC; 770e1ea03a3Smacallan DONE(CRIME_DEBUG_XRENDER); 771e1ea03a3Smacallan return TRUE; 772e1ea03a3Smacallan} 773e1ea03a3Smacallan 774e1ea03a3Smacallanvoid 775e1ea03a3SmacallanCrimeSubsequentCPUToScreenAlphaTexture ( 776e1ea03a3Smacallan ScrnInfoPtr pScrn, 777e1ea03a3Smacallan int dstx, 778e1ea03a3Smacallan int dsty, 779e1ea03a3Smacallan int srcx, 780e1ea03a3Smacallan int srcy, 781e1ea03a3Smacallan int width, 782e1ea03a3Smacallan int height 783e1ea03a3Smacallan) 784e1ea03a3Smacallan{ 785e1ea03a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 786e1ea03a3Smacallan unsigned char *aptr; 787e1ea03a3Smacallan uint32_t *dptr, aval; 788e1ea03a3Smacallan int i, j; 789e1ea03a3Smacallan int bufnum = 0; 790e1ea03a3Smacallan 791e1ea03a3Smacallan LOG(CRIME_DEBUG_XRENDER); 792e1ea03a3Smacallan#ifdef CRIME_DEBUG_LOUD 793e1ea03a3Smacallan xf86Msg(X_ERROR, "%d %d %d %d %d %d\n",srcx, srcy, dstx, dsty, width, 794e1ea03a3Smacallan height); 795e1ea03a3Smacallan#endif 796e1ea03a3Smacallan aptr = fPtr->alpha_texture + (fPtr->us * srcy) + srcx; 797e1ea03a3Smacallan for (i = 0; i < height; i++) { 798e1ea03a3Smacallan dptr = (uint32_t *)fPtr->buffers[bufnum]; 799e1ea03a3Smacallan if (fPtr->alpha_color == 0) { 800e1ea03a3Smacallan memcpy(dptr, aptr, width); 801e1ea03a3Smacallan } else { 802e1ea03a3Smacallan for (j = 0; j < width; j++) { 803e1ea03a3Smacallan aval = aptr[j]; 804e1ea03a3Smacallan *dptr = aval | fPtr->alpha_color; 805e1ea03a3Smacallan dptr++; 806e1ea03a3Smacallan } 807e1ea03a3Smacallan } 80826dcc2a3Smacallan MAKE_ROOM(3); 809e1ea03a3Smacallan WRITE4(CRIME_DE_XFER_ADDR_SRC, bufnum * 8192); 810e1ea03a3Smacallan WRITE4(CRIME_DE_X_VERTEX_0, dstx << 16 | (dsty + i)); 811e1ea03a3Smacallan WRITE4ST(CRIME_DE_X_VERTEX_1, 812e1ea03a3Smacallan ((dstx + width - 1) << 16) | (dsty + i)); 813e1ea03a3Smacallan bufnum++; 814e1ea03a3Smacallan if (bufnum == 8) bufnum = 0; 815e1ea03a3Smacallan aptr += fPtr->us; 816e1ea03a3Smacallan } 817e1ea03a3Smacallan DONE(CRIME_DEBUG_XRENDER); 818e1ea03a3Smacallan} 819e1ea03a3Smacallan 82009f0d67cSmacallanvoid 82109f0d67cSmacallanCrimeSubsequentCPUToScreenAlphaTexture32 ( 82209f0d67cSmacallan ScrnInfoPtr pScrn, 82309f0d67cSmacallan int dstx, 82409f0d67cSmacallan int dsty, 82509f0d67cSmacallan int srcx, 82609f0d67cSmacallan int srcy, 82709f0d67cSmacallan int width, 82809f0d67cSmacallan int height 82909f0d67cSmacallan) 83009f0d67cSmacallan{ 83109f0d67cSmacallan CrimePtr fPtr = CRIMEPTR(pScrn); 83209f0d67cSmacallan uint8_t *aptr; 83309f0d67cSmacallan uint32_t *dptr, *sptr; 83409f0d67cSmacallan int i, j; 83509f0d67cSmacallan int bufnum = 0; 83609f0d67cSmacallan 83709f0d67cSmacallan LOG(CRIME_DEBUG_XRENDER); 83826dcc2a3Smacallan#ifdef CRIME_DEBUG_LOUD 83909f0d67cSmacallan xf86Msg(X_ERROR, "%d %d %d %d %d %d\n",srcx, srcy, dstx, dsty, width, 84009f0d67cSmacallan height); 84109f0d67cSmacallan#endif 84209f0d67cSmacallan aptr = fPtr->alpha_texture + (fPtr->us * srcy) + (srcx << 2); 84309f0d67cSmacallan for (i = 0; i < height; i++) { 84409f0d67cSmacallan dptr = (uint32_t *)fPtr->buffers[bufnum]; 84509f0d67cSmacallan sptr = (uint32_t *)aptr; 84609f0d67cSmacallan for (j = 0; j < width; j++) { 84709f0d67cSmacallan *dptr = (*sptr >> 24) | fPtr->alpha_color; 84809f0d67cSmacallan#ifdef CRIME_DEBUG_LOUD 84909f0d67cSmacallan xf86Msg(X_ERROR, "%08x %08x\n", *sptr, *dptr); 85009f0d67cSmacallan#endif 85109f0d67cSmacallan sptr++; 85209f0d67cSmacallan dptr++; 85309f0d67cSmacallan } 85426dcc2a3Smacallan MAKE_ROOM(3); 85509f0d67cSmacallan WRITE4(CRIME_DE_XFER_ADDR_SRC, bufnum * 8192); 85609f0d67cSmacallan WRITE4(CRIME_DE_X_VERTEX_0, dstx << 16 | (dsty + i)); 85709f0d67cSmacallan WRITE4ST(CRIME_DE_X_VERTEX_1, 85809f0d67cSmacallan ((dstx + width - 1) << 16) | (dsty + i)); 85909f0d67cSmacallan bufnum++; 86009f0d67cSmacallan if (bufnum == 8) bufnum = 0; 86109f0d67cSmacallan aptr += fPtr->us; 86209f0d67cSmacallan } 86309f0d67cSmacallan DONE(CRIME_DEBUG_XRENDER); 86409f0d67cSmacallan} 86509f0d67cSmacallan 866e1ea03a3Smacallanstatic Bool 867e1ea03a3SmacallanCrimeSetupForCPUToScreenTexture ( 868e1ea03a3Smacallan ScrnInfoPtr pScrn, 869e1ea03a3Smacallan int op, 870e1ea03a3Smacallan int texType, 871e1ea03a3Smacallan CARD8 *texPtr, 872e1ea03a3Smacallan int texPitch, 873e1ea03a3Smacallan int width, 874e1ea03a3Smacallan int height, 875e1ea03a3Smacallan int flags 876e1ea03a3Smacallan) 877e1ea03a3Smacallan{ 878e1ea03a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 879e1ea03a3Smacallan 880e1ea03a3Smacallan if (op != PictOpOver) { 881e1ea03a3Smacallan xf86Msg(X_ERROR, "%s: op %d\n", __func__, op); 882e1ea03a3Smacallan op = PictOpOver; 883e1ea03a3Smacallan } 884e1ea03a3Smacallan 885e1ea03a3Smacallan LOG(CRIME_DEBUG_XRENDER); 886e1ea03a3Smacallan 887e1ea03a3Smacallan fPtr->uw = width; 888e1ea03a3Smacallan fPtr->uh = height; 889e1ea03a3Smacallan fPtr->us = texPitch; 890e1ea03a3Smacallan fPtr->alpha_texture = texPtr; 89126dcc2a3Smacallan MAKE_ROOM(6); 89226dcc2a3Smacallan WRITE4(CRIME_DE_MODE_DST, DE_MODE_TLB_A | DE_MODE_BUFDEPTH_32 | 89326dcc2a3Smacallan DE_MODE_TYPE_RGBA | DE_MODE_PIXDEPTH_32); 894e1ea03a3Smacallan if (texType == PICT_a8b8g8r8) { 895e1ea03a3Smacallan WRITE4(CRIME_DE_MODE_SRC, DE_MODE_LIN_A | DE_MODE_BUFDEPTH_32 | 896e1ea03a3Smacallan DE_MODE_TYPE_ABGR | DE_MODE_PIXDEPTH_32); 897e1ea03a3Smacallan } else { 898e1ea03a3Smacallan WRITE4(CRIME_DE_MODE_SRC, DE_MODE_LIN_A | DE_MODE_BUFDEPTH_32 | 899e1ea03a3Smacallan DE_MODE_TYPE_RGBA | DE_MODE_PIXDEPTH_32); 900e1ea03a3Smacallan } 901e1ea03a3Smacallan fPtr->format = texType; 902e1ea03a3Smacallan WRITE4(CRIME_DE_XFER_STEP_X, 4); 903e1ea03a3Smacallan WRITE4(CRIME_DE_ALPHA_FUNC, 904e1ea03a3Smacallan DE_ALPHA_ADD | 905e1ea03a3Smacallan (DE_ALPHA_OP_ONE/*SRC_ALPHA*/ << DE_ALPHA_OP_SRC_SHIFT) | 906e1ea03a3Smacallan (DE_ALPHA_OP_1_MINUS_SRC_ALPHA << DE_ALPHA_OP_DST_SHIFT)); 907e1ea03a3Smacallan WRITE4(CRIME_DE_DRAWMODE, 908e1ea03a3Smacallan DE_DRAWMODE_BYTEMASK | DE_DRAWMODE_ALPHA_BLEND | 909e1ea03a3Smacallan DE_DRAWMODE_XFER_EN); 910e1ea03a3Smacallan WRITE4(CRIME_DE_PRIMITIVE, 911e1ea03a3Smacallan DE_PRIM_RECTANGLE | DE_PRIM_LR | DE_PRIM_TB); 91226dcc2a3Smacallan SYNC; 913e1ea03a3Smacallan DONE(CRIME_DEBUG_XRENDER); 914e1ea03a3Smacallan return TRUE; 915e1ea03a3Smacallan} 916e1ea03a3Smacallan 917e1ea03a3Smacallanvoid 918e1ea03a3SmacallanCrimeSubsequentCPUToScreenTexture ( 919e1ea03a3Smacallan ScrnInfoPtr pScrn, 920e1ea03a3Smacallan int dstx, 921e1ea03a3Smacallan int dsty, 922e1ea03a3Smacallan int srcx, 923e1ea03a3Smacallan int srcy, 924e1ea03a3Smacallan int width, 925e1ea03a3Smacallan int height 926e1ea03a3Smacallan) 927e1ea03a3Smacallan{ 928e1ea03a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 929e1ea03a3Smacallan unsigned char *aptr, *lptr; 930e1ea03a3Smacallan uint32_t *dptr, *sptr, aval, pixel; 931e1ea03a3Smacallan int i, j, k, l, rep = 1, period = fPtr->uw, xoff, lcnt, xa, xe; 932e1ea03a3Smacallan int bufnum = 0; 933e1ea03a3Smacallan 934e1ea03a3Smacallan LOG(CRIME_DEBUG_XRENDER); 935e1ea03a3Smacallan#ifdef CRIME_DEBUG_LOUD 936e1ea03a3Smacallan xf86Msg(X_ERROR, "%s: %d %d %d %d %d %d\n", __func__, 937e1ea03a3Smacallan srcx, srcy, dstx, dsty, width, height); 938e1ea03a3Smacallan#endif 939e1ea03a3Smacallan if ((width == 1) || (fPtr->format != PICT_a8r8g8b8)) { 940e1ea03a3Smacallan xf86Msg(X_ERROR, "%s: %d %d %d %d %d %d %d %d\n", __func__, 941e1ea03a3Smacallan srcx, srcy, dstx, dsty, width, height, fPtr->uw, fPtr->us); 942e1ea03a3Smacallan return; 943e1ea03a3Smacallan } 944e1ea03a3Smacallan 945e1ea03a3Smacallan aptr = fPtr->alpha_texture + (srcx << 2); 946e1ea03a3Smacallan lptr = aptr + (fPtr->us * srcy); 947e1ea03a3Smacallan if ((fPtr->uw < 128) && (fPtr->uw < width)) { 948e1ea03a3Smacallan rep = 128 / fPtr->uw; 949e1ea03a3Smacallan period = rep * fPtr->uw; 950e1ea03a3Smacallan } 951e1ea03a3Smacallan 952e1ea03a3Smacallan if (fPtr->format == PICT_a8b8g8r8) { 953e1ea03a3Smacallan#ifdef CRIME_DEBUG_LOUD 954e1ea03a3Smacallan xf86Msg(X_ERROR, "ABGR\n"); 955e1ea03a3Smacallan#endif 956e1ea03a3Smacallan for (i = 0; i < height; i++) { 957e1ea03a3Smacallan dptr = (uint32_t *)fPtr->buffers[bufnum]; 958e1ea03a3Smacallan memcpy(dptr, aptr, fPtr->us); 95926dcc2a3Smacallan MAKE_ROOM(3); 960e1ea03a3Smacallan WRITE4(CRIME_DE_XFER_ADDR_SRC, bufnum * 8192); 961e1ea03a3Smacallan WRITE4(CRIME_DE_X_VERTEX_0, dstx << 16 | (dsty + i)); 962e1ea03a3Smacallan WRITE4ST(CRIME_DE_X_VERTEX_1, 963e1ea03a3Smacallan ((dstx + width - 1) << 16) | (dsty + i)); 964e1ea03a3Smacallan bufnum++; 965e1ea03a3Smacallan if (bufnum == 8) bufnum = 0; 966e1ea03a3Smacallan aptr += fPtr->us; 967e1ea03a3Smacallan } 968e1ea03a3Smacallan } else { 969e1ea03a3Smacallan#ifdef CRIME_DEBUG_LOUD 970e1ea03a3Smacallan xf86Msg(X_ERROR, "ARGB %08x %d\n", (uint32_t)aptr, fPtr->uw); 971e1ea03a3Smacallan#endif 972e1ea03a3Smacallan lcnt = fPtr->uh - srcy; 973e1ea03a3Smacallan for (i = 0; i < height; i++) { 974e1ea03a3Smacallan dptr = (uint32_t *)fPtr->buffers[bufnum]; 975e1ea03a3Smacallan for (k = 0; k < rep; k++) { 976e1ea03a3Smacallan sptr = (uint32_t *)aptr; 977e1ea03a3Smacallan for (j = 0; j < fPtr->uw; j++) { 978e1ea03a3Smacallan pixel = *sptr; 979e1ea03a3Smacallan *dptr = (pixel << 8) | (pixel >> 24); 980e1ea03a3Smacallan dptr++; 981e1ea03a3Smacallan sptr++; 982e1ea03a3Smacallan } 983e1ea03a3Smacallan } 984e1ea03a3Smacallan xoff = 0; 98526dcc2a3Smacallan MAKE_ROOM(1); 986e1ea03a3Smacallan WRITE4(CRIME_DE_XFER_ADDR_SRC, bufnum * 8192); 987e1ea03a3Smacallan while (xoff < width) { 988e1ea03a3Smacallan xa = dstx + xoff; 989e1ea03a3Smacallan xe = dstx + min(xoff + period, width) - 1; 99026dcc2a3Smacallan MAKE_ROOM(2); 991e1ea03a3Smacallan WRITE4(CRIME_DE_X_VERTEX_0, 992e1ea03a3Smacallan xa << 16 | (dsty + i)); 993e1ea03a3Smacallan WRITE4ST(CRIME_DE_X_VERTEX_1, 994e1ea03a3Smacallan (xe << 16) | (dsty + i)); 995e1ea03a3Smacallan xoff += period; 996e1ea03a3Smacallan } 997e1ea03a3Smacallan bufnum++; 998e1ea03a3Smacallan if (bufnum == 8) bufnum = 0; 999e1ea03a3Smacallan lcnt--; 1000e1ea03a3Smacallan if (lcnt == 0) { 1001e1ea03a3Smacallan aptr = lptr; 1002e1ea03a3Smacallan lcnt = fPtr->uh; 1003e1ea03a3Smacallan } else 1004e1ea03a3Smacallan aptr += fPtr->us; 1005e1ea03a3Smacallan } 1006e1ea03a3Smacallan } 1007e1ea03a3Smacallan DONE(CRIME_DEBUG_XRENDER); 1008e1ea03a3Smacallan} 1009e1ea03a3Smacallan 1010e1ea03a3Smacallanstatic Bool 1011e1ea03a3SmacallanCrimeSetupForCPUToScreenTextureMask( 1012e1ea03a3Smacallan ScrnInfoPtr pScrn, 1013e1ea03a3Smacallan int op, 1014e1ea03a3Smacallan int texType, 1015e1ea03a3Smacallan CARD8 *srcPtr, 1016e1ea03a3Smacallan int srcPitch, 1017e1ea03a3Smacallan CARD8 *mskPtr, 1018e1ea03a3Smacallan int mskPitch, 1019e1ea03a3Smacallan int width, 1020e1ea03a3Smacallan int height, 1021e1ea03a3Smacallan int flags 1022e1ea03a3Smacallan) 1023e1ea03a3Smacallan{ 1024e1ea03a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 1025e1ea03a3Smacallan 1026e1ea03a3Smacallan if (op != PictOpOver) { 1027e1ea03a3Smacallan xf86Msg(X_ERROR, "%s: op %d\n", __func__, op); 1028e1ea03a3Smacallan op = PictOpOver; 1029e1ea03a3Smacallan } 1030e1ea03a3Smacallan 1031e1ea03a3Smacallan LOG(CRIME_DEBUG_XRENDER); 1032e1ea03a3Smacallan 1033e1ea03a3Smacallan fPtr->uw = width; 1034e1ea03a3Smacallan fPtr->uh = height; 1035e1ea03a3Smacallan fPtr->us = srcPitch >> 2; 1036e1ea03a3Smacallan if (PICT_FORMAT_BPP(texType) == 32) { 1037e1ea03a3Smacallan fPtr->um = mskPitch >> 2; 1038e1ea03a3Smacallan } else 1039e1ea03a3Smacallan fPtr->um = mskPitch; 1040e1ea03a3Smacallan fPtr->msk = (uint8_t *)mskPtr; 1041e1ea03a3Smacallan fPtr->src = (uint8_t *)srcPtr; 1042e1ea03a3Smacallan fPtr->texture_depth = PICT_FORMAT_BPP(texType); 1043e1ea03a3Smacallan 104426dcc2a3Smacallan MAKE_ROOM(6); 1045e1ea03a3Smacallan /* always expect ARGB for now */ 1046e1ea03a3Smacallan WRITE4(CRIME_DE_MODE_SRC, DE_MODE_LIN_A | DE_MODE_BUFDEPTH_32 | 1047e1ea03a3Smacallan DE_MODE_TYPE_RGBA | DE_MODE_PIXDEPTH_32); 104826dcc2a3Smacallan WRITE4(CRIME_DE_MODE_DST, DE_MODE_TLB_A | DE_MODE_BUFDEPTH_32 | 104926dcc2a3Smacallan DE_MODE_TYPE_RGBA | DE_MODE_PIXDEPTH_32); 1050e1ea03a3Smacallan fPtr->format = texType; 1051e1ea03a3Smacallan WRITE4(CRIME_DE_ALPHA_FUNC, 1052e1ea03a3Smacallan DE_ALPHA_ADD | 1053e1ea03a3Smacallan (DE_ALPHA_OP_SRC_ALPHA << DE_ALPHA_OP_SRC_SHIFT) | 1054e1ea03a3Smacallan (DE_ALPHA_OP_1_MINUS_SRC_ALPHA << DE_ALPHA_OP_DST_SHIFT)); 1055e1ea03a3Smacallan WRITE4(CRIME_DE_XFER_STEP_X, 4); 1056e1ea03a3Smacallan WRITE4(CRIME_DE_DRAWMODE, 1057e1ea03a3Smacallan DE_DRAWMODE_BYTEMASK | DE_DRAWMODE_ALPHA_BLEND | 1058e1ea03a3Smacallan DE_DRAWMODE_XFER_EN); 1059e1ea03a3Smacallan WRITE4(CRIME_DE_PRIMITIVE, 1060e1ea03a3Smacallan DE_PRIM_RECTANGLE | DE_PRIM_LR | DE_PRIM_TB); 106126dcc2a3Smacallan SYNC; 1062e1ea03a3Smacallan DONE(CRIME_DEBUG_XRENDER); 1063e1ea03a3Smacallan return TRUE; 1064e1ea03a3Smacallan} 1065e1ea03a3Smacallan 1066e1ea03a3Smacallanvoid 1067e1ea03a3SmacallanCrimeSubsequentCPUToScreenTextureMask32( 1068e1ea03a3Smacallan ScrnInfoPtr pScrn, 1069e1ea03a3Smacallan int dstx, 1070e1ea03a3Smacallan int dsty, 1071e1ea03a3Smacallan int srcx, 1072e1ea03a3Smacallan int srcy, 1073e1ea03a3Smacallan int maskx, 1074e1ea03a3Smacallan int masky, 1075e1ea03a3Smacallan int width, 1076e1ea03a3Smacallan int height 1077e1ea03a3Smacallan) 1078e1ea03a3Smacallan{ 1079e1ea03a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 1080e1ea03a3Smacallan uint32_t *lsptr, *lmptr, *asptr, *amptr; 1081e1ea03a3Smacallan uint32_t *dptr, *sptr, *mptr, aval, pixel, mask; 1082e1ea03a3Smacallan int i, j, k, l, rep = 1, period = fPtr->uw, xoff, lcnt, xa, xe; 1083e1ea03a3Smacallan int bufnum = 0; 1084e1ea03a3Smacallan int sr, sg, sb, sa, mr, mg, mb, ma, rr, gg, bb, aa; 1085e1ea03a3Smacallan 1086e1ea03a3Smacallan LOG(CRIME_DEBUG_XRENDER); 1087e1ea03a3Smacallan#ifdef CRIME_DEBUG_LOUD 1088e1ea03a3Smacallan xf86Msg(X_ERROR, "%s: %d %d %d %d %d %d; %d %d %d\n", __func__, 1089e1ea03a3Smacallan srcx, srcy, dstx, dsty, width, height, maskx, masky, fPtr->um); 1090e1ea03a3Smacallan#endif 1091e1ea03a3Smacallan sptr = fPtr->src + (srcx << 2); 1092e1ea03a3Smacallan mptr = fPtr->msk + (srcx << 2); 1093e1ea03a3Smacallan lsptr = sptr + (fPtr->us * srcy); 1094e1ea03a3Smacallan lmptr = mptr + (fPtr->um * srcy); 1095e1ea03a3Smacallan if ((fPtr->uw < 128) && (fPtr->uw < width)) { 1096e1ea03a3Smacallan rep = 128 / fPtr->uw; 1097e1ea03a3Smacallan period = rep * fPtr->uw; 1098e1ea03a3Smacallan } 1099e1ea03a3Smacallan 1100e1ea03a3Smacallan#ifdef CRIME_DEBUG_LOUD 1101e1ea03a3Smacallan xf86Msg(X_ERROR, "ARGB %08x %d\n", (uint32_t)aptr, fPtr->uw); 1102e1ea03a3Smacallan#endif 1103e1ea03a3Smacallan lcnt = fPtr->uh - srcy; 1104e1ea03a3Smacallan for (i = 0; i < height; i++) { 1105e1ea03a3Smacallan dptr = (uint32_t *)fPtr->buffers[bufnum]; 1106e1ea03a3Smacallan for (k = 0; k < rep; k++) { 1107e1ea03a3Smacallan asptr = lsptr; 1108e1ea03a3Smacallan amptr = lmptr; 1109e1ea03a3Smacallan for (j = 0; j < fPtr->uw; j++) { 1110e1ea03a3Smacallan pixel = *asptr; 1111e1ea03a3Smacallan mask = *amptr; 1112e1ea03a3Smacallan if (mask == 0xffffffff) { 1113e1ea03a3Smacallan *dptr = (pixel >> 24) | (pixel << 8); 1114e1ea03a3Smacallan } else if (mask == 0x00000000) { 1115e1ea03a3Smacallan *dptr = 0; 1116e1ea03a3Smacallan } else { 1117e1ea03a3Smacallan /* input is ARGB */ 1118e1ea03a3Smacallan sb = pixel & 0xff; 1119e1ea03a3Smacallan sg = (pixel >> 8) & 0xff; 1120e1ea03a3Smacallan sr = (pixel >> 16) & 0xff; 1121e1ea03a3Smacallan sa = (pixel >> 24) & 0xff; 1122e1ea03a3Smacallan mb = mask & 0xff; 1123e1ea03a3Smacallan mg = (mask >> 8) & 0xff; 1124e1ea03a3Smacallan mr = (mask >> 16) & 0xff; 1125e1ea03a3Smacallan ma = (mask >> 24) & 0xff; 1126e1ea03a3Smacallan 1127e1ea03a3Smacallan /* and here we need an RGBA pixel */ 1128e1ea03a3Smacallan bb = (((sb * mb) + 0x80) & 0xff00); 1129e1ea03a3Smacallan gg = (((sg * mg) + 0x80) & 0xff00) << 8; 1130e1ea03a3Smacallan rr = (((sr * mr) + 0x80) & 0xff00) << 16; 1131e1ea03a3Smacallan aa = (((sa * ma) + 0x80) & 0xff00) >> 8; 1132e1ea03a3Smacallan /* 1133e1ea03a3Smacallan * actually we could let the HW do this stuff 1134e1ea03a3Smacallan */ 1135e1ea03a3Smacallan *dptr = aa | rr | gg | bb; 1136e1ea03a3Smacallan } 1137e1ea03a3Smacallan dptr++; 1138e1ea03a3Smacallan asptr++; 1139e1ea03a3Smacallan amptr++; 1140e1ea03a3Smacallan } 1141e1ea03a3Smacallan } 1142e1ea03a3Smacallan xoff = 0; 114326dcc2a3Smacallan MAKE_ROOM(1); 1144e1ea03a3Smacallan WRITE4(CRIME_DE_XFER_ADDR_SRC, bufnum * 8192); 1145e1ea03a3Smacallan while (xoff < width) { 1146e1ea03a3Smacallan xa = dstx + xoff; 1147e1ea03a3Smacallan xe = dstx + min(xoff + period, width) - 1; 114826dcc2a3Smacallan MAKE_ROOM(2); 1149e1ea03a3Smacallan WRITE4(CRIME_DE_X_VERTEX_0, 1150e1ea03a3Smacallan xa << 16 | (dsty + i)); 1151e1ea03a3Smacallan WRITE4ST(CRIME_DE_X_VERTEX_1, 1152e1ea03a3Smacallan (xe << 16) | (dsty + i)); 1153e1ea03a3Smacallan xoff += period; 1154e1ea03a3Smacallan } 1155e1ea03a3Smacallan bufnum++; 1156e1ea03a3Smacallan if (bufnum == 8) bufnum = 0; 1157e1ea03a3Smacallan lcnt--; 1158e1ea03a3Smacallan if (lcnt == 0) { 1159e1ea03a3Smacallan /* back to the beginning */ 1160e1ea03a3Smacallan lsptr = sptr; 1161e1ea03a3Smacallan lmptr = mptr; 1162e1ea03a3Smacallan lcnt = fPtr->uh; 1163e1ea03a3Smacallan } else 1164e1ea03a3Smacallan /* next line */ 1165e1ea03a3Smacallan lsptr += fPtr->us; 1166e1ea03a3Smacallan lmptr += fPtr->um; 1167e1ea03a3Smacallan } 1168e1ea03a3Smacallan DONE(CRIME_DEBUG_XRENDER); 1169e1ea03a3Smacallan} 1170e1ea03a3Smacallan 1171e1ea03a3Smacallanvoid 1172e1ea03a3SmacallanCrimeSubsequentCPUToScreenTextureMask8( 1173e1ea03a3Smacallan ScrnInfoPtr pScrn, 1174e1ea03a3Smacallan int dstx, 1175e1ea03a3Smacallan int dsty, 1176e1ea03a3Smacallan int srcx, 1177e1ea03a3Smacallan int srcy, 1178e1ea03a3Smacallan int maskx, 1179e1ea03a3Smacallan int masky, 1180e1ea03a3Smacallan int width, 1181e1ea03a3Smacallan int height 1182e1ea03a3Smacallan) 1183e1ea03a3Smacallan{ 1184e1ea03a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 1185e1ea03a3Smacallan uint32_t *lsptr, *asptr; 1186e1ea03a3Smacallan uint32_t *dptr, *sptr, aval, pixel, mask; 1187e1ea03a3Smacallan uint8_t *lmptr, *amptr, *mptr; 1188e1ea03a3Smacallan int i, j, k, l, rep = 1, period = fPtr->uw, xoff, lcnt, xa, xe; 1189e1ea03a3Smacallan int bufnum = 0; 1190e1ea03a3Smacallan int sr, sg, sb, sa, rr, gg, bb, aa; 1191e1ea03a3Smacallan 1192e1ea03a3Smacallan LOG(CRIME_DEBUG_XRENDER); 11935b2650b9Smacallan#ifdef CRIME_DEBUG_LOUD 1194e1ea03a3Smacallan xf86Msg(X_ERROR, "%s: %d %d %d %d %d %d\n", __func__, 1195e1ea03a3Smacallan srcx, srcy, dstx, dsty, width, height); 1196e1ea03a3Smacallan#endif 1197e1ea03a3Smacallan sptr = (uint32_t *)fPtr->src + (fPtr->us * srcy) + (srcx << 2); 1198e1ea03a3Smacallan mptr = (uint8_t *)fPtr->msk + (fPtr->um * srcy) + srcx; 1199e1ea03a3Smacallan lsptr = sptr; 1200e1ea03a3Smacallan lmptr = mptr; 1201e1ea03a3Smacallan if ((fPtr->uw < 128) && (fPtr->uw < width)) { 1202e1ea03a3Smacallan rep = 128 / fPtr->uw; 1203e1ea03a3Smacallan period = rep * fPtr->uw; 1204e1ea03a3Smacallan } 1205e1ea03a3Smacallan 1206e1ea03a3Smacallan#ifdef CRIME_DEBUG_LOUD 1207e1ea03a3Smacallan xf86Msg(X_ERROR, "ARGB %08x %d\n", (uint32_t)aptr, fPtr->uw); 1208e1ea03a3Smacallan#endif 1209e1ea03a3Smacallan lcnt = fPtr->uh; 1210e1ea03a3Smacallan for (i = 0; i < height; i++) { 1211e1ea03a3Smacallan dptr = (uint32_t *)fPtr->buffers[bufnum]; 1212e1ea03a3Smacallan for (k = 0; k < rep; k++) { 1213e1ea03a3Smacallan asptr = lsptr; 1214e1ea03a3Smacallan amptr = lmptr; 1215e1ea03a3Smacallan for (j = 0; j < fPtr->uw; j++) { 1216e1ea03a3Smacallan pixel = *asptr; 1217e1ea03a3Smacallan mask = *amptr; 1218e1ea03a3Smacallan if (mask == 0xff) { 1219e1ea03a3Smacallan *dptr = (pixel >> 24) | (pixel << 8); 1220e1ea03a3Smacallan } else if (mask == 0x00) { 1221e1ea03a3Smacallan *dptr = 0; 1222e1ea03a3Smacallan } else { 1223e1ea03a3Smacallan /* input is ARGB */ 1224e1ea03a3Smacallan sb = pixel & 0xff; 1225e1ea03a3Smacallan sg = (pixel >> 8) & 0xff; 1226e1ea03a3Smacallan sr = (pixel >> 16) & 0xff; 1227e1ea03a3Smacallan sa = (pixel >> 24) & 0xff; 1228e1ea03a3Smacallan 1229e1ea03a3Smacallan /* and here we need an RGBA pixel */ 1230e1ea03a3Smacallan bb = (((sb * mask) + 0x80) & 0xff00); 1231e1ea03a3Smacallan gg = (((sg * mask) + 0x80) & 0xff00) 1232e1ea03a3Smacallan << 8; 1233e1ea03a3Smacallan rr = (((sr * mask) + 0x80) & 0xff00) 1234e1ea03a3Smacallan << 16; 1235e1ea03a3Smacallan aa = (((sa * mask) + 0x80) & 0xff00) 1236e1ea03a3Smacallan >> 8; 1237e1ea03a3Smacallan /* 1238e1ea03a3Smacallan * actually we could let the HW do this 1239e1ea03a3Smacallan * stuff 1240e1ea03a3Smacallan */ 1241e1ea03a3Smacallan *dptr = aa | rr | gg | bb; 1242e1ea03a3Smacallan } 1243e1ea03a3Smacallan dptr++; 1244e1ea03a3Smacallan asptr++; 1245e1ea03a3Smacallan amptr++; 1246e1ea03a3Smacallan } 1247e1ea03a3Smacallan } 1248e1ea03a3Smacallan xoff = 0; 124926dcc2a3Smacallan MAKE_ROOM(1); 1250e1ea03a3Smacallan WRITE4(CRIME_DE_XFER_ADDR_SRC, bufnum * 8192); 1251e1ea03a3Smacallan while (xoff < width) { 1252e1ea03a3Smacallan xa = dstx + xoff; 1253e1ea03a3Smacallan xe = dstx + min(xoff + period, width) - 1; 125426dcc2a3Smacallan MAKE_ROOM(2); 1255e1ea03a3Smacallan WRITE4(CRIME_DE_X_VERTEX_0, 1256e1ea03a3Smacallan xa << 16 | (dsty + i)); 1257e1ea03a3Smacallan WRITE4ST(CRIME_DE_X_VERTEX_1, 1258e1ea03a3Smacallan (xe << 16) | (dsty + i)); 1259e1ea03a3Smacallan xoff += period; 1260e1ea03a3Smacallan } 1261e1ea03a3Smacallan bufnum++; 1262e1ea03a3Smacallan if (bufnum == 8) bufnum = 0; 1263e1ea03a3Smacallan lcnt--; 1264e1ea03a3Smacallan if (lcnt == 0) { 1265e1ea03a3Smacallan /* back to the beginning */ 1266e1ea03a3Smacallan lsptr = sptr; 1267e1ea03a3Smacallan lmptr = mptr; 1268e1ea03a3Smacallan lcnt = fPtr->uh; 1269e1ea03a3Smacallan } else 1270e1ea03a3Smacallan /* next line */ 1271e1ea03a3Smacallan lsptr += fPtr->us; 1272e1ea03a3Smacallan lmptr += fPtr->um; 1273e1ea03a3Smacallan } 1274e1ea03a3Smacallan DONE(CRIME_DEBUG_XRENDER); 1275e1ea03a3Smacallan} 1276e1ea03a3Smacallan 1277e1ea03a3Smacallanstatic void 1278e1ea03a3SmacallanCrimeDoCPUToScreenComposite( 1279e1ea03a3Smacallan CARD8 op, 1280e1ea03a3Smacallan PicturePtr pSrc, 1281e1ea03a3Smacallan PicturePtr pMask, 1282e1ea03a3Smacallan PicturePtr pDst, 1283e1ea03a3Smacallan INT16 xSrc, 1284e1ea03a3Smacallan INT16 ySrc, 1285e1ea03a3Smacallan INT16 xMask, 1286e1ea03a3Smacallan INT16 yMask, 1287e1ea03a3Smacallan INT16 xDst, 1288e1ea03a3Smacallan INT16 yDst, 1289e1ea03a3Smacallan CARD16 width, 1290e1ea03a3Smacallan CARD16 height 1291e1ea03a3Smacallan) 1292e1ea03a3Smacallan{ 1293e1ea03a3Smacallan ScreenPtr pScreen = pDst->pDrawable->pScreen; 1294e1ea03a3Smacallan XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen); 1295e1ea03a3Smacallan RegionRec region; 1296e1ea03a3Smacallan CARD32 *formats; 1297e1ea03a3Smacallan int flags = 0; 1298e1ea03a3Smacallan BoxPtr pbox; 1299e1ea03a3Smacallan int nbox, w, h; 1300e1ea03a3Smacallan 1301e1ea03a3Smacallan LOG(CRIME_DEBUG_XRENDER); 1302e1ea03a3Smacallan if (pSrc->transform || (pMask && pMask->transform)) { 1303e1ea03a3Smacallan xf86Msg(X_ERROR, "%s: transform?!\n", __func__); 1304e1ea03a3Smacallan return; 1305e1ea03a3Smacallan } 1306e1ea03a3Smacallan 1307e1ea03a3Smacallan if (pDst->alphaMap || pSrc->alphaMap || (pMask && pMask->alphaMap)) { 1308e1ea03a3Smacallan xf86Msg(X_ERROR, "%s: alpha-map?!\n", __func__); 1309e1ea03a3Smacallan return; 1310e1ea03a3Smacallan } 1311e1ea03a3Smacallan 1312e1ea03a3Smacallan xDst += pDst->pDrawable->x; 1313e1ea03a3Smacallan yDst += pDst->pDrawable->y; 1314e1ea03a3Smacallan xSrc += pSrc->pDrawable->x; 1315e1ea03a3Smacallan ySrc += pSrc->pDrawable->y; 1316e1ea03a3Smacallan 1317e1ea03a3Smacallan if(pMask) { 1318e1ea03a3Smacallan CARD16 red, green, blue, alpha; 1319e1ea03a3Smacallan CARD32 pixel = 1320e1ea03a3Smacallan *((CARD32*)(((PixmapPtr)(pSrc->pDrawable))->devPrivate.ptr)); 132109f0d67cSmacallan#ifdef CRIME_DEBUG_LOUD 1322e1ea03a3Smacallan if(pMask->componentAlpha) { 1323e1ea03a3Smacallan xf86Msg(X_ERROR, "%s: alpha component mask\n", 1324e1ea03a3Smacallan __func__); 132509f0d67cSmacallan xf86Msg(X_ERROR, "src: %d x %d\n", pSrc->pDrawable->width, 132609f0d67cSmacallan pSrc->pDrawable->height); 1327e1ea03a3Smacallan } 132809f0d67cSmacallan#endif 1329e1ea03a3Smacallan if ((pSrc->pDrawable->width == 1) && 1330e1ea03a3Smacallan (pSrc->pDrawable->height == 1)) { 1331e1ea03a3Smacallan 1332e1ea03a3Smacallan if(!XAAGetRGBAFromPixel(pixel, &red, &green, &blue, 1333e1ea03a3Smacallan &alpha, pSrc->format)) { 1334e1ea03a3Smacallan xf86Msg(X_ERROR, "%s: can't read pixel\n", __func__); 1335e1ea03a3Smacallan return; 1336e1ea03a3Smacallan } 1337e1ea03a3Smacallan xMask += pMask->pDrawable->x; 1338e1ea03a3Smacallan yMask += pMask->pDrawable->y; 1339e1ea03a3Smacallan 1340e1ea03a3Smacallan /* pull out color expandable operations here */ 1341e1ea03a3Smacallan if(pMask->format == PICT_a1) { 1342e1ea03a3Smacallan PixmapPtr pPix = (PixmapPtr)(pMask->pDrawable); 1343e1ea03a3Smacallan int skipleft; 1344e1ea03a3Smacallan 1345e1ea03a3Smacallan if (op != PictOpOver) { 1346e1ea03a3Smacallan xf86Msg(X_ERROR, "!over\n"); 1347e1ea03a3Smacallan return; 1348e1ea03a3Smacallan } 1349e1ea03a3Smacallan if (pMask->repeat) { 1350e1ea03a3Smacallan xf86Msg(X_ERROR, "mono repeat\n"); 1351e1ea03a3Smacallan return; 1352e1ea03a3Smacallan } 1353e1ea03a3Smacallan if (!miComputeCompositeRegion (®ion, pSrc, 1354e1ea03a3Smacallan pMask, pDst, xSrc, ySrc, xMask, yMask, xDst, 1355e1ea03a3Smacallan yDst, width, height)) { 1356e1ea03a3Smacallan return; 1357e1ea03a3Smacallan } 1358e1ea03a3Smacallan 1359e1ea03a3Smacallan nbox = REGION_NUM_RECTS(®ion); 1360e1ea03a3Smacallan pbox = REGION_RECTS(®ion); 1361e1ea03a3Smacallan 1362e1ea03a3Smacallan if(!nbox) { 1363e1ea03a3Smacallan return; 1364e1ea03a3Smacallan } 1365e1ea03a3Smacallan 1366e1ea03a3Smacallan XAAGetPixelFromRGBA(&pixel, red, green, blue, 0, 1367e1ea03a3Smacallan pDst->format); 1368e1ea03a3Smacallan 1369e1ea03a3Smacallan xMask -= xDst; 1370e1ea03a3Smacallan yMask -= yDst; 1371e1ea03a3Smacallan 1372e1ea03a3Smacallan while(nbox--) { 1373e1ea03a3Smacallan skipleft = pbox->x1 + xMask; 1374e1ea03a3Smacallan 1375e1ea03a3Smacallan (*infoRec->WriteBitmap)(infoRec->pScrn, pbox->x1, pbox->y1, 1376e1ea03a3Smacallan pbox->x2 - pbox->x1, 1377e1ea03a3Smacallan pbox->y2 - pbox->y1, 1378e1ea03a3Smacallan (unsigned char*)(pPix->devPrivate.ptr) + (pPix->devKind * 1379e1ea03a3Smacallan (pbox->y1 + yMask)) + ((skipleft >> 3) & ~3), 1380e1ea03a3Smacallan pPix->devKind, skipleft & 31, pixel, -1, 1381e1ea03a3Smacallan GXcopy, ~0); 1382e1ea03a3Smacallan pbox++; 1383e1ea03a3Smacallan } 1384e1ea03a3Smacallan 1385e1ea03a3Smacallan /* WriteBitmap sets the Sync flag */ 1386e1ea03a3Smacallan REGION_UNINIT(pScreen, ®ion); 1387e1ea03a3Smacallan DONE(CRIME_DEBUG_XRENDER); 1388e1ea03a3Smacallan return; 1389e1ea03a3Smacallan } 139009f0d67cSmacallan if((pMask->format == PICT_a8) || 139109f0d67cSmacallan (pMask->format == PICT_a8r8g8b8)) { 1392e1ea03a3Smacallan 1393e1ea03a3Smacallan w = pMask->pDrawable->width; 1394e1ea03a3Smacallan h = pMask->pDrawable->height; 1395e1ea03a3Smacallan 1396e1ea03a3Smacallan if(pMask->repeat) { 1397e1ea03a3Smacallan flags |= XAA_RENDER_REPEAT; 1398e1ea03a3Smacallan } 1399e1ea03a3Smacallan 1400e1ea03a3Smacallan if (!miComputeCompositeRegion (®ion, pSrc, pMask, 1401e1ea03a3Smacallan pDst, xSrc, ySrc, xMask, yMask, xDst, yDst, 1402e1ea03a3Smacallan width, height)) { 1403e1ea03a3Smacallan return; 1404e1ea03a3Smacallan } 1405e1ea03a3Smacallan 1406e1ea03a3Smacallan nbox = REGION_NUM_RECTS(®ion); 1407e1ea03a3Smacallan pbox = REGION_RECTS(®ion); 1408e1ea03a3Smacallan 1409e1ea03a3Smacallan if(!nbox) { 1410e1ea03a3Smacallan REGION_UNINIT(pScreen, ®ion); 1411e1ea03a3Smacallan return; 1412e1ea03a3Smacallan } 1413e1ea03a3Smacallan 1414e1ea03a3Smacallan CrimeSetupForCPUToScreenAlphaTexture(infoRec->pScrn, 1415e1ea03a3Smacallan op, red, green, blue, alpha, pMask->format, 1416e1ea03a3Smacallan ((PixmapPtr)(pMask->pDrawable))->devPrivate.ptr, 1417e1ea03a3Smacallan ((PixmapPtr)(pMask->pDrawable))->devKind, 1418e1ea03a3Smacallan w, h, flags); 1419e1ea03a3Smacallan 1420e1ea03a3Smacallan xMask -= xDst; 1421e1ea03a3Smacallan yMask -= yDst; 1422e1ea03a3Smacallan 142309f0d67cSmacallan if (pMask->format != PICT_a8) { 142409f0d67cSmacallan while(nbox--) { 142509f0d67cSmacallan CrimeSubsequentCPUToScreenAlphaTexture32( 142609f0d67cSmacallan infoRec->pScrn, 142709f0d67cSmacallan pbox->x1, pbox->y1, pbox->x1 + xMask, 142809f0d67cSmacallan pbox->y1 + yMask, pbox->x2 - pbox->x1, 142909f0d67cSmacallan pbox->y2 - pbox->y1); 143009f0d67cSmacallan pbox++; 143109f0d67cSmacallan } 143209f0d67cSmacallan } else { 143309f0d67cSmacallan while(nbox--) { 143409f0d67cSmacallan CrimeSubsequentCPUToScreenAlphaTexture( 143509f0d67cSmacallan infoRec->pScrn, 143609f0d67cSmacallan pbox->x1, pbox->y1, pbox->x1 + xMask, 143709f0d67cSmacallan pbox->y1 + yMask, pbox->x2 - pbox->x1, 143809f0d67cSmacallan pbox->y2 - pbox->y1); 143909f0d67cSmacallan pbox++; 144009f0d67cSmacallan } 1441e1ea03a3Smacallan } 1442e1ea03a3Smacallan SET_SYNC_FLAG(infoRec); 1443e1ea03a3Smacallan REGION_UNINIT(pScreen, ®ion); 1444e1ea03a3Smacallan DONE(CRIME_DEBUG_XRENDER); 1445e1ea03a3Smacallan return; 1446e1ea03a3Smacallan } else { 1447e1ea03a3Smacallan xf86Msg(X_ERROR, "unknown mask %x\n", pMask->format); 1448e1ea03a3Smacallan } 1449e1ea03a3Smacallan REGION_UNINIT(pScreen, ®ion); 1450e1ea03a3Smacallan DONE(CRIME_DEBUG_XRENDER); 1451e1ea03a3Smacallan return; 1452e1ea03a3Smacallan } else { 1453e1ea03a3Smacallan /* source isn't solid */ 1454e1ea03a3Smacallan 1455e1ea03a3Smacallan w = pSrc->pDrawable->width; 1456e1ea03a3Smacallan h = pSrc->pDrawable->height; 1457e1ea03a3Smacallan 1458e1ea03a3Smacallan if(pSrc->repeat) 1459e1ea03a3Smacallan flags |= XAA_RENDER_REPEAT; 1460e1ea03a3Smacallan 1461e1ea03a3Smacallan if (!miComputeCompositeRegion (®ion, pSrc, pMask, 1462e1ea03a3Smacallan pDst, xSrc, ySrc, xMask, yMask, xDst, yDst, 1463e1ea03a3Smacallan width, height)) { 1464e1ea03a3Smacallan return; 1465e1ea03a3Smacallan } 1466e1ea03a3Smacallan 1467e1ea03a3Smacallan nbox = REGION_NUM_RECTS(®ion); 1468e1ea03a3Smacallan pbox = REGION_RECTS(®ion); 1469e1ea03a3Smacallan 1470e1ea03a3Smacallan if(!nbox) { 1471e1ea03a3Smacallan REGION_UNINIT(pScreen, ®ion); 1472e1ea03a3Smacallan return; 1473e1ea03a3Smacallan } 1474e1ea03a3Smacallan CrimeSetupForCPUToScreenTextureMask( 1475e1ea03a3Smacallan infoRec->pScrn, op, pMask->format, 1476e1ea03a3Smacallan ((PixmapPtr)(pSrc->pDrawable))->devPrivate.ptr, 1477e1ea03a3Smacallan ((PixmapPtr)(pSrc->pDrawable))->devKind, 1478e1ea03a3Smacallan ((PixmapPtr)(pMask->pDrawable))->devPrivate.ptr, 1479e1ea03a3Smacallan ((PixmapPtr)(pMask->pDrawable))->devKind, 1480e1ea03a3Smacallan w, h, flags); 1481e1ea03a3Smacallan 1482e1ea03a3Smacallan xSrc -= xDst; 1483e1ea03a3Smacallan ySrc -= yDst; 1484e1ea03a3Smacallan 1485e1ea03a3Smacallan if (PICT_FORMAT_BPP(pMask->format) == 32) { 1486e1ea03a3Smacallan while(nbox--) { 1487e1ea03a3Smacallan CrimeSubsequentCPUToScreenTextureMask32( 1488e1ea03a3Smacallan infoRec->pScrn, 1489e1ea03a3Smacallan pbox->x1, pbox->y1, 1490e1ea03a3Smacallan pbox->x1 + xSrc, pbox->y1 + ySrc, 1491e1ea03a3Smacallan xMask, yMask, 1492e1ea03a3Smacallan pbox->x2 - pbox->x1, pbox->y2 - pbox->y1); 1493e1ea03a3Smacallan pbox++; 1494e1ea03a3Smacallan } 1495e1ea03a3Smacallan } else { 1496e1ea03a3Smacallan while(nbox--) { 1497e1ea03a3Smacallan CrimeSubsequentCPUToScreenTextureMask8( 1498e1ea03a3Smacallan infoRec->pScrn, 1499e1ea03a3Smacallan pbox->x1, pbox->y1, pbox->x1 + xSrc, 1500e1ea03a3Smacallan pbox->y1 + ySrc, 1501e1ea03a3Smacallan xMask, yMask, 1502e1ea03a3Smacallan pbox->x2 - pbox->x1, 1503e1ea03a3Smacallan pbox->y2 - pbox->y1); 1504e1ea03a3Smacallan pbox++; 1505e1ea03a3Smacallan } 1506e1ea03a3Smacallan } 1507e1ea03a3Smacallan 1508e1ea03a3Smacallan SET_SYNC_FLAG(infoRec); 1509e1ea03a3Smacallan REGION_UNINIT(pScreen, ®ion); 1510e1ea03a3Smacallan DONE(CRIME_DEBUG_XRENDER); 1511e1ea03a3Smacallan return; 1512e1ea03a3Smacallan } 1513e1ea03a3Smacallan } else { /* no mask */ 1514e1ea03a3Smacallan formats = infoRec->CPUToScreenTextureFormats; 1515e1ea03a3Smacallan 1516e1ea03a3Smacallan w = pSrc->pDrawable->width; 1517e1ea03a3Smacallan h = pSrc->pDrawable->height; 1518e1ea03a3Smacallan 1519e1ea03a3Smacallan if(pSrc->repeat) 1520e1ea03a3Smacallan flags |= XAA_RENDER_REPEAT; 1521e1ea03a3Smacallan 1522e1ea03a3Smacallan while(*formats != pSrc->format) { 1523e1ea03a3Smacallan if(!(*formats)) { 1524e1ea03a3Smacallan xf86Msg(X_ERROR, 1525e1ea03a3Smacallan "%s: format %x not found\n", 1526e1ea03a3Smacallan __func__, pSrc->format); 1527e1ea03a3Smacallan return; 1528e1ea03a3Smacallan } 1529e1ea03a3Smacallan formats++; 1530e1ea03a3Smacallan } 1531e1ea03a3Smacallan 1532e1ea03a3Smacallan if (!miComputeCompositeRegion (®ion, pSrc, pMask, pDst, 1533e1ea03a3Smacallan xSrc, ySrc, xMask, yMask, xDst, yDst, 1534e1ea03a3Smacallan width, height)) { 1535e1ea03a3Smacallan return; 1536e1ea03a3Smacallan } 1537e1ea03a3Smacallan 1538e1ea03a3Smacallan nbox = REGION_NUM_RECTS(®ion); 1539e1ea03a3Smacallan pbox = REGION_RECTS(®ion); 1540e1ea03a3Smacallan 1541e1ea03a3Smacallan if(!nbox) { 1542e1ea03a3Smacallan REGION_UNINIT(pScreen, ®ion); 1543e1ea03a3Smacallan return; 1544e1ea03a3Smacallan } 1545e1ea03a3Smacallan 1546e1ea03a3Smacallan CrimeSetupForCPUToScreenTexture(infoRec->pScrn, 1547e1ea03a3Smacallan op, pSrc->format, 1548e1ea03a3Smacallan ((PixmapPtr)(pSrc->pDrawable))->devPrivate.ptr, 1549e1ea03a3Smacallan ((PixmapPtr)(pSrc->pDrawable))->devKind, 1550e1ea03a3Smacallan w, h, flags); 1551e1ea03a3Smacallan 1552e1ea03a3Smacallan xSrc -= xDst; 1553e1ea03a3Smacallan ySrc -= yDst; 1554e1ea03a3Smacallan 1555e1ea03a3Smacallan while(nbox--) { 1556e1ea03a3Smacallan CrimeSubsequentCPUToScreenTexture(infoRec->pScrn, 1557e1ea03a3Smacallan pbox->x1, pbox->y1, pbox->x1 + xSrc, 1558e1ea03a3Smacallan pbox->y1 + ySrc, pbox->x2 - pbox->x1, 1559e1ea03a3Smacallan pbox->y2 - pbox->y1); 1560e1ea03a3Smacallan pbox++; 1561e1ea03a3Smacallan } 1562e1ea03a3Smacallan 1563e1ea03a3Smacallan SET_SYNC_FLAG(infoRec); 1564e1ea03a3Smacallan REGION_UNINIT(pScreen, ®ion); 1565e1ea03a3Smacallan DONE(CRIME_DEBUG_XRENDER); 1566e1ea03a3Smacallan return; 1567e1ea03a3Smacallan } 1568e1ea03a3Smacallan xf86Msg(X_ERROR, "%s: shouldn't be here\n", __func__); 1569e1ea03a3Smacallan} 1570e1ea03a3Smacallan 1571e1ea03a3Smacallanstatic void 1572e1ea03a3SmacallanCrimeDoScreenToScreenComposite( 1573e1ea03a3Smacallan CARD8 op, 1574e1ea03a3Smacallan PicturePtr pSrc, 1575e1ea03a3Smacallan PicturePtr pMask, 1576e1ea03a3Smacallan PicturePtr pDst, 1577e1ea03a3Smacallan INT16 xSrc, 1578e1ea03a3Smacallan INT16 ySrc, 1579e1ea03a3Smacallan INT16 xMask, 1580e1ea03a3Smacallan INT16 yMask, 1581e1ea03a3Smacallan INT16 xDst, 1582e1ea03a3Smacallan INT16 yDst, 1583e1ea03a3Smacallan CARD16 width, 1584e1ea03a3Smacallan CARD16 height 1585e1ea03a3Smacallan) 1586e1ea03a3Smacallan{ 1587e1ea03a3Smacallan ScreenPtr pScreen = pDst->pDrawable->pScreen; 1588e1ea03a3Smacallan XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen); 1589e1ea03a3Smacallan ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 1590e1ea03a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 1591e1ea03a3Smacallan RegionRec region; 1592e1ea03a3Smacallan CARD32 *formats; 1593e1ea03a3Smacallan int flags = 0; 1594e1ea03a3Smacallan BoxPtr pbox; 1595e1ea03a3Smacallan int nbox; 1596e1ea03a3Smacallan int xs, ys, xd, yd, w, h; 1597e1ea03a3Smacallan 1598e1ea03a3Smacallan LOG(CRIME_DEBUG_XRENDER); 1599e1ea03a3Smacallan if (pSrc->transform || (pMask && pMask->transform)) { 1600e1ea03a3Smacallan xf86Msg(X_ERROR, "%s: mask?!\n", __func__); 1601e1ea03a3Smacallan return; 1602e1ea03a3Smacallan } 1603e1ea03a3Smacallan xf86Msg(X_ERROR, "%s: %d\n", __func__, op); 1604e1ea03a3Smacallan if (pDst->alphaMap || pSrc->alphaMap || (pMask && pMask->alphaMap)) { 1605e1ea03a3Smacallan xf86Msg(X_ERROR, "%s: alpha-map\n", __func__); 1606e1ea03a3Smacallan return; 1607e1ea03a3Smacallan } 1608e1ea03a3Smacallan 1609e1ea03a3Smacallan xDst += pDst->pDrawable->x; 1610e1ea03a3Smacallan yDst += pDst->pDrawable->y; 1611e1ea03a3Smacallan xSrc += pSrc->pDrawable->x; 1612e1ea03a3Smacallan ySrc += pSrc->pDrawable->y; 1613e1ea03a3Smacallan 1614e1ea03a3Smacallan formats = infoRec->CPUToScreenTextureFormats; 1615e1ea03a3Smacallan 1616e1ea03a3Smacallan w = pSrc->pDrawable->width; 1617e1ea03a3Smacallan h = pSrc->pDrawable->height; 1618e1ea03a3Smacallan 1619e1ea03a3Smacallan if(pSrc->repeat) 1620e1ea03a3Smacallan flags |= XAA_RENDER_REPEAT; 1621e1ea03a3Smacallan 1622e1ea03a3Smacallan while(*formats != pSrc->format) { 1623e1ea03a3Smacallan if(!(*formats)) return; 1624e1ea03a3Smacallan formats++; 1625e1ea03a3Smacallan } 1626e1ea03a3Smacallan 1627e1ea03a3Smacallan if (!miComputeCompositeRegion (®ion, pSrc, pMask, pDst, 1628e1ea03a3Smacallan xSrc, ySrc, xMask, yMask, xDst, yDst, width, height)) 1629e1ea03a3Smacallan return; 1630e1ea03a3Smacallan 1631e1ea03a3Smacallan nbox = REGION_NUM_RECTS(®ion); 1632e1ea03a3Smacallan pbox = REGION_RECTS(®ion); 1633e1ea03a3Smacallan 1634e1ea03a3Smacallan if(!nbox) { 1635e1ea03a3Smacallan REGION_UNINIT(pScreen, ®ion); 1636e1ea03a3Smacallan return; 1637e1ea03a3Smacallan } 1638e1ea03a3Smacallan 163926dcc2a3Smacallan MAKE_ROOM(6); 1640e1ea03a3Smacallan WRITE4(CRIME_DE_MODE_SRC, DE_MODE_TLB_A | DE_MODE_BUFDEPTH_32 | 1641e1ea03a3Smacallan DE_MODE_TYPE_RGBA | DE_MODE_PIXDEPTH_32); 164226dcc2a3Smacallan WRITE4(CRIME_DE_MODE_DST, DE_MODE_TLB_A | DE_MODE_BUFDEPTH_32 | 164326dcc2a3Smacallan DE_MODE_TYPE_RGBA | DE_MODE_PIXDEPTH_32); 1644e1ea03a3Smacallan WRITE4(CRIME_DE_XFER_STEP_X, 1); 1645e1ea03a3Smacallan WRITE4(CRIME_DE_ALPHA_FUNC, 1646e1ea03a3Smacallan DE_ALPHA_ADD | 1647e1ea03a3Smacallan (DE_ALPHA_OP_SRC_ALPHA << DE_ALPHA_OP_SRC_SHIFT) | 1648e1ea03a3Smacallan (DE_ALPHA_OP_1_MINUS_SRC_ALPHA << DE_ALPHA_OP_DST_SHIFT)); 1649e1ea03a3Smacallan WRITE4(CRIME_DE_DRAWMODE, 1650e1ea03a3Smacallan DE_DRAWMODE_BYTEMASK | DE_DRAWMODE_ALPHA_BLEND | 1651e1ea03a3Smacallan DE_DRAWMODE_XFER_EN); 1652e1ea03a3Smacallan WRITE4(CRIME_DE_PRIMITIVE, 1653e1ea03a3Smacallan DE_PRIM_RECTANGLE | DE_PRIM_LR | DE_PRIM_TB); 165426dcc2a3Smacallan SYNC; 1655e1ea03a3Smacallan xSrc -= xDst; 1656e1ea03a3Smacallan ySrc -= yDst; 1657e1ea03a3Smacallan 1658e1ea03a3Smacallan /* assume no overlap - might bite us in the arse at some point */ 1659e1ea03a3Smacallan while(nbox--) { 1660e1ea03a3Smacallan xs = pbox->x1 + xSrc; 1661e1ea03a3Smacallan ys = pbox->y1 + ySrc; 1662e1ea03a3Smacallan xd = pbox->x1; 1663e1ea03a3Smacallan yd = pbox->y1; 1664e1ea03a3Smacallan w = pbox->x2 - pbox->x1; 1665e1ea03a3Smacallan h = pbox->y2 - pbox->y1; 166626dcc2a3Smacallan MAKE_ROOM(3); 1667e1ea03a3Smacallan WRITE4(CRIME_DE_XFER_ADDR_SRC,(xs << 16) | (ys & 0xffff)); 1668e1ea03a3Smacallan WRITE4(CRIME_DE_X_VERTEX_0, (xd << 16) | (yd & 0xffff)); 1669e1ea03a3Smacallan WRITE4ST(CRIME_DE_X_VERTEX_1, 1670e1ea03a3Smacallan ((xd + w - 1) << 16) | ((yd + h - 1) & 0xffff)); 1671e1ea03a3Smacallan pbox++; 1672e1ea03a3Smacallan } 1673e1ea03a3Smacallan 1674e1ea03a3Smacallan SET_SYNC_FLAG(infoRec); 1675e1ea03a3Smacallan REGION_UNINIT(pScreen, ®ion); 1676e1ea03a3Smacallan return; 1677e1ea03a3Smacallan} 1678e1ea03a3Smacallan 1679e1ea03a3Smacallanstatic Bool 1680e1ea03a3SmacallanCrimeComposite( 1681e1ea03a3Smacallan CARD8 op, 1682e1ea03a3Smacallan PicturePtr pSrc, 1683e1ea03a3Smacallan PicturePtr pMask, 1684e1ea03a3Smacallan PicturePtr pDst, 1685e1ea03a3Smacallan INT16 xSrc, 1686e1ea03a3Smacallan INT16 ySrc, 1687e1ea03a3Smacallan INT16 xMask, 1688e1ea03a3Smacallan INT16 yMask, 1689e1ea03a3Smacallan INT16 xDst, 1690e1ea03a3Smacallan INT16 yDst, 1691e1ea03a3Smacallan CARD16 width, 1692e1ea03a3Smacallan CARD16 height 1693e1ea03a3Smacallan) 1694e1ea03a3Smacallan{ 1695e1ea03a3Smacallan ScreenPtr pScreen = pDst->pDrawable->pScreen; 1696e1ea03a3Smacallan XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen); 1697e1ea03a3Smacallan 1698e1ea03a3Smacallan LOG(CRIME_DEBUG_XRENDER); 1699e1ea03a3Smacallan 1700e1ea03a3Smacallan if(!REGION_NUM_RECTS(pDst->pCompositeClip)) 1701e1ea03a3Smacallan return TRUE; 1702e1ea03a3Smacallan 1703e1ea03a3Smacallan if(!infoRec->pScrn->vtSema) 1704e1ea03a3Smacallan return FALSE; 1705e1ea03a3Smacallan 1706e1ea03a3Smacallan if((pDst->pDrawable->type == DRAWABLE_WINDOW) || 1707e1ea03a3Smacallan IS_OFFSCREEN_PIXMAP(pDst->pDrawable)) { 1708e1ea03a3Smacallan if ((pSrc->pDrawable->type == DRAWABLE_WINDOW) || 1709e1ea03a3Smacallan IS_OFFSCREEN_PIXMAP(pSrc->pDrawable)) { 1710e1ea03a3Smacallan /* screen-to-screen */ 1711e1ea03a3Smacallan CrimeDoScreenToScreenComposite(op, pSrc, pMask, pDst, 1712e1ea03a3Smacallan xSrc, ySrc, xMask, yMask, 1713e1ea03a3Smacallan xDst, yDst, width, height); 1714e1ea03a3Smacallan return TRUE; 1715e1ea03a3Smacallan } else { 1716e1ea03a3Smacallan /* CPU-to-screen composite */ 1717e1ea03a3Smacallan if (op != PictOpOver) 1718e1ea03a3Smacallan xf86Msg(X_ERROR, "%s: op %d\n", __func__, op); 1719e1ea03a3Smacallan CrimeDoCPUToScreenComposite(op, pSrc, pMask, pDst, 1720e1ea03a3Smacallan xSrc, ySrc, xMask, yMask, 1721e1ea03a3Smacallan xDst, yDst, width, height); 1722e1ea03a3Smacallan return TRUE; 1723e1ea03a3Smacallan } 1724e1ea03a3Smacallan } else { 1725e1ea03a3Smacallan if ((pSrc->pDrawable->type == DRAWABLE_WINDOW) || 1726e1ea03a3Smacallan IS_OFFSCREEN_PIXMAP(pSrc->pDrawable)) { 1727e1ea03a3Smacallan /* screen-to-RAM */ 1728e1ea03a3Smacallan xf86Msg(X_ERROR, "%s: screen-to-RAM composite\n", 1729e1ea03a3Smacallan __func__); 1730e1ea03a3Smacallan return TRUE; 1731e1ea03a3Smacallan } else { 1732e1ea03a3Smacallan /* RAM-to-RAM */ 1733e1ea03a3Smacallan return FALSE; 1734e1ea03a3Smacallan } 1735e1ea03a3Smacallan } 1736e1ea03a3Smacallan xf86Msg(X_ERROR, "composite fucked\n"); 1737e1ea03a3Smacallan} 1738e1ea03a3Smacallan 1739e1ea03a3Smacallanstatic void 1740e1ea03a3SmacallanCrimePolyPoint( 1741e1ea03a3Smacallan DrawablePtr pDraw, 1742e1ea03a3Smacallan GCPtr pGC, 1743e1ea03a3Smacallan int mode, 1744e1ea03a3Smacallan int npt, 1745e1ea03a3Smacallan xPoint *pptInit 1746e1ea03a3Smacallan) 1747e1ea03a3Smacallan{ 1748e1ea03a3Smacallan ScreenPtr pScreen = pDraw->pScreen; 1749e1ea03a3Smacallan ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 1750e1ea03a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 1751e1ea03a3Smacallan BoxPtr pBox; 1752e1ea03a3Smacallan xPoint *ppt, *pts; 1753e1ea03a3Smacallan int x1, x2, y1, y2, x, y, i, nBox; 1754e1ea03a3Smacallan 1755e1ea03a3Smacallan /* make pointlist origin relative */ 1756e1ea03a3Smacallan ppt = pptInit; 1757e1ea03a3Smacallan if (mode == CoordModePrevious) { 1758e1ea03a3Smacallan for (i = 0; i < npt; i++) { 1759e1ea03a3Smacallan ppt++; 1760e1ea03a3Smacallan ppt->x += (ppt-1)->x; 1761e1ea03a3Smacallan ppt->y += (ppt-1)->y; 1762e1ea03a3Smacallan } 1763e1ea03a3Smacallan } 176426dcc2a3Smacallan MAKE_ROOM(6); 176526dcc2a3Smacallan WRITE4(CRIME_DE_MODE_DST, DE_MODE_TLB_A | DE_MODE_BUFDEPTH_32 | 176626dcc2a3Smacallan DE_MODE_TYPE_RGBA | DE_MODE_PIXDEPTH_32); 1767e1ea03a3Smacallan WRITE4(CRIME_DE_FG, pGC->fgPixel << 8); 1768e1ea03a3Smacallan WRITE4(CRIME_DE_ROP, pGC->alu); 1769e1ea03a3Smacallan WRITE4(CRIME_DE_PLANEMASK, pGC->planemask); 1770e1ea03a3Smacallan WRITE4(CRIME_DE_DRAWMODE, 1771e1ea03a3Smacallan DE_DRAWMODE_PLANEMASK | DE_DRAWMODE_BYTEMASK | DE_DRAWMODE_ROP); 1772e1ea03a3Smacallan WRITE4(CRIME_DE_PRIMITIVE, DE_PRIM_POINT); 177326dcc2a3Smacallan SYNC; 1774e1ea03a3Smacallan for (nBox = REGION_NUM_RECTS (pGC->pCompositeClip), 1775e1ea03a3Smacallan pBox = REGION_RECTS (pGC->pCompositeClip); 1776e1ea03a3Smacallan nBox--; pBox++) { 1777e1ea03a3Smacallan 1778e1ea03a3Smacallan pts = pptInit; 1779e1ea03a3Smacallan for (i = 0; i < npt; i++) { 1780e1ea03a3Smacallan x1 = pBox->x1; 1781e1ea03a3Smacallan y1 = pBox->y1; 1782e1ea03a3Smacallan x2 = pBox->x2; 1783e1ea03a3Smacallan y2 = pBox->y2; 1784e1ea03a3Smacallan x = pts->x + pDraw->x; 1785e1ea03a3Smacallan y = pts->y + pDraw->y; 1786e1ea03a3Smacallan if (x1 <= x && x < x2 && y1 <= y && y < y2) { 1787e1ea03a3Smacallan 178826dcc2a3Smacallan MAKE_ROOM(1); 1789e1ea03a3Smacallan WRITE4ST(CRIME_DE_X_VERTEX_0, 1790e1ea03a3Smacallan (x << 16) | y); 1791e1ea03a3Smacallan } 1792e1ea03a3Smacallan pts++; 1793e1ea03a3Smacallan } 1794e1ea03a3Smacallan } 1795e1ea03a3Smacallan} 1796e1ea03a3Smacallan 1797e1ea03a3Smacallanstatic void 1798e1ea03a3SmacallanCrimeValidatePolyPoint( 1799e1ea03a3Smacallan GCPtr pGC, 1800e1ea03a3Smacallan unsigned long changes, 1801e1ea03a3Smacallan DrawablePtr pDraw ) 1802e1ea03a3Smacallan{ 1803e1ea03a3Smacallan 1804e1ea03a3Smacallan if ((pDraw->type == DRAWABLE_WINDOW) || 1805e1ea03a3Smacallan IS_OFFSCREEN_PIXMAP(pDraw)) { 1806e1ea03a3Smacallan pGC->ops->PolyPoint = CrimePolyPoint; 1807e1ea03a3Smacallan } else 1808e1ea03a3Smacallan xf86Msg(X_ERROR, "boo\n"); 1809e1ea03a3Smacallan} 181034c4e112Smacallanstatic void 181134c4e112SmacallanCrimePolyArc(DrawablePtr pDraw, 181234c4e112Smacallan GCPtr pGC, 181334c4e112Smacallan int narcs, 181434c4e112Smacallan xArc *parcs) 181534c4e112Smacallan{ 181634c4e112Smacallan xArc *arc; 181734c4e112Smacallan BoxRec box; 181834c4e112Smacallan int i, x2, y2; 181934c4e112Smacallan RegionPtr cclip; 182034c4e112Smacallan 182134c4e112Smacallan cclip = pGC->pCompositeClip; 182234c4e112Smacallan 182334c4e112Smacallan if(!REGION_NUM_RECTS(cclip)) 182434c4e112Smacallan return; 182534c4e112Smacallan 182634c4e112Smacallan for (arc = parcs, i = narcs; --i >= 0; arc++) { 182734c4e112Smacallan if (miCanZeroArc(arc)) { 182834c4e112Smacallan box.x1 = arc->x + pDraw->x; 182934c4e112Smacallan box.y1 = arc->y + pDraw->y; 183034c4e112Smacallan x2 = box.x1 + (int)arc->width + 1; 183134c4e112Smacallan box.x2 = x2; 183234c4e112Smacallan y2 = box.y1 + (int)arc->height + 1; 183334c4e112Smacallan box.y2 = y2; 183434c4e112Smacallan if ( (x2 <= SHRT_MAX) && (y2 <= SHRT_MAX) && 183534c4e112Smacallan (RECT_IN_REGION(pDraw->pScreen, cclip, &box) == rgnIN) ) 183634c4e112Smacallan miZeroPolyArc(pDraw, pGC, 1, arc); 183734c4e112Smacallan } 183834c4e112Smacallan else 183934c4e112Smacallan miPolyArc(pDraw, pGC, 1, arc); 184034c4e112Smacallan } 184134c4e112Smacallan} 184234c4e112Smacallan 184334c4e112Smacallanstatic void 184434c4e112SmacallanCrimeValidatePolyArc(GCPtr pGC, 184534c4e112Smacallan unsigned long changes, 184634c4e112Smacallan DrawablePtr pDraw) 184734c4e112Smacallan{ 184834c4e112Smacallan if ((pDraw->type == DRAWABLE_WINDOW) || 184934c4e112Smacallan IS_OFFSCREEN_PIXMAP(pDraw)) { 185034c4e112Smacallan pGC->ops->PolyPoint = CrimePolyPoint; 185134c4e112Smacallan /*pGC->ops->PolyArc = miPolyArc;*/ 185234c4e112Smacallan pGC->ops->PolyArc = CrimePolyArc; 185334c4e112Smacallan } else 185434c4e112Smacallan { 185534c4e112Smacallan pGC->ops->PolyPoint = XAAGetFallbackOps()->PolyPoint; 185634c4e112Smacallan pGC->ops->PolyArc = XAAGetFallbackOps()->PolyArc; 185734c4e112Smacallan } 185834c4e112Smacallan} 1859e1ea03a3Smacallan 186026dcc2a3Smacallanstatic void copyRGBAtoARGB(uint32_t *dest, uint32_t *src, int len) 186126dcc2a3Smacallan{ 186226dcc2a3Smacallan while (len > 0) { 186326dcc2a3Smacallan *dest = *src >> 8; 186426dcc2a3Smacallan dest++; 186526dcc2a3Smacallan src++; 186626dcc2a3Smacallan len--; 186726dcc2a3Smacallan } 186826dcc2a3Smacallan} 186926dcc2a3Smacallan 187034c4e112Smacallanstatic void 187134c4e112SmacallanCrimeReadPixmap(ScrnInfoPtr pScrn, 187234c4e112Smacallan int x, 187334c4e112Smacallan int y, 187434c4e112Smacallan int w, 187534c4e112Smacallan int h, 187634c4e112Smacallan unsigned char *dst, 187734c4e112Smacallan int dstwidth, 187834c4e112Smacallan int bpp, 187934c4e112Smacallan int depth) 188034c4e112Smacallan{ 188126dcc2a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 188226dcc2a3Smacallan int bufno = 0; 188326dcc2a3Smacallan int nextbuf, i, len = w << 2; 188426dcc2a3Smacallan int mx = x << 2, offset; 188526dcc2a3Smacallan 188626dcc2a3Smacallan offset = mx & 0x3f; 188726dcc2a3Smacallan mx &= ~0x3f; 188826dcc2a3Smacallan len = (len + offset + 0x3f) & ~0x3f; 188926dcc2a3Smacallan 189026dcc2a3Smacallan LOG(CRIME_DEBUG_IMAGEREAD); 189126dcc2a3Smacallan 189226dcc2a3Smacallan#ifdef CRIME_DEBUG_LOUD 189326dcc2a3Smacallan xf86Msg(X_ERROR, "%s: %d %d %d %d\n", __func__, x, y, w, h); 189426dcc2a3Smacallan#endif 189526dcc2a3Smacallan 189626dcc2a3Smacallan MAKE_ROOM(3); 189726dcc2a3Smacallan 189826dcc2a3Smacallan /* 189926dcc2a3Smacallan * apparently all MTE coordinates are in bytes, not pixels 190026dcc2a3Smacallan * also, the MTE has some crazy alignment requirements - if 190126dcc2a3Smacallan * we don't do as above the thing will deadlock sooner or later 190226dcc2a3Smacallan * We use the MTE here because I couldn't get the rendering engine 190326dcc2a3Smacallan * to actually transfer anything into a linear buffer. The other 190426dcc2a3Smacallan * way around works just fine though. Shouldn't make much of a 190526dcc2a3Smacallan * difference, transfer times should be dominated by copying 190626dcc2a3Smacallan * data in and out of the DMA buffer anyway 190726dcc2a3Smacallan */ 190826dcc2a3Smacallan WRITE4(CRIME_MTE_MODE, (MTE_TLB_LIN_A << MTE_DST_TLB_SHIFT) | 190926dcc2a3Smacallan (MTE_TLB_A << MTE_SRC_TLB_SHIFT) | 191026dcc2a3Smacallan (MTE_DEPTH_8 << MTE_DEPTH_SHIFT) | 191126dcc2a3Smacallan MTE_MODE_DST_ECC | MTE_MODE_COPY); 191226dcc2a3Smacallan WRITE4(CRIME_MTE_SRC_Y_STEP, 1); 191326dcc2a3Smacallan WRITE4(CRIME_MTE_DST_Y_STEP, 1); 191426dcc2a3Smacallan SYNCMTE; 191526dcc2a3Smacallan WRITE4(CRIME_MTE_SRC0, (mx << 16) | y); 191626dcc2a3Smacallan WRITE4(CRIME_MTE_SRC1, ((mx + len) << 16) | y); 191726dcc2a3Smacallan WRITE4(CRIME_MTE_DST0, (bufno << 13)); 191826dcc2a3Smacallan WRITE4ST(CRIME_MTE_DST1, (bufno << 13) + len); 191926dcc2a3Smacallan for (i = y + 1; i < y + h; i++) { 192026dcc2a3Smacallan nextbuf = (bufno + 1) & 7; 192126dcc2a3Smacallan SYNCMTE; 192226dcc2a3Smacallan WRITE4(CRIME_MTE_SRC0, (mx << 16) | i); 192326dcc2a3Smacallan WRITE4(CRIME_MTE_SRC1, ((mx + len) << 16) | i); 192426dcc2a3Smacallan WRITE4(CRIME_MTE_DST0, (nextbuf << 13)); 192526dcc2a3Smacallan WRITE4ST(CRIME_MTE_DST1, (nextbuf << 13) + len); 192626dcc2a3Smacallan copyRGBAtoARGB((uint32_t *)dst, 192726dcc2a3Smacallan (uint32_t *)(fPtr->buffers[bufno] + offset), w); 192826dcc2a3Smacallan dst += dstwidth; 192926dcc2a3Smacallan bufno = nextbuf; 193026dcc2a3Smacallan } 193126dcc2a3Smacallan SYNCMTE; 193226dcc2a3Smacallan copyRGBAtoARGB((uint32_t *)dst, 193326dcc2a3Smacallan (uint32_t *)(fPtr->buffers[bufno] + offset), w); 193426dcc2a3Smacallan DONE(CRIME_DEBUG_IMAGEREAD); 193526dcc2a3Smacallan 193634c4e112Smacallan} 1937e1ea03a3Smacallanint 1938e1ea03a3SmacallanCrimeAccelInit(ScrnInfoPtr pScrn) 1939e1ea03a3Smacallan{ 1940e1ea03a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 1941e1ea03a3Smacallan XAAInfoRecPtr pXAAInfo = fPtr->pXAA; 1942e1ea03a3Smacallan int i; 1943e1ea03a3Smacallan 1944e1ea03a3Smacallan for (i = 0; i < 0x1000; i++) regcache[i] = 0x12345678; 1945e1ea03a3Smacallan LOG(CRIME_DEBUG_ALL); 1946e1ea03a3Smacallan SYNC; 1947e1ea03a3Smacallan WRITE4(CRIME_DE_MODE_DST, DE_MODE_TLB_A | DE_MODE_BUFDEPTH_32 | 1948e1ea03a3Smacallan DE_MODE_TYPE_RGBA | DE_MODE_PIXDEPTH_32); 1949e1ea03a3Smacallan 1950e1ea03a3Smacallan WRITE4(CRIME_DE_XFER_STEP_Y, 1); 195126dcc2a3Smacallan WRITE4(CRIME_DE_XFER_STRD_DST, 4); 1952e1ea03a3Smacallan WRITE4(CRIME_DE_XFER_STRD_SRC, 1); 1953e1ea03a3Smacallan 1954e1ea03a3Smacallan WRITE4(CRIME_MTE_BYTEMASK, 0xffffffff); 1955e1ea03a3Smacallan WRITE4(CRIME_MTE_SRC_Y_STEP, 4); 1956e1ea03a3Smacallan WRITE4(CRIME_MTE_DST_Y_STEP, 4); 195726dcc2a3Smacallan SYNC; 1958e1ea03a3Smacallan 1959e1ea03a3Smacallan /* blit the screen black */ 1960e1ea03a3Smacallan WRITE4(CRIME_DE_DRAWMODE, 1961e1ea03a3Smacallan DE_DRAWMODE_PLANEMASK | DE_DRAWMODE_BYTEMASK | DE_DRAWMODE_ROP); 1962e1ea03a3Smacallan WRITE4(CRIME_DE_ROP, 3); 1963e1ea03a3Smacallan WRITE4(CRIME_DE_PRIMITIVE, DE_PRIM_RECTANGLE | DE_PRIM_LR | DE_PRIM_TB); 1964e1ea03a3Smacallan WRITE4(CRIME_DE_FG, 0); 1965e1ea03a3Smacallan WRITE4(CRIME_DE_X_VERTEX_0, 0); 1966e1ea03a3Smacallan WRITE4ST(CRIME_DE_X_VERTEX_1, 1967e1ea03a3Smacallan fPtr->info.width << 16 | fPtr->info.height); 1968e1ea03a3Smacallan SYNC; 1969e1ea03a3Smacallan 197034c4e112Smacallan pXAAInfo->Flags = /*LINEAR_FRAMEBUFFER |*/ PIXMAP_CACHE | OFFSCREEN_PIXMAPS; 1971e1ea03a3Smacallan pXAAInfo->maxOffPixWidth = fPtr->info.width; 1972e1ea03a3Smacallan pXAAInfo->maxOffPixHeight = 2048; 1973e1ea03a3Smacallan 1974e1ea03a3Smacallan /* Sync */ 1975e1ea03a3Smacallan pXAAInfo->Sync = CrimeSync; 1976e1ea03a3Smacallan 19778e5567ffSmacallan CrimeDisableClipping(pScrn); 19788e5567ffSmacallan 1979e1ea03a3Smacallan /* Screen-to-screen copy */ 1980e1ea03a3Smacallan pXAAInfo->ScreenToScreenCopyFlags = NO_TRANSPARENCY; 1981e1ea03a3Smacallan pXAAInfo->SetupForScreenToScreenCopy = CrimeSetupForScreenToScreenCopy; 1982e1ea03a3Smacallan pXAAInfo->SubsequentScreenToScreenCopy = 1983e1ea03a3Smacallan CrimeSubsequentScreenToScreenCopy; 1984e1ea03a3Smacallan 1985e1ea03a3Smacallan /* rectangle fills */ 1986e1ea03a3Smacallan pXAAInfo->SetupForSolidFill = CrimeSetupForSolidFill; 1987e1ea03a3Smacallan pXAAInfo->SubsequentSolidFillRect = CrimeSubsequentSolidFillRect; 1988e1ea03a3Smacallan 1989e1ea03a3Smacallan /* image writes */ 1990e1ea03a3Smacallan pXAAInfo->ScanlineImageWriteFlags = 1991e1ea03a3Smacallan NO_TRANSPARENCY | LEFT_EDGE_CLIPPING | 1992e1ea03a3Smacallan LEFT_EDGE_CLIPPING_NEGATIVE_X | 1993e1ea03a3Smacallan CPU_TRANSFER_PAD_DWORD | SCANLINE_PAD_DWORD; 1994e1ea03a3Smacallan pXAAInfo->NumScanlineImageWriteBuffers = 8; 1995e1ea03a3Smacallan for (i = 0; i < 8; i++) 1996e1ea03a3Smacallan fPtr->buffers[i] = fPtr->linear + (i * 8192); 1997e1ea03a3Smacallan pXAAInfo->ScanlineImageWriteBuffers = fPtr->buffers; 1998e1ea03a3Smacallan pXAAInfo->SetupForScanlineImageWrite = 1999e1ea03a3Smacallan CrimeSetupForScanlineImageWrite; 2000e1ea03a3Smacallan pXAAInfo->SubsequentScanlineImageWriteRect = 2001e1ea03a3Smacallan CrimeSubsequentImageWriteRect; 2002e1ea03a3Smacallan pXAAInfo->SubsequentImageWriteScanline = 2003e1ea03a3Smacallan CrimeSubsequentImageWriteScanline; 2004e1ea03a3Smacallan 200534c4e112Smacallan /* read pixmap */ 200634c4e112Smacallan pXAAInfo->ReadPixmapFlags = 0 200734c4e112Smacallan | CPU_TRANSFER_PAD_DWORD 200834c4e112Smacallan ; 200934c4e112Smacallan pXAAInfo->ReadPixmap = CrimeReadPixmap; 201034c4e112Smacallan 2011e1ea03a3Smacallan /* colour expansion */ 2012e1ea03a3Smacallan pXAAInfo->ScanlineCPUToScreenColorExpandFillFlags = 2013e1ea03a3Smacallan LEFT_EDGE_CLIPPING; 2014e1ea03a3Smacallan pXAAInfo->NumScanlineColorExpandBuffers = 1; 2015e1ea03a3Smacallan fPtr->expandbuffers[0] = (uint8_t *)fPtr->expand; 2016e1ea03a3Smacallan pXAAInfo->ScanlineColorExpandBuffers = (void *)&fPtr->expandbuffers; 2017e1ea03a3Smacallan pXAAInfo->SetupForScanlineCPUToScreenColorExpandFill = 2018e1ea03a3Smacallan CrimeSetupForCPUToScreenColorExpandFill; 2019e1ea03a3Smacallan pXAAInfo->SubsequentScanlineCPUToScreenColorExpandFill = 2020e1ea03a3Smacallan CrimeSubsequentScanlineCPUToScreenColorExpandFill; 2021e1ea03a3Smacallan pXAAInfo->SubsequentColorExpandScanline = 2022e1ea03a3Smacallan CrimeSubsequentColorExpandScanline; 2023e1ea03a3Smacallan 2024e1ea03a3Smacallan /* clipping */ 2025e1ea03a3Smacallan pXAAInfo->ClippingFlags = HARDWARE_CLIP_SCREEN_TO_SCREEN_COPY | 20267a6652bbSmacallan HARDWARE_CLIP_SOLID_FILL | 20277a6652bbSmacallan HARDWARE_CLIP_SOLID_LINE | 20285b2650b9Smacallan HARDWARE_CLIP_MONO_8x8_FILL | HARDWARE_CLIP_DASHED_LINE; 2029e1ea03a3Smacallan pXAAInfo->SetClippingRectangle = CrimeSetClippingRectangle; 2030e1ea03a3Smacallan pXAAInfo->DisableClipping = CrimeDisableClipping; 2031e1ea03a3Smacallan 2032e1ea03a3Smacallan /* solid line drawing */ 2033e1ea03a3Smacallan pXAAInfo->SetupForSolidLine = CrimeSetupForSolidLine; 2034e1ea03a3Smacallan pXAAInfo->SubsequentSolidTwoPointLine = 2035e1ea03a3Smacallan CrimeSubsequentSolidTwoPointLine; 20365b2650b9Smacallan pXAAInfo->SolidLineFlags = 0; 2037e1ea03a3Smacallan 2038e1ea03a3Smacallan /* dashed line drawing */ 2039e1ea03a3Smacallan pXAAInfo->SetupForDashedLine = CrimeSetupForDashedLine; 2040e1ea03a3Smacallan pXAAInfo->SubsequentDashedTwoPointLine = 2041e1ea03a3Smacallan CrimeSubsequentDashedTwoPointLine; 2042e1ea03a3Smacallan pXAAInfo->DashedLineFlags = LINE_PATTERN_MSBFIRST_MSBJUSTIFIED; 2043e1ea03a3Smacallan pXAAInfo->DashPatternMaxLength = 32; 2044e1ea03a3Smacallan 20455b2650b9Smacallan /* mono pattern fills */ 20465b2650b9Smacallan pXAAInfo->Mono8x8PatternFillFlags = HARDWARE_PATTERN_PROGRAMMED_BITS | 20475b2650b9Smacallan HARDWARE_PATTERN_PROGRAMMED_ORIGIN | BIT_ORDER_IN_BYTE_MSBFIRST; 20485b2650b9Smacallan pXAAInfo->SetupForMono8x8PatternFill = CrimeSetupForMono8x8PatternFill; 20495b2650b9Smacallan pXAAInfo->SubsequentMono8x8PatternFillRect = 20505b2650b9Smacallan CrimeSubsequentMono8x8PatternFillRect; 20515b2650b9Smacallan 2052e1ea03a3Smacallan /* XRender acceleration */ 2053e1ea03a3Smacallan#ifdef RENDER 2054e1ea03a3Smacallan pXAAInfo->CPUToScreenAlphaTextureFlags = 0; 2055e1ea03a3Smacallan pXAAInfo->SetupForCPUToScreenAlphaTexture = 2056e1ea03a3Smacallan CrimeSetupForCPUToScreenAlphaTexture; 2057e1ea03a3Smacallan pXAAInfo->SubsequentCPUToScreenAlphaTexture = 2058e1ea03a3Smacallan CrimeSubsequentCPUToScreenAlphaTexture; 2059e1ea03a3Smacallan pXAAInfo->CPUToScreenAlphaTextureFormats = CrimeAlphaTextureFormats; 2060e1ea03a3Smacallan 2061e1ea03a3Smacallan pXAAInfo->SetupForCPUToScreenTexture = CrimeSetupForCPUToScreenTexture; 2062e1ea03a3Smacallan pXAAInfo->SubsequentCPUToScreenTexture = 2063e1ea03a3Smacallan CrimeSubsequentCPUToScreenTexture; 2064e1ea03a3Smacallan pXAAInfo->CPUToScreenTextureFlags = 0; 2065e1ea03a3Smacallan pXAAInfo->CPUToScreenTextureFormats = CrimeTextureFormats; 2066e1ea03a3Smacallan pXAAInfo->Composite = CrimeComposite; 2067e1ea03a3Smacallan#endif 2068e1ea03a3Smacallan pXAAInfo->ValidatePolyPoint = CrimeValidatePolyPoint; 2069e1ea03a3Smacallan pXAAInfo->PolyPointMask = GCFunction; 207034c4e112Smacallan pXAAInfo->ValidatePolyArc = CrimeValidatePolyArc; 207134c4e112Smacallan pXAAInfo->PolyArcMask = GCFunction | GCLineWidth; 2072e1ea03a3Smacallan 2073e1ea03a3Smacallan return -1; 2074e1ea03a3Smacallan} 2075