crime_accel.c revision 29406fd8
129406fd8Smacallan/* $NetBSD: crime_accel.c,v 1.13 2009/10/21 03:28:40 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" 3829406fd8Smacallan#include "mipict.h" 39e1ea03a3Smacallan 40e1ea03a3Smacallanuint32_t regcache[0x1000]; 41e1ea03a3Smacallan 42e1ea03a3Smacallan#define CRIMEREG(p) (volatile uint32_t *)(fPtr->engine + p) 4329406fd8Smacallan#define WBFLUSH __asm("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) 63e1ea03a3Smacallan#endif 6429406fd8Smacallan#define SYNCMTE do {} while ((*CRIMEREG(0x4000) & CRIME_DE_MTE_IDLE) == 0) 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); 7829406fd8Smacallan#if defined(CRIME_DEBUG_LOUD) && (CRIME_DEBUG_MASK & CRIME_DEBUG_SYNC) 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); 15229406fd8Smacallan#if defined(CRIME_DEBUG_LOUD) && (CRIME_DEBUG_MASK & CRIME_DEBUG_BITBLT) 153e1ea03a3Smacallan xf86Msg(X_ERROR, "%s: %d, %d; %d x %d -> %d %d\n", __func__, 154e1ea03a3Smacallan xSrc, ySrc, w, h, xDst, yDst); 155e1ea03a3Smacallan#endif 15629406fd8Smacallan if ((fPtr->use_mte) && (w > 64) && (abs(ySrc - yDst) > 4) && 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 } else { 182e1ea03a3Smacallan if (fPtr->xdir == -1) { 183e1ea03a3Smacallan prim |= DE_PRIM_RL; 184e1ea03a3Smacallan rxe = xDst; 185e1ea03a3Smacallan rxa = xDst + w - 1; 186e1ea03a3Smacallan rxs = xSrc + w - 1; 187e1ea03a3Smacallan } else { 188e1ea03a3Smacallan prim |= DE_PRIM_LR; 189e1ea03a3Smacallan rxe = xDst + w - 1; 190e1ea03a3Smacallan rxa = xDst; 191e1ea03a3Smacallan rxs = xSrc; 192e1ea03a3Smacallan } 193e1ea03a3Smacallan if (fPtr->ydir == -1) { 194e1ea03a3Smacallan prim |= DE_PRIM_BT; 195e1ea03a3Smacallan rye = yDst; 196e1ea03a3Smacallan rya = yDst + h - 1; 197e1ea03a3Smacallan rys = ySrc + h - 1; 198e1ea03a3Smacallan } else { 199e1ea03a3Smacallan prim |= DE_PRIM_TB; 200e1ea03a3Smacallan rye = yDst + h - 1; 201e1ea03a3Smacallan rya = yDst; 202e1ea03a3Smacallan rys = ySrc; 203e1ea03a3Smacallan } 204e1ea03a3Smacallan 20526dcc2a3Smacallan MAKE_ROOM(4); 206e1ea03a3Smacallan WRITE4(CRIME_DE_PRIMITIVE, prim); 207e1ea03a3Smacallan WRITE4(CRIME_DE_XFER_ADDR_SRC,(rxs << 16) | (rys & 0xffff)); 208e1ea03a3Smacallan WRITE4(CRIME_DE_X_VERTEX_0, (rxa << 16) | (rya & 0xffff)); 209e1ea03a3Smacallan WRITE4ST(CRIME_DE_X_VERTEX_1, (rxe << 16) | (rye & 0xffff)); 210e1ea03a3Smacallan } 211e1ea03a3Smacallan DONE(CRIME_DEBUG_BITBLT); 212e1ea03a3Smacallan} 213e1ea03a3Smacallan 214e1ea03a3Smacallanstatic void 215e1ea03a3SmacallanCrimeSetupForSolidFill 216e1ea03a3Smacallan( 217e1ea03a3Smacallan ScrnInfoPtr pScrn, 218e1ea03a3Smacallan int colour, 219e1ea03a3Smacallan int rop, 220e1ea03a3Smacallan unsigned int planemask 221e1ea03a3Smacallan) 222e1ea03a3Smacallan{ 223e1ea03a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 224e1ea03a3Smacallan int i; 225e1ea03a3Smacallan 226e1ea03a3Smacallan LOG(CRIME_DEBUG_RECTFILL); 227850ab569Smacallan#ifdef MTE_DRAW_RECT 228231734e4Smacallan if (rop == GXcopy) { 229231734e4Smacallan fPtr->use_mte = 1; 230231734e4Smacallan MAKE_ROOM(3); 231231734e4Smacallan WRITE4(CRIME_MTE_MODE, MTE_MODE_DST_ECC | 232231734e4Smacallan MTE_TLB_A << MTE_DST_TLB_SHIFT | 233231734e4Smacallan MTE_TLB_A << MTE_SRC_TLB_SHIFT | 234231734e4Smacallan MTE_DEPTH_32 << MTE_DEPTH_SHIFT); 235231734e4Smacallan WRITE4(CRIME_MTE_DST_Y_STEP, 1); 236231734e4Smacallan WRITE4(CRIME_MTE_BG, colour << 8); 237231734e4Smacallan SYNCMTE; 238850ab569Smacallan } else 239850ab569Smacallan#endif 240850ab569Smacallan { 241231734e4Smacallan fPtr->use_mte = 0; 242231734e4Smacallan MAKE_ROOM(7); 243231734e4Smacallan WRITE4(CRIME_DE_PLANEMASK, planemask); 244231734e4Smacallan WRITE4(CRIME_DE_ROP, rop); 245231734e4Smacallan WRITE4(CRIME_DE_FG, colour << 8); 246231734e4Smacallan WRITE4(CRIME_DE_DRAWMODE, 247231734e4Smacallan DE_DRAWMODE_PLANEMASK | DE_DRAWMODE_BYTEMASK | 248231734e4Smacallan DE_DRAWMODE_ROP |\ 249231734e4Smacallan DE_DRAWMODE_SCISSOR_EN); 250231734e4Smacallan WRITE4(CRIME_DE_PRIMITIVE, 251231734e4Smacallan DE_PRIM_RECTANGLE | DE_PRIM_LR | DE_PRIM_TB); 252231734e4Smacallan WRITE4(CRIME_DE_MODE_DST, DE_MODE_TLB_A | DE_MODE_BUFDEPTH_32 | 253231734e4Smacallan DE_MODE_TYPE_RGBA | DE_MODE_PIXDEPTH_32); 254231734e4Smacallan SYNC; 255231734e4Smacallan } 256e1ea03a3Smacallan DONE(CRIME_DEBUG_RECTFILL); 257e1ea03a3Smacallan} 258e1ea03a3Smacallan 259e1ea03a3Smacallanstatic void 260e1ea03a3SmacallanCrimeSubsequentSolidFillRect 261e1ea03a3Smacallan( 262e1ea03a3Smacallan ScrnInfoPtr pScrn, 263e1ea03a3Smacallan int x, 264e1ea03a3Smacallan int y, 265e1ea03a3Smacallan int w, 266e1ea03a3Smacallan int h 267e1ea03a3Smacallan) 268e1ea03a3Smacallan{ 269e1ea03a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 2707a6652bbSmacallan int xa, xe, ya, ye; 271e1ea03a3Smacallan 272e1ea03a3Smacallan LOG(CRIME_DEBUG_RECTFILL); 273850ab569Smacallan#ifdef MTE_DRAW_RECT 274231734e4Smacallan if (fPtr->use_mte) { 2757a6652bbSmacallan 2767a6652bbSmacallan /* 2777a6652bbSmacallan * the MTE doesn't support clipping so we have to do it 2787a6652bbSmacallan * ourselves - luckily it's trivial with rectangles 2797a6652bbSmacallan */ 2807a6652bbSmacallan xa = MAX(fPtr->cxa, x); 2817a6652bbSmacallan ya = MAX(fPtr->cya, y); 2827a6652bbSmacallan xe = MIN(fPtr->cxe, x + w); 2837a6652bbSmacallan ye = MIN(fPtr->cye, y + h); 2847a6652bbSmacallan if ((xa < xe) && (ya < ye)) { 2857a6652bbSmacallan MAKE_ROOM(2); 2867a6652bbSmacallan WRITE4(CRIME_MTE_DST0, (xa << 18) | (ya & 0xffff)); 2877a6652bbSmacallan WRITE4ST(CRIME_MTE_DST1, 2887a6652bbSmacallan (((xe << 2) - 1 ) << 16) | ((ye - 1) & 0xffff)); 2897a6652bbSmacallan } 290850ab569Smacallan } else 291850ab569Smacallan#endif 292850ab569Smacallan { 293231734e4Smacallan MAKE_ROOM(2); 294231734e4Smacallan WRITE4(CRIME_DE_X_VERTEX_0, (x << 16) | (y & 0xffff)); 295231734e4Smacallan WRITE4ST(CRIME_DE_X_VERTEX_1, 296231734e4Smacallan ((x + w - 1) << 16) | ((y + h - 1) & 0xffff)); 297231734e4Smacallan } 298e1ea03a3Smacallan DONE(CRIME_DEBUG_RECTFILL); 299e1ea03a3Smacallan} 300e1ea03a3Smacallan 3015b2650b9Smacallanstatic void 3025b2650b9SmacallanCrimeSetupForMono8x8PatternFill(ScrnInfoPtr pScrn, int patx, int paty, 3035b2650b9Smacallan int fg, int bg, int rop, unsigned int planemask) 3045b2650b9Smacallan{ 3055b2650b9Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 3065b2650b9Smacallan uint32_t pat; 3075b2650b9Smacallan 3085b2650b9Smacallan LOG(CRIME_DEBUG_RECTFILL); 3095b2650b9Smacallan MAKE_ROOM(7); 3105b2650b9Smacallan WRITE4(CRIME_DE_PLANEMASK, planemask); 3115b2650b9Smacallan WRITE4(CRIME_DE_ROP, rop); 3125b2650b9Smacallan WRITE4(CRIME_DE_FG, fg << 8); 3135b2650b9Smacallan if (bg == -1) { 3145b2650b9Smacallan WRITE4(CRIME_DE_DRAWMODE, 3155b2650b9Smacallan DE_DRAWMODE_PLANEMASK | DE_DRAWMODE_BYTEMASK | 3165b2650b9Smacallan DE_DRAWMODE_ROP | DE_DRAWMODE_POLY_STIP | 3175b2650b9Smacallan DE_DRAWMODE_SCISSOR_EN); 3185b2650b9Smacallan } else { 3195b2650b9Smacallan WRITE4(CRIME_DE_BG, bg << 8); 3205b2650b9Smacallan WRITE4(CRIME_DE_DRAWMODE, 3215b2650b9Smacallan DE_DRAWMODE_PLANEMASK | DE_DRAWMODE_BYTEMASK | 3225b2650b9Smacallan DE_DRAWMODE_ROP | DE_DRAWMODE_POLY_STIP | 3235b2650b9Smacallan DE_DRAWMODE_OPAQUE_STIP | DE_DRAWMODE_SCISSOR_EN); 3245b2650b9Smacallan } 3255b2650b9Smacallan WRITE4(CRIME_DE_PRIMITIVE, 3265b2650b9Smacallan DE_PRIM_RECTANGLE | DE_PRIM_LR | DE_PRIM_TB); 3275b2650b9Smacallan WRITE4(CRIME_DE_MODE_DST, DE_MODE_TLB_A | DE_MODE_BUFDEPTH_32 | 3285b2650b9Smacallan DE_MODE_TYPE_RGBA | DE_MODE_PIXDEPTH_32); 3295b2650b9Smacallan 3305b2650b9Smacallan /* 3315b2650b9Smacallan * we need to store the pattern so we can just hammer it into the 3325b2650b9Smacallan * stipple register later on 3335b2650b9Smacallan */ 3345b2650b9Smacallan pat = patx & 0xff000000; 3355b2650b9Smacallan pat |= pat >> 8; 3365b2650b9Smacallan fPtr->pattern[0] = pat | (pat >> 16); 3375b2650b9Smacallan pat = patx & 0x00ff0000; 3385b2650b9Smacallan pat |= pat << 8; 3395b2650b9Smacallan fPtr->pattern[1] = pat | (pat >> 16); 3405b2650b9Smacallan pat = patx & 0x0000ff00; 3415b2650b9Smacallan pat |= pat >> 8; 3425b2650b9Smacallan fPtr->pattern[2] = pat | (pat << 16); 3435b2650b9Smacallan pat = patx & 0x000000ff; 3445b2650b9Smacallan pat |= pat << 8; 3455b2650b9Smacallan fPtr->pattern[3] = pat | (pat << 16); 3465b2650b9Smacallan 3475b2650b9Smacallan pat = paty & 0xff000000; 3485b2650b9Smacallan pat |= pat >> 8; 3495b2650b9Smacallan fPtr->pattern[4] = pat | (pat >> 16); 3505b2650b9Smacallan pat = paty & 0x00ff0000; 3515b2650b9Smacallan pat |= pat << 8; 3525b2650b9Smacallan fPtr->pattern[5] = pat | (pat >> 16); 3535b2650b9Smacallan pat = paty & 0x0000ff00; 3545b2650b9Smacallan pat |= pat >> 8; 3555b2650b9Smacallan fPtr->pattern[6] = pat | (pat << 16); 3565b2650b9Smacallan pat = paty & 0x000000ff; 3575b2650b9Smacallan pat |= pat << 8; 3585b2650b9Smacallan fPtr->pattern[7] = pat | (pat << 16); 3595b2650b9Smacallan SYNC; 3605b2650b9Smacallan DONE(CRIME_DEBUG_RECTFILL); 3615b2650b9Smacallan} 3625b2650b9Smacallan 3635b2650b9Smacallanstatic void 3645b2650b9SmacallanCrimeSubsequentMono8x8PatternFillRect( ScrnInfoPtr pScrn, 3655b2650b9Smacallan int patx, int paty, int x, int y, int w, int h) 3665b2650b9Smacallan{ 3675b2650b9Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 3685b2650b9Smacallan int i, pat; 3695b2650b9Smacallan 3705b2650b9Smacallan LOG(CRIME_DEBUG_RECTFILL); 3715b2650b9Smacallan 3725b2650b9Smacallan /* first setup the stipple stuff */ 3735b2650b9Smacallan 3745b2650b9Smacallan MAKE_ROOM(1); 3755b2650b9Smacallan WRITE4(CRIME_DE_STIPPLE_MODE, 0x001f0000 | (patx << 24)); 3765b2650b9Smacallan pat = paty; 3775b2650b9Smacallan 3785b2650b9Smacallan for (i = 0; i < h; i++) { 3795b2650b9Smacallan MAKE_ROOM(3); 3805b2650b9Smacallan WRITE4(CRIME_DE_STIPPLE_PAT, fPtr->pattern[pat]); 3815b2650b9Smacallan WRITE4(CRIME_DE_X_VERTEX_0, (x << 16) | ((y + i) & 0xffff)); 3825b2650b9Smacallan WRITE4ST(CRIME_DE_X_VERTEX_1, 3835b2650b9Smacallan ((x + w - 1) << 16) | ((y + i) & 0xffff)); 3845b2650b9Smacallan pat = (pat + 1) & 7; 3855b2650b9Smacallan } 3865b2650b9Smacallan DONE(CRIME_DEBUG_RECTFILL); 3875b2650b9Smacallan} 3885b2650b9Smacallan 3895b2650b9Smacallanstatic void 390e1ea03a3SmacallanCrimeSetupForScanlineImageWrite(ScrnInfoPtr pScrn, int rop, 391e1ea03a3Smacallan unsigned int planemask, int trans_color, 392e1ea03a3Smacallan int bpp, int depth) 393e1ea03a3Smacallan{ 394e1ea03a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 395e1ea03a3Smacallan 396e1ea03a3Smacallan LOG(CRIME_DEBUG_IMAGEWRITE); 39729406fd8Smacallan#if defined(CRIME_DEBUG_LOUD) && (CRIME_DEBUG_MASK & CRIME_DEBUG_IMAGEWRITE) 398e1ea03a3Smacallan if ((bpp == 24) || (depth == 24)) 399e1ea03a3Smacallan xf86Msg(X_ERROR, "%s: %d %d \n", __func__, bpp, depth); 400e1ea03a3Smacallan#endif 40126dcc2a3Smacallan MAKE_ROOM(7); 402e1ea03a3Smacallan WRITE4(CRIME_DE_MODE_SRC, DE_MODE_LIN_A | DE_MODE_BUFDEPTH_32 | 403e1ea03a3Smacallan DE_MODE_TYPE_RGB | DE_MODE_PIXDEPTH_32); 40426dcc2a3Smacallan WRITE4(CRIME_DE_MODE_DST, DE_MODE_TLB_A | DE_MODE_BUFDEPTH_32 | 40526dcc2a3Smacallan DE_MODE_TYPE_RGBA | DE_MODE_PIXDEPTH_32); 406e1ea03a3Smacallan WRITE4(CRIME_DE_PLANEMASK, planemask); 407e1ea03a3Smacallan WRITE4(CRIME_DE_XFER_STEP_X, 4); 408e1ea03a3Smacallan WRITE4(CRIME_DE_ROP, rop); 409e1ea03a3Smacallan WRITE4(CRIME_DE_DRAWMODE, 410e1ea03a3Smacallan DE_DRAWMODE_PLANEMASK | DE_DRAWMODE_BYTEMASK | DE_DRAWMODE_ROP | 411e1ea03a3Smacallan DE_DRAWMODE_XFER_EN); 412e1ea03a3Smacallan WRITE4(CRIME_DE_PRIMITIVE, 413e1ea03a3Smacallan DE_PRIM_RECTANGLE | DE_PRIM_LR | DE_PRIM_TB); 41426dcc2a3Smacallan SYNC; 415e1ea03a3Smacallan DONE(CRIME_DEBUG_IMAGEWRITE); 416e1ea03a3Smacallan} 417e1ea03a3Smacallan 4185b2650b9Smacallanstatic void 419e1ea03a3SmacallanCrimeSubsequentImageWriteRect(ScrnInfoPtr pScrn, 420e1ea03a3Smacallan int x, int y, int w, int h, int skipleft) 421e1ea03a3Smacallan{ 422e1ea03a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 423e1ea03a3Smacallan 424e1ea03a3Smacallan LOG(CRIME_DEBUG_IMAGEWRITE); 425e1ea03a3Smacallan 42629406fd8Smacallan#if defined(CRIME_DEBUG_LOUD) && (CRIME_DEBUG_MASK & CRIME_DEBUG_IMAGEWRITE) 427e1ea03a3Smacallan xf86Msg(X_ERROR, "%s: %d %d %d %d\n", __func__, x, y, w, h); 428e1ea03a3Smacallan#endif 429e1ea03a3Smacallan 430e1ea03a3Smacallan fPtr->start = skipleft; 431e1ea03a3Smacallan x += skipleft; 432e1ea03a3Smacallan w -= skipleft; 433e1ea03a3Smacallan if (x < 0) { 434e1ea03a3Smacallan fPtr->ux = 0; 435e1ea03a3Smacallan w += x; 436e1ea03a3Smacallan fPtr->start -= x; 437e1ea03a3Smacallan } else { 438e1ea03a3Smacallan fPtr->ux = x; 439e1ea03a3Smacallan } 440e1ea03a3Smacallan fPtr->uy = y; 441e1ea03a3Smacallan fPtr->uw = w; 442e1ea03a3Smacallan fPtr->uh = h; 443e1ea03a3Smacallan DONE(CRIME_DEBUG_IMAGEWRITE); 444e1ea03a3Smacallan} 445e1ea03a3Smacallan 4465b2650b9Smacallanstatic void 447e1ea03a3SmacallanCrimeSubsequentImageWriteScanline(ScrnInfoPtr pScrn, int bufno) 448e1ea03a3Smacallan{ 449e1ea03a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 450e1ea03a3Smacallan 451e1ea03a3Smacallan LOG(CRIME_DEBUG_IMAGEWRITE); 45226dcc2a3Smacallan /* 45326dcc2a3Smacallan * we need to sync here, otherwise we might queue up more copy 45426dcc2a3Smacallan * commands than we have buffers 45526dcc2a3Smacallan */ 45634c4e112Smacallan SYNC; 457e1ea03a3Smacallan WRITE4(CRIME_DE_XFER_ADDR_SRC, (bufno << 13) + (fPtr->start << 2)); 458e1ea03a3Smacallan WRITE4(CRIME_DE_X_VERTEX_0, (fPtr->ux << 16) | fPtr->uy); 459e1ea03a3Smacallan WRITE4ST(CRIME_DE_X_VERTEX_1, 460e1ea03a3Smacallan ((fPtr->ux + fPtr->uw - 1) << 16) | (fPtr->uy)); 461e1ea03a3Smacallan fPtr->uy++; 462e1ea03a3Smacallan DONE(CRIME_DEBUG_IMAGEWRITE); 463e1ea03a3Smacallan} 464e1ea03a3Smacallan 465e1ea03a3Smacallanstatic void 466e1ea03a3SmacallanCrimeSetupForCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, 467e1ea03a3Smacallan int fg, int bg, 468e1ea03a3Smacallan int rop, 469e1ea03a3Smacallan unsigned int planemask) 470e1ea03a3Smacallan{ 471e1ea03a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 472e1ea03a3Smacallan 473e1ea03a3Smacallan LOG(CRIME_DEBUG_COLOUREXPAND); 47426dcc2a3Smacallan MAKE_ROOM(7); 47526dcc2a3Smacallan WRITE4(CRIME_DE_MODE_DST, DE_MODE_TLB_A | DE_MODE_BUFDEPTH_32 | 47626dcc2a3Smacallan DE_MODE_TYPE_RGBA | DE_MODE_PIXDEPTH_32); 477e1ea03a3Smacallan WRITE4(CRIME_DE_PLANEMASK, planemask); 478e1ea03a3Smacallan WRITE4(CRIME_DE_ROP, rop); 479e1ea03a3Smacallan WRITE4(CRIME_DE_FG, fg << 8); 480e1ea03a3Smacallan if (bg == -1) { 481e1ea03a3Smacallan /* transparent */ 482e1ea03a3Smacallan WRITE4(CRIME_DE_DRAWMODE, 483e1ea03a3Smacallan DE_DRAWMODE_PLANEMASK | DE_DRAWMODE_BYTEMASK | 484e1ea03a3Smacallan DE_DRAWMODE_ROP | DE_DRAWMODE_POLY_STIP); 485e1ea03a3Smacallan } else { 486e1ea03a3Smacallan WRITE4(CRIME_DE_BG, bg << 8); 487e1ea03a3Smacallan WRITE4(CRIME_DE_DRAWMODE, 488e1ea03a3Smacallan DE_DRAWMODE_PLANEMASK | DE_DRAWMODE_BYTEMASK | 489e1ea03a3Smacallan DE_DRAWMODE_ROP | 490e1ea03a3Smacallan DE_DRAWMODE_OPAQUE_STIP | DE_DRAWMODE_POLY_STIP); 491e1ea03a3Smacallan } 492e1ea03a3Smacallan WRITE4(CRIME_DE_PRIMITIVE, 493e1ea03a3Smacallan DE_PRIM_RECTANGLE | DE_PRIM_LR | DE_PRIM_TB); 49426dcc2a3Smacallan SYNC; 495e1ea03a3Smacallan DONE(CRIME_DEBUG_COLOUREXPAND); 496e1ea03a3Smacallan} 497e1ea03a3Smacallan 498e1ea03a3Smacallanstatic void 499e1ea03a3SmacallanCrimeSubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, 500e1ea03a3Smacallan int x, int y, int w, int h, 501e1ea03a3Smacallan int skipleft ) 502e1ea03a3Smacallan{ 503e1ea03a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 504e1ea03a3Smacallan 505e1ea03a3Smacallan LOG(CRIME_DEBUG_COLOUREXPAND); 506e1ea03a3Smacallan 507e1ea03a3Smacallan fPtr->start = skipleft; 508e1ea03a3Smacallan fPtr->ux = x; 509e1ea03a3Smacallan fPtr->uy = y; 510e1ea03a3Smacallan fPtr->uw = w; 511e1ea03a3Smacallan fPtr->uh = h; 512e1ea03a3Smacallan DONE(CRIME_DEBUG_COLOUREXPAND); 513e1ea03a3Smacallan} 514e1ea03a3Smacallan 515e1ea03a3Smacallanstatic void 516e1ea03a3SmacallanCrimeSubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno) 517e1ea03a3Smacallan{ 518e1ea03a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 519e1ea03a3Smacallan uint32_t *boo = (uint32_t *)fPtr->expandbuffers[bufno]; 520e1ea03a3Smacallan int idx = fPtr->uw, x = fPtr->ux; 521e1ea03a3Smacallan 522e1ea03a3Smacallan LOG(CRIME_DEBUG_COLOUREXPAND); 523e1ea03a3Smacallan 52426dcc2a3Smacallan MAKE_ROOM(5); 525e1ea03a3Smacallan WRITE4(CRIME_DE_STIPPLE_MODE, 0x001f0000 | (fPtr->start << 24)); 526e1ea03a3Smacallan WRITE4(CRIME_DE_STIPPLE_PAT, *boo); 527e1ea03a3Smacallan boo++; 528e1ea03a3Smacallan WRITE4(CRIME_DE_X_VERTEX_0, (x + fPtr->start << 16) | fPtr->uy); 529e1ea03a3Smacallan WRITE4ST(CRIME_DE_X_VERTEX_1, 530e1ea03a3Smacallan ((x + min(idx, 32) - 1) << 16) | (fPtr->uy)); 531e1ea03a3Smacallan idx -= 32; 532e1ea03a3Smacallan x += 32; 533e1ea03a3Smacallan WRITE4(CRIME_DE_STIPPLE_MODE, 0x001f0000); 534e1ea03a3Smacallan 535e1ea03a3Smacallan while (idx > 0) { 53626dcc2a3Smacallan MAKE_ROOM(3); 537e1ea03a3Smacallan WRITE4(CRIME_DE_STIPPLE_PAT, *boo); 538e1ea03a3Smacallan boo++; 539e1ea03a3Smacallan WRITE4(CRIME_DE_X_VERTEX_0, (x << 16) | fPtr->uy); 540e1ea03a3Smacallan WRITE4ST(CRIME_DE_X_VERTEX_1, 541e1ea03a3Smacallan ((x + min(idx, 32) - 1) << 16) | (fPtr->uy)); 542e1ea03a3Smacallan idx -= 32; 543e1ea03a3Smacallan x += 32; 544e1ea03a3Smacallan } 545e1ea03a3Smacallan fPtr->uy++; 546e1ea03a3Smacallan DONE(CRIME_DEBUG_COLOUREXPAND); 547e1ea03a3Smacallan} 548e1ea03a3Smacallan 549e1ea03a3Smacallanstatic void 550e1ea03a3SmacallanCrimeSetupForSolidLine(ScrnInfoPtr pScrn, int color, int rop, 551e1ea03a3Smacallan unsigned int planemask) 552e1ea03a3Smacallan{ 553e1ea03a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 554e1ea03a3Smacallan 555e1ea03a3Smacallan LOG(CRIME_DEBUG_LINES); 556e1ea03a3Smacallan 55726dcc2a3Smacallan MAKE_ROOM(5); 55826dcc2a3Smacallan WRITE4(CRIME_DE_MODE_DST, DE_MODE_TLB_A | DE_MODE_BUFDEPTH_32 | 55926dcc2a3Smacallan DE_MODE_TYPE_RGBA | DE_MODE_PIXDEPTH_32); 560e1ea03a3Smacallan WRITE4(CRIME_DE_PLANEMASK, planemask); 561e1ea03a3Smacallan WRITE4(CRIME_DE_ROP, rop); 562e1ea03a3Smacallan WRITE4(CRIME_DE_FG, color << 8); 563e1ea03a3Smacallan WRITE4(CRIME_DE_DRAWMODE, 564e1ea03a3Smacallan DE_DRAWMODE_PLANEMASK | DE_DRAWMODE_BYTEMASK | 56593351543Smacallan DE_DRAWMODE_ROP | DE_DRAWMODE_SCISSOR_EN); 56626dcc2a3Smacallan SYNC; 567e1ea03a3Smacallan DONE(CRIME_DEBUG_LINES); 568e1ea03a3Smacallan} 569e1ea03a3Smacallan 570e1ea03a3Smacallanstatic void 571e1ea03a3SmacallanCrimeSubsequentSolidTwoPointLine(ScrnInfoPtr pScrn, int x1, int y1, int x2, 572e1ea03a3Smacallan int y2, int flags) 573e1ea03a3Smacallan{ 574e1ea03a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 575e1ea03a3Smacallan 576e1ea03a3Smacallan LOG(CRIME_DEBUG_LINES); 57726dcc2a3Smacallan MAKE_ROOM(3); 578e1ea03a3Smacallan if (flags & OMIT_LAST) { 579e1ea03a3Smacallan WRITE4(CRIME_DE_PRIMITIVE, 580e1ea03a3Smacallan DE_PRIM_LINE | DE_PRIM_LINE_SKIP_END | 2); 581e1ea03a3Smacallan } else { 582e1ea03a3Smacallan WRITE4(CRIME_DE_PRIMITIVE, 583e1ea03a3Smacallan DE_PRIM_LINE | 2); 584e1ea03a3Smacallan } 585e1ea03a3Smacallan WRITE4(CRIME_DE_X_VERTEX_0, (x1 << 16) | y1); 586e1ea03a3Smacallan WRITE4ST(CRIME_DE_X_VERTEX_1, (x2 << 16) | y2); 587e1ea03a3Smacallan DONE(CRIME_DEBUG_LINES); 588850ab569Smacallan} 589e1ea03a3Smacallan 590e1ea03a3Smacallanvoid 591e1ea03a3SmacallanCrimeSetupForDashedLine(ScrnInfoPtr pScrn, 592e1ea03a3Smacallan int fg, int bg, int rop, unsigned int planemask, 593e1ea03a3Smacallan int length, unsigned char *pattern) 594e1ea03a3Smacallan{ 595e1ea03a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 596e1ea03a3Smacallan uint32_t pat; 597e1ea03a3Smacallan 598e1ea03a3Smacallan LOG(CRIME_DEBUG_LINES); 599e1ea03a3Smacallan 600e1ea03a3Smacallan fPtr->uw = length; 60126dcc2a3Smacallan MAKE_ROOM(7); 60226dcc2a3Smacallan WRITE4(CRIME_DE_MODE_DST, DE_MODE_TLB_A | DE_MODE_BUFDEPTH_32 | 60326dcc2a3Smacallan DE_MODE_TYPE_RGBA | DE_MODE_PIXDEPTH_32); 604e1ea03a3Smacallan WRITE4(CRIME_DE_PLANEMASK, planemask); 605e1ea03a3Smacallan WRITE4(CRIME_DE_ROP, rop); 606e1ea03a3Smacallan WRITE4(CRIME_DE_FG, fg << 8); 607e1ea03a3Smacallan if (bg == -1) { 608e1ea03a3Smacallan /* transparent */ 609e1ea03a3Smacallan WRITE4(CRIME_DE_DRAWMODE, 610e1ea03a3Smacallan DE_DRAWMODE_PLANEMASK | DE_DRAWMODE_BYTEMASK | 61193351543Smacallan DE_DRAWMODE_ROP | DE_DRAWMODE_LINE_STIP | 61293351543Smacallan DE_DRAWMODE_SCISSOR_EN); 613e1ea03a3Smacallan } else { 614e1ea03a3Smacallan WRITE4(CRIME_DE_BG, bg << 8); 615e1ea03a3Smacallan WRITE4(CRIME_DE_DRAWMODE, 616e1ea03a3Smacallan DE_DRAWMODE_PLANEMASK | DE_DRAWMODE_BYTEMASK | 61793351543Smacallan DE_DRAWMODE_ROP | DE_DRAWMODE_SCISSOR_EN | 618e1ea03a3Smacallan DE_DRAWMODE_OPAQUE_STIP | DE_DRAWMODE_LINE_STIP); 619e1ea03a3Smacallan } 620e1ea03a3Smacallan /* 621e1ea03a3Smacallan * can we trust the Xserver to always hand us a 32bit aligned 622e1ea03a3Smacallan * pattern buffer? 623e1ea03a3Smacallan */ 624e1ea03a3Smacallan memcpy(&pat, pattern, 4); 625e1ea03a3Smacallan WRITE4(CRIME_DE_STIPPLE_PAT, pat); 62626dcc2a3Smacallan SYNC; 627e1ea03a3Smacallan DONE(CRIME_DEBUG_LINES); 628e1ea03a3Smacallan} 629e1ea03a3Smacallan 630e1ea03a3Smacallanvoid 631e1ea03a3SmacallanCrimeSubsequentDashedTwoPointLine( ScrnInfoPtr pScrn, 632e1ea03a3Smacallan int x1, int y1, int x2, int y2, int flags, int phase) 633e1ea03a3Smacallan{ 634e1ea03a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 635e1ea03a3Smacallan uint32_t stipmode; 636e1ea03a3Smacallan 637e1ea03a3Smacallan LOG(CRIME_DEBUG_LINES); 63826dcc2a3Smacallan MAKE_ROOM(4); 639e1ea03a3Smacallan 640e1ea03a3Smacallan if (flags & OMIT_LAST) { 641e1ea03a3Smacallan WRITE4(CRIME_DE_PRIMITIVE, 642e1ea03a3Smacallan DE_PRIM_LINE | DE_PRIM_LINE_SKIP_END | 2); 643e1ea03a3Smacallan } else { 644e1ea03a3Smacallan WRITE4(CRIME_DE_PRIMITIVE, 645e1ea03a3Smacallan DE_PRIM_LINE | 2); 646e1ea03a3Smacallan } 647e1ea03a3Smacallan 648e1ea03a3Smacallan stipmode = ((fPtr->uw - 1) << 16) | (phase << 24); 649e1ea03a3Smacallan WRITE4(CRIME_DE_STIPPLE_MODE, stipmode); 650e1ea03a3Smacallan WRITE4(CRIME_DE_X_VERTEX_0, (x1 << 16) | y1); 651e1ea03a3Smacallan WRITE4ST(CRIME_DE_X_VERTEX_1, (x2 << 16) | y2); 652e1ea03a3Smacallan DONE(CRIME_DEBUG_LINES); 653e1ea03a3Smacallan} 654e1ea03a3Smacallan 655e1ea03a3Smacallanvoid 656e1ea03a3SmacallanCrimeSetClippingRectangle ( ScrnInfoPtr pScrn, 657e1ea03a3Smacallan int left, int top, int right, int bottom) 658e1ea03a3Smacallan{ 659e1ea03a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 660e1ea03a3Smacallan 661e1ea03a3Smacallan LOG(CRIME_DEBUG_CLIPPING); 66226dcc2a3Smacallan MAKE_ROOM(2); 66393351543Smacallan WRITE4(CRIME_DE_SCISSOR, (left << 16) | top); 66493351543Smacallan WRITE4(CRIME_DE_SCISSOR + 4, ((right + 1) << 16) | (bottom + 1)); 6657a6652bbSmacallan fPtr->cxa = left; 6667a6652bbSmacallan fPtr->cxe = right; 6677a6652bbSmacallan fPtr->cya = top; 6687a6652bbSmacallan fPtr->cye = bottom; 66926dcc2a3Smacallan SYNC; 670e1ea03a3Smacallan DONE(CRIME_DEBUG_CLIPPING); 671e1ea03a3Smacallan} 672e1ea03a3Smacallan 673e1ea03a3Smacallanvoid 674e1ea03a3SmacallanCrimeDisableClipping (ScrnInfoPtr pScrn) 675e1ea03a3Smacallan{ 676e1ea03a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 677e1ea03a3Smacallan 678e1ea03a3Smacallan LOG(CRIME_DEBUG_CLIPPING); 67926dcc2a3Smacallan MAKE_ROOM(2); 68093351543Smacallan WRITE4(CRIME_DE_SCISSOR, 0); 68193351543Smacallan WRITE4(CRIME_DE_SCISSOR + 4, 0x3fff3fff); 6827a6652bbSmacallan fPtr->cxa = 0; 6837a6652bbSmacallan fPtr->cxe = 2047; 6847a6652bbSmacallan fPtr->cya = 0; 6857a6652bbSmacallan fPtr->cye = 2047; 68626dcc2a3Smacallan SYNC; 687e1ea03a3Smacallan DONE(CRIME_DEBUG_CLIPPING); 688e1ea03a3Smacallan} 689e1ea03a3Smacallan 690e1ea03a3Smacallanstatic Bool 691e1ea03a3SmacallanCrimeSetupForCPUToScreenAlphaTexture ( 692e1ea03a3Smacallan ScrnInfoPtr pScrn, 693e1ea03a3Smacallan int op, 694e1ea03a3Smacallan CARD16 red, 695e1ea03a3Smacallan CARD16 green, 696e1ea03a3Smacallan CARD16 blue, 697e1ea03a3Smacallan CARD16 alpha, 698e1ea03a3Smacallan int alphaType, 699e1ea03a3Smacallan CARD8 *alphaPtr, 700e1ea03a3Smacallan int alphaPitch, 701e1ea03a3Smacallan int width, 702e1ea03a3Smacallan int height, 703e1ea03a3Smacallan int flags 704e1ea03a3Smacallan) 705e1ea03a3Smacallan{ 706e1ea03a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 707e1ea03a3Smacallan 708e1ea03a3Smacallan if (op != PictOpOver) { 709e1ea03a3Smacallan xf86Msg(X_ERROR, "%s: op %d\n", __func__, op); 710e1ea03a3Smacallan op = PictOpOver; 711e1ea03a3Smacallan } 712e1ea03a3Smacallan 713e1ea03a3Smacallan LOG(CRIME_DEBUG_XRENDER); 714e1ea03a3Smacallan 715e1ea03a3Smacallan fPtr->alpha_color = ((red & 0xff00) << 16) | 716e1ea03a3Smacallan ((green & 0xff00) << 8) | 71709f0d67cSmacallan (blue & 0xff00); 718e1ea03a3Smacallan fPtr->uw = width; 719e1ea03a3Smacallan fPtr->uh = height; 720e1ea03a3Smacallan fPtr->us = alphaPitch; 721e1ea03a3Smacallan fPtr->alpha_texture = alphaPtr; 72209f0d67cSmacallan fPtr->format = alphaType; 7235b2650b9Smacallan#ifdef CRIME_DEBUG_LOUD 72409f0d67cSmacallan if (alphaType != PICT_a8) { 72509f0d67cSmacallan xf86Msg(X_ERROR, "ARGB mask %08x %d\n", (uint32_t)alphaPtr, 72609f0d67cSmacallan alphaPitch); 72709f0d67cSmacallan } 72829406fd8Smacallan xf86Msg(X_ERROR, "%s: %x %x %x\n", __func__, red, green, blue); 7295b2650b9Smacallan#endif 73026dcc2a3Smacallan MAKE_ROOM(7); 73126dcc2a3Smacallan WRITE4(CRIME_DE_MODE_DST, DE_MODE_TLB_A | DE_MODE_BUFDEPTH_32 | 73226dcc2a3Smacallan DE_MODE_TYPE_RGBA | DE_MODE_PIXDEPTH_32); 733e1ea03a3Smacallan /* XXX this register is not where it's supposed to be */ 734e1ea03a3Smacallan WRITE4(CRIME_DE_ALPHA_COLOR, fPtr->alpha_color); 73509f0d67cSmacallan if (alphaType == PICT_a8) { 73609f0d67cSmacallan if (fPtr->alpha_color == 0) { 73709f0d67cSmacallan WRITE4(CRIME_DE_MODE_SRC, DE_MODE_LIN_A | DE_MODE_BUFDEPTH_8 | 738e1ea03a3Smacallan DE_MODE_TYPE_RGBA | DE_MODE_PIXDEPTH_32); 73909f0d67cSmacallan WRITE4(CRIME_DE_XFER_STEP_X, 1); 74009f0d67cSmacallan WRITE4(CRIME_DE_ALPHA_FUNC, 74109f0d67cSmacallan DE_ALPHA_ADD | 74209f0d67cSmacallan (DE_ALPHA_OP_ZERO << DE_ALPHA_OP_SRC_SHIFT) | 74309f0d67cSmacallan (DE_ALPHA_OP_1_MINUS_SRC_ALPHA << DE_ALPHA_OP_DST_SHIFT)); 74409f0d67cSmacallan } else { 74509f0d67cSmacallan WRITE4(CRIME_DE_MODE_SRC, DE_MODE_LIN_A | DE_MODE_BUFDEPTH_32 | 74609f0d67cSmacallan DE_MODE_TYPE_RGBA | DE_MODE_PIXDEPTH_32); 74709f0d67cSmacallan WRITE4(CRIME_DE_XFER_STEP_X, 4); 74809f0d67cSmacallan WRITE4(CRIME_DE_ALPHA_FUNC, 74909f0d67cSmacallan DE_ALPHA_ADD | 75009f0d67cSmacallan (DE_ALPHA_OP_SRC_ALPHA << DE_ALPHA_OP_SRC_SHIFT) | 75109f0d67cSmacallan (DE_ALPHA_OP_1_MINUS_SRC_ALPHA << DE_ALPHA_OP_DST_SHIFT)); 75209f0d67cSmacallan } 753e1ea03a3Smacallan } else { 754e1ea03a3Smacallan WRITE4(CRIME_DE_MODE_SRC, DE_MODE_LIN_A | DE_MODE_BUFDEPTH_32 | 755e1ea03a3Smacallan DE_MODE_TYPE_RGBA | DE_MODE_PIXDEPTH_32); 756e1ea03a3Smacallan WRITE4(CRIME_DE_XFER_STEP_X, 4); 757e1ea03a3Smacallan WRITE4(CRIME_DE_ALPHA_FUNC, 758e1ea03a3Smacallan DE_ALPHA_ADD | 759e1ea03a3Smacallan (DE_ALPHA_OP_SRC_ALPHA << DE_ALPHA_OP_SRC_SHIFT) | 760e1ea03a3Smacallan (DE_ALPHA_OP_1_MINUS_SRC_ALPHA << DE_ALPHA_OP_DST_SHIFT)); 76109f0d67cSmacallan } 762e1ea03a3Smacallan WRITE4(CRIME_DE_DRAWMODE, 763e1ea03a3Smacallan DE_DRAWMODE_BYTEMASK | DE_DRAWMODE_ALPHA_BLEND | 764e1ea03a3Smacallan DE_DRAWMODE_XFER_EN); 765e1ea03a3Smacallan WRITE4(CRIME_DE_PRIMITIVE, 766e1ea03a3Smacallan DE_PRIM_RECTANGLE | DE_PRIM_LR | DE_PRIM_TB); 76726dcc2a3Smacallan SYNC; 768e1ea03a3Smacallan DONE(CRIME_DEBUG_XRENDER); 769e1ea03a3Smacallan return TRUE; 770e1ea03a3Smacallan} 771e1ea03a3Smacallan 772e1ea03a3Smacallanvoid 773e1ea03a3SmacallanCrimeSubsequentCPUToScreenAlphaTexture ( 774e1ea03a3Smacallan ScrnInfoPtr pScrn, 775e1ea03a3Smacallan int dstx, 776e1ea03a3Smacallan int dsty, 777e1ea03a3Smacallan int srcx, 778e1ea03a3Smacallan int srcy, 779e1ea03a3Smacallan int width, 780e1ea03a3Smacallan int height 781e1ea03a3Smacallan) 782e1ea03a3Smacallan{ 783e1ea03a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 784e1ea03a3Smacallan unsigned char *aptr; 785e1ea03a3Smacallan uint32_t *dptr, aval; 786e1ea03a3Smacallan int i, j; 787e1ea03a3Smacallan int bufnum = 0; 788e1ea03a3Smacallan 789e1ea03a3Smacallan LOG(CRIME_DEBUG_XRENDER); 790e1ea03a3Smacallan#ifdef CRIME_DEBUG_LOUD 791e1ea03a3Smacallan xf86Msg(X_ERROR, "%d %d %d %d %d %d\n",srcx, srcy, dstx, dsty, width, 792e1ea03a3Smacallan height); 793e1ea03a3Smacallan#endif 794e1ea03a3Smacallan aptr = fPtr->alpha_texture + (fPtr->us * srcy) + srcx; 795e1ea03a3Smacallan for (i = 0; i < height; i++) { 796e1ea03a3Smacallan dptr = (uint32_t *)fPtr->buffers[bufnum]; 797e1ea03a3Smacallan if (fPtr->alpha_color == 0) { 798e1ea03a3Smacallan memcpy(dptr, aptr, width); 799e1ea03a3Smacallan } else { 800e1ea03a3Smacallan for (j = 0; j < width; j++) { 801e1ea03a3Smacallan aval = aptr[j]; 802e1ea03a3Smacallan *dptr = aval | fPtr->alpha_color; 803e1ea03a3Smacallan dptr++; 804e1ea03a3Smacallan } 805e1ea03a3Smacallan } 80626dcc2a3Smacallan MAKE_ROOM(3); 807e1ea03a3Smacallan WRITE4(CRIME_DE_XFER_ADDR_SRC, bufnum * 8192); 808e1ea03a3Smacallan WRITE4(CRIME_DE_X_VERTEX_0, dstx << 16 | (dsty + i)); 809e1ea03a3Smacallan WRITE4ST(CRIME_DE_X_VERTEX_1, 810e1ea03a3Smacallan ((dstx + width - 1) << 16) | (dsty + i)); 811e1ea03a3Smacallan bufnum++; 812e1ea03a3Smacallan if (bufnum == 8) bufnum = 0; 813e1ea03a3Smacallan aptr += fPtr->us; 814e1ea03a3Smacallan } 815e1ea03a3Smacallan DONE(CRIME_DEBUG_XRENDER); 816e1ea03a3Smacallan} 817e1ea03a3Smacallan 81809f0d67cSmacallanvoid 81909f0d67cSmacallanCrimeSubsequentCPUToScreenAlphaTexture32 ( 82009f0d67cSmacallan ScrnInfoPtr pScrn, 82109f0d67cSmacallan int dstx, 82209f0d67cSmacallan int dsty, 82309f0d67cSmacallan int srcx, 82409f0d67cSmacallan int srcy, 82509f0d67cSmacallan int width, 82609f0d67cSmacallan int height 82709f0d67cSmacallan) 82809f0d67cSmacallan{ 82909f0d67cSmacallan CrimePtr fPtr = CRIMEPTR(pScrn); 83009f0d67cSmacallan uint8_t *aptr; 83109f0d67cSmacallan uint32_t *dptr, *sptr; 83209f0d67cSmacallan int i, j; 83309f0d67cSmacallan int bufnum = 0; 83409f0d67cSmacallan 83509f0d67cSmacallan LOG(CRIME_DEBUG_XRENDER); 83629406fd8Smacallan#ifdef CRIME_DEBUG_LOUD_ 83709f0d67cSmacallan xf86Msg(X_ERROR, "%d %d %d %d %d %d\n",srcx, srcy, dstx, dsty, width, 83809f0d67cSmacallan height); 83909f0d67cSmacallan#endif 84009f0d67cSmacallan aptr = fPtr->alpha_texture + (fPtr->us * srcy) + (srcx << 2); 84109f0d67cSmacallan for (i = 0; i < height; i++) { 84209f0d67cSmacallan dptr = (uint32_t *)fPtr->buffers[bufnum]; 84309f0d67cSmacallan sptr = (uint32_t *)aptr; 84409f0d67cSmacallan for (j = 0; j < width; j++) { 84509f0d67cSmacallan *dptr = (*sptr >> 24) | fPtr->alpha_color; 84629406fd8Smacallan#ifdef CRIME_DEBUG_LOUD_ 84709f0d67cSmacallan xf86Msg(X_ERROR, "%08x %08x\n", *sptr, *dptr); 84809f0d67cSmacallan#endif 84909f0d67cSmacallan sptr++; 85009f0d67cSmacallan dptr++; 85109f0d67cSmacallan } 85226dcc2a3Smacallan MAKE_ROOM(3); 85309f0d67cSmacallan WRITE4(CRIME_DE_XFER_ADDR_SRC, bufnum * 8192); 85409f0d67cSmacallan WRITE4(CRIME_DE_X_VERTEX_0, dstx << 16 | (dsty + i)); 85509f0d67cSmacallan WRITE4ST(CRIME_DE_X_VERTEX_1, 85609f0d67cSmacallan ((dstx + width - 1) << 16) | (dsty + i)); 85709f0d67cSmacallan bufnum++; 85809f0d67cSmacallan if (bufnum == 8) bufnum = 0; 85909f0d67cSmacallan aptr += fPtr->us; 86009f0d67cSmacallan } 86109f0d67cSmacallan DONE(CRIME_DEBUG_XRENDER); 86209f0d67cSmacallan} 86309f0d67cSmacallan 864e1ea03a3Smacallanstatic Bool 865e1ea03a3SmacallanCrimeSetupForCPUToScreenTexture ( 866e1ea03a3Smacallan ScrnInfoPtr pScrn, 867e1ea03a3Smacallan int op, 868e1ea03a3Smacallan int texType, 869e1ea03a3Smacallan CARD8 *texPtr, 870e1ea03a3Smacallan int texPitch, 871e1ea03a3Smacallan int width, 872e1ea03a3Smacallan int height, 873e1ea03a3Smacallan int flags 874e1ea03a3Smacallan) 875e1ea03a3Smacallan{ 876e1ea03a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 877e1ea03a3Smacallan 878e1ea03a3Smacallan if (op != PictOpOver) { 879e1ea03a3Smacallan xf86Msg(X_ERROR, "%s: op %d\n", __func__, op); 880e1ea03a3Smacallan op = PictOpOver; 881e1ea03a3Smacallan } 882e1ea03a3Smacallan 883e1ea03a3Smacallan LOG(CRIME_DEBUG_XRENDER); 884e1ea03a3Smacallan 885e1ea03a3Smacallan fPtr->uw = width; 886e1ea03a3Smacallan fPtr->uh = height; 887e1ea03a3Smacallan fPtr->us = texPitch; 888e1ea03a3Smacallan fPtr->alpha_texture = texPtr; 88926dcc2a3Smacallan MAKE_ROOM(6); 89026dcc2a3Smacallan WRITE4(CRIME_DE_MODE_DST, DE_MODE_TLB_A | DE_MODE_BUFDEPTH_32 | 89126dcc2a3Smacallan DE_MODE_TYPE_RGBA | DE_MODE_PIXDEPTH_32); 892e1ea03a3Smacallan if (texType == PICT_a8b8g8r8) { 893e1ea03a3Smacallan WRITE4(CRIME_DE_MODE_SRC, DE_MODE_LIN_A | DE_MODE_BUFDEPTH_32 | 894e1ea03a3Smacallan DE_MODE_TYPE_ABGR | DE_MODE_PIXDEPTH_32); 895e1ea03a3Smacallan } else { 896e1ea03a3Smacallan WRITE4(CRIME_DE_MODE_SRC, DE_MODE_LIN_A | DE_MODE_BUFDEPTH_32 | 897e1ea03a3Smacallan DE_MODE_TYPE_RGBA | DE_MODE_PIXDEPTH_32); 898e1ea03a3Smacallan } 899e1ea03a3Smacallan fPtr->format = texType; 900e1ea03a3Smacallan WRITE4(CRIME_DE_XFER_STEP_X, 4); 901e1ea03a3Smacallan WRITE4(CRIME_DE_ALPHA_FUNC, 902e1ea03a3Smacallan DE_ALPHA_ADD | 903e1ea03a3Smacallan (DE_ALPHA_OP_ONE/*SRC_ALPHA*/ << DE_ALPHA_OP_SRC_SHIFT) | 904e1ea03a3Smacallan (DE_ALPHA_OP_1_MINUS_SRC_ALPHA << DE_ALPHA_OP_DST_SHIFT)); 905e1ea03a3Smacallan WRITE4(CRIME_DE_DRAWMODE, 906e1ea03a3Smacallan DE_DRAWMODE_BYTEMASK | DE_DRAWMODE_ALPHA_BLEND | 907e1ea03a3Smacallan DE_DRAWMODE_XFER_EN); 908e1ea03a3Smacallan WRITE4(CRIME_DE_PRIMITIVE, 909e1ea03a3Smacallan DE_PRIM_RECTANGLE | DE_PRIM_LR | DE_PRIM_TB); 91026dcc2a3Smacallan SYNC; 911e1ea03a3Smacallan DONE(CRIME_DEBUG_XRENDER); 912e1ea03a3Smacallan return TRUE; 913e1ea03a3Smacallan} 914e1ea03a3Smacallan 915e1ea03a3Smacallanvoid 916e1ea03a3SmacallanCrimeSubsequentCPUToScreenTexture ( 917e1ea03a3Smacallan ScrnInfoPtr pScrn, 918e1ea03a3Smacallan int dstx, 919e1ea03a3Smacallan int dsty, 920e1ea03a3Smacallan int srcx, 921e1ea03a3Smacallan int srcy, 922e1ea03a3Smacallan int width, 923e1ea03a3Smacallan int height 924e1ea03a3Smacallan) 925e1ea03a3Smacallan{ 926e1ea03a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 927e1ea03a3Smacallan unsigned char *aptr, *lptr; 928e1ea03a3Smacallan uint32_t *dptr, *sptr, aval, pixel; 929e1ea03a3Smacallan int i, j, k, l, rep = 1, period = fPtr->uw, xoff, lcnt, xa, xe; 930e1ea03a3Smacallan int bufnum = 0; 931e1ea03a3Smacallan 932e1ea03a3Smacallan LOG(CRIME_DEBUG_XRENDER); 933e1ea03a3Smacallan#ifdef CRIME_DEBUG_LOUD 934e1ea03a3Smacallan xf86Msg(X_ERROR, "%s: %d %d %d %d %d %d\n", __func__, 935e1ea03a3Smacallan srcx, srcy, dstx, dsty, width, height); 936e1ea03a3Smacallan#endif 937e1ea03a3Smacallan if ((width == 1) || (fPtr->format != PICT_a8r8g8b8)) { 938e1ea03a3Smacallan xf86Msg(X_ERROR, "%s: %d %d %d %d %d %d %d %d\n", __func__, 939e1ea03a3Smacallan srcx, srcy, dstx, dsty, width, height, fPtr->uw, fPtr->us); 940e1ea03a3Smacallan return; 941e1ea03a3Smacallan } 942e1ea03a3Smacallan 943e1ea03a3Smacallan aptr = fPtr->alpha_texture + (srcx << 2); 944e1ea03a3Smacallan lptr = aptr + (fPtr->us * srcy); 945e1ea03a3Smacallan if ((fPtr->uw < 128) && (fPtr->uw < width)) { 946e1ea03a3Smacallan rep = 128 / fPtr->uw; 947e1ea03a3Smacallan period = rep * fPtr->uw; 948e1ea03a3Smacallan } 949e1ea03a3Smacallan 950e1ea03a3Smacallan if (fPtr->format == PICT_a8b8g8r8) { 951e1ea03a3Smacallan#ifdef CRIME_DEBUG_LOUD 952e1ea03a3Smacallan xf86Msg(X_ERROR, "ABGR\n"); 953e1ea03a3Smacallan#endif 954e1ea03a3Smacallan for (i = 0; i < height; i++) { 955e1ea03a3Smacallan dptr = (uint32_t *)fPtr->buffers[bufnum]; 956e1ea03a3Smacallan memcpy(dptr, aptr, fPtr->us); 95726dcc2a3Smacallan MAKE_ROOM(3); 958e1ea03a3Smacallan WRITE4(CRIME_DE_XFER_ADDR_SRC, bufnum * 8192); 959e1ea03a3Smacallan WRITE4(CRIME_DE_X_VERTEX_0, dstx << 16 | (dsty + i)); 960e1ea03a3Smacallan WRITE4ST(CRIME_DE_X_VERTEX_1, 961e1ea03a3Smacallan ((dstx + width - 1) << 16) | (dsty + i)); 962e1ea03a3Smacallan bufnum++; 963e1ea03a3Smacallan if (bufnum == 8) bufnum = 0; 964e1ea03a3Smacallan aptr += fPtr->us; 965e1ea03a3Smacallan } 966e1ea03a3Smacallan } else { 967e1ea03a3Smacallan#ifdef CRIME_DEBUG_LOUD 968e1ea03a3Smacallan xf86Msg(X_ERROR, "ARGB %08x %d\n", (uint32_t)aptr, fPtr->uw); 969e1ea03a3Smacallan#endif 970e1ea03a3Smacallan lcnt = fPtr->uh - srcy; 971e1ea03a3Smacallan for (i = 0; i < height; i++) { 972e1ea03a3Smacallan dptr = (uint32_t *)fPtr->buffers[bufnum]; 973e1ea03a3Smacallan for (k = 0; k < rep; k++) { 974e1ea03a3Smacallan sptr = (uint32_t *)aptr; 975e1ea03a3Smacallan for (j = 0; j < fPtr->uw; j++) { 976e1ea03a3Smacallan pixel = *sptr; 977e1ea03a3Smacallan *dptr = (pixel << 8) | (pixel >> 24); 978e1ea03a3Smacallan dptr++; 979e1ea03a3Smacallan sptr++; 980e1ea03a3Smacallan } 981e1ea03a3Smacallan } 982e1ea03a3Smacallan xoff = 0; 98326dcc2a3Smacallan MAKE_ROOM(1); 984e1ea03a3Smacallan WRITE4(CRIME_DE_XFER_ADDR_SRC, bufnum * 8192); 985e1ea03a3Smacallan while (xoff < width) { 986e1ea03a3Smacallan xa = dstx + xoff; 987e1ea03a3Smacallan xe = dstx + min(xoff + period, width) - 1; 98826dcc2a3Smacallan MAKE_ROOM(2); 989e1ea03a3Smacallan WRITE4(CRIME_DE_X_VERTEX_0, 990e1ea03a3Smacallan xa << 16 | (dsty + i)); 991e1ea03a3Smacallan WRITE4ST(CRIME_DE_X_VERTEX_1, 992e1ea03a3Smacallan (xe << 16) | (dsty + i)); 993e1ea03a3Smacallan xoff += period; 994e1ea03a3Smacallan } 995e1ea03a3Smacallan bufnum++; 996e1ea03a3Smacallan if (bufnum == 8) bufnum = 0; 997e1ea03a3Smacallan lcnt--; 998e1ea03a3Smacallan if (lcnt == 0) { 999e1ea03a3Smacallan aptr = lptr; 1000e1ea03a3Smacallan lcnt = fPtr->uh; 1001e1ea03a3Smacallan } else 1002e1ea03a3Smacallan aptr += fPtr->us; 1003e1ea03a3Smacallan } 1004e1ea03a3Smacallan } 1005e1ea03a3Smacallan DONE(CRIME_DEBUG_XRENDER); 1006e1ea03a3Smacallan} 1007e1ea03a3Smacallan 1008e1ea03a3Smacallanstatic Bool 1009e1ea03a3SmacallanCrimeSetupForCPUToScreenTextureMask( 1010e1ea03a3Smacallan ScrnInfoPtr pScrn, 1011e1ea03a3Smacallan int op, 1012e1ea03a3Smacallan int texType, 1013e1ea03a3Smacallan CARD8 *srcPtr, 1014e1ea03a3Smacallan int srcPitch, 1015e1ea03a3Smacallan CARD8 *mskPtr, 1016e1ea03a3Smacallan int mskPitch, 1017e1ea03a3Smacallan int width, 1018e1ea03a3Smacallan int height, 1019e1ea03a3Smacallan int flags 1020e1ea03a3Smacallan) 1021e1ea03a3Smacallan{ 1022e1ea03a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 1023e1ea03a3Smacallan 1024e1ea03a3Smacallan if (op != PictOpOver) { 1025e1ea03a3Smacallan xf86Msg(X_ERROR, "%s: op %d\n", __func__, op); 1026e1ea03a3Smacallan op = PictOpOver; 1027e1ea03a3Smacallan } 1028e1ea03a3Smacallan 1029e1ea03a3Smacallan LOG(CRIME_DEBUG_XRENDER); 1030e1ea03a3Smacallan 1031e1ea03a3Smacallan fPtr->uw = width; 1032e1ea03a3Smacallan fPtr->uh = height; 1033e1ea03a3Smacallan fPtr->us = srcPitch >> 2; 1034e1ea03a3Smacallan if (PICT_FORMAT_BPP(texType) == 32) { 1035e1ea03a3Smacallan fPtr->um = mskPitch >> 2; 1036e1ea03a3Smacallan } else 1037e1ea03a3Smacallan fPtr->um = mskPitch; 1038e1ea03a3Smacallan fPtr->msk = (uint8_t *)mskPtr; 1039e1ea03a3Smacallan fPtr->src = (uint8_t *)srcPtr; 1040e1ea03a3Smacallan fPtr->texture_depth = PICT_FORMAT_BPP(texType); 1041e1ea03a3Smacallan 104226dcc2a3Smacallan MAKE_ROOM(6); 1043e1ea03a3Smacallan /* always expect ARGB for now */ 1044e1ea03a3Smacallan WRITE4(CRIME_DE_MODE_SRC, DE_MODE_LIN_A | DE_MODE_BUFDEPTH_32 | 1045e1ea03a3Smacallan DE_MODE_TYPE_RGBA | DE_MODE_PIXDEPTH_32); 104626dcc2a3Smacallan WRITE4(CRIME_DE_MODE_DST, DE_MODE_TLB_A | DE_MODE_BUFDEPTH_32 | 104726dcc2a3Smacallan DE_MODE_TYPE_RGBA | DE_MODE_PIXDEPTH_32); 1048e1ea03a3Smacallan fPtr->format = texType; 1049e1ea03a3Smacallan WRITE4(CRIME_DE_ALPHA_FUNC, 1050e1ea03a3Smacallan DE_ALPHA_ADD | 1051e1ea03a3Smacallan (DE_ALPHA_OP_SRC_ALPHA << DE_ALPHA_OP_SRC_SHIFT) | 1052e1ea03a3Smacallan (DE_ALPHA_OP_1_MINUS_SRC_ALPHA << DE_ALPHA_OP_DST_SHIFT)); 1053e1ea03a3Smacallan WRITE4(CRIME_DE_XFER_STEP_X, 4); 1054e1ea03a3Smacallan WRITE4(CRIME_DE_DRAWMODE, 1055e1ea03a3Smacallan DE_DRAWMODE_BYTEMASK | DE_DRAWMODE_ALPHA_BLEND | 1056e1ea03a3Smacallan DE_DRAWMODE_XFER_EN); 1057e1ea03a3Smacallan WRITE4(CRIME_DE_PRIMITIVE, 1058e1ea03a3Smacallan DE_PRIM_RECTANGLE | DE_PRIM_LR | DE_PRIM_TB); 105926dcc2a3Smacallan SYNC; 1060e1ea03a3Smacallan DONE(CRIME_DEBUG_XRENDER); 1061e1ea03a3Smacallan return TRUE; 1062e1ea03a3Smacallan} 1063e1ea03a3Smacallan 1064e1ea03a3Smacallanvoid 1065e1ea03a3SmacallanCrimeSubsequentCPUToScreenTextureMask32( 1066e1ea03a3Smacallan ScrnInfoPtr pScrn, 1067e1ea03a3Smacallan int dstx, 1068e1ea03a3Smacallan int dsty, 1069e1ea03a3Smacallan int srcx, 1070e1ea03a3Smacallan int srcy, 1071e1ea03a3Smacallan int maskx, 1072e1ea03a3Smacallan int masky, 1073e1ea03a3Smacallan int width, 1074e1ea03a3Smacallan int height 1075e1ea03a3Smacallan) 1076e1ea03a3Smacallan{ 1077e1ea03a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 1078e1ea03a3Smacallan uint32_t *lsptr, *lmptr, *asptr, *amptr; 1079e1ea03a3Smacallan uint32_t *dptr, *sptr, *mptr, aval, pixel, mask; 1080e1ea03a3Smacallan int i, j, k, l, rep = 1, period = fPtr->uw, xoff, lcnt, xa, xe; 1081e1ea03a3Smacallan int bufnum = 0; 1082e1ea03a3Smacallan int sr, sg, sb, sa, mr, mg, mb, ma, rr, gg, bb, aa; 1083e1ea03a3Smacallan 1084e1ea03a3Smacallan LOG(CRIME_DEBUG_XRENDER); 1085e1ea03a3Smacallan#ifdef CRIME_DEBUG_LOUD 1086e1ea03a3Smacallan xf86Msg(X_ERROR, "%s: %d %d %d %d %d %d; %d %d %d\n", __func__, 1087e1ea03a3Smacallan srcx, srcy, dstx, dsty, width, height, maskx, masky, fPtr->um); 1088e1ea03a3Smacallan#endif 1089e1ea03a3Smacallan sptr = fPtr->src + (srcx << 2); 1090e1ea03a3Smacallan mptr = fPtr->msk + (srcx << 2); 1091e1ea03a3Smacallan lsptr = sptr + (fPtr->us * srcy); 1092e1ea03a3Smacallan lmptr = mptr + (fPtr->um * srcy); 1093e1ea03a3Smacallan if ((fPtr->uw < 128) && (fPtr->uw < width)) { 1094e1ea03a3Smacallan rep = 128 / fPtr->uw; 1095e1ea03a3Smacallan period = rep * fPtr->uw; 1096e1ea03a3Smacallan } 1097e1ea03a3Smacallan 1098e1ea03a3Smacallan#ifdef CRIME_DEBUG_LOUD 109929406fd8Smacallan xf86Msg(X_ERROR, "ARGB %08x %d\n", (uint32_t)asptr, fPtr->uw); 1100e1ea03a3Smacallan#endif 1101e1ea03a3Smacallan lcnt = fPtr->uh - srcy; 1102e1ea03a3Smacallan for (i = 0; i < height; i++) { 1103e1ea03a3Smacallan dptr = (uint32_t *)fPtr->buffers[bufnum]; 1104e1ea03a3Smacallan for (k = 0; k < rep; k++) { 1105e1ea03a3Smacallan asptr = lsptr; 1106e1ea03a3Smacallan amptr = lmptr; 1107e1ea03a3Smacallan for (j = 0; j < fPtr->uw; j++) { 1108e1ea03a3Smacallan pixel = *asptr; 1109e1ea03a3Smacallan mask = *amptr; 1110e1ea03a3Smacallan if (mask == 0xffffffff) { 1111e1ea03a3Smacallan *dptr = (pixel >> 24) | (pixel << 8); 1112e1ea03a3Smacallan } else if (mask == 0x00000000) { 1113e1ea03a3Smacallan *dptr = 0; 1114e1ea03a3Smacallan } else { 1115e1ea03a3Smacallan /* input is ARGB */ 1116e1ea03a3Smacallan sb = pixel & 0xff; 1117e1ea03a3Smacallan sg = (pixel >> 8) & 0xff; 1118e1ea03a3Smacallan sr = (pixel >> 16) & 0xff; 1119e1ea03a3Smacallan sa = (pixel >> 24) & 0xff; 1120e1ea03a3Smacallan mb = mask & 0xff; 1121e1ea03a3Smacallan mg = (mask >> 8) & 0xff; 1122e1ea03a3Smacallan mr = (mask >> 16) & 0xff; 1123e1ea03a3Smacallan ma = (mask >> 24) & 0xff; 1124e1ea03a3Smacallan 1125e1ea03a3Smacallan /* and here we need an RGBA pixel */ 1126e1ea03a3Smacallan bb = (((sb * mb) + 0x80) & 0xff00); 1127e1ea03a3Smacallan gg = (((sg * mg) + 0x80) & 0xff00) << 8; 1128e1ea03a3Smacallan rr = (((sr * mr) + 0x80) & 0xff00) << 16; 1129e1ea03a3Smacallan aa = (((sa * ma) + 0x80) & 0xff00) >> 8; 1130e1ea03a3Smacallan /* 1131e1ea03a3Smacallan * actually we could let the HW do this stuff 1132e1ea03a3Smacallan */ 1133e1ea03a3Smacallan *dptr = aa | rr | gg | bb; 1134e1ea03a3Smacallan } 1135e1ea03a3Smacallan dptr++; 1136e1ea03a3Smacallan asptr++; 1137e1ea03a3Smacallan amptr++; 1138e1ea03a3Smacallan } 1139e1ea03a3Smacallan } 1140e1ea03a3Smacallan xoff = 0; 114126dcc2a3Smacallan MAKE_ROOM(1); 1142e1ea03a3Smacallan WRITE4(CRIME_DE_XFER_ADDR_SRC, bufnum * 8192); 1143e1ea03a3Smacallan while (xoff < width) { 1144e1ea03a3Smacallan xa = dstx + xoff; 1145e1ea03a3Smacallan xe = dstx + min(xoff + period, width) - 1; 114626dcc2a3Smacallan MAKE_ROOM(2); 1147e1ea03a3Smacallan WRITE4(CRIME_DE_X_VERTEX_0, 1148e1ea03a3Smacallan xa << 16 | (dsty + i)); 1149e1ea03a3Smacallan WRITE4ST(CRIME_DE_X_VERTEX_1, 1150e1ea03a3Smacallan (xe << 16) | (dsty + i)); 1151e1ea03a3Smacallan xoff += period; 1152e1ea03a3Smacallan } 1153e1ea03a3Smacallan bufnum++; 1154e1ea03a3Smacallan if (bufnum == 8) bufnum = 0; 1155e1ea03a3Smacallan lcnt--; 1156e1ea03a3Smacallan if (lcnt == 0) { 1157e1ea03a3Smacallan /* back to the beginning */ 1158e1ea03a3Smacallan lsptr = sptr; 1159e1ea03a3Smacallan lmptr = mptr; 1160e1ea03a3Smacallan lcnt = fPtr->uh; 1161e1ea03a3Smacallan } else 1162e1ea03a3Smacallan /* next line */ 1163e1ea03a3Smacallan lsptr += fPtr->us; 1164e1ea03a3Smacallan lmptr += fPtr->um; 1165e1ea03a3Smacallan } 1166e1ea03a3Smacallan DONE(CRIME_DEBUG_XRENDER); 1167e1ea03a3Smacallan} 1168e1ea03a3Smacallan 1169e1ea03a3Smacallanvoid 1170e1ea03a3SmacallanCrimeSubsequentCPUToScreenTextureMask8( 1171e1ea03a3Smacallan ScrnInfoPtr pScrn, 1172e1ea03a3Smacallan int dstx, 1173e1ea03a3Smacallan int dsty, 1174e1ea03a3Smacallan int srcx, 1175e1ea03a3Smacallan int srcy, 1176e1ea03a3Smacallan int maskx, 1177e1ea03a3Smacallan int masky, 1178e1ea03a3Smacallan int width, 1179e1ea03a3Smacallan int height 1180e1ea03a3Smacallan) 1181e1ea03a3Smacallan{ 1182e1ea03a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 1183e1ea03a3Smacallan uint32_t *lsptr, *asptr; 1184e1ea03a3Smacallan uint32_t *dptr, *sptr, aval, pixel, mask; 1185e1ea03a3Smacallan uint8_t *lmptr, *amptr, *mptr; 1186e1ea03a3Smacallan int i, j, k, l, rep = 1, period = fPtr->uw, xoff, lcnt, xa, xe; 1187e1ea03a3Smacallan int bufnum = 0; 1188e1ea03a3Smacallan int sr, sg, sb, sa, rr, gg, bb, aa; 1189e1ea03a3Smacallan 1190e1ea03a3Smacallan LOG(CRIME_DEBUG_XRENDER); 11915b2650b9Smacallan#ifdef CRIME_DEBUG_LOUD 1192e1ea03a3Smacallan xf86Msg(X_ERROR, "%s: %d %d %d %d %d %d\n", __func__, 1193e1ea03a3Smacallan srcx, srcy, dstx, dsty, width, height); 1194e1ea03a3Smacallan#endif 1195e1ea03a3Smacallan sptr = (uint32_t *)fPtr->src + (fPtr->us * srcy) + (srcx << 2); 1196e1ea03a3Smacallan mptr = (uint8_t *)fPtr->msk + (fPtr->um * srcy) + srcx; 1197e1ea03a3Smacallan lsptr = sptr; 1198e1ea03a3Smacallan lmptr = mptr; 1199e1ea03a3Smacallan if ((fPtr->uw < 128) && (fPtr->uw < width)) { 1200e1ea03a3Smacallan rep = 128 / fPtr->uw; 1201e1ea03a3Smacallan period = rep * fPtr->uw; 1202e1ea03a3Smacallan } 1203e1ea03a3Smacallan 1204e1ea03a3Smacallan#ifdef CRIME_DEBUG_LOUD 120529406fd8Smacallan xf86Msg(X_ERROR, "ARGB %08x %d\n", (uint32_t)asptr, fPtr->uw); 1206e1ea03a3Smacallan#endif 1207e1ea03a3Smacallan lcnt = fPtr->uh; 1208e1ea03a3Smacallan for (i = 0; i < height; i++) { 1209e1ea03a3Smacallan dptr = (uint32_t *)fPtr->buffers[bufnum]; 1210e1ea03a3Smacallan for (k = 0; k < rep; k++) { 1211e1ea03a3Smacallan asptr = lsptr; 1212e1ea03a3Smacallan amptr = lmptr; 1213e1ea03a3Smacallan for (j = 0; j < fPtr->uw; j++) { 1214e1ea03a3Smacallan pixel = *asptr; 1215e1ea03a3Smacallan mask = *amptr; 1216e1ea03a3Smacallan if (mask == 0xff) { 1217e1ea03a3Smacallan *dptr = (pixel >> 24) | (pixel << 8); 1218e1ea03a3Smacallan } else if (mask == 0x00) { 1219e1ea03a3Smacallan *dptr = 0; 1220e1ea03a3Smacallan } else { 1221e1ea03a3Smacallan /* input is ARGB */ 1222e1ea03a3Smacallan sb = pixel & 0xff; 1223e1ea03a3Smacallan sg = (pixel >> 8) & 0xff; 1224e1ea03a3Smacallan sr = (pixel >> 16) & 0xff; 1225e1ea03a3Smacallan sa = (pixel >> 24) & 0xff; 1226e1ea03a3Smacallan 1227e1ea03a3Smacallan /* and here we need an RGBA pixel */ 1228e1ea03a3Smacallan bb = (((sb * mask) + 0x80) & 0xff00); 1229e1ea03a3Smacallan gg = (((sg * mask) + 0x80) & 0xff00) 1230e1ea03a3Smacallan << 8; 1231e1ea03a3Smacallan rr = (((sr * mask) + 0x80) & 0xff00) 1232e1ea03a3Smacallan << 16; 1233e1ea03a3Smacallan aa = (((sa * mask) + 0x80) & 0xff00) 1234e1ea03a3Smacallan >> 8; 1235e1ea03a3Smacallan /* 1236e1ea03a3Smacallan * actually we could let the HW do this 1237e1ea03a3Smacallan * stuff 1238e1ea03a3Smacallan */ 1239e1ea03a3Smacallan *dptr = aa | rr | gg | bb; 1240e1ea03a3Smacallan } 1241e1ea03a3Smacallan dptr++; 1242e1ea03a3Smacallan asptr++; 1243e1ea03a3Smacallan amptr++; 1244e1ea03a3Smacallan } 1245e1ea03a3Smacallan } 1246e1ea03a3Smacallan xoff = 0; 124726dcc2a3Smacallan MAKE_ROOM(1); 1248e1ea03a3Smacallan WRITE4(CRIME_DE_XFER_ADDR_SRC, bufnum * 8192); 1249e1ea03a3Smacallan while (xoff < width) { 1250e1ea03a3Smacallan xa = dstx + xoff; 1251e1ea03a3Smacallan xe = dstx + min(xoff + period, width) - 1; 125226dcc2a3Smacallan MAKE_ROOM(2); 1253e1ea03a3Smacallan WRITE4(CRIME_DE_X_VERTEX_0, 1254e1ea03a3Smacallan xa << 16 | (dsty + i)); 1255e1ea03a3Smacallan WRITE4ST(CRIME_DE_X_VERTEX_1, 1256e1ea03a3Smacallan (xe << 16) | (dsty + i)); 1257e1ea03a3Smacallan xoff += period; 1258e1ea03a3Smacallan } 1259e1ea03a3Smacallan bufnum++; 1260e1ea03a3Smacallan if (bufnum == 8) bufnum = 0; 1261e1ea03a3Smacallan lcnt--; 1262e1ea03a3Smacallan if (lcnt == 0) { 1263e1ea03a3Smacallan /* back to the beginning */ 1264e1ea03a3Smacallan lsptr = sptr; 1265e1ea03a3Smacallan lmptr = mptr; 1266e1ea03a3Smacallan lcnt = fPtr->uh; 1267e1ea03a3Smacallan } else 1268e1ea03a3Smacallan /* next line */ 1269e1ea03a3Smacallan lsptr += fPtr->us; 1270e1ea03a3Smacallan lmptr += fPtr->um; 1271e1ea03a3Smacallan } 1272e1ea03a3Smacallan DONE(CRIME_DEBUG_XRENDER); 1273e1ea03a3Smacallan} 1274e1ea03a3Smacallan 1275e1ea03a3Smacallanstatic void 1276e1ea03a3SmacallanCrimeDoCPUToScreenComposite( 1277e1ea03a3Smacallan CARD8 op, 1278e1ea03a3Smacallan PicturePtr pSrc, 1279e1ea03a3Smacallan PicturePtr pMask, 1280e1ea03a3Smacallan PicturePtr pDst, 1281e1ea03a3Smacallan INT16 xSrc, 1282e1ea03a3Smacallan INT16 ySrc, 1283e1ea03a3Smacallan INT16 xMask, 1284e1ea03a3Smacallan INT16 yMask, 1285e1ea03a3Smacallan INT16 xDst, 1286e1ea03a3Smacallan INT16 yDst, 1287e1ea03a3Smacallan CARD16 width, 1288e1ea03a3Smacallan CARD16 height 1289e1ea03a3Smacallan) 1290e1ea03a3Smacallan{ 1291e1ea03a3Smacallan ScreenPtr pScreen = pDst->pDrawable->pScreen; 1292e1ea03a3Smacallan XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen); 1293e1ea03a3Smacallan RegionRec region; 1294e1ea03a3Smacallan CARD32 *formats; 1295e1ea03a3Smacallan int flags = 0; 1296e1ea03a3Smacallan BoxPtr pbox; 1297e1ea03a3Smacallan int nbox, w, h; 1298e1ea03a3Smacallan 1299e1ea03a3Smacallan LOG(CRIME_DEBUG_XRENDER); 1300e1ea03a3Smacallan if (pSrc->transform || (pMask && pMask->transform)) { 1301e1ea03a3Smacallan xf86Msg(X_ERROR, "%s: transform?!\n", __func__); 1302e1ea03a3Smacallan return; 1303e1ea03a3Smacallan } 1304e1ea03a3Smacallan 1305e1ea03a3Smacallan if (pDst->alphaMap || pSrc->alphaMap || (pMask && pMask->alphaMap)) { 1306e1ea03a3Smacallan xf86Msg(X_ERROR, "%s: alpha-map?!\n", __func__); 1307e1ea03a3Smacallan return; 1308e1ea03a3Smacallan } 1309e1ea03a3Smacallan 1310e1ea03a3Smacallan xDst += pDst->pDrawable->x; 1311e1ea03a3Smacallan yDst += pDst->pDrawable->y; 1312e1ea03a3Smacallan xSrc += pSrc->pDrawable->x; 1313e1ea03a3Smacallan ySrc += pSrc->pDrawable->y; 1314e1ea03a3Smacallan 1315e1ea03a3Smacallan if(pMask) { 1316e1ea03a3Smacallan CARD16 red, green, blue, alpha; 1317e1ea03a3Smacallan CARD32 pixel = 131829406fd8Smacallan *((CARD32*)(((PixmapPtr)(pSrc->pDrawable))->devPrivate.ptr)); 131909f0d67cSmacallan#ifdef CRIME_DEBUG_LOUD 1320e1ea03a3Smacallan if(pMask->componentAlpha) { 1321e1ea03a3Smacallan xf86Msg(X_ERROR, "%s: alpha component mask\n", 1322e1ea03a3Smacallan __func__); 132329406fd8Smacallan xf86Msg(X_ERROR, "src: %d x %d\n", 132429406fd8Smacallan pSrc->pDrawable->width, 132509f0d67cSmacallan pSrc->pDrawable->height); 1326e1ea03a3Smacallan } 132709f0d67cSmacallan#endif 1328e1ea03a3Smacallan if ((pSrc->pDrawable->width == 1) && 1329e1ea03a3Smacallan (pSrc->pDrawable->height == 1)) { 1330e1ea03a3Smacallan 1331e1ea03a3Smacallan if(!XAAGetRGBAFromPixel(pixel, &red, &green, &blue, 1332e1ea03a3Smacallan &alpha, pSrc->format)) { 133329406fd8Smacallan xf86Msg(X_ERROR, "%s: can't read pixel\n", 133429406fd8Smacallan __func__); 1335e1ea03a3Smacallan return; 1336e1ea03a3Smacallan } 133729406fd8Smacallan#ifdef CRIME_DEBUG_LOUD 133829406fd8Smacallan xf86Msg(X_ERROR, "RGBA: %d %d %d %d\n", red, green, 133929406fd8Smacallan blue, alpha); 134029406fd8Smacallan#endif 1341e1ea03a3Smacallan xMask += pMask->pDrawable->x; 1342e1ea03a3Smacallan yMask += pMask->pDrawable->y; 1343e1ea03a3Smacallan 1344e1ea03a3Smacallan /* pull out color expandable operations here */ 1345e1ea03a3Smacallan if(pMask->format == PICT_a1) { 1346e1ea03a3Smacallan PixmapPtr pPix = (PixmapPtr)(pMask->pDrawable); 1347e1ea03a3Smacallan int skipleft; 1348e1ea03a3Smacallan 1349e1ea03a3Smacallan if (op != PictOpOver) { 1350e1ea03a3Smacallan xf86Msg(X_ERROR, "!over\n"); 1351e1ea03a3Smacallan return; 1352e1ea03a3Smacallan } 1353e1ea03a3Smacallan if (pMask->repeat) { 1354e1ea03a3Smacallan xf86Msg(X_ERROR, "mono repeat\n"); 1355e1ea03a3Smacallan return; 1356e1ea03a3Smacallan } 1357e1ea03a3Smacallan if (!miComputeCompositeRegion (®ion, pSrc, 1358e1ea03a3Smacallan pMask, pDst, xSrc, ySrc, xMask, yMask, xDst, 1359e1ea03a3Smacallan yDst, width, height)) { 1360e1ea03a3Smacallan return; 1361e1ea03a3Smacallan } 1362e1ea03a3Smacallan 1363e1ea03a3Smacallan nbox = REGION_NUM_RECTS(®ion); 1364e1ea03a3Smacallan pbox = REGION_RECTS(®ion); 1365e1ea03a3Smacallan 1366e1ea03a3Smacallan if(!nbox) { 1367e1ea03a3Smacallan return; 1368e1ea03a3Smacallan } 1369e1ea03a3Smacallan 1370e1ea03a3Smacallan XAAGetPixelFromRGBA(&pixel, red, green, blue, 0, 1371e1ea03a3Smacallan pDst->format); 1372e1ea03a3Smacallan 1373e1ea03a3Smacallan xMask -= xDst; 1374e1ea03a3Smacallan yMask -= yDst; 1375e1ea03a3Smacallan 1376e1ea03a3Smacallan while(nbox--) { 1377e1ea03a3Smacallan skipleft = pbox->x1 + xMask; 1378e1ea03a3Smacallan 137929406fd8Smacallan (*infoRec->WriteBitmap)(infoRec->pScrn, pbox->x1, pbox->y1, 1380e1ea03a3Smacallan pbox->x2 - pbox->x1, 1381e1ea03a3Smacallan pbox->y2 - pbox->y1, 138229406fd8Smacallan (unsigned char*) 138329406fd8Smacallan (pPix->devPrivate.ptr) + 138429406fd8Smacallan (pPix->devKind * 138529406fd8Smacallan (pbox->y1 + yMask)) + 138629406fd8Smacallan ((skipleft >> 3) & ~3), 138729406fd8Smacallan pPix->devKind, skipleft & 31, pixel, 138829406fd8Smacallan -1, GXcopy, ~0); 1389e1ea03a3Smacallan pbox++; 1390e1ea03a3Smacallan } 1391e1ea03a3Smacallan 1392e1ea03a3Smacallan /* WriteBitmap sets the Sync flag */ 1393e1ea03a3Smacallan REGION_UNINIT(pScreen, ®ion); 1394e1ea03a3Smacallan DONE(CRIME_DEBUG_XRENDER); 1395e1ea03a3Smacallan return; 1396e1ea03a3Smacallan } 139709f0d67cSmacallan if((pMask->format == PICT_a8) || 139809f0d67cSmacallan (pMask->format == PICT_a8r8g8b8)) { 1399e1ea03a3Smacallan 1400e1ea03a3Smacallan w = pMask->pDrawable->width; 1401e1ea03a3Smacallan h = pMask->pDrawable->height; 1402e1ea03a3Smacallan 1403e1ea03a3Smacallan if(pMask->repeat) { 1404e1ea03a3Smacallan flags |= XAA_RENDER_REPEAT; 1405e1ea03a3Smacallan } 1406e1ea03a3Smacallan 1407e1ea03a3Smacallan if (!miComputeCompositeRegion (®ion, pSrc, pMask, 1408e1ea03a3Smacallan pDst, xSrc, ySrc, xMask, yMask, xDst, yDst, 1409e1ea03a3Smacallan width, height)) { 1410e1ea03a3Smacallan return; 1411e1ea03a3Smacallan } 1412e1ea03a3Smacallan 1413e1ea03a3Smacallan nbox = REGION_NUM_RECTS(®ion); 1414e1ea03a3Smacallan pbox = REGION_RECTS(®ion); 1415e1ea03a3Smacallan 1416e1ea03a3Smacallan if(!nbox) { 1417e1ea03a3Smacallan REGION_UNINIT(pScreen, ®ion); 1418e1ea03a3Smacallan return; 1419e1ea03a3Smacallan } 1420e1ea03a3Smacallan 142129406fd8Smacallan CrimeSetupForCPUToScreenAlphaTexture( 142229406fd8Smacallan infoRec->pScrn, op, red, green, blue, alpha, 142329406fd8Smacallan pMask->format, 1424e1ea03a3Smacallan ((PixmapPtr)(pMask->pDrawable))->devPrivate.ptr, 1425e1ea03a3Smacallan ((PixmapPtr)(pMask->pDrawable))->devKind, 1426e1ea03a3Smacallan w, h, flags); 1427e1ea03a3Smacallan 1428e1ea03a3Smacallan xMask -= xDst; 1429e1ea03a3Smacallan yMask -= yDst; 1430e1ea03a3Smacallan 143109f0d67cSmacallan if (pMask->format != PICT_a8) { 143209f0d67cSmacallan while(nbox--) { 143309f0d67cSmacallan CrimeSubsequentCPUToScreenAlphaTexture32( 143409f0d67cSmacallan infoRec->pScrn, 143509f0d67cSmacallan pbox->x1, pbox->y1, pbox->x1 + xMask, 143609f0d67cSmacallan pbox->y1 + yMask, pbox->x2 - pbox->x1, 143709f0d67cSmacallan pbox->y2 - pbox->y1); 143809f0d67cSmacallan pbox++; 143909f0d67cSmacallan } 144009f0d67cSmacallan } else { 144109f0d67cSmacallan while(nbox--) { 144209f0d67cSmacallan CrimeSubsequentCPUToScreenAlphaTexture( 144309f0d67cSmacallan infoRec->pScrn, 144429406fd8Smacallan pbox->x1, pbox->y1, 144529406fd8Smacallan pbox->x1 + xMask, 144629406fd8Smacallan pbox->y1 + yMask, 144729406fd8Smacallan pbox->x2 - pbox->x1, 144809f0d67cSmacallan pbox->y2 - pbox->y1); 144909f0d67cSmacallan pbox++; 145009f0d67cSmacallan } 1451e1ea03a3Smacallan } 1452e1ea03a3Smacallan SET_SYNC_FLAG(infoRec); 1453e1ea03a3Smacallan REGION_UNINIT(pScreen, ®ion); 1454e1ea03a3Smacallan DONE(CRIME_DEBUG_XRENDER); 1455e1ea03a3Smacallan return; 1456e1ea03a3Smacallan } else { 145729406fd8Smacallan xf86Msg(X_ERROR, "unknown mask %x\n", 145829406fd8Smacallan pMask->format); 1459e1ea03a3Smacallan } 1460e1ea03a3Smacallan REGION_UNINIT(pScreen, ®ion); 1461e1ea03a3Smacallan DONE(CRIME_DEBUG_XRENDER); 1462e1ea03a3Smacallan return; 1463e1ea03a3Smacallan } else { 1464e1ea03a3Smacallan /* source isn't solid */ 1465e1ea03a3Smacallan 1466e1ea03a3Smacallan w = pSrc->pDrawable->width; 1467e1ea03a3Smacallan h = pSrc->pDrawable->height; 1468e1ea03a3Smacallan 1469e1ea03a3Smacallan if(pSrc->repeat) 1470e1ea03a3Smacallan flags |= XAA_RENDER_REPEAT; 1471e1ea03a3Smacallan 1472e1ea03a3Smacallan if (!miComputeCompositeRegion (®ion, pSrc, pMask, 1473e1ea03a3Smacallan pDst, xSrc, ySrc, xMask, yMask, xDst, yDst, 1474e1ea03a3Smacallan width, height)) { 1475e1ea03a3Smacallan return; 1476e1ea03a3Smacallan } 1477e1ea03a3Smacallan 1478e1ea03a3Smacallan nbox = REGION_NUM_RECTS(®ion); 1479e1ea03a3Smacallan pbox = REGION_RECTS(®ion); 1480e1ea03a3Smacallan 1481e1ea03a3Smacallan if(!nbox) { 1482e1ea03a3Smacallan REGION_UNINIT(pScreen, ®ion); 1483e1ea03a3Smacallan return; 1484e1ea03a3Smacallan } 1485e1ea03a3Smacallan CrimeSetupForCPUToScreenTextureMask( 1486e1ea03a3Smacallan infoRec->pScrn, op, pMask->format, 1487e1ea03a3Smacallan ((PixmapPtr)(pSrc->pDrawable))->devPrivate.ptr, 1488e1ea03a3Smacallan ((PixmapPtr)(pSrc->pDrawable))->devKind, 1489e1ea03a3Smacallan ((PixmapPtr)(pMask->pDrawable))->devPrivate.ptr, 1490e1ea03a3Smacallan ((PixmapPtr)(pMask->pDrawable))->devKind, 1491e1ea03a3Smacallan w, h, flags); 1492e1ea03a3Smacallan 1493e1ea03a3Smacallan xSrc -= xDst; 1494e1ea03a3Smacallan ySrc -= yDst; 1495e1ea03a3Smacallan 1496e1ea03a3Smacallan if (PICT_FORMAT_BPP(pMask->format) == 32) { 1497e1ea03a3Smacallan while(nbox--) { 1498e1ea03a3Smacallan CrimeSubsequentCPUToScreenTextureMask32( 1499e1ea03a3Smacallan infoRec->pScrn, 1500e1ea03a3Smacallan pbox->x1, pbox->y1, 1501e1ea03a3Smacallan pbox->x1 + xSrc, pbox->y1 + ySrc, 1502e1ea03a3Smacallan xMask, yMask, 150329406fd8Smacallan pbox->x2 - pbox->x1, 150429406fd8Smacallan pbox->y2 - pbox->y1); 1505e1ea03a3Smacallan pbox++; 1506e1ea03a3Smacallan } 1507e1ea03a3Smacallan } else { 1508e1ea03a3Smacallan while(nbox--) { 1509e1ea03a3Smacallan CrimeSubsequentCPUToScreenTextureMask8( 1510e1ea03a3Smacallan infoRec->pScrn, 1511e1ea03a3Smacallan pbox->x1, pbox->y1, pbox->x1 + xSrc, 1512e1ea03a3Smacallan pbox->y1 + ySrc, 1513e1ea03a3Smacallan xMask, yMask, 1514e1ea03a3Smacallan pbox->x2 - pbox->x1, 1515e1ea03a3Smacallan pbox->y2 - pbox->y1); 1516e1ea03a3Smacallan pbox++; 1517e1ea03a3Smacallan } 1518e1ea03a3Smacallan } 1519e1ea03a3Smacallan 1520e1ea03a3Smacallan SET_SYNC_FLAG(infoRec); 1521e1ea03a3Smacallan REGION_UNINIT(pScreen, ®ion); 1522e1ea03a3Smacallan DONE(CRIME_DEBUG_XRENDER); 1523e1ea03a3Smacallan return; 1524e1ea03a3Smacallan } 1525e1ea03a3Smacallan } else { /* no mask */ 1526e1ea03a3Smacallan formats = infoRec->CPUToScreenTextureFormats; 1527e1ea03a3Smacallan 1528e1ea03a3Smacallan w = pSrc->pDrawable->width; 1529e1ea03a3Smacallan h = pSrc->pDrawable->height; 1530e1ea03a3Smacallan 1531e1ea03a3Smacallan if(pSrc->repeat) 1532e1ea03a3Smacallan flags |= XAA_RENDER_REPEAT; 1533e1ea03a3Smacallan 1534e1ea03a3Smacallan while(*formats != pSrc->format) { 1535e1ea03a3Smacallan if(!(*formats)) { 1536e1ea03a3Smacallan xf86Msg(X_ERROR, 1537e1ea03a3Smacallan "%s: format %x not found\n", 1538e1ea03a3Smacallan __func__, pSrc->format); 1539e1ea03a3Smacallan return; 1540e1ea03a3Smacallan } 1541e1ea03a3Smacallan formats++; 1542e1ea03a3Smacallan } 1543e1ea03a3Smacallan 1544e1ea03a3Smacallan if (!miComputeCompositeRegion (®ion, pSrc, pMask, pDst, 1545e1ea03a3Smacallan xSrc, ySrc, xMask, yMask, xDst, yDst, 1546e1ea03a3Smacallan width, height)) { 1547e1ea03a3Smacallan return; 1548e1ea03a3Smacallan } 1549e1ea03a3Smacallan 1550e1ea03a3Smacallan nbox = REGION_NUM_RECTS(®ion); 1551e1ea03a3Smacallan pbox = REGION_RECTS(®ion); 1552e1ea03a3Smacallan 1553e1ea03a3Smacallan if(!nbox) { 1554e1ea03a3Smacallan REGION_UNINIT(pScreen, ®ion); 1555e1ea03a3Smacallan return; 1556e1ea03a3Smacallan } 1557e1ea03a3Smacallan 1558e1ea03a3Smacallan CrimeSetupForCPUToScreenTexture(infoRec->pScrn, 1559e1ea03a3Smacallan op, pSrc->format, 1560e1ea03a3Smacallan ((PixmapPtr)(pSrc->pDrawable))->devPrivate.ptr, 1561e1ea03a3Smacallan ((PixmapPtr)(pSrc->pDrawable))->devKind, 1562e1ea03a3Smacallan w, h, flags); 1563e1ea03a3Smacallan 1564e1ea03a3Smacallan xSrc -= xDst; 1565e1ea03a3Smacallan ySrc -= yDst; 1566e1ea03a3Smacallan 1567e1ea03a3Smacallan while(nbox--) { 1568e1ea03a3Smacallan CrimeSubsequentCPUToScreenTexture(infoRec->pScrn, 1569e1ea03a3Smacallan pbox->x1, pbox->y1, pbox->x1 + xSrc, 1570e1ea03a3Smacallan pbox->y1 + ySrc, pbox->x2 - pbox->x1, 1571e1ea03a3Smacallan pbox->y2 - pbox->y1); 1572e1ea03a3Smacallan pbox++; 1573e1ea03a3Smacallan } 1574e1ea03a3Smacallan 1575e1ea03a3Smacallan SET_SYNC_FLAG(infoRec); 1576e1ea03a3Smacallan REGION_UNINIT(pScreen, ®ion); 1577e1ea03a3Smacallan DONE(CRIME_DEBUG_XRENDER); 1578e1ea03a3Smacallan return; 1579e1ea03a3Smacallan } 1580e1ea03a3Smacallan xf86Msg(X_ERROR, "%s: shouldn't be here\n", __func__); 1581e1ea03a3Smacallan} 1582e1ea03a3Smacallan 1583e1ea03a3Smacallanstatic void 1584e1ea03a3SmacallanCrimeDoScreenToScreenComposite( 1585e1ea03a3Smacallan CARD8 op, 1586e1ea03a3Smacallan PicturePtr pSrc, 1587e1ea03a3Smacallan PicturePtr pMask, 1588e1ea03a3Smacallan PicturePtr pDst, 1589e1ea03a3Smacallan INT16 xSrc, 1590e1ea03a3Smacallan INT16 ySrc, 1591e1ea03a3Smacallan INT16 xMask, 1592e1ea03a3Smacallan INT16 yMask, 1593e1ea03a3Smacallan INT16 xDst, 1594e1ea03a3Smacallan INT16 yDst, 1595e1ea03a3Smacallan CARD16 width, 1596e1ea03a3Smacallan CARD16 height 1597e1ea03a3Smacallan) 1598e1ea03a3Smacallan{ 1599e1ea03a3Smacallan ScreenPtr pScreen = pDst->pDrawable->pScreen; 1600e1ea03a3Smacallan XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen); 1601e1ea03a3Smacallan ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 1602e1ea03a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 1603e1ea03a3Smacallan RegionRec region; 1604e1ea03a3Smacallan CARD32 *formats; 1605e1ea03a3Smacallan int flags = 0; 1606e1ea03a3Smacallan BoxPtr pbox; 1607e1ea03a3Smacallan int nbox; 1608e1ea03a3Smacallan int xs, ys, xd, yd, w, h; 160929406fd8Smacallanxf86Msg(X_ERROR, "CRIME screen-to-screen composite\n"); 1610e1ea03a3Smacallan LOG(CRIME_DEBUG_XRENDER); 1611e1ea03a3Smacallan if (pSrc->transform || (pMask && pMask->transform)) { 1612e1ea03a3Smacallan xf86Msg(X_ERROR, "%s: mask?!\n", __func__); 1613e1ea03a3Smacallan return; 1614e1ea03a3Smacallan } 1615e1ea03a3Smacallan xf86Msg(X_ERROR, "%s: %d\n", __func__, op); 1616e1ea03a3Smacallan if (pDst->alphaMap || pSrc->alphaMap || (pMask && pMask->alphaMap)) { 1617e1ea03a3Smacallan xf86Msg(X_ERROR, "%s: alpha-map\n", __func__); 1618e1ea03a3Smacallan return; 1619e1ea03a3Smacallan } 1620e1ea03a3Smacallan 1621e1ea03a3Smacallan xDst += pDst->pDrawable->x; 1622e1ea03a3Smacallan yDst += pDst->pDrawable->y; 1623e1ea03a3Smacallan xSrc += pSrc->pDrawable->x; 1624e1ea03a3Smacallan ySrc += pSrc->pDrawable->y; 1625e1ea03a3Smacallan 1626e1ea03a3Smacallan formats = infoRec->CPUToScreenTextureFormats; 1627e1ea03a3Smacallan 1628e1ea03a3Smacallan w = pSrc->pDrawable->width; 1629e1ea03a3Smacallan h = pSrc->pDrawable->height; 1630e1ea03a3Smacallan 1631e1ea03a3Smacallan if(pSrc->repeat) 1632e1ea03a3Smacallan flags |= XAA_RENDER_REPEAT; 1633e1ea03a3Smacallan 1634e1ea03a3Smacallan while(*formats != pSrc->format) { 1635e1ea03a3Smacallan if(!(*formats)) return; 1636e1ea03a3Smacallan formats++; 1637e1ea03a3Smacallan } 1638e1ea03a3Smacallan 1639e1ea03a3Smacallan if (!miComputeCompositeRegion (®ion, pSrc, pMask, pDst, 1640e1ea03a3Smacallan xSrc, ySrc, xMask, yMask, xDst, yDst, width, height)) 1641e1ea03a3Smacallan return; 1642e1ea03a3Smacallan 1643e1ea03a3Smacallan nbox = REGION_NUM_RECTS(®ion); 1644e1ea03a3Smacallan pbox = REGION_RECTS(®ion); 1645e1ea03a3Smacallan 1646e1ea03a3Smacallan if(!nbox) { 1647e1ea03a3Smacallan REGION_UNINIT(pScreen, ®ion); 1648e1ea03a3Smacallan return; 1649e1ea03a3Smacallan } 1650e1ea03a3Smacallan 165126dcc2a3Smacallan MAKE_ROOM(6); 1652e1ea03a3Smacallan WRITE4(CRIME_DE_MODE_SRC, DE_MODE_TLB_A | DE_MODE_BUFDEPTH_32 | 1653e1ea03a3Smacallan DE_MODE_TYPE_RGBA | DE_MODE_PIXDEPTH_32); 165426dcc2a3Smacallan WRITE4(CRIME_DE_MODE_DST, DE_MODE_TLB_A | DE_MODE_BUFDEPTH_32 | 165526dcc2a3Smacallan DE_MODE_TYPE_RGBA | DE_MODE_PIXDEPTH_32); 1656e1ea03a3Smacallan WRITE4(CRIME_DE_XFER_STEP_X, 1); 1657e1ea03a3Smacallan WRITE4(CRIME_DE_ALPHA_FUNC, 1658e1ea03a3Smacallan DE_ALPHA_ADD | 1659e1ea03a3Smacallan (DE_ALPHA_OP_SRC_ALPHA << DE_ALPHA_OP_SRC_SHIFT) | 1660e1ea03a3Smacallan (DE_ALPHA_OP_1_MINUS_SRC_ALPHA << DE_ALPHA_OP_DST_SHIFT)); 1661e1ea03a3Smacallan WRITE4(CRIME_DE_DRAWMODE, 1662e1ea03a3Smacallan DE_DRAWMODE_BYTEMASK | DE_DRAWMODE_ALPHA_BLEND | 1663e1ea03a3Smacallan DE_DRAWMODE_XFER_EN); 1664e1ea03a3Smacallan WRITE4(CRIME_DE_PRIMITIVE, 1665e1ea03a3Smacallan DE_PRIM_RECTANGLE | DE_PRIM_LR | DE_PRIM_TB); 166626dcc2a3Smacallan SYNC; 1667e1ea03a3Smacallan xSrc -= xDst; 1668e1ea03a3Smacallan ySrc -= yDst; 1669e1ea03a3Smacallan 1670e1ea03a3Smacallan /* assume no overlap - might bite us in the arse at some point */ 1671e1ea03a3Smacallan while(nbox--) { 1672e1ea03a3Smacallan xs = pbox->x1 + xSrc; 1673e1ea03a3Smacallan ys = pbox->y1 + ySrc; 1674e1ea03a3Smacallan xd = pbox->x1; 1675e1ea03a3Smacallan yd = pbox->y1; 1676e1ea03a3Smacallan w = pbox->x2 - pbox->x1; 1677e1ea03a3Smacallan h = pbox->y2 - pbox->y1; 167826dcc2a3Smacallan MAKE_ROOM(3); 1679e1ea03a3Smacallan WRITE4(CRIME_DE_XFER_ADDR_SRC,(xs << 16) | (ys & 0xffff)); 1680e1ea03a3Smacallan WRITE4(CRIME_DE_X_VERTEX_0, (xd << 16) | (yd & 0xffff)); 1681e1ea03a3Smacallan WRITE4ST(CRIME_DE_X_VERTEX_1, 1682e1ea03a3Smacallan ((xd + w - 1) << 16) | ((yd + h - 1) & 0xffff)); 1683e1ea03a3Smacallan pbox++; 1684e1ea03a3Smacallan } 1685e1ea03a3Smacallan 1686e1ea03a3Smacallan SET_SYNC_FLAG(infoRec); 1687e1ea03a3Smacallan REGION_UNINIT(pScreen, ®ion); 1688e1ea03a3Smacallan return; 1689e1ea03a3Smacallan} 1690e1ea03a3Smacallan 1691e1ea03a3Smacallanstatic Bool 1692e1ea03a3SmacallanCrimeComposite( 1693e1ea03a3Smacallan CARD8 op, 1694e1ea03a3Smacallan PicturePtr pSrc, 1695e1ea03a3Smacallan PicturePtr pMask, 1696e1ea03a3Smacallan PicturePtr pDst, 1697e1ea03a3Smacallan INT16 xSrc, 1698e1ea03a3Smacallan INT16 ySrc, 1699e1ea03a3Smacallan INT16 xMask, 1700e1ea03a3Smacallan INT16 yMask, 1701e1ea03a3Smacallan INT16 xDst, 1702e1ea03a3Smacallan INT16 yDst, 1703e1ea03a3Smacallan CARD16 width, 1704e1ea03a3Smacallan CARD16 height 1705e1ea03a3Smacallan) 1706e1ea03a3Smacallan{ 1707e1ea03a3Smacallan ScreenPtr pScreen = pDst->pDrawable->pScreen; 1708e1ea03a3Smacallan XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen); 1709e1ea03a3Smacallan 1710e1ea03a3Smacallan LOG(CRIME_DEBUG_XRENDER); 1711e1ea03a3Smacallan 171229406fd8Smacallan if(!REGION_NUM_RECTS(pDst->pCompositeClip)) { 171329406fd8Smacallan#ifdef CRIME_DEBUG_LOUD 171429406fd8Smacallan xf86Msg(X_ERROR, "%s: empty clip\n", __func__); 171529406fd8Smacallan#endif 1716e1ea03a3Smacallan return TRUE; 171729406fd8Smacallan } 1718e1ea03a3Smacallan 171929406fd8Smacallan if(!infoRec->pScrn->vtSema) { 172029406fd8Smacallan#ifdef CRIME_DEBUG_LOUD 172129406fd8Smacallan xf86Msg(X_ERROR, "%s: semaphore\n", __func__); 172229406fd8Smacallan#endif 1723e1ea03a3Smacallan return FALSE; 172429406fd8Smacallan } 1725e1ea03a3Smacallan 1726e1ea03a3Smacallan if((pDst->pDrawable->type == DRAWABLE_WINDOW) || 1727f282839bSmacallan IS_OFFSCREEN_PIXMAP(pDst->pDrawable) || 1728f282839bSmacallan PIXMAP_IS_SCREEN(pDst->pDrawable)) { 1729e1ea03a3Smacallan if ((pSrc->pDrawable->type == DRAWABLE_WINDOW) || 1730f282839bSmacallan IS_OFFSCREEN_PIXMAP(pSrc->pDrawable) || 1731f282839bSmacallan PIXMAP_IS_SCREEN(pSrc->pDrawable)) { 1732e1ea03a3Smacallan /* screen-to-screen */ 1733e1ea03a3Smacallan CrimeDoScreenToScreenComposite(op, pSrc, pMask, pDst, 1734e1ea03a3Smacallan xSrc, ySrc, xMask, yMask, 1735e1ea03a3Smacallan xDst, yDst, width, height); 1736e1ea03a3Smacallan return TRUE; 1737e1ea03a3Smacallan } else { 1738e1ea03a3Smacallan /* CPU-to-screen composite */ 1739e1ea03a3Smacallan if (op != PictOpOver) 1740e1ea03a3Smacallan xf86Msg(X_ERROR, "%s: op %d\n", __func__, op); 1741e1ea03a3Smacallan CrimeDoCPUToScreenComposite(op, pSrc, pMask, pDst, 1742e1ea03a3Smacallan xSrc, ySrc, xMask, yMask, 1743e1ea03a3Smacallan xDst, yDst, width, height); 1744e1ea03a3Smacallan return TRUE; 1745e1ea03a3Smacallan } 1746e1ea03a3Smacallan } else { 1747e1ea03a3Smacallan if ((pSrc->pDrawable->type == DRAWABLE_WINDOW) || 174829406fd8Smacallan IS_OFFSCREEN_PIXMAP(pSrc->pDrawable) || 174929406fd8Smacallan PIXMAP_IS_SCREEN(pSrc->pDrawable)) { 175029406fd8Smacallan /* 175129406fd8Smacallan * screen-to-RAM 175229406fd8Smacallan * Download from screen, then composite 175329406fd8Smacallan */ 1754e1ea03a3Smacallan xf86Msg(X_ERROR, "%s: screen-to-RAM composite\n", 1755e1ea03a3Smacallan __func__); 1756e1ea03a3Smacallan return TRUE; 1757e1ea03a3Smacallan } else { 1758e1ea03a3Smacallan /* RAM-to-RAM */ 175929406fd8Smacallan#ifdef CRIME_DEBUG_LOUD 176029406fd8Smacallan xf86Msg(X_ERROR, "%s: fallback %d, %08x %08x %08x\n", 176129406fd8Smacallan __func__, op, (uint32_t)pSrc->format, 176229406fd8Smacallan (uint32_t)pDst->format, 176329406fd8Smacallan pMask == NULL ? 0 : (uint32_t)pMask->format); 176429406fd8Smacallan#endif 176529406fd8Smacallan#if 0 1766e1ea03a3Smacallan return FALSE; 176729406fd8Smacallan#else 176829406fd8Smacallan return fbComposite(op, pSrc, pMask, pDst, xSrc, ySrc, 176929406fd8Smacallan xMask, yMask, xDst, yDst, width, height); 177029406fd8Smacallan#endif 1771e1ea03a3Smacallan } 1772e1ea03a3Smacallan } 1773e1ea03a3Smacallan xf86Msg(X_ERROR, "composite fucked\n"); 1774e1ea03a3Smacallan} 1775e1ea03a3Smacallan 177629406fd8Smacallanstatic Bool 177729406fd8SmacallanCrimeGlyphs (CARD8 op, 177829406fd8Smacallan PicturePtr pSrc, 177929406fd8Smacallan PicturePtr pDst, 178029406fd8Smacallan PictFormatPtr maskFormat, 178129406fd8Smacallan INT16 xSrc, 178229406fd8Smacallan INT16 ySrc, 178329406fd8Smacallan int nlist, 178429406fd8Smacallan GlyphListPtr list, 178529406fd8Smacallan GlyphPtr *glyphs) 178629406fd8Smacallan{ 178729406fd8Smacallan ScreenPtr pScreen = pDst->pDrawable->pScreen; 178829406fd8Smacallan PicturePtr pPicture; 178929406fd8Smacallan GlyphPtr glyph; 179029406fd8Smacallan int xDst = list->xOff, yDst = list->yOff; 179129406fd8Smacallan int x = 0, y = 0, i, n; 179229406fd8Smacallan 179329406fd8Smacallan while (nlist--) { 179429406fd8Smacallan x += list->xOff; 179529406fd8Smacallan y += list->yOff; 179629406fd8Smacallan n = list->len; 179729406fd8Smacallan while (n--) { 179829406fd8Smacallan glyph = *glyphs++; 179929406fd8Smacallan pPicture = GlyphPicture (glyph)[pScreen->myNum]; 180029406fd8Smacallan 180129406fd8Smacallan CrimeComposite (op, 180229406fd8Smacallan pSrc, 180329406fd8Smacallan pPicture, 180429406fd8Smacallan pDst, 180529406fd8Smacallan xSrc + (x - glyph->info.x) - xDst, 180629406fd8Smacallan ySrc + (y - glyph->info.y) - yDst, 180729406fd8Smacallan 0, 0, 180829406fd8Smacallan x - glyph->info.x, 180929406fd8Smacallan y - glyph->info.y, 181029406fd8Smacallan glyph->info.width, 181129406fd8Smacallan glyph->info.height); 181229406fd8Smacallan 181329406fd8Smacallan x += glyph->info.xOff; 181429406fd8Smacallan y += glyph->info.yOff; 181529406fd8Smacallan } 181629406fd8Smacallan list++; 181729406fd8Smacallan } 181829406fd8Smacallan return TRUE; 181929406fd8Smacallan} 182029406fd8Smacallan 1821e1ea03a3Smacallanstatic void 1822e1ea03a3SmacallanCrimePolyPoint( 1823e1ea03a3Smacallan DrawablePtr pDraw, 1824e1ea03a3Smacallan GCPtr pGC, 1825e1ea03a3Smacallan int mode, 1826e1ea03a3Smacallan int npt, 1827e1ea03a3Smacallan xPoint *pptInit 1828e1ea03a3Smacallan) 1829e1ea03a3Smacallan{ 1830e1ea03a3Smacallan ScreenPtr pScreen = pDraw->pScreen; 1831e1ea03a3Smacallan ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 1832e1ea03a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 1833e1ea03a3Smacallan BoxPtr pBox; 1834e1ea03a3Smacallan xPoint *ppt, *pts; 1835e1ea03a3Smacallan int x1, x2, y1, y2, x, y, i, nBox; 1836e1ea03a3Smacallan 1837e1ea03a3Smacallan /* make pointlist origin relative */ 1838e1ea03a3Smacallan ppt = pptInit; 1839e1ea03a3Smacallan if (mode == CoordModePrevious) { 1840e1ea03a3Smacallan for (i = 0; i < npt; i++) { 1841e1ea03a3Smacallan ppt++; 1842e1ea03a3Smacallan ppt->x += (ppt-1)->x; 1843e1ea03a3Smacallan ppt->y += (ppt-1)->y; 1844e1ea03a3Smacallan } 1845e1ea03a3Smacallan } 184626dcc2a3Smacallan MAKE_ROOM(6); 184726dcc2a3Smacallan WRITE4(CRIME_DE_MODE_DST, DE_MODE_TLB_A | DE_MODE_BUFDEPTH_32 | 184826dcc2a3Smacallan DE_MODE_TYPE_RGBA | DE_MODE_PIXDEPTH_32); 1849e1ea03a3Smacallan WRITE4(CRIME_DE_FG, pGC->fgPixel << 8); 1850e1ea03a3Smacallan WRITE4(CRIME_DE_ROP, pGC->alu); 1851e1ea03a3Smacallan WRITE4(CRIME_DE_PLANEMASK, pGC->planemask); 1852e1ea03a3Smacallan WRITE4(CRIME_DE_DRAWMODE, 1853e1ea03a3Smacallan DE_DRAWMODE_PLANEMASK | DE_DRAWMODE_BYTEMASK | DE_DRAWMODE_ROP); 1854e1ea03a3Smacallan WRITE4(CRIME_DE_PRIMITIVE, DE_PRIM_POINT); 185526dcc2a3Smacallan SYNC; 1856e1ea03a3Smacallan for (nBox = REGION_NUM_RECTS (pGC->pCompositeClip), 1857e1ea03a3Smacallan pBox = REGION_RECTS (pGC->pCompositeClip); 1858e1ea03a3Smacallan nBox--; pBox++) { 1859e1ea03a3Smacallan 1860e1ea03a3Smacallan pts = pptInit; 1861e1ea03a3Smacallan for (i = 0; i < npt; i++) { 1862e1ea03a3Smacallan x1 = pBox->x1; 1863e1ea03a3Smacallan y1 = pBox->y1; 1864e1ea03a3Smacallan x2 = pBox->x2; 1865e1ea03a3Smacallan y2 = pBox->y2; 1866e1ea03a3Smacallan x = pts->x + pDraw->x; 1867e1ea03a3Smacallan y = pts->y + pDraw->y; 1868e1ea03a3Smacallan if (x1 <= x && x < x2 && y1 <= y && y < y2) { 1869e1ea03a3Smacallan 187026dcc2a3Smacallan MAKE_ROOM(1); 1871e1ea03a3Smacallan WRITE4ST(CRIME_DE_X_VERTEX_0, 1872e1ea03a3Smacallan (x << 16) | y); 1873e1ea03a3Smacallan } 1874e1ea03a3Smacallan pts++; 1875e1ea03a3Smacallan } 1876e1ea03a3Smacallan } 1877e1ea03a3Smacallan} 1878e1ea03a3Smacallan 1879e1ea03a3Smacallanstatic void 1880e1ea03a3SmacallanCrimeValidatePolyPoint( 1881e1ea03a3Smacallan GCPtr pGC, 1882e1ea03a3Smacallan unsigned long changes, 1883e1ea03a3Smacallan DrawablePtr pDraw ) 1884e1ea03a3Smacallan{ 1885e1ea03a3Smacallan 1886e1ea03a3Smacallan if ((pDraw->type == DRAWABLE_WINDOW) || 1887e1ea03a3Smacallan IS_OFFSCREEN_PIXMAP(pDraw)) { 1888e1ea03a3Smacallan pGC->ops->PolyPoint = CrimePolyPoint; 1889e1ea03a3Smacallan } else 1890e1ea03a3Smacallan xf86Msg(X_ERROR, "boo\n"); 1891e1ea03a3Smacallan} 189234c4e112Smacallanstatic void 189334c4e112SmacallanCrimePolyArc(DrawablePtr pDraw, 189434c4e112Smacallan GCPtr pGC, 189534c4e112Smacallan int narcs, 189634c4e112Smacallan xArc *parcs) 189734c4e112Smacallan{ 189834c4e112Smacallan xArc *arc; 189934c4e112Smacallan BoxRec box; 190034c4e112Smacallan int i, x2, y2; 190134c4e112Smacallan RegionPtr cclip; 190234c4e112Smacallan 190334c4e112Smacallan cclip = pGC->pCompositeClip; 190434c4e112Smacallan 190534c4e112Smacallan if(!REGION_NUM_RECTS(cclip)) 190634c4e112Smacallan return; 190734c4e112Smacallan 190834c4e112Smacallan for (arc = parcs, i = narcs; --i >= 0; arc++) { 190934c4e112Smacallan if (miCanZeroArc(arc)) { 191034c4e112Smacallan box.x1 = arc->x + pDraw->x; 191134c4e112Smacallan box.y1 = arc->y + pDraw->y; 191234c4e112Smacallan x2 = box.x1 + (int)arc->width + 1; 191334c4e112Smacallan box.x2 = x2; 191434c4e112Smacallan y2 = box.y1 + (int)arc->height + 1; 191534c4e112Smacallan box.y2 = y2; 191634c4e112Smacallan if ( (x2 <= SHRT_MAX) && (y2 <= SHRT_MAX) && 191734c4e112Smacallan (RECT_IN_REGION(pDraw->pScreen, cclip, &box) == rgnIN) ) 191834c4e112Smacallan miZeroPolyArc(pDraw, pGC, 1, arc); 191934c4e112Smacallan } 192034c4e112Smacallan else 192134c4e112Smacallan miPolyArc(pDraw, pGC, 1, arc); 192234c4e112Smacallan } 192334c4e112Smacallan} 192434c4e112Smacallan 192534c4e112Smacallanstatic void 192634c4e112SmacallanCrimeValidatePolyArc(GCPtr pGC, 192734c4e112Smacallan unsigned long changes, 192834c4e112Smacallan DrawablePtr pDraw) 192934c4e112Smacallan{ 193034c4e112Smacallan if ((pDraw->type == DRAWABLE_WINDOW) || 193134c4e112Smacallan IS_OFFSCREEN_PIXMAP(pDraw)) { 193234c4e112Smacallan pGC->ops->PolyPoint = CrimePolyPoint; 193334c4e112Smacallan /*pGC->ops->PolyArc = miPolyArc;*/ 193434c4e112Smacallan pGC->ops->PolyArc = CrimePolyArc; 193534c4e112Smacallan } else 193634c4e112Smacallan { 193734c4e112Smacallan pGC->ops->PolyPoint = XAAGetFallbackOps()->PolyPoint; 193834c4e112Smacallan pGC->ops->PolyArc = XAAGetFallbackOps()->PolyArc; 193934c4e112Smacallan } 194034c4e112Smacallan} 1941e1ea03a3Smacallan 194226dcc2a3Smacallanstatic void copyRGBAtoARGB(uint32_t *dest, uint32_t *src, int len) 194326dcc2a3Smacallan{ 194426dcc2a3Smacallan while (len > 0) { 194526dcc2a3Smacallan *dest = *src >> 8; 194626dcc2a3Smacallan dest++; 194726dcc2a3Smacallan src++; 194826dcc2a3Smacallan len--; 194926dcc2a3Smacallan } 195026dcc2a3Smacallan} 195126dcc2a3Smacallan 195234c4e112Smacallanstatic void 195334c4e112SmacallanCrimeReadPixmap(ScrnInfoPtr pScrn, 195434c4e112Smacallan int x, 195534c4e112Smacallan int y, 195634c4e112Smacallan int w, 195734c4e112Smacallan int h, 195834c4e112Smacallan unsigned char *dst, 195934c4e112Smacallan int dstwidth, 196034c4e112Smacallan int bpp, 196134c4e112Smacallan int depth) 196234c4e112Smacallan{ 196326dcc2a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 196426dcc2a3Smacallan int bufno = 0; 196526dcc2a3Smacallan int nextbuf, i, len = w << 2; 196626dcc2a3Smacallan int mx = x << 2, offset; 196726dcc2a3Smacallan 196826dcc2a3Smacallan offset = mx & 0x3f; 196926dcc2a3Smacallan mx &= ~0x3f; 197026dcc2a3Smacallan len = (len + offset + 0x3f) & ~0x3f; 197126dcc2a3Smacallan 197226dcc2a3Smacallan LOG(CRIME_DEBUG_IMAGEREAD); 197326dcc2a3Smacallan 197426dcc2a3Smacallan#ifdef CRIME_DEBUG_LOUD 197526dcc2a3Smacallan xf86Msg(X_ERROR, "%s: %d %d %d %d\n", __func__, x, y, w, h); 197626dcc2a3Smacallan#endif 197726dcc2a3Smacallan 197826dcc2a3Smacallan MAKE_ROOM(3); 197926dcc2a3Smacallan 198026dcc2a3Smacallan /* 198126dcc2a3Smacallan * apparently all MTE coordinates are in bytes, not pixels 198226dcc2a3Smacallan * also, the MTE has some crazy alignment requirements - if 198326dcc2a3Smacallan * we don't do as above the thing will deadlock sooner or later 198426dcc2a3Smacallan * We use the MTE here because I couldn't get the rendering engine 198526dcc2a3Smacallan * to actually transfer anything into a linear buffer. The other 198626dcc2a3Smacallan * way around works just fine though. Shouldn't make much of a 198726dcc2a3Smacallan * difference, transfer times should be dominated by copying 198826dcc2a3Smacallan * data in and out of the DMA buffer anyway 198926dcc2a3Smacallan */ 199026dcc2a3Smacallan WRITE4(CRIME_MTE_MODE, (MTE_TLB_LIN_A << MTE_DST_TLB_SHIFT) | 199126dcc2a3Smacallan (MTE_TLB_A << MTE_SRC_TLB_SHIFT) | 199226dcc2a3Smacallan (MTE_DEPTH_8 << MTE_DEPTH_SHIFT) | 199326dcc2a3Smacallan MTE_MODE_DST_ECC | MTE_MODE_COPY); 199426dcc2a3Smacallan WRITE4(CRIME_MTE_SRC_Y_STEP, 1); 199526dcc2a3Smacallan WRITE4(CRIME_MTE_DST_Y_STEP, 1); 199626dcc2a3Smacallan SYNCMTE; 199726dcc2a3Smacallan WRITE4(CRIME_MTE_SRC0, (mx << 16) | y); 199826dcc2a3Smacallan WRITE4(CRIME_MTE_SRC1, ((mx + len) << 16) | y); 199926dcc2a3Smacallan WRITE4(CRIME_MTE_DST0, (bufno << 13)); 200026dcc2a3Smacallan WRITE4ST(CRIME_MTE_DST1, (bufno << 13) + len); 200126dcc2a3Smacallan for (i = y + 1; i < y + h; i++) { 200226dcc2a3Smacallan nextbuf = (bufno + 1) & 7; 200326dcc2a3Smacallan SYNCMTE; 200426dcc2a3Smacallan WRITE4(CRIME_MTE_SRC0, (mx << 16) | i); 200526dcc2a3Smacallan WRITE4(CRIME_MTE_SRC1, ((mx + len) << 16) | i); 200626dcc2a3Smacallan WRITE4(CRIME_MTE_DST0, (nextbuf << 13)); 200726dcc2a3Smacallan WRITE4ST(CRIME_MTE_DST1, (nextbuf << 13) + len); 200826dcc2a3Smacallan copyRGBAtoARGB((uint32_t *)dst, 200926dcc2a3Smacallan (uint32_t *)(fPtr->buffers[bufno] + offset), w); 201026dcc2a3Smacallan dst += dstwidth; 201126dcc2a3Smacallan bufno = nextbuf; 201226dcc2a3Smacallan } 201326dcc2a3Smacallan SYNCMTE; 201426dcc2a3Smacallan copyRGBAtoARGB((uint32_t *)dst, 201526dcc2a3Smacallan (uint32_t *)(fPtr->buffers[bufno] + offset), w); 201626dcc2a3Smacallan DONE(CRIME_DEBUG_IMAGEREAD); 201726dcc2a3Smacallan 201834c4e112Smacallan} 201929406fd8Smacallan 2020e1ea03a3Smacallanint 2021e1ea03a3SmacallanCrimeAccelInit(ScrnInfoPtr pScrn) 2022e1ea03a3Smacallan{ 2023e1ea03a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 2024e1ea03a3Smacallan XAAInfoRecPtr pXAAInfo = fPtr->pXAA; 2025e1ea03a3Smacallan int i; 2026e1ea03a3Smacallan 2027e1ea03a3Smacallan for (i = 0; i < 0x1000; i++) regcache[i] = 0x12345678; 2028e1ea03a3Smacallan LOG(CRIME_DEBUG_ALL); 2029e1ea03a3Smacallan SYNC; 2030e1ea03a3Smacallan WRITE4(CRIME_DE_MODE_DST, DE_MODE_TLB_A | DE_MODE_BUFDEPTH_32 | 2031e1ea03a3Smacallan DE_MODE_TYPE_RGBA | DE_MODE_PIXDEPTH_32); 2032e1ea03a3Smacallan 2033e1ea03a3Smacallan WRITE4(CRIME_DE_XFER_STEP_Y, 1); 203426dcc2a3Smacallan WRITE4(CRIME_DE_XFER_STRD_DST, 4); 2035e1ea03a3Smacallan WRITE4(CRIME_DE_XFER_STRD_SRC, 1); 2036e1ea03a3Smacallan 2037e1ea03a3Smacallan WRITE4(CRIME_MTE_BYTEMASK, 0xffffffff); 2038e1ea03a3Smacallan WRITE4(CRIME_MTE_SRC_Y_STEP, 4); 2039e1ea03a3Smacallan WRITE4(CRIME_MTE_DST_Y_STEP, 4); 204026dcc2a3Smacallan SYNC; 2041e1ea03a3Smacallan 2042e1ea03a3Smacallan /* blit the screen black */ 2043e1ea03a3Smacallan WRITE4(CRIME_DE_DRAWMODE, 2044e1ea03a3Smacallan DE_DRAWMODE_PLANEMASK | DE_DRAWMODE_BYTEMASK | DE_DRAWMODE_ROP); 2045e1ea03a3Smacallan WRITE4(CRIME_DE_ROP, 3); 2046e1ea03a3Smacallan WRITE4(CRIME_DE_PRIMITIVE, DE_PRIM_RECTANGLE | DE_PRIM_LR | DE_PRIM_TB); 2047e1ea03a3Smacallan WRITE4(CRIME_DE_FG, 0); 2048e1ea03a3Smacallan WRITE4(CRIME_DE_X_VERTEX_0, 0); 2049e1ea03a3Smacallan WRITE4ST(CRIME_DE_X_VERTEX_1, 2050e1ea03a3Smacallan fPtr->info.width << 16 | fPtr->info.height); 2051e1ea03a3Smacallan SYNC; 2052e1ea03a3Smacallan 205334c4e112Smacallan pXAAInfo->Flags = /*LINEAR_FRAMEBUFFER |*/ PIXMAP_CACHE | OFFSCREEN_PIXMAPS; 2054e1ea03a3Smacallan pXAAInfo->maxOffPixWidth = fPtr->info.width; 2055e1ea03a3Smacallan pXAAInfo->maxOffPixHeight = 2048; 2056e1ea03a3Smacallan 2057e1ea03a3Smacallan /* Sync */ 2058e1ea03a3Smacallan pXAAInfo->Sync = CrimeSync; 2059e1ea03a3Smacallan 20608e5567ffSmacallan CrimeDisableClipping(pScrn); 20618e5567ffSmacallan 2062e1ea03a3Smacallan /* Screen-to-screen copy */ 2063e1ea03a3Smacallan pXAAInfo->ScreenToScreenCopyFlags = NO_TRANSPARENCY; 2064e1ea03a3Smacallan pXAAInfo->SetupForScreenToScreenCopy = CrimeSetupForScreenToScreenCopy; 2065e1ea03a3Smacallan pXAAInfo->SubsequentScreenToScreenCopy = 2066e1ea03a3Smacallan CrimeSubsequentScreenToScreenCopy; 2067e1ea03a3Smacallan 2068e1ea03a3Smacallan /* rectangle fills */ 2069e1ea03a3Smacallan pXAAInfo->SetupForSolidFill = CrimeSetupForSolidFill; 2070e1ea03a3Smacallan pXAAInfo->SubsequentSolidFillRect = CrimeSubsequentSolidFillRect; 2071e1ea03a3Smacallan 2072e1ea03a3Smacallan /* image writes */ 2073e1ea03a3Smacallan pXAAInfo->ScanlineImageWriteFlags = 2074e1ea03a3Smacallan NO_TRANSPARENCY | LEFT_EDGE_CLIPPING | 2075e1ea03a3Smacallan LEFT_EDGE_CLIPPING_NEGATIVE_X | 2076e1ea03a3Smacallan CPU_TRANSFER_PAD_DWORD | SCANLINE_PAD_DWORD; 2077e1ea03a3Smacallan pXAAInfo->NumScanlineImageWriteBuffers = 8; 2078e1ea03a3Smacallan for (i = 0; i < 8; i++) 2079e1ea03a3Smacallan fPtr->buffers[i] = fPtr->linear + (i * 8192); 2080e1ea03a3Smacallan pXAAInfo->ScanlineImageWriteBuffers = fPtr->buffers; 2081e1ea03a3Smacallan pXAAInfo->SetupForScanlineImageWrite = 2082e1ea03a3Smacallan CrimeSetupForScanlineImageWrite; 2083e1ea03a3Smacallan pXAAInfo->SubsequentScanlineImageWriteRect = 2084e1ea03a3Smacallan CrimeSubsequentImageWriteRect; 2085e1ea03a3Smacallan pXAAInfo->SubsequentImageWriteScanline = 2086e1ea03a3Smacallan CrimeSubsequentImageWriteScanline; 2087e1ea03a3Smacallan 208834c4e112Smacallan /* read pixmap */ 208934c4e112Smacallan pXAAInfo->ReadPixmapFlags = 0 209034c4e112Smacallan | CPU_TRANSFER_PAD_DWORD 209134c4e112Smacallan ; 209234c4e112Smacallan pXAAInfo->ReadPixmap = CrimeReadPixmap; 209334c4e112Smacallan 2094e1ea03a3Smacallan /* colour expansion */ 2095e1ea03a3Smacallan pXAAInfo->ScanlineCPUToScreenColorExpandFillFlags = 2096e1ea03a3Smacallan LEFT_EDGE_CLIPPING; 2097e1ea03a3Smacallan pXAAInfo->NumScanlineColorExpandBuffers = 1; 2098e1ea03a3Smacallan fPtr->expandbuffers[0] = (uint8_t *)fPtr->expand; 2099e1ea03a3Smacallan pXAAInfo->ScanlineColorExpandBuffers = (void *)&fPtr->expandbuffers; 2100e1ea03a3Smacallan pXAAInfo->SetupForScanlineCPUToScreenColorExpandFill = 2101e1ea03a3Smacallan CrimeSetupForCPUToScreenColorExpandFill; 2102e1ea03a3Smacallan pXAAInfo->SubsequentScanlineCPUToScreenColorExpandFill = 2103e1ea03a3Smacallan CrimeSubsequentScanlineCPUToScreenColorExpandFill; 2104e1ea03a3Smacallan pXAAInfo->SubsequentColorExpandScanline = 2105e1ea03a3Smacallan CrimeSubsequentColorExpandScanline; 2106e1ea03a3Smacallan 2107e1ea03a3Smacallan /* clipping */ 2108e1ea03a3Smacallan pXAAInfo->ClippingFlags = HARDWARE_CLIP_SCREEN_TO_SCREEN_COPY | 21097a6652bbSmacallan HARDWARE_CLIP_SOLID_FILL | 21107a6652bbSmacallan HARDWARE_CLIP_SOLID_LINE | 21115b2650b9Smacallan HARDWARE_CLIP_MONO_8x8_FILL | HARDWARE_CLIP_DASHED_LINE; 2112e1ea03a3Smacallan pXAAInfo->SetClippingRectangle = CrimeSetClippingRectangle; 2113e1ea03a3Smacallan pXAAInfo->DisableClipping = CrimeDisableClipping; 2114e1ea03a3Smacallan 2115e1ea03a3Smacallan /* solid line drawing */ 2116e1ea03a3Smacallan pXAAInfo->SetupForSolidLine = CrimeSetupForSolidLine; 2117e1ea03a3Smacallan pXAAInfo->SubsequentSolidTwoPointLine = 2118e1ea03a3Smacallan CrimeSubsequentSolidTwoPointLine; 21195b2650b9Smacallan pXAAInfo->SolidLineFlags = 0; 2120e1ea03a3Smacallan 2121e1ea03a3Smacallan /* dashed line drawing */ 2122e1ea03a3Smacallan pXAAInfo->SetupForDashedLine = CrimeSetupForDashedLine; 2123e1ea03a3Smacallan pXAAInfo->SubsequentDashedTwoPointLine = 2124e1ea03a3Smacallan CrimeSubsequentDashedTwoPointLine; 2125e1ea03a3Smacallan pXAAInfo->DashedLineFlags = LINE_PATTERN_MSBFIRST_MSBJUSTIFIED; 2126e1ea03a3Smacallan pXAAInfo->DashPatternMaxLength = 32; 2127e1ea03a3Smacallan 21285b2650b9Smacallan /* mono pattern fills */ 21295b2650b9Smacallan pXAAInfo->Mono8x8PatternFillFlags = HARDWARE_PATTERN_PROGRAMMED_BITS | 21305b2650b9Smacallan HARDWARE_PATTERN_PROGRAMMED_ORIGIN | BIT_ORDER_IN_BYTE_MSBFIRST; 21315b2650b9Smacallan pXAAInfo->SetupForMono8x8PatternFill = CrimeSetupForMono8x8PatternFill; 21325b2650b9Smacallan pXAAInfo->SubsequentMono8x8PatternFillRect = 21335b2650b9Smacallan CrimeSubsequentMono8x8PatternFillRect; 21345b2650b9Smacallan 2135e1ea03a3Smacallan /* XRender acceleration */ 2136e1ea03a3Smacallan#ifdef RENDER 2137e1ea03a3Smacallan pXAAInfo->CPUToScreenAlphaTextureFlags = 0; 2138e1ea03a3Smacallan pXAAInfo->SetupForCPUToScreenAlphaTexture = 2139e1ea03a3Smacallan CrimeSetupForCPUToScreenAlphaTexture; 2140e1ea03a3Smacallan pXAAInfo->SubsequentCPUToScreenAlphaTexture = 2141e1ea03a3Smacallan CrimeSubsequentCPUToScreenAlphaTexture; 2142e1ea03a3Smacallan pXAAInfo->CPUToScreenAlphaTextureFormats = CrimeAlphaTextureFormats; 2143e1ea03a3Smacallan 2144e1ea03a3Smacallan pXAAInfo->SetupForCPUToScreenTexture = CrimeSetupForCPUToScreenTexture; 2145e1ea03a3Smacallan pXAAInfo->SubsequentCPUToScreenTexture = 2146e1ea03a3Smacallan CrimeSubsequentCPUToScreenTexture; 2147e1ea03a3Smacallan pXAAInfo->CPUToScreenTextureFlags = 0; 2148e1ea03a3Smacallan pXAAInfo->CPUToScreenTextureFormats = CrimeTextureFormats; 2149e1ea03a3Smacallan pXAAInfo->Composite = CrimeComposite; 215029406fd8Smacallan pXAAInfo->Glyphs = CrimeGlyphs; 2151e1ea03a3Smacallan#endif 2152e1ea03a3Smacallan pXAAInfo->ValidatePolyPoint = CrimeValidatePolyPoint; 2153e1ea03a3Smacallan pXAAInfo->PolyPointMask = GCFunction; 215434c4e112Smacallan pXAAInfo->ValidatePolyArc = CrimeValidatePolyArc; 215534c4e112Smacallan pXAAInfo->PolyArcMask = GCFunction | GCLineWidth; 2156e1ea03a3Smacallan 2157e1ea03a3Smacallan return -1; 2158e1ea03a3Smacallan} 2159