crime_accel.c revision 8e5567ff
18e5567ffSmacallan/* $NetBSD: crime_accel.c,v 1.7 2009/04/01 14:58:03 macallan Exp $ */ 2e1ea03a3Smacallan/* 3e1ea03a3Smacallan * Copyright (c) 2008 Michael Lorenz 4e1ea03a3Smacallan * All rights reserved. 5e1ea03a3Smacallan * 6e1ea03a3Smacallan * Redistribution and use in source and binary forms, with or without 7e1ea03a3Smacallan * modification, are permitted provided that the following conditions 8e1ea03a3Smacallan * are met: 9e1ea03a3Smacallan * 10e1ea03a3Smacallan * - Redistributions of source code must retain the above copyright 11e1ea03a3Smacallan * notice, this list of conditions and the following disclaimer. 12e1ea03a3Smacallan * - Redistributions in binary form must reproduce the above 13e1ea03a3Smacallan * copyright notice, this list of conditions and the following 14e1ea03a3Smacallan * disclaimer in the documentation and/or other materials provided 15e1ea03a3Smacallan * with the distribution. 16e1ea03a3Smacallan * 17e1ea03a3Smacallan * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18e1ea03a3Smacallan * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19e1ea03a3Smacallan * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 20e1ea03a3Smacallan * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 21e1ea03a3Smacallan * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 22e1ea03a3Smacallan * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 23e1ea03a3Smacallan * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24e1ea03a3Smacallan * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25e1ea03a3Smacallan * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26e1ea03a3Smacallan * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 27e1ea03a3Smacallan * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28e1ea03a3Smacallan * POSSIBILITY OF SUCH DAMAGE. 29e1ea03a3Smacallan * 30e1ea03a3Smacallan */ 31e1ea03a3Smacallan 32e1ea03a3Smacallan/* a driver for the CRIME rendering engine foundin SGI O2 workstations */ 33e1ea03a3Smacallan 34e1ea03a3Smacallan#include "crime.h" 35e1ea03a3Smacallan#include "picturestr.h" 36e1ea03a3Smacallan#include "xaalocal.h" 37e1ea03a3Smacallan 38e1ea03a3Smacallanuint32_t regcache[0x1000]; 39e1ea03a3Smacallan 40e1ea03a3Smacallan#define CRIMEREG(p) (volatile uint32_t *)(fPtr->engine + p) 41e1ea03a3Smacallan/*#define WBFLUSH { volatile uint32_t boo = *CRIMEREG(0x4000); }*/ 42e1ea03a3Smacallan#define WBFLUSH __asm__ ("nop; sync;") 43e1ea03a3Smacallan#if 0 44e1ea03a3Smacallan#define WRITE4(r, v) {if (regcache[r >> 2] != v) { \ 45e1ea03a3Smacallan *CRIMEREG(r) = v; \ 46e1ea03a3Smacallan regcache[r >> 2] = v; } } 47e1ea03a3Smacallan#else 48e1ea03a3Smacallan#define WRITE4(r, v) { *CRIMEREG(r) = v; } 49e1ea03a3Smacallan#endif 50e1ea03a3Smacallan#define WRITE4ST(r, v) {WBFLUSH; *CRIMEREG(r + CRIME_DE_START) = v; WBFLUSH;} 51e1ea03a3Smacallan#ifdef DEBUG 52e1ea03a3Smacallan#define SYNC { int bail = 0; do {bail++; } \ 53e1ea03a3Smacallan while(((*CRIMEREG(0x4000) & CRIME_DE_IDLE) == 0) && (bail < 10000000)); \ 54e1ea03a3Smacallan if (bail == 10000000) { \ 55e1ea03a3Smacallan xf86Msg(X_ERROR, "sync timeout\n"); \ 56e1ea03a3Smacallan WRITE4ST(CRIME_MTE_FLUSH, 0); \ 57e1ea03a3Smacallan WRITE4ST(CRIME_DE_FLUSH, 0); \ 58e1ea03a3Smacallan } \ 59e1ea03a3Smacallan } 60e1ea03a3Smacallan#else 61e1ea03a3Smacallan#define SYNC do {} while ((*CRIMEREG(0x4000) & CRIME_DE_IDLE) == 0) 6226dcc2a3Smacallan#define SYNCMTE do {} while ((*CRIMEREG(0x4000) & CRIME_DE_MTE_IDLE) == 0) 63e1ea03a3Smacallan#endif 6426dcc2a3Smacallan#define MAKE_ROOM(x) do {} while ((16 - \ 6526dcc2a3Smacallan CRIME_PIPE_LEVEL(*CRIMEREG(0x4000))) < x); 66e1ea03a3Smacallan 67e1ea03a3SmacallanCARD32 CrimeAlphaTextureFormats[] = {PICT_a8, 0}; 68e1ea03a3SmacallanCARD32 CrimeTextureFormats[] = {PICT_a8b8g8r8, PICT_a8r8g8b8, 0}; 69e1ea03a3Smacallan 70e1ea03a3Smacallanvoid 71e1ea03a3SmacallanCrimeSync(ScrnInfoPtr pScrn) 72e1ea03a3Smacallan{ 73e1ea03a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 74e1ea03a3Smacallan#ifdef CRIME_DEBUG_LOUD 75e1ea03a3Smacallan volatile uint32_t *status = CRIMEREG(CRIME_DE_STATUS); 76e1ea03a3Smacallan 77e1ea03a3Smacallan xf86Msg(X_ERROR, "%s: %08x\n", __func__, *status); 78e1ea03a3Smacallan#endif 79e1ea03a3Smacallan LOG(CRIME_DEBUG_SYNC); 80e1ea03a3Smacallan SYNC; 81e1ea03a3Smacallan} 82e1ea03a3Smacallan 83e1ea03a3Smacallanstatic void 84e1ea03a3SmacallanCrimeSetupForScreenToScreenCopy( 85e1ea03a3Smacallan ScrnInfoPtr pScrn, 86e1ea03a3Smacallan int xdir, 87e1ea03a3Smacallan int ydir, 88e1ea03a3Smacallan int rop, 89e1ea03a3Smacallan unsigned int planemask, 90e1ea03a3Smacallan int TransparencyColour 91e1ea03a3Smacallan) 92e1ea03a3Smacallan{ 93e1ea03a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 94e1ea03a3Smacallan 95e1ea03a3Smacallan LOG(CRIME_DEBUG_BITBLT); 9626dcc2a3Smacallan MAKE_ROOM(9); 97e1ea03a3Smacallan#if 0 98e1ea03a3Smacallan if ((rop == GXcopy) && (planemask == 0xffffffff) && (xdir > 0)) { 99e1ea03a3Smacallan /* use the MTE */ 100e1ea03a3Smacallan WRITE4(CRIME_MTE_MODE, MTE_MODE_DST_ECC | 101e1ea03a3Smacallan MTE_TLB_A << MTE_DST_TLB_SHIFT | 102e1ea03a3Smacallan MTE_TLB_A << MTE_SRC_TLB_SHIFT | 103e1ea03a3Smacallan MTE_DEPTH_32 << MTE_DEPTH_SHIFT | 104e1ea03a3Smacallan MTE_MODE_COPY); 105e1ea03a3Smacallan fPtr->use_mte = 1; 106e1ea03a3Smacallan if (ydir > 0) { 107e1ea03a3Smacallan WRITE4(CRIME_MTE_DST_Y_STEP, 1); 108e1ea03a3Smacallan WRITE4(CRIME_MTE_SRC_Y_STEP, 1); 109e1ea03a3Smacallan } else { 110e1ea03a3Smacallan WRITE4(CRIME_MTE_DST_Y_STEP, -1); 111e1ea03a3Smacallan WRITE4(CRIME_MTE_SRC_Y_STEP, -1); 112e1ea03a3Smacallan } 113e1ea03a3Smacallan } else 114e1ea03a3Smacallan#endif 115e1ea03a3Smacallan fPtr->use_mte = 0; 116e1ea03a3Smacallan 117e1ea03a3Smacallan WRITE4(CRIME_DE_XFER_STEP_X, 1); 118e1ea03a3Smacallan WRITE4(CRIME_DE_PLANEMASK, planemask); 119e1ea03a3Smacallan WRITE4(CRIME_DE_ROP, rop); 120e1ea03a3Smacallan WRITE4(CRIME_DE_DRAWMODE, 121e1ea03a3Smacallan DE_DRAWMODE_PLANEMASK | DE_DRAWMODE_BYTEMASK | 122e1ea03a3Smacallan DE_DRAWMODE_ROP | DE_DRAWMODE_XFER_EN); 123e1ea03a3Smacallan WRITE4(CRIME_DE_MODE_SRC, DE_MODE_TLB_A | DE_MODE_BUFDEPTH_32 | 124e1ea03a3Smacallan DE_MODE_TYPE_RGBA | DE_MODE_PIXDEPTH_32); 12526dcc2a3Smacallan WRITE4(CRIME_DE_MODE_DST, DE_MODE_TLB_A | DE_MODE_BUFDEPTH_32 | 12626dcc2a3Smacallan DE_MODE_TYPE_RGBA | DE_MODE_PIXDEPTH_32); 127e1ea03a3Smacallan fPtr->xdir = xdir; 128e1ea03a3Smacallan fPtr->ydir = ydir; 12926dcc2a3Smacallan SYNC; 130e1ea03a3Smacallan DONE(CRIME_DEBUG_BITBLT); 131e1ea03a3Smacallan} 132e1ea03a3Smacallan 133e1ea03a3Smacallanstatic void 134e1ea03a3SmacallanCrimeSubsequentScreenToScreenCopy 135e1ea03a3Smacallan( 136e1ea03a3Smacallan ScrnInfoPtr pScrn, 137e1ea03a3Smacallan int xSrc, 138e1ea03a3Smacallan int ySrc, 139e1ea03a3Smacallan int xDst, 140e1ea03a3Smacallan int yDst, 141e1ea03a3Smacallan int w, 142e1ea03a3Smacallan int h 143e1ea03a3Smacallan) 144e1ea03a3Smacallan{ 145e1ea03a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 146e1ea03a3Smacallan uint32_t prim = DE_PRIM_RECTANGLE; 147e1ea03a3Smacallan volatile uint32_t reg, oreg; 148e1ea03a3Smacallan uint32_t rxa, rya, rxe, rye, rxs, rys, rxd, ryd, rxde, ryde; 149e1ea03a3Smacallan 150e1ea03a3Smacallan LOG(CRIME_DEBUG_BITBLT); 151e1ea03a3Smacallan#ifdef CRIME_DEBUG_LOUD 152e1ea03a3Smacallan xf86Msg(X_ERROR, "%s: %d, %d; %d x %d -> %d %d\n", __func__, 153e1ea03a3Smacallan xSrc, ySrc, w, h, xDst, yDst); 154e1ea03a3Smacallan#endif 155e1ea03a3Smacallan 156e1ea03a3Smacallan if ((fPtr->use_mte) && (w > 64) && ((w & 3) == 0) && ((xSrc & 3) == 0) && ((xDst & 3) == 0)) { 157e1ea03a3Smacallan if (fPtr->ydir == -1) { 158e1ea03a3Smacallan /* bottom to top */ 159e1ea03a3Smacallan rye = ySrc; 160e1ea03a3Smacallan rya = ySrc + h - 1; 161e1ea03a3Smacallan ryd = yDst + h - 1; 162e1ea03a3Smacallan ryde = yDst; 163e1ea03a3Smacallan } else { 164e1ea03a3Smacallan /* top to bottom */ 165e1ea03a3Smacallan rye = ySrc + h - 1; 166e1ea03a3Smacallan rya = ySrc; 167e1ea03a3Smacallan ryd = yDst; 168e1ea03a3Smacallan ryde = yDst + h - 1; 169e1ea03a3Smacallan } 170e1ea03a3Smacallan rxa = xSrc << 2; 171e1ea03a3Smacallan rxe = ((xSrc + w) << 2) - 1; 172e1ea03a3Smacallan rxd = xDst << 2; 173e1ea03a3Smacallan rxde = ((xDst + w) << 2) - 1; 174e1ea03a3Smacallan oreg = *CRIMEREG(0x4000); 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 reg = *CRIMEREG(0x4000); 181e1ea03a3Smacallan 182e1ea03a3Smacallan#ifdef CRIME_DEBUG_LOUD 183e1ea03a3Smacallan xf86Msg(X_ERROR, "reg: %08x %08x\n", oreg, reg); 184e1ea03a3Smacallan#endif 185e1ea03a3Smacallan } else { 186e1ea03a3Smacallan if (fPtr->xdir == -1) { 187e1ea03a3Smacallan prim |= DE_PRIM_RL; 188e1ea03a3Smacallan rxe = xDst; 189e1ea03a3Smacallan rxa = xDst + w - 1; 190e1ea03a3Smacallan rxs = xSrc + w - 1; 191e1ea03a3Smacallan } else { 192e1ea03a3Smacallan prim |= DE_PRIM_LR; 193e1ea03a3Smacallan rxe = xDst + w - 1; 194e1ea03a3Smacallan rxa = xDst; 195e1ea03a3Smacallan rxs = xSrc; 196e1ea03a3Smacallan } 197e1ea03a3Smacallan if (fPtr->ydir == -1) { 198e1ea03a3Smacallan prim |= DE_PRIM_BT; 199e1ea03a3Smacallan rye = yDst; 200e1ea03a3Smacallan rya = yDst + h - 1; 201e1ea03a3Smacallan rys = ySrc + h - 1; 202e1ea03a3Smacallan } else { 203e1ea03a3Smacallan prim |= DE_PRIM_TB; 204e1ea03a3Smacallan rye = yDst + h - 1; 205e1ea03a3Smacallan rya = yDst; 206e1ea03a3Smacallan rys = ySrc; 207e1ea03a3Smacallan } 208e1ea03a3Smacallan 20926dcc2a3Smacallan MAKE_ROOM(4); 210e1ea03a3Smacallan WRITE4(CRIME_DE_PRIMITIVE, prim); 211e1ea03a3Smacallan WRITE4(CRIME_DE_XFER_ADDR_SRC,(rxs << 16) | (rys & 0xffff)); 212e1ea03a3Smacallan WRITE4(CRIME_DE_X_VERTEX_0, (rxa << 16) | (rya & 0xffff)); 213e1ea03a3Smacallan WRITE4ST(CRIME_DE_X_VERTEX_1, (rxe << 16) | (rye & 0xffff)); 214e1ea03a3Smacallan } 215e1ea03a3Smacallan DONE(CRIME_DEBUG_BITBLT); 216e1ea03a3Smacallan} 217e1ea03a3Smacallan 218e1ea03a3Smacallanstatic void 219e1ea03a3SmacallanCrimeSetupForSolidFill 220e1ea03a3Smacallan( 221e1ea03a3Smacallan ScrnInfoPtr pScrn, 222e1ea03a3Smacallan int colour, 223e1ea03a3Smacallan int rop, 224e1ea03a3Smacallan unsigned int planemask 225e1ea03a3Smacallan) 226e1ea03a3Smacallan{ 227e1ea03a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 228e1ea03a3Smacallan int i; 229e1ea03a3Smacallan 230e1ea03a3Smacallan LOG(CRIME_DEBUG_RECTFILL); 23126dcc2a3Smacallan MAKE_ROOM(7); 232e1ea03a3Smacallan WRITE4(CRIME_DE_PLANEMASK, planemask); 233e1ea03a3Smacallan WRITE4(CRIME_DE_ROP, rop); 234e1ea03a3Smacallan WRITE4(CRIME_DE_FG, colour << 8); 235e1ea03a3Smacallan WRITE4(CRIME_DE_DRAWMODE, 23693351543Smacallan DE_DRAWMODE_PLANEMASK | DE_DRAWMODE_BYTEMASK | DE_DRAWMODE_ROP | 23793351543Smacallan DE_DRAWMODE_SCISSOR_EN); 238e1ea03a3Smacallan WRITE4(CRIME_DE_PRIMITIVE, 239e1ea03a3Smacallan DE_PRIM_RECTANGLE | DE_PRIM_LR | DE_PRIM_TB); 24026dcc2a3Smacallan WRITE4(CRIME_DE_MODE_DST, DE_MODE_TLB_A | DE_MODE_BUFDEPTH_32 | 24126dcc2a3Smacallan DE_MODE_TYPE_RGBA | DE_MODE_PIXDEPTH_32); 24226dcc2a3Smacallan SYNC; 243e1ea03a3Smacallan DONE(CRIME_DEBUG_RECTFILL); 244e1ea03a3Smacallan} 245e1ea03a3Smacallan 246e1ea03a3Smacallanstatic void 247e1ea03a3SmacallanCrimeSubsequentSolidFillRect 248e1ea03a3Smacallan( 249e1ea03a3Smacallan ScrnInfoPtr pScrn, 250e1ea03a3Smacallan int x, 251e1ea03a3Smacallan int y, 252e1ea03a3Smacallan int w, 253e1ea03a3Smacallan int h 254e1ea03a3Smacallan) 255e1ea03a3Smacallan{ 256e1ea03a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 257e1ea03a3Smacallan 258e1ea03a3Smacallan LOG(CRIME_DEBUG_RECTFILL); 25926dcc2a3Smacallan MAKE_ROOM(2); 260e1ea03a3Smacallan WRITE4(CRIME_DE_X_VERTEX_0, (x << 16) | (y & 0xffff)); 261e1ea03a3Smacallan WRITE4ST(CRIME_DE_X_VERTEX_1, 262e1ea03a3Smacallan ((x + w - 1) << 16) | ((y + h - 1) & 0xffff)); 263e1ea03a3Smacallan DONE(CRIME_DEBUG_RECTFILL); 264e1ea03a3Smacallan} 265e1ea03a3Smacallan 2665b2650b9Smacallanstatic void 2675b2650b9SmacallanCrimeSetupForMono8x8PatternFill(ScrnInfoPtr pScrn, int patx, int paty, 2685b2650b9Smacallan int fg, int bg, int rop, unsigned int planemask) 2695b2650b9Smacallan{ 2705b2650b9Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 2715b2650b9Smacallan uint32_t pat; 2725b2650b9Smacallan 2735b2650b9Smacallan LOG(CRIME_DEBUG_RECTFILL); 2745b2650b9Smacallan MAKE_ROOM(7); 2755b2650b9Smacallan WRITE4(CRIME_DE_PLANEMASK, planemask); 2765b2650b9Smacallan WRITE4(CRIME_DE_ROP, rop); 2775b2650b9Smacallan WRITE4(CRIME_DE_FG, fg << 8); 2785b2650b9Smacallan if (bg == -1) { 2795b2650b9Smacallan WRITE4(CRIME_DE_DRAWMODE, 2805b2650b9Smacallan DE_DRAWMODE_PLANEMASK | DE_DRAWMODE_BYTEMASK | 2815b2650b9Smacallan DE_DRAWMODE_ROP | DE_DRAWMODE_POLY_STIP | 2825b2650b9Smacallan DE_DRAWMODE_SCISSOR_EN); 2835b2650b9Smacallan } else { 2845b2650b9Smacallan WRITE4(CRIME_DE_BG, bg << 8); 2855b2650b9Smacallan WRITE4(CRIME_DE_DRAWMODE, 2865b2650b9Smacallan DE_DRAWMODE_PLANEMASK | DE_DRAWMODE_BYTEMASK | 2875b2650b9Smacallan DE_DRAWMODE_ROP | DE_DRAWMODE_POLY_STIP | 2885b2650b9Smacallan DE_DRAWMODE_OPAQUE_STIP | DE_DRAWMODE_SCISSOR_EN); 2895b2650b9Smacallan } 2905b2650b9Smacallan WRITE4(CRIME_DE_PRIMITIVE, 2915b2650b9Smacallan DE_PRIM_RECTANGLE | DE_PRIM_LR | DE_PRIM_TB); 2925b2650b9Smacallan WRITE4(CRIME_DE_MODE_DST, DE_MODE_TLB_A | DE_MODE_BUFDEPTH_32 | 2935b2650b9Smacallan DE_MODE_TYPE_RGBA | DE_MODE_PIXDEPTH_32); 2945b2650b9Smacallan 2955b2650b9Smacallan /* 2965b2650b9Smacallan * we need to store the pattern so we can just hammer it into the 2975b2650b9Smacallan * stipple register later on 2985b2650b9Smacallan */ 2995b2650b9Smacallan pat = patx & 0xff000000; 3005b2650b9Smacallan pat |= pat >> 8; 3015b2650b9Smacallan fPtr->pattern[0] = pat | (pat >> 16); 3025b2650b9Smacallan pat = patx & 0x00ff0000; 3035b2650b9Smacallan pat |= pat << 8; 3045b2650b9Smacallan fPtr->pattern[1] = pat | (pat >> 16); 3055b2650b9Smacallan pat = patx & 0x0000ff00; 3065b2650b9Smacallan pat |= pat >> 8; 3075b2650b9Smacallan fPtr->pattern[2] = pat | (pat << 16); 3085b2650b9Smacallan pat = patx & 0x000000ff; 3095b2650b9Smacallan pat |= pat << 8; 3105b2650b9Smacallan fPtr->pattern[3] = pat | (pat << 16); 3115b2650b9Smacallan 3125b2650b9Smacallan pat = paty & 0xff000000; 3135b2650b9Smacallan pat |= pat >> 8; 3145b2650b9Smacallan fPtr->pattern[4] = pat | (pat >> 16); 3155b2650b9Smacallan pat = paty & 0x00ff0000; 3165b2650b9Smacallan pat |= pat << 8; 3175b2650b9Smacallan fPtr->pattern[5] = pat | (pat >> 16); 3185b2650b9Smacallan pat = paty & 0x0000ff00; 3195b2650b9Smacallan pat |= pat >> 8; 3205b2650b9Smacallan fPtr->pattern[6] = pat | (pat << 16); 3215b2650b9Smacallan pat = paty & 0x000000ff; 3225b2650b9Smacallan pat |= pat << 8; 3235b2650b9Smacallan fPtr->pattern[7] = pat | (pat << 16); 3245b2650b9Smacallan SYNC; 3255b2650b9Smacallan DONE(CRIME_DEBUG_RECTFILL); 3265b2650b9Smacallan} 3275b2650b9Smacallan 3285b2650b9Smacallanstatic void 3295b2650b9SmacallanCrimeSubsequentMono8x8PatternFillRect( ScrnInfoPtr pScrn, 3305b2650b9Smacallan int patx, int paty, int x, int y, int w, int h) 3315b2650b9Smacallan{ 3325b2650b9Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 3335b2650b9Smacallan int i, pat; 3345b2650b9Smacallan 3355b2650b9Smacallan LOG(CRIME_DEBUG_RECTFILL); 3365b2650b9Smacallan 3375b2650b9Smacallan /* first setup the stipple stuff */ 3385b2650b9Smacallan 3395b2650b9Smacallan MAKE_ROOM(1); 3405b2650b9Smacallan WRITE4(CRIME_DE_STIPPLE_MODE, 0x001f0000 | (patx << 24)); 3415b2650b9Smacallan pat = paty; 3425b2650b9Smacallan 3435b2650b9Smacallan for (i = 0; i < h; i++) { 3445b2650b9Smacallan MAKE_ROOM(3); 3455b2650b9Smacallan WRITE4(CRIME_DE_STIPPLE_PAT, fPtr->pattern[pat]); 3465b2650b9Smacallan WRITE4(CRIME_DE_X_VERTEX_0, (x << 16) | ((y + i) & 0xffff)); 3475b2650b9Smacallan WRITE4ST(CRIME_DE_X_VERTEX_1, 3485b2650b9Smacallan ((x + w - 1) << 16) | ((y + i) & 0xffff)); 3495b2650b9Smacallan pat = (pat + 1) & 7; 3505b2650b9Smacallan } 3515b2650b9Smacallan DONE(CRIME_DEBUG_RECTFILL); 3525b2650b9Smacallan} 3535b2650b9Smacallan 3545b2650b9Smacallanstatic void 355e1ea03a3SmacallanCrimeSetupForScanlineImageWrite(ScrnInfoPtr pScrn, int rop, 356e1ea03a3Smacallan unsigned int planemask, int trans_color, 357e1ea03a3Smacallan int bpp, int depth) 358e1ea03a3Smacallan{ 359e1ea03a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 360e1ea03a3Smacallan 361e1ea03a3Smacallan LOG(CRIME_DEBUG_IMAGEWRITE); 362e1ea03a3Smacallan#ifdef CRIME_DEBUG_LOUD 363e1ea03a3Smacallan if ((bpp == 24) || (depth == 24)) 364e1ea03a3Smacallan xf86Msg(X_ERROR, "%s: %d %d \n", __func__, bpp, depth); 365e1ea03a3Smacallan#endif 36626dcc2a3Smacallan MAKE_ROOM(7); 367e1ea03a3Smacallan WRITE4(CRIME_DE_MODE_SRC, DE_MODE_LIN_A | DE_MODE_BUFDEPTH_32 | 368e1ea03a3Smacallan DE_MODE_TYPE_RGB | DE_MODE_PIXDEPTH_32); 36926dcc2a3Smacallan WRITE4(CRIME_DE_MODE_DST, DE_MODE_TLB_A | DE_MODE_BUFDEPTH_32 | 37026dcc2a3Smacallan DE_MODE_TYPE_RGBA | DE_MODE_PIXDEPTH_32); 371e1ea03a3Smacallan WRITE4(CRIME_DE_PLANEMASK, planemask); 372e1ea03a3Smacallan WRITE4(CRIME_DE_XFER_STEP_X, 4); 373e1ea03a3Smacallan WRITE4(CRIME_DE_ROP, rop); 374e1ea03a3Smacallan WRITE4(CRIME_DE_DRAWMODE, 375e1ea03a3Smacallan DE_DRAWMODE_PLANEMASK | DE_DRAWMODE_BYTEMASK | DE_DRAWMODE_ROP | 376e1ea03a3Smacallan DE_DRAWMODE_XFER_EN); 377e1ea03a3Smacallan WRITE4(CRIME_DE_PRIMITIVE, 378e1ea03a3Smacallan DE_PRIM_RECTANGLE | DE_PRIM_LR | DE_PRIM_TB); 37926dcc2a3Smacallan SYNC; 380e1ea03a3Smacallan DONE(CRIME_DEBUG_IMAGEWRITE); 381e1ea03a3Smacallan} 382e1ea03a3Smacallan 3835b2650b9Smacallanstatic void 384e1ea03a3SmacallanCrimeSubsequentImageWriteRect(ScrnInfoPtr pScrn, 385e1ea03a3Smacallan int x, int y, int w, int h, int skipleft) 386e1ea03a3Smacallan{ 387e1ea03a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 388e1ea03a3Smacallan 389e1ea03a3Smacallan LOG(CRIME_DEBUG_IMAGEWRITE); 390e1ea03a3Smacallan 391e1ea03a3Smacallan#ifdef CRIME_DEBUG_LOUD 392e1ea03a3Smacallan xf86Msg(X_ERROR, "%s: %d %d %d %d\n", __func__, x, y, w, h); 393e1ea03a3Smacallan#endif 394e1ea03a3Smacallan 395e1ea03a3Smacallan fPtr->start = skipleft; 396e1ea03a3Smacallan x += skipleft; 397e1ea03a3Smacallan w -= skipleft; 398e1ea03a3Smacallan if (x < 0) { 399e1ea03a3Smacallan fPtr->ux = 0; 400e1ea03a3Smacallan w += x; 401e1ea03a3Smacallan fPtr->start -= x; 402e1ea03a3Smacallan } else { 403e1ea03a3Smacallan fPtr->ux = x; 404e1ea03a3Smacallan } 405e1ea03a3Smacallan fPtr->uy = y; 406e1ea03a3Smacallan fPtr->uw = w; 407e1ea03a3Smacallan fPtr->uh = h; 408e1ea03a3Smacallan DONE(CRIME_DEBUG_IMAGEWRITE); 409e1ea03a3Smacallan} 410e1ea03a3Smacallan 4115b2650b9Smacallanstatic void 412e1ea03a3SmacallanCrimeSubsequentImageWriteScanline(ScrnInfoPtr pScrn, int bufno) 413e1ea03a3Smacallan{ 414e1ea03a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 415e1ea03a3Smacallan 416e1ea03a3Smacallan LOG(CRIME_DEBUG_IMAGEWRITE); 41726dcc2a3Smacallan /* 41826dcc2a3Smacallan * we need to sync here, otherwise we might queue up more copy 41926dcc2a3Smacallan * commands than we have buffers 42026dcc2a3Smacallan */ 42134c4e112Smacallan SYNC; 422e1ea03a3Smacallan WRITE4(CRIME_DE_XFER_ADDR_SRC, (bufno << 13) + (fPtr->start << 2)); 423e1ea03a3Smacallan WRITE4(CRIME_DE_X_VERTEX_0, (fPtr->ux << 16) | fPtr->uy); 424e1ea03a3Smacallan WRITE4ST(CRIME_DE_X_VERTEX_1, 425e1ea03a3Smacallan ((fPtr->ux + fPtr->uw - 1) << 16) | (fPtr->uy)); 426e1ea03a3Smacallan fPtr->uy++; 427e1ea03a3Smacallan DONE(CRIME_DEBUG_IMAGEWRITE); 428e1ea03a3Smacallan} 429e1ea03a3Smacallan 430e1ea03a3Smacallanstatic void 431e1ea03a3SmacallanCrimeSetupForCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, 432e1ea03a3Smacallan int fg, int bg, 433e1ea03a3Smacallan int rop, 434e1ea03a3Smacallan unsigned int planemask) 435e1ea03a3Smacallan{ 436e1ea03a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 437e1ea03a3Smacallan 438e1ea03a3Smacallan LOG(CRIME_DEBUG_COLOUREXPAND); 43926dcc2a3Smacallan MAKE_ROOM(7); 44026dcc2a3Smacallan WRITE4(CRIME_DE_MODE_DST, DE_MODE_TLB_A | DE_MODE_BUFDEPTH_32 | 44126dcc2a3Smacallan DE_MODE_TYPE_RGBA | DE_MODE_PIXDEPTH_32); 442e1ea03a3Smacallan WRITE4(CRIME_DE_PLANEMASK, planemask); 443e1ea03a3Smacallan WRITE4(CRIME_DE_ROP, rop); 444e1ea03a3Smacallan WRITE4(CRIME_DE_FG, fg << 8); 445e1ea03a3Smacallan if (bg == -1) { 446e1ea03a3Smacallan /* transparent */ 447e1ea03a3Smacallan WRITE4(CRIME_DE_DRAWMODE, 448e1ea03a3Smacallan DE_DRAWMODE_PLANEMASK | DE_DRAWMODE_BYTEMASK | 449e1ea03a3Smacallan DE_DRAWMODE_ROP | DE_DRAWMODE_POLY_STIP); 450e1ea03a3Smacallan } else { 451e1ea03a3Smacallan WRITE4(CRIME_DE_BG, bg << 8); 452e1ea03a3Smacallan WRITE4(CRIME_DE_DRAWMODE, 453e1ea03a3Smacallan DE_DRAWMODE_PLANEMASK | DE_DRAWMODE_BYTEMASK | 454e1ea03a3Smacallan DE_DRAWMODE_ROP | 455e1ea03a3Smacallan DE_DRAWMODE_OPAQUE_STIP | DE_DRAWMODE_POLY_STIP); 456e1ea03a3Smacallan } 457e1ea03a3Smacallan WRITE4(CRIME_DE_PRIMITIVE, 458e1ea03a3Smacallan DE_PRIM_RECTANGLE | DE_PRIM_LR | DE_PRIM_TB); 45926dcc2a3Smacallan SYNC; 460e1ea03a3Smacallan DONE(CRIME_DEBUG_COLOUREXPAND); 461e1ea03a3Smacallan} 462e1ea03a3Smacallan 463e1ea03a3Smacallanstatic void 464e1ea03a3SmacallanCrimeSubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, 465e1ea03a3Smacallan int x, int y, int w, int h, 466e1ea03a3Smacallan int skipleft ) 467e1ea03a3Smacallan{ 468e1ea03a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 469e1ea03a3Smacallan 470e1ea03a3Smacallan LOG(CRIME_DEBUG_COLOUREXPAND); 471e1ea03a3Smacallan 472e1ea03a3Smacallan fPtr->start = skipleft; 473e1ea03a3Smacallan fPtr->ux = x; 474e1ea03a3Smacallan fPtr->uy = y; 475e1ea03a3Smacallan fPtr->uw = w; 476e1ea03a3Smacallan fPtr->uh = h; 477e1ea03a3Smacallan DONE(CRIME_DEBUG_COLOUREXPAND); 478e1ea03a3Smacallan} 479e1ea03a3Smacallan 480e1ea03a3Smacallanstatic void 481e1ea03a3SmacallanCrimeSubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno) 482e1ea03a3Smacallan{ 483e1ea03a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 484e1ea03a3Smacallan uint32_t *boo = (uint32_t *)fPtr->expandbuffers[bufno]; 485e1ea03a3Smacallan int idx = fPtr->uw, x = fPtr->ux; 486e1ea03a3Smacallan 487e1ea03a3Smacallan LOG(CRIME_DEBUG_COLOUREXPAND); 488e1ea03a3Smacallan 48926dcc2a3Smacallan MAKE_ROOM(5); 490e1ea03a3Smacallan WRITE4(CRIME_DE_STIPPLE_MODE, 0x001f0000 | (fPtr->start << 24)); 491e1ea03a3Smacallan WRITE4(CRIME_DE_STIPPLE_PAT, *boo); 492e1ea03a3Smacallan boo++; 493e1ea03a3Smacallan WRITE4(CRIME_DE_X_VERTEX_0, (x + fPtr->start << 16) | fPtr->uy); 494e1ea03a3Smacallan WRITE4ST(CRIME_DE_X_VERTEX_1, 495e1ea03a3Smacallan ((x + min(idx, 32) - 1) << 16) | (fPtr->uy)); 496e1ea03a3Smacallan idx -= 32; 497e1ea03a3Smacallan x += 32; 498e1ea03a3Smacallan WRITE4(CRIME_DE_STIPPLE_MODE, 0x001f0000); 499e1ea03a3Smacallan 500e1ea03a3Smacallan while (idx > 0) { 50126dcc2a3Smacallan MAKE_ROOM(3); 502e1ea03a3Smacallan WRITE4(CRIME_DE_STIPPLE_PAT, *boo); 503e1ea03a3Smacallan boo++; 504e1ea03a3Smacallan WRITE4(CRIME_DE_X_VERTEX_0, (x << 16) | fPtr->uy); 505e1ea03a3Smacallan WRITE4ST(CRIME_DE_X_VERTEX_1, 506e1ea03a3Smacallan ((x + min(idx, 32) - 1) << 16) | (fPtr->uy)); 507e1ea03a3Smacallan idx -= 32; 508e1ea03a3Smacallan x += 32; 509e1ea03a3Smacallan } 510e1ea03a3Smacallan fPtr->uy++; 511e1ea03a3Smacallan DONE(CRIME_DEBUG_COLOUREXPAND); 512e1ea03a3Smacallan} 513e1ea03a3Smacallan 514e1ea03a3Smacallanstatic void 515e1ea03a3SmacallanCrimeSetupForSolidLine(ScrnInfoPtr pScrn, int color, int rop, 516e1ea03a3Smacallan unsigned int planemask) 517e1ea03a3Smacallan{ 518e1ea03a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 519e1ea03a3Smacallan 520e1ea03a3Smacallan LOG(CRIME_DEBUG_LINES); 521e1ea03a3Smacallan 52226dcc2a3Smacallan MAKE_ROOM(5); 52326dcc2a3Smacallan WRITE4(CRIME_DE_MODE_DST, DE_MODE_TLB_A | DE_MODE_BUFDEPTH_32 | 52426dcc2a3Smacallan DE_MODE_TYPE_RGBA | DE_MODE_PIXDEPTH_32); 525e1ea03a3Smacallan WRITE4(CRIME_DE_PLANEMASK, planemask); 526e1ea03a3Smacallan WRITE4(CRIME_DE_ROP, rop); 527e1ea03a3Smacallan WRITE4(CRIME_DE_FG, color << 8); 528e1ea03a3Smacallan WRITE4(CRIME_DE_DRAWMODE, 529e1ea03a3Smacallan DE_DRAWMODE_PLANEMASK | DE_DRAWMODE_BYTEMASK | 53093351543Smacallan DE_DRAWMODE_ROP | DE_DRAWMODE_SCISSOR_EN); 53126dcc2a3Smacallan SYNC; 532e1ea03a3Smacallan DONE(CRIME_DEBUG_LINES); 533e1ea03a3Smacallan} 534e1ea03a3Smacallan 535e1ea03a3Smacallanstatic void 536e1ea03a3SmacallanCrimeSubsequentSolidTwoPointLine(ScrnInfoPtr pScrn, int x1, int y1, int x2, 537e1ea03a3Smacallan int y2, int flags) 538e1ea03a3Smacallan{ 539e1ea03a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 540e1ea03a3Smacallan 541e1ea03a3Smacallan LOG(CRIME_DEBUG_LINES); 54226dcc2a3Smacallan MAKE_ROOM(3); 543e1ea03a3Smacallan if (flags & OMIT_LAST) { 544e1ea03a3Smacallan WRITE4(CRIME_DE_PRIMITIVE, 545e1ea03a3Smacallan DE_PRIM_LINE | DE_PRIM_LINE_SKIP_END | 2); 546e1ea03a3Smacallan } else { 547e1ea03a3Smacallan WRITE4(CRIME_DE_PRIMITIVE, 548e1ea03a3Smacallan DE_PRIM_LINE | 2); 549e1ea03a3Smacallan } 550e1ea03a3Smacallan WRITE4(CRIME_DE_X_VERTEX_0, (x1 << 16) | y1); 551e1ea03a3Smacallan WRITE4ST(CRIME_DE_X_VERTEX_1, (x2 << 16) | y2); 552e1ea03a3Smacallan DONE(CRIME_DEBUG_LINES); 553e1ea03a3Smacallan} 554e1ea03a3Smacallan 555e1ea03a3Smacallanvoid 556e1ea03a3SmacallanCrimeSetupForDashedLine(ScrnInfoPtr pScrn, 557e1ea03a3Smacallan int fg, int bg, int rop, unsigned int planemask, 558e1ea03a3Smacallan int length, unsigned char *pattern) 559e1ea03a3Smacallan{ 560e1ea03a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 561e1ea03a3Smacallan uint32_t pat; 562e1ea03a3Smacallan 563e1ea03a3Smacallan LOG(CRIME_DEBUG_LINES); 564e1ea03a3Smacallan 565e1ea03a3Smacallan fPtr->uw = length; 56626dcc2a3Smacallan MAKE_ROOM(7); 56726dcc2a3Smacallan WRITE4(CRIME_DE_MODE_DST, DE_MODE_TLB_A | DE_MODE_BUFDEPTH_32 | 56826dcc2a3Smacallan DE_MODE_TYPE_RGBA | DE_MODE_PIXDEPTH_32); 569e1ea03a3Smacallan WRITE4(CRIME_DE_PLANEMASK, planemask); 570e1ea03a3Smacallan WRITE4(CRIME_DE_ROP, rop); 571e1ea03a3Smacallan WRITE4(CRIME_DE_FG, fg << 8); 572e1ea03a3Smacallan if (bg == -1) { 573e1ea03a3Smacallan /* transparent */ 574e1ea03a3Smacallan WRITE4(CRIME_DE_DRAWMODE, 575e1ea03a3Smacallan DE_DRAWMODE_PLANEMASK | DE_DRAWMODE_BYTEMASK | 57693351543Smacallan DE_DRAWMODE_ROP | DE_DRAWMODE_LINE_STIP | 57793351543Smacallan DE_DRAWMODE_SCISSOR_EN); 578e1ea03a3Smacallan } else { 579e1ea03a3Smacallan WRITE4(CRIME_DE_BG, bg << 8); 580e1ea03a3Smacallan WRITE4(CRIME_DE_DRAWMODE, 581e1ea03a3Smacallan DE_DRAWMODE_PLANEMASK | DE_DRAWMODE_BYTEMASK | 58293351543Smacallan DE_DRAWMODE_ROP | DE_DRAWMODE_SCISSOR_EN | 583e1ea03a3Smacallan DE_DRAWMODE_OPAQUE_STIP | DE_DRAWMODE_LINE_STIP); 584e1ea03a3Smacallan } 585e1ea03a3Smacallan /* 586e1ea03a3Smacallan * can we trust the Xserver to always hand us a 32bit aligned 587e1ea03a3Smacallan * pattern buffer? 588e1ea03a3Smacallan */ 589e1ea03a3Smacallan memcpy(&pat, pattern, 4); 590e1ea03a3Smacallan WRITE4(CRIME_DE_STIPPLE_PAT, pat); 59126dcc2a3Smacallan SYNC; 592e1ea03a3Smacallan DONE(CRIME_DEBUG_LINES); 593e1ea03a3Smacallan} 594e1ea03a3Smacallan 595e1ea03a3Smacallanvoid 596e1ea03a3SmacallanCrimeSubsequentDashedTwoPointLine( ScrnInfoPtr pScrn, 597e1ea03a3Smacallan int x1, int y1, int x2, int y2, int flags, int phase) 598e1ea03a3Smacallan{ 599e1ea03a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 600e1ea03a3Smacallan uint32_t stipmode; 601e1ea03a3Smacallan 602e1ea03a3Smacallan LOG(CRIME_DEBUG_LINES); 60326dcc2a3Smacallan MAKE_ROOM(4); 604e1ea03a3Smacallan 605e1ea03a3Smacallan if (flags & OMIT_LAST) { 606e1ea03a3Smacallan WRITE4(CRIME_DE_PRIMITIVE, 607e1ea03a3Smacallan DE_PRIM_LINE | DE_PRIM_LINE_SKIP_END | 2); 608e1ea03a3Smacallan } else { 609e1ea03a3Smacallan WRITE4(CRIME_DE_PRIMITIVE, 610e1ea03a3Smacallan DE_PRIM_LINE | 2); 611e1ea03a3Smacallan } 612e1ea03a3Smacallan 613e1ea03a3Smacallan stipmode = ((fPtr->uw - 1) << 16) | (phase << 24); 614e1ea03a3Smacallan WRITE4(CRIME_DE_STIPPLE_MODE, stipmode); 615e1ea03a3Smacallan WRITE4(CRIME_DE_X_VERTEX_0, (x1 << 16) | y1); 616e1ea03a3Smacallan WRITE4ST(CRIME_DE_X_VERTEX_1, (x2 << 16) | y2); 617e1ea03a3Smacallan DONE(CRIME_DEBUG_LINES); 618e1ea03a3Smacallan} 619e1ea03a3Smacallan 620e1ea03a3Smacallanvoid 621e1ea03a3SmacallanCrimeSetClippingRectangle ( ScrnInfoPtr pScrn, 622e1ea03a3Smacallan int left, int top, int right, int bottom) 623e1ea03a3Smacallan{ 624e1ea03a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 625e1ea03a3Smacallan 626e1ea03a3Smacallan LOG(CRIME_DEBUG_CLIPPING); 62726dcc2a3Smacallan MAKE_ROOM(2); 62893351543Smacallan WRITE4(CRIME_DE_SCISSOR, (left << 16) | top); 62993351543Smacallan WRITE4(CRIME_DE_SCISSOR + 4, ((right + 1) << 16) | (bottom + 1)); 63026dcc2a3Smacallan SYNC; 631e1ea03a3Smacallan DONE(CRIME_DEBUG_CLIPPING); 632e1ea03a3Smacallan} 633e1ea03a3Smacallan 634e1ea03a3Smacallanvoid 635e1ea03a3SmacallanCrimeDisableClipping (ScrnInfoPtr pScrn) 636e1ea03a3Smacallan{ 637e1ea03a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 638e1ea03a3Smacallan 639e1ea03a3Smacallan LOG(CRIME_DEBUG_CLIPPING); 64026dcc2a3Smacallan MAKE_ROOM(2); 64193351543Smacallan WRITE4(CRIME_DE_SCISSOR, 0); 64293351543Smacallan WRITE4(CRIME_DE_SCISSOR + 4, 0x3fff3fff); 64326dcc2a3Smacallan SYNC; 644e1ea03a3Smacallan DONE(CRIME_DEBUG_CLIPPING); 645e1ea03a3Smacallan} 646e1ea03a3Smacallan 647e1ea03a3Smacallanstatic Bool 648e1ea03a3SmacallanCrimeSetupForCPUToScreenAlphaTexture ( 649e1ea03a3Smacallan ScrnInfoPtr pScrn, 650e1ea03a3Smacallan int op, 651e1ea03a3Smacallan CARD16 red, 652e1ea03a3Smacallan CARD16 green, 653e1ea03a3Smacallan CARD16 blue, 654e1ea03a3Smacallan CARD16 alpha, 655e1ea03a3Smacallan int alphaType, 656e1ea03a3Smacallan CARD8 *alphaPtr, 657e1ea03a3Smacallan int alphaPitch, 658e1ea03a3Smacallan int width, 659e1ea03a3Smacallan int height, 660e1ea03a3Smacallan int flags 661e1ea03a3Smacallan) 662e1ea03a3Smacallan{ 663e1ea03a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 664e1ea03a3Smacallan 665e1ea03a3Smacallan if (op != PictOpOver) { 666e1ea03a3Smacallan xf86Msg(X_ERROR, "%s: op %d\n", __func__, op); 667e1ea03a3Smacallan op = PictOpOver; 668e1ea03a3Smacallan } 669e1ea03a3Smacallan 670e1ea03a3Smacallan LOG(CRIME_DEBUG_XRENDER); 671e1ea03a3Smacallan 672e1ea03a3Smacallan fPtr->alpha_color = ((red & 0xff00) << 16) | 673e1ea03a3Smacallan ((green & 0xff00) << 8) | 67409f0d67cSmacallan (blue & 0xff00); 675e1ea03a3Smacallan fPtr->uw = width; 676e1ea03a3Smacallan fPtr->uh = height; 677e1ea03a3Smacallan fPtr->us = alphaPitch; 678e1ea03a3Smacallan fPtr->alpha_texture = alphaPtr; 67909f0d67cSmacallan fPtr->format = alphaType; 6805b2650b9Smacallan#ifdef CRIME_DEBUG_LOUD 68109f0d67cSmacallan if (alphaType != PICT_a8) { 68209f0d67cSmacallan xf86Msg(X_ERROR, "ARGB mask %08x %d\n", (uint32_t)alphaPtr, 68309f0d67cSmacallan alphaPitch); 68409f0d67cSmacallan } 6855b2650b9Smacallan#endif 68626dcc2a3Smacallan MAKE_ROOM(7); 68726dcc2a3Smacallan WRITE4(CRIME_DE_MODE_DST, DE_MODE_TLB_A | DE_MODE_BUFDEPTH_32 | 68826dcc2a3Smacallan DE_MODE_TYPE_RGBA | DE_MODE_PIXDEPTH_32); 689e1ea03a3Smacallan /* XXX this register is not where it's supposed to be */ 690e1ea03a3Smacallan WRITE4(CRIME_DE_ALPHA_COLOR, fPtr->alpha_color); 69109f0d67cSmacallan if (alphaType == PICT_a8) { 69209f0d67cSmacallan if (fPtr->alpha_color == 0) { 69309f0d67cSmacallan WRITE4(CRIME_DE_MODE_SRC, DE_MODE_LIN_A | DE_MODE_BUFDEPTH_8 | 694e1ea03a3Smacallan DE_MODE_TYPE_RGBA | DE_MODE_PIXDEPTH_32); 69509f0d67cSmacallan WRITE4(CRIME_DE_XFER_STEP_X, 1); 69609f0d67cSmacallan WRITE4(CRIME_DE_ALPHA_FUNC, 69709f0d67cSmacallan DE_ALPHA_ADD | 69809f0d67cSmacallan (DE_ALPHA_OP_ZERO << DE_ALPHA_OP_SRC_SHIFT) | 69909f0d67cSmacallan (DE_ALPHA_OP_1_MINUS_SRC_ALPHA << DE_ALPHA_OP_DST_SHIFT)); 70009f0d67cSmacallan } else { 70109f0d67cSmacallan WRITE4(CRIME_DE_MODE_SRC, DE_MODE_LIN_A | DE_MODE_BUFDEPTH_32 | 70209f0d67cSmacallan DE_MODE_TYPE_RGBA | DE_MODE_PIXDEPTH_32); 70309f0d67cSmacallan WRITE4(CRIME_DE_XFER_STEP_X, 4); 70409f0d67cSmacallan WRITE4(CRIME_DE_ALPHA_FUNC, 70509f0d67cSmacallan DE_ALPHA_ADD | 70609f0d67cSmacallan (DE_ALPHA_OP_SRC_ALPHA << DE_ALPHA_OP_SRC_SHIFT) | 70709f0d67cSmacallan (DE_ALPHA_OP_1_MINUS_SRC_ALPHA << DE_ALPHA_OP_DST_SHIFT)); 70809f0d67cSmacallan } 709e1ea03a3Smacallan } else { 710e1ea03a3Smacallan WRITE4(CRIME_DE_MODE_SRC, DE_MODE_LIN_A | DE_MODE_BUFDEPTH_32 | 711e1ea03a3Smacallan DE_MODE_TYPE_RGBA | DE_MODE_PIXDEPTH_32); 712e1ea03a3Smacallan WRITE4(CRIME_DE_XFER_STEP_X, 4); 713e1ea03a3Smacallan WRITE4(CRIME_DE_ALPHA_FUNC, 714e1ea03a3Smacallan DE_ALPHA_ADD | 715e1ea03a3Smacallan (DE_ALPHA_OP_SRC_ALPHA << DE_ALPHA_OP_SRC_SHIFT) | 716e1ea03a3Smacallan (DE_ALPHA_OP_1_MINUS_SRC_ALPHA << DE_ALPHA_OP_DST_SHIFT)); 71709f0d67cSmacallan } 718e1ea03a3Smacallan WRITE4(CRIME_DE_DRAWMODE, 719e1ea03a3Smacallan DE_DRAWMODE_BYTEMASK | DE_DRAWMODE_ALPHA_BLEND | 720e1ea03a3Smacallan DE_DRAWMODE_XFER_EN); 721e1ea03a3Smacallan WRITE4(CRIME_DE_PRIMITIVE, 722e1ea03a3Smacallan DE_PRIM_RECTANGLE | DE_PRIM_LR | DE_PRIM_TB); 72326dcc2a3Smacallan SYNC; 724e1ea03a3Smacallan DONE(CRIME_DEBUG_XRENDER); 725e1ea03a3Smacallan return TRUE; 726e1ea03a3Smacallan} 727e1ea03a3Smacallan 728e1ea03a3Smacallanvoid 729e1ea03a3SmacallanCrimeSubsequentCPUToScreenAlphaTexture ( 730e1ea03a3Smacallan ScrnInfoPtr pScrn, 731e1ea03a3Smacallan int dstx, 732e1ea03a3Smacallan int dsty, 733e1ea03a3Smacallan int srcx, 734e1ea03a3Smacallan int srcy, 735e1ea03a3Smacallan int width, 736e1ea03a3Smacallan int height 737e1ea03a3Smacallan) 738e1ea03a3Smacallan{ 739e1ea03a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 740e1ea03a3Smacallan unsigned char *aptr; 741e1ea03a3Smacallan uint32_t *dptr, aval; 742e1ea03a3Smacallan int i, j; 743e1ea03a3Smacallan int bufnum = 0; 744e1ea03a3Smacallan 745e1ea03a3Smacallan LOG(CRIME_DEBUG_XRENDER); 746e1ea03a3Smacallan#ifdef CRIME_DEBUG_LOUD 747e1ea03a3Smacallan xf86Msg(X_ERROR, "%d %d %d %d %d %d\n",srcx, srcy, dstx, dsty, width, 748e1ea03a3Smacallan height); 749e1ea03a3Smacallan#endif 750e1ea03a3Smacallan aptr = fPtr->alpha_texture + (fPtr->us * srcy) + srcx; 751e1ea03a3Smacallan for (i = 0; i < height; i++) { 752e1ea03a3Smacallan dptr = (uint32_t *)fPtr->buffers[bufnum]; 753e1ea03a3Smacallan if (fPtr->alpha_color == 0) { 754e1ea03a3Smacallan memcpy(dptr, aptr, width); 755e1ea03a3Smacallan } else { 756e1ea03a3Smacallan for (j = 0; j < width; j++) { 757e1ea03a3Smacallan aval = aptr[j]; 758e1ea03a3Smacallan *dptr = aval | fPtr->alpha_color; 759e1ea03a3Smacallan dptr++; 760e1ea03a3Smacallan } 761e1ea03a3Smacallan } 76226dcc2a3Smacallan MAKE_ROOM(3); 763e1ea03a3Smacallan WRITE4(CRIME_DE_XFER_ADDR_SRC, bufnum * 8192); 764e1ea03a3Smacallan WRITE4(CRIME_DE_X_VERTEX_0, dstx << 16 | (dsty + i)); 765e1ea03a3Smacallan WRITE4ST(CRIME_DE_X_VERTEX_1, 766e1ea03a3Smacallan ((dstx + width - 1) << 16) | (dsty + i)); 767e1ea03a3Smacallan bufnum++; 768e1ea03a3Smacallan if (bufnum == 8) bufnum = 0; 769e1ea03a3Smacallan aptr += fPtr->us; 770e1ea03a3Smacallan } 771e1ea03a3Smacallan DONE(CRIME_DEBUG_XRENDER); 772e1ea03a3Smacallan} 773e1ea03a3Smacallan 77409f0d67cSmacallanvoid 77509f0d67cSmacallanCrimeSubsequentCPUToScreenAlphaTexture32 ( 77609f0d67cSmacallan ScrnInfoPtr pScrn, 77709f0d67cSmacallan int dstx, 77809f0d67cSmacallan int dsty, 77909f0d67cSmacallan int srcx, 78009f0d67cSmacallan int srcy, 78109f0d67cSmacallan int width, 78209f0d67cSmacallan int height 78309f0d67cSmacallan) 78409f0d67cSmacallan{ 78509f0d67cSmacallan CrimePtr fPtr = CRIMEPTR(pScrn); 78609f0d67cSmacallan uint8_t *aptr; 78709f0d67cSmacallan uint32_t *dptr, *sptr; 78809f0d67cSmacallan int i, j; 78909f0d67cSmacallan int bufnum = 0; 79009f0d67cSmacallan 79109f0d67cSmacallan LOG(CRIME_DEBUG_XRENDER); 79226dcc2a3Smacallan#ifdef CRIME_DEBUG_LOUD 79309f0d67cSmacallan xf86Msg(X_ERROR, "%d %d %d %d %d %d\n",srcx, srcy, dstx, dsty, width, 79409f0d67cSmacallan height); 79509f0d67cSmacallan#endif 79609f0d67cSmacallan aptr = fPtr->alpha_texture + (fPtr->us * srcy) + (srcx << 2); 79709f0d67cSmacallan for (i = 0; i < height; i++) { 79809f0d67cSmacallan dptr = (uint32_t *)fPtr->buffers[bufnum]; 79909f0d67cSmacallan sptr = (uint32_t *)aptr; 80009f0d67cSmacallan for (j = 0; j < width; j++) { 80109f0d67cSmacallan *dptr = (*sptr >> 24) | fPtr->alpha_color; 80209f0d67cSmacallan#ifdef CRIME_DEBUG_LOUD 80309f0d67cSmacallan xf86Msg(X_ERROR, "%08x %08x\n", *sptr, *dptr); 80409f0d67cSmacallan#endif 80509f0d67cSmacallan sptr++; 80609f0d67cSmacallan dptr++; 80709f0d67cSmacallan } 80826dcc2a3Smacallan MAKE_ROOM(3); 80909f0d67cSmacallan WRITE4(CRIME_DE_XFER_ADDR_SRC, bufnum * 8192); 81009f0d67cSmacallan WRITE4(CRIME_DE_X_VERTEX_0, dstx << 16 | (dsty + i)); 81109f0d67cSmacallan WRITE4ST(CRIME_DE_X_VERTEX_1, 81209f0d67cSmacallan ((dstx + width - 1) << 16) | (dsty + i)); 81309f0d67cSmacallan bufnum++; 81409f0d67cSmacallan if (bufnum == 8) bufnum = 0; 81509f0d67cSmacallan aptr += fPtr->us; 81609f0d67cSmacallan } 81709f0d67cSmacallan DONE(CRIME_DEBUG_XRENDER); 81809f0d67cSmacallan} 81909f0d67cSmacallan 820e1ea03a3Smacallanstatic Bool 821e1ea03a3SmacallanCrimeSetupForCPUToScreenTexture ( 822e1ea03a3Smacallan ScrnInfoPtr pScrn, 823e1ea03a3Smacallan int op, 824e1ea03a3Smacallan int texType, 825e1ea03a3Smacallan CARD8 *texPtr, 826e1ea03a3Smacallan int texPitch, 827e1ea03a3Smacallan int width, 828e1ea03a3Smacallan int height, 829e1ea03a3Smacallan int flags 830e1ea03a3Smacallan) 831e1ea03a3Smacallan{ 832e1ea03a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 833e1ea03a3Smacallan 834e1ea03a3Smacallan if (op != PictOpOver) { 835e1ea03a3Smacallan xf86Msg(X_ERROR, "%s: op %d\n", __func__, op); 836e1ea03a3Smacallan op = PictOpOver; 837e1ea03a3Smacallan } 838e1ea03a3Smacallan 839e1ea03a3Smacallan LOG(CRIME_DEBUG_XRENDER); 840e1ea03a3Smacallan 841e1ea03a3Smacallan fPtr->uw = width; 842e1ea03a3Smacallan fPtr->uh = height; 843e1ea03a3Smacallan fPtr->us = texPitch; 844e1ea03a3Smacallan fPtr->alpha_texture = texPtr; 84526dcc2a3Smacallan MAKE_ROOM(6); 84626dcc2a3Smacallan WRITE4(CRIME_DE_MODE_DST, DE_MODE_TLB_A | DE_MODE_BUFDEPTH_32 | 84726dcc2a3Smacallan DE_MODE_TYPE_RGBA | DE_MODE_PIXDEPTH_32); 848e1ea03a3Smacallan if (texType == PICT_a8b8g8r8) { 849e1ea03a3Smacallan WRITE4(CRIME_DE_MODE_SRC, DE_MODE_LIN_A | DE_MODE_BUFDEPTH_32 | 850e1ea03a3Smacallan DE_MODE_TYPE_ABGR | DE_MODE_PIXDEPTH_32); 851e1ea03a3Smacallan } else { 852e1ea03a3Smacallan WRITE4(CRIME_DE_MODE_SRC, DE_MODE_LIN_A | DE_MODE_BUFDEPTH_32 | 853e1ea03a3Smacallan DE_MODE_TYPE_RGBA | DE_MODE_PIXDEPTH_32); 854e1ea03a3Smacallan } 855e1ea03a3Smacallan fPtr->format = texType; 856e1ea03a3Smacallan WRITE4(CRIME_DE_XFER_STEP_X, 4); 857e1ea03a3Smacallan WRITE4(CRIME_DE_ALPHA_FUNC, 858e1ea03a3Smacallan DE_ALPHA_ADD | 859e1ea03a3Smacallan (DE_ALPHA_OP_ONE/*SRC_ALPHA*/ << DE_ALPHA_OP_SRC_SHIFT) | 860e1ea03a3Smacallan (DE_ALPHA_OP_1_MINUS_SRC_ALPHA << DE_ALPHA_OP_DST_SHIFT)); 861e1ea03a3Smacallan WRITE4(CRIME_DE_DRAWMODE, 862e1ea03a3Smacallan DE_DRAWMODE_BYTEMASK | DE_DRAWMODE_ALPHA_BLEND | 863e1ea03a3Smacallan DE_DRAWMODE_XFER_EN); 864e1ea03a3Smacallan WRITE4(CRIME_DE_PRIMITIVE, 865e1ea03a3Smacallan DE_PRIM_RECTANGLE | DE_PRIM_LR | DE_PRIM_TB); 86626dcc2a3Smacallan SYNC; 867e1ea03a3Smacallan DONE(CRIME_DEBUG_XRENDER); 868e1ea03a3Smacallan return TRUE; 869e1ea03a3Smacallan} 870e1ea03a3Smacallan 871e1ea03a3Smacallanvoid 872e1ea03a3SmacallanCrimeSubsequentCPUToScreenTexture ( 873e1ea03a3Smacallan ScrnInfoPtr pScrn, 874e1ea03a3Smacallan int dstx, 875e1ea03a3Smacallan int dsty, 876e1ea03a3Smacallan int srcx, 877e1ea03a3Smacallan int srcy, 878e1ea03a3Smacallan int width, 879e1ea03a3Smacallan int height 880e1ea03a3Smacallan) 881e1ea03a3Smacallan{ 882e1ea03a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 883e1ea03a3Smacallan unsigned char *aptr, *lptr; 884e1ea03a3Smacallan uint32_t *dptr, *sptr, aval, pixel; 885e1ea03a3Smacallan int i, j, k, l, rep = 1, period = fPtr->uw, xoff, lcnt, xa, xe; 886e1ea03a3Smacallan int bufnum = 0; 887e1ea03a3Smacallan 888e1ea03a3Smacallan LOG(CRIME_DEBUG_XRENDER); 889e1ea03a3Smacallan#ifdef CRIME_DEBUG_LOUD 890e1ea03a3Smacallan xf86Msg(X_ERROR, "%s: %d %d %d %d %d %d\n", __func__, 891e1ea03a3Smacallan srcx, srcy, dstx, dsty, width, height); 892e1ea03a3Smacallan#endif 893e1ea03a3Smacallan if ((width == 1) || (fPtr->format != PICT_a8r8g8b8)) { 894e1ea03a3Smacallan xf86Msg(X_ERROR, "%s: %d %d %d %d %d %d %d %d\n", __func__, 895e1ea03a3Smacallan srcx, srcy, dstx, dsty, width, height, fPtr->uw, fPtr->us); 896e1ea03a3Smacallan return; 897e1ea03a3Smacallan } 898e1ea03a3Smacallan 899e1ea03a3Smacallan aptr = fPtr->alpha_texture + (srcx << 2); 900e1ea03a3Smacallan lptr = aptr + (fPtr->us * srcy); 901e1ea03a3Smacallan if ((fPtr->uw < 128) && (fPtr->uw < width)) { 902e1ea03a3Smacallan rep = 128 / fPtr->uw; 903e1ea03a3Smacallan period = rep * fPtr->uw; 904e1ea03a3Smacallan } 905e1ea03a3Smacallan 906e1ea03a3Smacallan if (fPtr->format == PICT_a8b8g8r8) { 907e1ea03a3Smacallan#ifdef CRIME_DEBUG_LOUD 908e1ea03a3Smacallan xf86Msg(X_ERROR, "ABGR\n"); 909e1ea03a3Smacallan#endif 910e1ea03a3Smacallan for (i = 0; i < height; i++) { 911e1ea03a3Smacallan dptr = (uint32_t *)fPtr->buffers[bufnum]; 912e1ea03a3Smacallan memcpy(dptr, aptr, fPtr->us); 91326dcc2a3Smacallan MAKE_ROOM(3); 914e1ea03a3Smacallan WRITE4(CRIME_DE_XFER_ADDR_SRC, bufnum * 8192); 915e1ea03a3Smacallan WRITE4(CRIME_DE_X_VERTEX_0, dstx << 16 | (dsty + i)); 916e1ea03a3Smacallan WRITE4ST(CRIME_DE_X_VERTEX_1, 917e1ea03a3Smacallan ((dstx + width - 1) << 16) | (dsty + i)); 918e1ea03a3Smacallan bufnum++; 919e1ea03a3Smacallan if (bufnum == 8) bufnum = 0; 920e1ea03a3Smacallan aptr += fPtr->us; 921e1ea03a3Smacallan } 922e1ea03a3Smacallan } else { 923e1ea03a3Smacallan#ifdef CRIME_DEBUG_LOUD 924e1ea03a3Smacallan xf86Msg(X_ERROR, "ARGB %08x %d\n", (uint32_t)aptr, fPtr->uw); 925e1ea03a3Smacallan#endif 926e1ea03a3Smacallan lcnt = fPtr->uh - srcy; 927e1ea03a3Smacallan for (i = 0; i < height; i++) { 928e1ea03a3Smacallan dptr = (uint32_t *)fPtr->buffers[bufnum]; 929e1ea03a3Smacallan for (k = 0; k < rep; k++) { 930e1ea03a3Smacallan sptr = (uint32_t *)aptr; 931e1ea03a3Smacallan for (j = 0; j < fPtr->uw; j++) { 932e1ea03a3Smacallan pixel = *sptr; 933e1ea03a3Smacallan *dptr = (pixel << 8) | (pixel >> 24); 934e1ea03a3Smacallan dptr++; 935e1ea03a3Smacallan sptr++; 936e1ea03a3Smacallan } 937e1ea03a3Smacallan } 938e1ea03a3Smacallan xoff = 0; 93926dcc2a3Smacallan MAKE_ROOM(1); 940e1ea03a3Smacallan WRITE4(CRIME_DE_XFER_ADDR_SRC, bufnum * 8192); 941e1ea03a3Smacallan while (xoff < width) { 942e1ea03a3Smacallan xa = dstx + xoff; 943e1ea03a3Smacallan xe = dstx + min(xoff + period, width) - 1; 94426dcc2a3Smacallan MAKE_ROOM(2); 945e1ea03a3Smacallan WRITE4(CRIME_DE_X_VERTEX_0, 946e1ea03a3Smacallan xa << 16 | (dsty + i)); 947e1ea03a3Smacallan WRITE4ST(CRIME_DE_X_VERTEX_1, 948e1ea03a3Smacallan (xe << 16) | (dsty + i)); 949e1ea03a3Smacallan xoff += period; 950e1ea03a3Smacallan } 951e1ea03a3Smacallan bufnum++; 952e1ea03a3Smacallan if (bufnum == 8) bufnum = 0; 953e1ea03a3Smacallan lcnt--; 954e1ea03a3Smacallan if (lcnt == 0) { 955e1ea03a3Smacallan aptr = lptr; 956e1ea03a3Smacallan lcnt = fPtr->uh; 957e1ea03a3Smacallan } else 958e1ea03a3Smacallan aptr += fPtr->us; 959e1ea03a3Smacallan } 960e1ea03a3Smacallan } 961e1ea03a3Smacallan DONE(CRIME_DEBUG_XRENDER); 962e1ea03a3Smacallan} 963e1ea03a3Smacallan 964e1ea03a3Smacallanstatic Bool 965e1ea03a3SmacallanCrimeSetupForCPUToScreenTextureMask( 966e1ea03a3Smacallan ScrnInfoPtr pScrn, 967e1ea03a3Smacallan int op, 968e1ea03a3Smacallan int texType, 969e1ea03a3Smacallan CARD8 *srcPtr, 970e1ea03a3Smacallan int srcPitch, 971e1ea03a3Smacallan CARD8 *mskPtr, 972e1ea03a3Smacallan int mskPitch, 973e1ea03a3Smacallan int width, 974e1ea03a3Smacallan int height, 975e1ea03a3Smacallan int flags 976e1ea03a3Smacallan) 977e1ea03a3Smacallan{ 978e1ea03a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 979e1ea03a3Smacallan 980e1ea03a3Smacallan if (op != PictOpOver) { 981e1ea03a3Smacallan xf86Msg(X_ERROR, "%s: op %d\n", __func__, op); 982e1ea03a3Smacallan op = PictOpOver; 983e1ea03a3Smacallan } 984e1ea03a3Smacallan 985e1ea03a3Smacallan LOG(CRIME_DEBUG_XRENDER); 986e1ea03a3Smacallan 987e1ea03a3Smacallan fPtr->uw = width; 988e1ea03a3Smacallan fPtr->uh = height; 989e1ea03a3Smacallan fPtr->us = srcPitch >> 2; 990e1ea03a3Smacallan if (PICT_FORMAT_BPP(texType) == 32) { 991e1ea03a3Smacallan fPtr->um = mskPitch >> 2; 992e1ea03a3Smacallan } else 993e1ea03a3Smacallan fPtr->um = mskPitch; 994e1ea03a3Smacallan fPtr->msk = (uint8_t *)mskPtr; 995e1ea03a3Smacallan fPtr->src = (uint8_t *)srcPtr; 996e1ea03a3Smacallan fPtr->texture_depth = PICT_FORMAT_BPP(texType); 997e1ea03a3Smacallan 99826dcc2a3Smacallan MAKE_ROOM(6); 999e1ea03a3Smacallan /* always expect ARGB for now */ 1000e1ea03a3Smacallan WRITE4(CRIME_DE_MODE_SRC, DE_MODE_LIN_A | DE_MODE_BUFDEPTH_32 | 1001e1ea03a3Smacallan DE_MODE_TYPE_RGBA | DE_MODE_PIXDEPTH_32); 100226dcc2a3Smacallan WRITE4(CRIME_DE_MODE_DST, DE_MODE_TLB_A | DE_MODE_BUFDEPTH_32 | 100326dcc2a3Smacallan DE_MODE_TYPE_RGBA | DE_MODE_PIXDEPTH_32); 1004e1ea03a3Smacallan fPtr->format = texType; 1005e1ea03a3Smacallan WRITE4(CRIME_DE_ALPHA_FUNC, 1006e1ea03a3Smacallan DE_ALPHA_ADD | 1007e1ea03a3Smacallan (DE_ALPHA_OP_SRC_ALPHA << DE_ALPHA_OP_SRC_SHIFT) | 1008e1ea03a3Smacallan (DE_ALPHA_OP_1_MINUS_SRC_ALPHA << DE_ALPHA_OP_DST_SHIFT)); 1009e1ea03a3Smacallan WRITE4(CRIME_DE_XFER_STEP_X, 4); 1010e1ea03a3Smacallan WRITE4(CRIME_DE_DRAWMODE, 1011e1ea03a3Smacallan DE_DRAWMODE_BYTEMASK | DE_DRAWMODE_ALPHA_BLEND | 1012e1ea03a3Smacallan DE_DRAWMODE_XFER_EN); 1013e1ea03a3Smacallan WRITE4(CRIME_DE_PRIMITIVE, 1014e1ea03a3Smacallan DE_PRIM_RECTANGLE | DE_PRIM_LR | DE_PRIM_TB); 101526dcc2a3Smacallan SYNC; 1016e1ea03a3Smacallan DONE(CRIME_DEBUG_XRENDER); 1017e1ea03a3Smacallan return TRUE; 1018e1ea03a3Smacallan} 1019e1ea03a3Smacallan 1020e1ea03a3Smacallanvoid 1021e1ea03a3SmacallanCrimeSubsequentCPUToScreenTextureMask32( 1022e1ea03a3Smacallan ScrnInfoPtr pScrn, 1023e1ea03a3Smacallan int dstx, 1024e1ea03a3Smacallan int dsty, 1025e1ea03a3Smacallan int srcx, 1026e1ea03a3Smacallan int srcy, 1027e1ea03a3Smacallan int maskx, 1028e1ea03a3Smacallan int masky, 1029e1ea03a3Smacallan int width, 1030e1ea03a3Smacallan int height 1031e1ea03a3Smacallan) 1032e1ea03a3Smacallan{ 1033e1ea03a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 1034e1ea03a3Smacallan uint32_t *lsptr, *lmptr, *asptr, *amptr; 1035e1ea03a3Smacallan uint32_t *dptr, *sptr, *mptr, aval, pixel, mask; 1036e1ea03a3Smacallan int i, j, k, l, rep = 1, period = fPtr->uw, xoff, lcnt, xa, xe; 1037e1ea03a3Smacallan int bufnum = 0; 1038e1ea03a3Smacallan int sr, sg, sb, sa, mr, mg, mb, ma, rr, gg, bb, aa; 1039e1ea03a3Smacallan 1040e1ea03a3Smacallan LOG(CRIME_DEBUG_XRENDER); 1041e1ea03a3Smacallan#ifdef CRIME_DEBUG_LOUD 1042e1ea03a3Smacallan xf86Msg(X_ERROR, "%s: %d %d %d %d %d %d; %d %d %d\n", __func__, 1043e1ea03a3Smacallan srcx, srcy, dstx, dsty, width, height, maskx, masky, fPtr->um); 1044e1ea03a3Smacallan#endif 1045e1ea03a3Smacallan sptr = fPtr->src + (srcx << 2); 1046e1ea03a3Smacallan mptr = fPtr->msk + (srcx << 2); 1047e1ea03a3Smacallan lsptr = sptr + (fPtr->us * srcy); 1048e1ea03a3Smacallan lmptr = mptr + (fPtr->um * srcy); 1049e1ea03a3Smacallan if ((fPtr->uw < 128) && (fPtr->uw < width)) { 1050e1ea03a3Smacallan rep = 128 / fPtr->uw; 1051e1ea03a3Smacallan period = rep * fPtr->uw; 1052e1ea03a3Smacallan } 1053e1ea03a3Smacallan 1054e1ea03a3Smacallan#ifdef CRIME_DEBUG_LOUD 1055e1ea03a3Smacallan xf86Msg(X_ERROR, "ARGB %08x %d\n", (uint32_t)aptr, fPtr->uw); 1056e1ea03a3Smacallan#endif 1057e1ea03a3Smacallan lcnt = fPtr->uh - srcy; 1058e1ea03a3Smacallan for (i = 0; i < height; i++) { 1059e1ea03a3Smacallan dptr = (uint32_t *)fPtr->buffers[bufnum]; 1060e1ea03a3Smacallan for (k = 0; k < rep; k++) { 1061e1ea03a3Smacallan asptr = lsptr; 1062e1ea03a3Smacallan amptr = lmptr; 1063e1ea03a3Smacallan for (j = 0; j < fPtr->uw; j++) { 1064e1ea03a3Smacallan pixel = *asptr; 1065e1ea03a3Smacallan mask = *amptr; 1066e1ea03a3Smacallan if (mask == 0xffffffff) { 1067e1ea03a3Smacallan *dptr = (pixel >> 24) | (pixel << 8); 1068e1ea03a3Smacallan } else if (mask == 0x00000000) { 1069e1ea03a3Smacallan *dptr = 0; 1070e1ea03a3Smacallan } else { 1071e1ea03a3Smacallan /* input is ARGB */ 1072e1ea03a3Smacallan sb = pixel & 0xff; 1073e1ea03a3Smacallan sg = (pixel >> 8) & 0xff; 1074e1ea03a3Smacallan sr = (pixel >> 16) & 0xff; 1075e1ea03a3Smacallan sa = (pixel >> 24) & 0xff; 1076e1ea03a3Smacallan mb = mask & 0xff; 1077e1ea03a3Smacallan mg = (mask >> 8) & 0xff; 1078e1ea03a3Smacallan mr = (mask >> 16) & 0xff; 1079e1ea03a3Smacallan ma = (mask >> 24) & 0xff; 1080e1ea03a3Smacallan 1081e1ea03a3Smacallan /* and here we need an RGBA pixel */ 1082e1ea03a3Smacallan bb = (((sb * mb) + 0x80) & 0xff00); 1083e1ea03a3Smacallan gg = (((sg * mg) + 0x80) & 0xff00) << 8; 1084e1ea03a3Smacallan rr = (((sr * mr) + 0x80) & 0xff00) << 16; 1085e1ea03a3Smacallan aa = (((sa * ma) + 0x80) & 0xff00) >> 8; 1086e1ea03a3Smacallan /* 1087e1ea03a3Smacallan * actually we could let the HW do this stuff 1088e1ea03a3Smacallan */ 1089e1ea03a3Smacallan *dptr = aa | rr | gg | bb; 1090e1ea03a3Smacallan } 1091e1ea03a3Smacallan dptr++; 1092e1ea03a3Smacallan asptr++; 1093e1ea03a3Smacallan amptr++; 1094e1ea03a3Smacallan } 1095e1ea03a3Smacallan } 1096e1ea03a3Smacallan xoff = 0; 109726dcc2a3Smacallan MAKE_ROOM(1); 1098e1ea03a3Smacallan WRITE4(CRIME_DE_XFER_ADDR_SRC, bufnum * 8192); 1099e1ea03a3Smacallan while (xoff < width) { 1100e1ea03a3Smacallan xa = dstx + xoff; 1101e1ea03a3Smacallan xe = dstx + min(xoff + period, width) - 1; 110226dcc2a3Smacallan MAKE_ROOM(2); 1103e1ea03a3Smacallan WRITE4(CRIME_DE_X_VERTEX_0, 1104e1ea03a3Smacallan xa << 16 | (dsty + i)); 1105e1ea03a3Smacallan WRITE4ST(CRIME_DE_X_VERTEX_1, 1106e1ea03a3Smacallan (xe << 16) | (dsty + i)); 1107e1ea03a3Smacallan xoff += period; 1108e1ea03a3Smacallan } 1109e1ea03a3Smacallan bufnum++; 1110e1ea03a3Smacallan if (bufnum == 8) bufnum = 0; 1111e1ea03a3Smacallan lcnt--; 1112e1ea03a3Smacallan if (lcnt == 0) { 1113e1ea03a3Smacallan /* back to the beginning */ 1114e1ea03a3Smacallan lsptr = sptr; 1115e1ea03a3Smacallan lmptr = mptr; 1116e1ea03a3Smacallan lcnt = fPtr->uh; 1117e1ea03a3Smacallan } else 1118e1ea03a3Smacallan /* next line */ 1119e1ea03a3Smacallan lsptr += fPtr->us; 1120e1ea03a3Smacallan lmptr += fPtr->um; 1121e1ea03a3Smacallan } 1122e1ea03a3Smacallan DONE(CRIME_DEBUG_XRENDER); 1123e1ea03a3Smacallan} 1124e1ea03a3Smacallan 1125e1ea03a3Smacallanvoid 1126e1ea03a3SmacallanCrimeSubsequentCPUToScreenTextureMask8( 1127e1ea03a3Smacallan ScrnInfoPtr pScrn, 1128e1ea03a3Smacallan int dstx, 1129e1ea03a3Smacallan int dsty, 1130e1ea03a3Smacallan int srcx, 1131e1ea03a3Smacallan int srcy, 1132e1ea03a3Smacallan int maskx, 1133e1ea03a3Smacallan int masky, 1134e1ea03a3Smacallan int width, 1135e1ea03a3Smacallan int height 1136e1ea03a3Smacallan) 1137e1ea03a3Smacallan{ 1138e1ea03a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 1139e1ea03a3Smacallan uint32_t *lsptr, *asptr; 1140e1ea03a3Smacallan uint32_t *dptr, *sptr, aval, pixel, mask; 1141e1ea03a3Smacallan uint8_t *lmptr, *amptr, *mptr; 1142e1ea03a3Smacallan int i, j, k, l, rep = 1, period = fPtr->uw, xoff, lcnt, xa, xe; 1143e1ea03a3Smacallan int bufnum = 0; 1144e1ea03a3Smacallan int sr, sg, sb, sa, rr, gg, bb, aa; 1145e1ea03a3Smacallan 1146e1ea03a3Smacallan LOG(CRIME_DEBUG_XRENDER); 11475b2650b9Smacallan#ifdef CRIME_DEBUG_LOUD 1148e1ea03a3Smacallan xf86Msg(X_ERROR, "%s: %d %d %d %d %d %d\n", __func__, 1149e1ea03a3Smacallan srcx, srcy, dstx, dsty, width, height); 1150e1ea03a3Smacallan#endif 1151e1ea03a3Smacallan sptr = (uint32_t *)fPtr->src + (fPtr->us * srcy) + (srcx << 2); 1152e1ea03a3Smacallan mptr = (uint8_t *)fPtr->msk + (fPtr->um * srcy) + srcx; 1153e1ea03a3Smacallan lsptr = sptr; 1154e1ea03a3Smacallan lmptr = mptr; 1155e1ea03a3Smacallan if ((fPtr->uw < 128) && (fPtr->uw < width)) { 1156e1ea03a3Smacallan rep = 128 / fPtr->uw; 1157e1ea03a3Smacallan period = rep * fPtr->uw; 1158e1ea03a3Smacallan } 1159e1ea03a3Smacallan 1160e1ea03a3Smacallan#ifdef CRIME_DEBUG_LOUD 1161e1ea03a3Smacallan xf86Msg(X_ERROR, "ARGB %08x %d\n", (uint32_t)aptr, fPtr->uw); 1162e1ea03a3Smacallan#endif 1163e1ea03a3Smacallan lcnt = fPtr->uh; 1164e1ea03a3Smacallan for (i = 0; i < height; i++) { 1165e1ea03a3Smacallan dptr = (uint32_t *)fPtr->buffers[bufnum]; 1166e1ea03a3Smacallan for (k = 0; k < rep; k++) { 1167e1ea03a3Smacallan asptr = lsptr; 1168e1ea03a3Smacallan amptr = lmptr; 1169e1ea03a3Smacallan for (j = 0; j < fPtr->uw; j++) { 1170e1ea03a3Smacallan pixel = *asptr; 1171e1ea03a3Smacallan mask = *amptr; 1172e1ea03a3Smacallan if (mask == 0xff) { 1173e1ea03a3Smacallan *dptr = (pixel >> 24) | (pixel << 8); 1174e1ea03a3Smacallan } else if (mask == 0x00) { 1175e1ea03a3Smacallan *dptr = 0; 1176e1ea03a3Smacallan } else { 1177e1ea03a3Smacallan /* input is ARGB */ 1178e1ea03a3Smacallan sb = pixel & 0xff; 1179e1ea03a3Smacallan sg = (pixel >> 8) & 0xff; 1180e1ea03a3Smacallan sr = (pixel >> 16) & 0xff; 1181e1ea03a3Smacallan sa = (pixel >> 24) & 0xff; 1182e1ea03a3Smacallan 1183e1ea03a3Smacallan /* and here we need an RGBA pixel */ 1184e1ea03a3Smacallan bb = (((sb * mask) + 0x80) & 0xff00); 1185e1ea03a3Smacallan gg = (((sg * mask) + 0x80) & 0xff00) 1186e1ea03a3Smacallan << 8; 1187e1ea03a3Smacallan rr = (((sr * mask) + 0x80) & 0xff00) 1188e1ea03a3Smacallan << 16; 1189e1ea03a3Smacallan aa = (((sa * mask) + 0x80) & 0xff00) 1190e1ea03a3Smacallan >> 8; 1191e1ea03a3Smacallan /* 1192e1ea03a3Smacallan * actually we could let the HW do this 1193e1ea03a3Smacallan * stuff 1194e1ea03a3Smacallan */ 1195e1ea03a3Smacallan *dptr = aa | rr | gg | bb; 1196e1ea03a3Smacallan } 1197e1ea03a3Smacallan dptr++; 1198e1ea03a3Smacallan asptr++; 1199e1ea03a3Smacallan amptr++; 1200e1ea03a3Smacallan } 1201e1ea03a3Smacallan } 1202e1ea03a3Smacallan xoff = 0; 120326dcc2a3Smacallan MAKE_ROOM(1); 1204e1ea03a3Smacallan WRITE4(CRIME_DE_XFER_ADDR_SRC, bufnum * 8192); 1205e1ea03a3Smacallan while (xoff < width) { 1206e1ea03a3Smacallan xa = dstx + xoff; 1207e1ea03a3Smacallan xe = dstx + min(xoff + period, width) - 1; 120826dcc2a3Smacallan MAKE_ROOM(2); 1209e1ea03a3Smacallan WRITE4(CRIME_DE_X_VERTEX_0, 1210e1ea03a3Smacallan xa << 16 | (dsty + i)); 1211e1ea03a3Smacallan WRITE4ST(CRIME_DE_X_VERTEX_1, 1212e1ea03a3Smacallan (xe << 16) | (dsty + i)); 1213e1ea03a3Smacallan xoff += period; 1214e1ea03a3Smacallan } 1215e1ea03a3Smacallan bufnum++; 1216e1ea03a3Smacallan if (bufnum == 8) bufnum = 0; 1217e1ea03a3Smacallan lcnt--; 1218e1ea03a3Smacallan if (lcnt == 0) { 1219e1ea03a3Smacallan /* back to the beginning */ 1220e1ea03a3Smacallan lsptr = sptr; 1221e1ea03a3Smacallan lmptr = mptr; 1222e1ea03a3Smacallan lcnt = fPtr->uh; 1223e1ea03a3Smacallan } else 1224e1ea03a3Smacallan /* next line */ 1225e1ea03a3Smacallan lsptr += fPtr->us; 1226e1ea03a3Smacallan lmptr += fPtr->um; 1227e1ea03a3Smacallan } 1228e1ea03a3Smacallan DONE(CRIME_DEBUG_XRENDER); 1229e1ea03a3Smacallan} 1230e1ea03a3Smacallan 1231e1ea03a3Smacallanstatic void 1232e1ea03a3SmacallanCrimeDoCPUToScreenComposite( 1233e1ea03a3Smacallan CARD8 op, 1234e1ea03a3Smacallan PicturePtr pSrc, 1235e1ea03a3Smacallan PicturePtr pMask, 1236e1ea03a3Smacallan PicturePtr pDst, 1237e1ea03a3Smacallan INT16 xSrc, 1238e1ea03a3Smacallan INT16 ySrc, 1239e1ea03a3Smacallan INT16 xMask, 1240e1ea03a3Smacallan INT16 yMask, 1241e1ea03a3Smacallan INT16 xDst, 1242e1ea03a3Smacallan INT16 yDst, 1243e1ea03a3Smacallan CARD16 width, 1244e1ea03a3Smacallan CARD16 height 1245e1ea03a3Smacallan) 1246e1ea03a3Smacallan{ 1247e1ea03a3Smacallan ScreenPtr pScreen = pDst->pDrawable->pScreen; 1248e1ea03a3Smacallan XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen); 1249e1ea03a3Smacallan RegionRec region; 1250e1ea03a3Smacallan CARD32 *formats; 1251e1ea03a3Smacallan int flags = 0; 1252e1ea03a3Smacallan BoxPtr pbox; 1253e1ea03a3Smacallan int nbox, w, h; 1254e1ea03a3Smacallan 1255e1ea03a3Smacallan LOG(CRIME_DEBUG_XRENDER); 1256e1ea03a3Smacallan if (pSrc->transform || (pMask && pMask->transform)) { 1257e1ea03a3Smacallan xf86Msg(X_ERROR, "%s: transform?!\n", __func__); 1258e1ea03a3Smacallan return; 1259e1ea03a3Smacallan } 1260e1ea03a3Smacallan 1261e1ea03a3Smacallan if (pDst->alphaMap || pSrc->alphaMap || (pMask && pMask->alphaMap)) { 1262e1ea03a3Smacallan xf86Msg(X_ERROR, "%s: alpha-map?!\n", __func__); 1263e1ea03a3Smacallan return; 1264e1ea03a3Smacallan } 1265e1ea03a3Smacallan 1266e1ea03a3Smacallan xDst += pDst->pDrawable->x; 1267e1ea03a3Smacallan yDst += pDst->pDrawable->y; 1268e1ea03a3Smacallan xSrc += pSrc->pDrawable->x; 1269e1ea03a3Smacallan ySrc += pSrc->pDrawable->y; 1270e1ea03a3Smacallan 1271e1ea03a3Smacallan if(pMask) { 1272e1ea03a3Smacallan CARD16 red, green, blue, alpha; 1273e1ea03a3Smacallan CARD32 pixel = 1274e1ea03a3Smacallan *((CARD32*)(((PixmapPtr)(pSrc->pDrawable))->devPrivate.ptr)); 127509f0d67cSmacallan#ifdef CRIME_DEBUG_LOUD 1276e1ea03a3Smacallan if(pMask->componentAlpha) { 1277e1ea03a3Smacallan xf86Msg(X_ERROR, "%s: alpha component mask\n", 1278e1ea03a3Smacallan __func__); 127909f0d67cSmacallan xf86Msg(X_ERROR, "src: %d x %d\n", pSrc->pDrawable->width, 128009f0d67cSmacallan pSrc->pDrawable->height); 1281e1ea03a3Smacallan } 128209f0d67cSmacallan#endif 1283e1ea03a3Smacallan if ((pSrc->pDrawable->width == 1) && 1284e1ea03a3Smacallan (pSrc->pDrawable->height == 1)) { 1285e1ea03a3Smacallan 1286e1ea03a3Smacallan if(!XAAGetRGBAFromPixel(pixel, &red, &green, &blue, 1287e1ea03a3Smacallan &alpha, pSrc->format)) { 1288e1ea03a3Smacallan xf86Msg(X_ERROR, "%s: can't read pixel\n", __func__); 1289e1ea03a3Smacallan return; 1290e1ea03a3Smacallan } 1291e1ea03a3Smacallan xMask += pMask->pDrawable->x; 1292e1ea03a3Smacallan yMask += pMask->pDrawable->y; 1293e1ea03a3Smacallan 1294e1ea03a3Smacallan /* pull out color expandable operations here */ 1295e1ea03a3Smacallan if(pMask->format == PICT_a1) { 1296e1ea03a3Smacallan PixmapPtr pPix = (PixmapPtr)(pMask->pDrawable); 1297e1ea03a3Smacallan int skipleft; 1298e1ea03a3Smacallan 1299e1ea03a3Smacallan if (alpha == 0xffff) { 1300e1ea03a3Smacallan /* actually we can but for now we don't care */ 1301e1ea03a3Smacallan xf86Msg(X_ERROR, 1302e1ea03a3Smacallan "can't colour expand with alpha\n"); 1303e1ea03a3Smacallan return; 1304e1ea03a3Smacallan } 1305e1ea03a3Smacallan if (op != PictOpOver) { 1306e1ea03a3Smacallan xf86Msg(X_ERROR, "!over\n"); 1307e1ea03a3Smacallan return; 1308e1ea03a3Smacallan } 1309e1ea03a3Smacallan if (pMask->repeat) { 1310e1ea03a3Smacallan xf86Msg(X_ERROR, "mono repeat\n"); 1311e1ea03a3Smacallan return; 1312e1ea03a3Smacallan } 1313e1ea03a3Smacallan if (!miComputeCompositeRegion (®ion, pSrc, 1314e1ea03a3Smacallan pMask, pDst, xSrc, ySrc, xMask, yMask, xDst, 1315e1ea03a3Smacallan yDst, width, height)) { 1316e1ea03a3Smacallan return; 1317e1ea03a3Smacallan } 1318e1ea03a3Smacallan 1319e1ea03a3Smacallan nbox = REGION_NUM_RECTS(®ion); 1320e1ea03a3Smacallan pbox = REGION_RECTS(®ion); 1321e1ea03a3Smacallan 1322e1ea03a3Smacallan if(!nbox) { 1323e1ea03a3Smacallan return; 1324e1ea03a3Smacallan } 1325e1ea03a3Smacallan 1326e1ea03a3Smacallan XAAGetPixelFromRGBA(&pixel, red, green, blue, 0, 1327e1ea03a3Smacallan pDst->format); 1328e1ea03a3Smacallan 1329e1ea03a3Smacallan xMask -= xDst; 1330e1ea03a3Smacallan yMask -= yDst; 1331e1ea03a3Smacallan 1332e1ea03a3Smacallan while(nbox--) { 1333e1ea03a3Smacallan skipleft = pbox->x1 + xMask; 1334e1ea03a3Smacallan 1335e1ea03a3Smacallan (*infoRec->WriteBitmap)(infoRec->pScrn, pbox->x1, pbox->y1, 1336e1ea03a3Smacallan pbox->x2 - pbox->x1, 1337e1ea03a3Smacallan pbox->y2 - pbox->y1, 1338e1ea03a3Smacallan (unsigned char*)(pPix->devPrivate.ptr) + (pPix->devKind * 1339e1ea03a3Smacallan (pbox->y1 + yMask)) + ((skipleft >> 3) & ~3), 1340e1ea03a3Smacallan pPix->devKind, skipleft & 31, pixel, -1, 1341e1ea03a3Smacallan GXcopy, ~0); 1342e1ea03a3Smacallan pbox++; 1343e1ea03a3Smacallan } 1344e1ea03a3Smacallan 1345e1ea03a3Smacallan /* WriteBitmap sets the Sync flag */ 1346e1ea03a3Smacallan REGION_UNINIT(pScreen, ®ion); 1347e1ea03a3Smacallan DONE(CRIME_DEBUG_XRENDER); 1348e1ea03a3Smacallan return; 1349e1ea03a3Smacallan } 135009f0d67cSmacallan if((pMask->format == PICT_a8) || 135109f0d67cSmacallan (pMask->format == PICT_a8r8g8b8)) { 1352e1ea03a3Smacallan 1353e1ea03a3Smacallan w = pMask->pDrawable->width; 1354e1ea03a3Smacallan h = pMask->pDrawable->height; 1355e1ea03a3Smacallan 1356e1ea03a3Smacallan if(pMask->repeat) { 1357e1ea03a3Smacallan flags |= XAA_RENDER_REPEAT; 1358e1ea03a3Smacallan } 1359e1ea03a3Smacallan 1360e1ea03a3Smacallan if (!miComputeCompositeRegion (®ion, pSrc, pMask, 1361e1ea03a3Smacallan pDst, xSrc, ySrc, xMask, yMask, xDst, yDst, 1362e1ea03a3Smacallan width, height)) { 1363e1ea03a3Smacallan return; 1364e1ea03a3Smacallan } 1365e1ea03a3Smacallan 1366e1ea03a3Smacallan nbox = REGION_NUM_RECTS(®ion); 1367e1ea03a3Smacallan pbox = REGION_RECTS(®ion); 1368e1ea03a3Smacallan 1369e1ea03a3Smacallan if(!nbox) { 1370e1ea03a3Smacallan REGION_UNINIT(pScreen, ®ion); 1371e1ea03a3Smacallan return; 1372e1ea03a3Smacallan } 1373e1ea03a3Smacallan 1374e1ea03a3Smacallan CrimeSetupForCPUToScreenAlphaTexture(infoRec->pScrn, 1375e1ea03a3Smacallan op, red, green, blue, alpha, pMask->format, 1376e1ea03a3Smacallan ((PixmapPtr)(pMask->pDrawable))->devPrivate.ptr, 1377e1ea03a3Smacallan ((PixmapPtr)(pMask->pDrawable))->devKind, 1378e1ea03a3Smacallan w, h, flags); 1379e1ea03a3Smacallan 1380e1ea03a3Smacallan xMask -= xDst; 1381e1ea03a3Smacallan yMask -= yDst; 1382e1ea03a3Smacallan 138309f0d67cSmacallan if (pMask->format != PICT_a8) { 138409f0d67cSmacallan while(nbox--) { 138509f0d67cSmacallan CrimeSubsequentCPUToScreenAlphaTexture32( 138609f0d67cSmacallan infoRec->pScrn, 138709f0d67cSmacallan pbox->x1, pbox->y1, pbox->x1 + xMask, 138809f0d67cSmacallan pbox->y1 + yMask, pbox->x2 - pbox->x1, 138909f0d67cSmacallan pbox->y2 - pbox->y1); 139009f0d67cSmacallan pbox++; 139109f0d67cSmacallan } 139209f0d67cSmacallan } else { 139309f0d67cSmacallan while(nbox--) { 139409f0d67cSmacallan CrimeSubsequentCPUToScreenAlphaTexture( 139509f0d67cSmacallan infoRec->pScrn, 139609f0d67cSmacallan pbox->x1, pbox->y1, pbox->x1 + xMask, 139709f0d67cSmacallan pbox->y1 + yMask, pbox->x2 - pbox->x1, 139809f0d67cSmacallan pbox->y2 - pbox->y1); 139909f0d67cSmacallan pbox++; 140009f0d67cSmacallan } 1401e1ea03a3Smacallan } 1402e1ea03a3Smacallan SET_SYNC_FLAG(infoRec); 1403e1ea03a3Smacallan REGION_UNINIT(pScreen, ®ion); 1404e1ea03a3Smacallan DONE(CRIME_DEBUG_XRENDER); 1405e1ea03a3Smacallan return; 1406e1ea03a3Smacallan } else { 1407e1ea03a3Smacallan xf86Msg(X_ERROR, "unknown mask %x\n", pMask->format); 1408e1ea03a3Smacallan } 1409e1ea03a3Smacallan REGION_UNINIT(pScreen, ®ion); 1410e1ea03a3Smacallan DONE(CRIME_DEBUG_XRENDER); 1411e1ea03a3Smacallan return; 1412e1ea03a3Smacallan } else { 1413e1ea03a3Smacallan /* source isn't solid */ 1414e1ea03a3Smacallan 1415e1ea03a3Smacallan w = pSrc->pDrawable->width; 1416e1ea03a3Smacallan h = pSrc->pDrawable->height; 1417e1ea03a3Smacallan 1418e1ea03a3Smacallan if(pSrc->repeat) 1419e1ea03a3Smacallan flags |= XAA_RENDER_REPEAT; 1420e1ea03a3Smacallan 1421e1ea03a3Smacallan if (!miComputeCompositeRegion (®ion, pSrc, pMask, 1422e1ea03a3Smacallan pDst, xSrc, ySrc, xMask, yMask, xDst, yDst, 1423e1ea03a3Smacallan width, height)) { 1424e1ea03a3Smacallan return; 1425e1ea03a3Smacallan } 1426e1ea03a3Smacallan 1427e1ea03a3Smacallan nbox = REGION_NUM_RECTS(®ion); 1428e1ea03a3Smacallan pbox = REGION_RECTS(®ion); 1429e1ea03a3Smacallan 1430e1ea03a3Smacallan if(!nbox) { 1431e1ea03a3Smacallan REGION_UNINIT(pScreen, ®ion); 1432e1ea03a3Smacallan return; 1433e1ea03a3Smacallan } 1434e1ea03a3Smacallan CrimeSetupForCPUToScreenTextureMask( 1435e1ea03a3Smacallan infoRec->pScrn, op, pMask->format, 1436e1ea03a3Smacallan ((PixmapPtr)(pSrc->pDrawable))->devPrivate.ptr, 1437e1ea03a3Smacallan ((PixmapPtr)(pSrc->pDrawable))->devKind, 1438e1ea03a3Smacallan ((PixmapPtr)(pMask->pDrawable))->devPrivate.ptr, 1439e1ea03a3Smacallan ((PixmapPtr)(pMask->pDrawable))->devKind, 1440e1ea03a3Smacallan w, h, flags); 1441e1ea03a3Smacallan 1442e1ea03a3Smacallan xSrc -= xDst; 1443e1ea03a3Smacallan ySrc -= yDst; 1444e1ea03a3Smacallan 1445e1ea03a3Smacallan if (PICT_FORMAT_BPP(pMask->format) == 32) { 1446e1ea03a3Smacallan while(nbox--) { 1447e1ea03a3Smacallan CrimeSubsequentCPUToScreenTextureMask32( 1448e1ea03a3Smacallan infoRec->pScrn, 1449e1ea03a3Smacallan pbox->x1, pbox->y1, 1450e1ea03a3Smacallan pbox->x1 + xSrc, pbox->y1 + ySrc, 1451e1ea03a3Smacallan xMask, yMask, 1452e1ea03a3Smacallan pbox->x2 - pbox->x1, pbox->y2 - pbox->y1); 1453e1ea03a3Smacallan pbox++; 1454e1ea03a3Smacallan } 1455e1ea03a3Smacallan } else { 1456e1ea03a3Smacallan while(nbox--) { 1457e1ea03a3Smacallan CrimeSubsequentCPUToScreenTextureMask8( 1458e1ea03a3Smacallan infoRec->pScrn, 1459e1ea03a3Smacallan pbox->x1, pbox->y1, pbox->x1 + xSrc, 1460e1ea03a3Smacallan pbox->y1 + ySrc, 1461e1ea03a3Smacallan xMask, yMask, 1462e1ea03a3Smacallan pbox->x2 - pbox->x1, 1463e1ea03a3Smacallan pbox->y2 - pbox->y1); 1464e1ea03a3Smacallan pbox++; 1465e1ea03a3Smacallan } 1466e1ea03a3Smacallan } 1467e1ea03a3Smacallan 1468e1ea03a3Smacallan SET_SYNC_FLAG(infoRec); 1469e1ea03a3Smacallan REGION_UNINIT(pScreen, ®ion); 1470e1ea03a3Smacallan DONE(CRIME_DEBUG_XRENDER); 1471e1ea03a3Smacallan return; 1472e1ea03a3Smacallan } 1473e1ea03a3Smacallan } else { /* no mask */ 1474e1ea03a3Smacallan formats = infoRec->CPUToScreenTextureFormats; 1475e1ea03a3Smacallan 1476e1ea03a3Smacallan w = pSrc->pDrawable->width; 1477e1ea03a3Smacallan h = pSrc->pDrawable->height; 1478e1ea03a3Smacallan 1479e1ea03a3Smacallan if(pSrc->repeat) 1480e1ea03a3Smacallan flags |= XAA_RENDER_REPEAT; 1481e1ea03a3Smacallan 1482e1ea03a3Smacallan while(*formats != pSrc->format) { 1483e1ea03a3Smacallan if(!(*formats)) { 1484e1ea03a3Smacallan xf86Msg(X_ERROR, 1485e1ea03a3Smacallan "%s: format %x not found\n", 1486e1ea03a3Smacallan __func__, pSrc->format); 1487e1ea03a3Smacallan return; 1488e1ea03a3Smacallan } 1489e1ea03a3Smacallan formats++; 1490e1ea03a3Smacallan } 1491e1ea03a3Smacallan 1492e1ea03a3Smacallan if (!miComputeCompositeRegion (®ion, pSrc, pMask, pDst, 1493e1ea03a3Smacallan xSrc, ySrc, xMask, yMask, xDst, yDst, 1494e1ea03a3Smacallan width, height)) { 1495e1ea03a3Smacallan return; 1496e1ea03a3Smacallan } 1497e1ea03a3Smacallan 1498e1ea03a3Smacallan nbox = REGION_NUM_RECTS(®ion); 1499e1ea03a3Smacallan pbox = REGION_RECTS(®ion); 1500e1ea03a3Smacallan 1501e1ea03a3Smacallan if(!nbox) { 1502e1ea03a3Smacallan REGION_UNINIT(pScreen, ®ion); 1503e1ea03a3Smacallan return; 1504e1ea03a3Smacallan } 1505e1ea03a3Smacallan 1506e1ea03a3Smacallan CrimeSetupForCPUToScreenTexture(infoRec->pScrn, 1507e1ea03a3Smacallan op, pSrc->format, 1508e1ea03a3Smacallan ((PixmapPtr)(pSrc->pDrawable))->devPrivate.ptr, 1509e1ea03a3Smacallan ((PixmapPtr)(pSrc->pDrawable))->devKind, 1510e1ea03a3Smacallan w, h, flags); 1511e1ea03a3Smacallan 1512e1ea03a3Smacallan xSrc -= xDst; 1513e1ea03a3Smacallan ySrc -= yDst; 1514e1ea03a3Smacallan 1515e1ea03a3Smacallan while(nbox--) { 1516e1ea03a3Smacallan CrimeSubsequentCPUToScreenTexture(infoRec->pScrn, 1517e1ea03a3Smacallan pbox->x1, pbox->y1, pbox->x1 + xSrc, 1518e1ea03a3Smacallan pbox->y1 + ySrc, pbox->x2 - pbox->x1, 1519e1ea03a3Smacallan pbox->y2 - pbox->y1); 1520e1ea03a3Smacallan pbox++; 1521e1ea03a3Smacallan } 1522e1ea03a3Smacallan 1523e1ea03a3Smacallan SET_SYNC_FLAG(infoRec); 1524e1ea03a3Smacallan REGION_UNINIT(pScreen, ®ion); 1525e1ea03a3Smacallan DONE(CRIME_DEBUG_XRENDER); 1526e1ea03a3Smacallan return; 1527e1ea03a3Smacallan } 1528e1ea03a3Smacallan xf86Msg(X_ERROR, "%s: shouldn't be here\n", __func__); 1529e1ea03a3Smacallan} 1530e1ea03a3Smacallan 1531e1ea03a3Smacallanstatic void 1532e1ea03a3SmacallanCrimeDoScreenToScreenComposite( 1533e1ea03a3Smacallan CARD8 op, 1534e1ea03a3Smacallan PicturePtr pSrc, 1535e1ea03a3Smacallan PicturePtr pMask, 1536e1ea03a3Smacallan PicturePtr pDst, 1537e1ea03a3Smacallan INT16 xSrc, 1538e1ea03a3Smacallan INT16 ySrc, 1539e1ea03a3Smacallan INT16 xMask, 1540e1ea03a3Smacallan INT16 yMask, 1541e1ea03a3Smacallan INT16 xDst, 1542e1ea03a3Smacallan INT16 yDst, 1543e1ea03a3Smacallan CARD16 width, 1544e1ea03a3Smacallan CARD16 height 1545e1ea03a3Smacallan) 1546e1ea03a3Smacallan{ 1547e1ea03a3Smacallan ScreenPtr pScreen = pDst->pDrawable->pScreen; 1548e1ea03a3Smacallan XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen); 1549e1ea03a3Smacallan ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 1550e1ea03a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 1551e1ea03a3Smacallan RegionRec region; 1552e1ea03a3Smacallan CARD32 *formats; 1553e1ea03a3Smacallan int flags = 0; 1554e1ea03a3Smacallan BoxPtr pbox; 1555e1ea03a3Smacallan int nbox; 1556e1ea03a3Smacallan int xs, ys, xd, yd, w, h; 1557e1ea03a3Smacallan 1558e1ea03a3Smacallan LOG(CRIME_DEBUG_XRENDER); 1559e1ea03a3Smacallan if (pSrc->transform || (pMask && pMask->transform)) { 1560e1ea03a3Smacallan xf86Msg(X_ERROR, "%s: mask?!\n", __func__); 1561e1ea03a3Smacallan return; 1562e1ea03a3Smacallan } 1563e1ea03a3Smacallan xf86Msg(X_ERROR, "%s: %d\n", __func__, op); 1564e1ea03a3Smacallan if (pDst->alphaMap || pSrc->alphaMap || (pMask && pMask->alphaMap)) { 1565e1ea03a3Smacallan xf86Msg(X_ERROR, "%s: alpha-map\n", __func__); 1566e1ea03a3Smacallan return; 1567e1ea03a3Smacallan } 1568e1ea03a3Smacallan 1569e1ea03a3Smacallan xDst += pDst->pDrawable->x; 1570e1ea03a3Smacallan yDst += pDst->pDrawable->y; 1571e1ea03a3Smacallan xSrc += pSrc->pDrawable->x; 1572e1ea03a3Smacallan ySrc += pSrc->pDrawable->y; 1573e1ea03a3Smacallan 1574e1ea03a3Smacallan formats = infoRec->CPUToScreenTextureFormats; 1575e1ea03a3Smacallan 1576e1ea03a3Smacallan w = pSrc->pDrawable->width; 1577e1ea03a3Smacallan h = pSrc->pDrawable->height; 1578e1ea03a3Smacallan 1579e1ea03a3Smacallan if(pSrc->repeat) 1580e1ea03a3Smacallan flags |= XAA_RENDER_REPEAT; 1581e1ea03a3Smacallan 1582e1ea03a3Smacallan while(*formats != pSrc->format) { 1583e1ea03a3Smacallan if(!(*formats)) return; 1584e1ea03a3Smacallan formats++; 1585e1ea03a3Smacallan } 1586e1ea03a3Smacallan 1587e1ea03a3Smacallan if (!miComputeCompositeRegion (®ion, pSrc, pMask, pDst, 1588e1ea03a3Smacallan xSrc, ySrc, xMask, yMask, xDst, yDst, width, height)) 1589e1ea03a3Smacallan return; 1590e1ea03a3Smacallan 1591e1ea03a3Smacallan nbox = REGION_NUM_RECTS(®ion); 1592e1ea03a3Smacallan pbox = REGION_RECTS(®ion); 1593e1ea03a3Smacallan 1594e1ea03a3Smacallan if(!nbox) { 1595e1ea03a3Smacallan REGION_UNINIT(pScreen, ®ion); 1596e1ea03a3Smacallan return; 1597e1ea03a3Smacallan } 1598e1ea03a3Smacallan 159926dcc2a3Smacallan MAKE_ROOM(6); 1600e1ea03a3Smacallan WRITE4(CRIME_DE_MODE_SRC, DE_MODE_TLB_A | DE_MODE_BUFDEPTH_32 | 1601e1ea03a3Smacallan DE_MODE_TYPE_RGBA | DE_MODE_PIXDEPTH_32); 160226dcc2a3Smacallan WRITE4(CRIME_DE_MODE_DST, DE_MODE_TLB_A | DE_MODE_BUFDEPTH_32 | 160326dcc2a3Smacallan DE_MODE_TYPE_RGBA | DE_MODE_PIXDEPTH_32); 1604e1ea03a3Smacallan WRITE4(CRIME_DE_XFER_STEP_X, 1); 1605e1ea03a3Smacallan WRITE4(CRIME_DE_ALPHA_FUNC, 1606e1ea03a3Smacallan DE_ALPHA_ADD | 1607e1ea03a3Smacallan (DE_ALPHA_OP_SRC_ALPHA << DE_ALPHA_OP_SRC_SHIFT) | 1608e1ea03a3Smacallan (DE_ALPHA_OP_1_MINUS_SRC_ALPHA << DE_ALPHA_OP_DST_SHIFT)); 1609e1ea03a3Smacallan WRITE4(CRIME_DE_DRAWMODE, 1610e1ea03a3Smacallan DE_DRAWMODE_BYTEMASK | DE_DRAWMODE_ALPHA_BLEND | 1611e1ea03a3Smacallan DE_DRAWMODE_XFER_EN); 1612e1ea03a3Smacallan WRITE4(CRIME_DE_PRIMITIVE, 1613e1ea03a3Smacallan DE_PRIM_RECTANGLE | DE_PRIM_LR | DE_PRIM_TB); 161426dcc2a3Smacallan SYNC; 1615e1ea03a3Smacallan xSrc -= xDst; 1616e1ea03a3Smacallan ySrc -= yDst; 1617e1ea03a3Smacallan 1618e1ea03a3Smacallan /* assume no overlap - might bite us in the arse at some point */ 1619e1ea03a3Smacallan while(nbox--) { 1620e1ea03a3Smacallan xs = pbox->x1 + xSrc; 1621e1ea03a3Smacallan ys = pbox->y1 + ySrc; 1622e1ea03a3Smacallan xd = pbox->x1; 1623e1ea03a3Smacallan yd = pbox->y1; 1624e1ea03a3Smacallan w = pbox->x2 - pbox->x1; 1625e1ea03a3Smacallan h = pbox->y2 - pbox->y1; 162626dcc2a3Smacallan MAKE_ROOM(3); 1627e1ea03a3Smacallan WRITE4(CRIME_DE_XFER_ADDR_SRC,(xs << 16) | (ys & 0xffff)); 1628e1ea03a3Smacallan WRITE4(CRIME_DE_X_VERTEX_0, (xd << 16) | (yd & 0xffff)); 1629e1ea03a3Smacallan WRITE4ST(CRIME_DE_X_VERTEX_1, 1630e1ea03a3Smacallan ((xd + w - 1) << 16) | ((yd + h - 1) & 0xffff)); 1631e1ea03a3Smacallan pbox++; 1632e1ea03a3Smacallan } 1633e1ea03a3Smacallan 1634e1ea03a3Smacallan SET_SYNC_FLAG(infoRec); 1635e1ea03a3Smacallan REGION_UNINIT(pScreen, ®ion); 1636e1ea03a3Smacallan return; 1637e1ea03a3Smacallan} 1638e1ea03a3Smacallan 1639e1ea03a3Smacallanstatic Bool 1640e1ea03a3SmacallanCrimeComposite( 1641e1ea03a3Smacallan CARD8 op, 1642e1ea03a3Smacallan PicturePtr pSrc, 1643e1ea03a3Smacallan PicturePtr pMask, 1644e1ea03a3Smacallan PicturePtr pDst, 1645e1ea03a3Smacallan INT16 xSrc, 1646e1ea03a3Smacallan INT16 ySrc, 1647e1ea03a3Smacallan INT16 xMask, 1648e1ea03a3Smacallan INT16 yMask, 1649e1ea03a3Smacallan INT16 xDst, 1650e1ea03a3Smacallan INT16 yDst, 1651e1ea03a3Smacallan CARD16 width, 1652e1ea03a3Smacallan CARD16 height 1653e1ea03a3Smacallan) 1654e1ea03a3Smacallan{ 1655e1ea03a3Smacallan ScreenPtr pScreen = pDst->pDrawable->pScreen; 1656e1ea03a3Smacallan XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen); 1657e1ea03a3Smacallan 1658e1ea03a3Smacallan LOG(CRIME_DEBUG_XRENDER); 1659e1ea03a3Smacallan 1660e1ea03a3Smacallan if(!REGION_NUM_RECTS(pDst->pCompositeClip)) 1661e1ea03a3Smacallan return TRUE; 1662e1ea03a3Smacallan 1663e1ea03a3Smacallan if(!infoRec->pScrn->vtSema) 1664e1ea03a3Smacallan return FALSE; 1665e1ea03a3Smacallan 1666e1ea03a3Smacallan if((pDst->pDrawable->type == DRAWABLE_WINDOW) || 1667e1ea03a3Smacallan IS_OFFSCREEN_PIXMAP(pDst->pDrawable)) { 1668e1ea03a3Smacallan if ((pSrc->pDrawable->type == DRAWABLE_WINDOW) || 1669e1ea03a3Smacallan IS_OFFSCREEN_PIXMAP(pSrc->pDrawable)) { 1670e1ea03a3Smacallan /* screen-to-screen */ 1671e1ea03a3Smacallan CrimeDoScreenToScreenComposite(op, pSrc, pMask, pDst, 1672e1ea03a3Smacallan xSrc, ySrc, xMask, yMask, 1673e1ea03a3Smacallan xDst, yDst, width, height); 1674e1ea03a3Smacallan return TRUE; 1675e1ea03a3Smacallan } else { 1676e1ea03a3Smacallan /* CPU-to-screen composite */ 1677e1ea03a3Smacallan if (op != PictOpOver) 1678e1ea03a3Smacallan xf86Msg(X_ERROR, "%s: op %d\n", __func__, op); 1679e1ea03a3Smacallan CrimeDoCPUToScreenComposite(op, pSrc, pMask, pDst, 1680e1ea03a3Smacallan xSrc, ySrc, xMask, yMask, 1681e1ea03a3Smacallan xDst, yDst, width, height); 1682e1ea03a3Smacallan return TRUE; 1683e1ea03a3Smacallan } 1684e1ea03a3Smacallan } else { 1685e1ea03a3Smacallan if ((pSrc->pDrawable->type == DRAWABLE_WINDOW) || 1686e1ea03a3Smacallan IS_OFFSCREEN_PIXMAP(pSrc->pDrawable)) { 1687e1ea03a3Smacallan /* screen-to-RAM */ 1688e1ea03a3Smacallan xf86Msg(X_ERROR, "%s: screen-to-RAM composite\n", 1689e1ea03a3Smacallan __func__); 1690e1ea03a3Smacallan return TRUE; 1691e1ea03a3Smacallan } else { 1692e1ea03a3Smacallan /* RAM-to-RAM */ 1693e1ea03a3Smacallan return FALSE; 1694e1ea03a3Smacallan } 1695e1ea03a3Smacallan } 1696e1ea03a3Smacallan xf86Msg(X_ERROR, "composite fucked\n"); 1697e1ea03a3Smacallan} 1698e1ea03a3Smacallan 1699e1ea03a3Smacallanstatic void 1700e1ea03a3SmacallanCrimePolyPoint( 1701e1ea03a3Smacallan DrawablePtr pDraw, 1702e1ea03a3Smacallan GCPtr pGC, 1703e1ea03a3Smacallan int mode, 1704e1ea03a3Smacallan int npt, 1705e1ea03a3Smacallan xPoint *pptInit 1706e1ea03a3Smacallan) 1707e1ea03a3Smacallan{ 1708e1ea03a3Smacallan ScreenPtr pScreen = pDraw->pScreen; 1709e1ea03a3Smacallan ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 1710e1ea03a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 1711e1ea03a3Smacallan BoxPtr pBox; 1712e1ea03a3Smacallan xPoint *ppt, *pts; 1713e1ea03a3Smacallan int x1, x2, y1, y2, x, y, i, nBox; 1714e1ea03a3Smacallan 1715e1ea03a3Smacallan /* make pointlist origin relative */ 1716e1ea03a3Smacallan ppt = pptInit; 1717e1ea03a3Smacallan if (mode == CoordModePrevious) { 1718e1ea03a3Smacallan for (i = 0; i < npt; i++) { 1719e1ea03a3Smacallan ppt++; 1720e1ea03a3Smacallan ppt->x += (ppt-1)->x; 1721e1ea03a3Smacallan ppt->y += (ppt-1)->y; 1722e1ea03a3Smacallan } 1723e1ea03a3Smacallan } 172426dcc2a3Smacallan MAKE_ROOM(6); 172526dcc2a3Smacallan WRITE4(CRIME_DE_MODE_DST, DE_MODE_TLB_A | DE_MODE_BUFDEPTH_32 | 172626dcc2a3Smacallan DE_MODE_TYPE_RGBA | DE_MODE_PIXDEPTH_32); 1727e1ea03a3Smacallan WRITE4(CRIME_DE_FG, pGC->fgPixel << 8); 1728e1ea03a3Smacallan WRITE4(CRIME_DE_ROP, pGC->alu); 1729e1ea03a3Smacallan WRITE4(CRIME_DE_PLANEMASK, pGC->planemask); 1730e1ea03a3Smacallan WRITE4(CRIME_DE_DRAWMODE, 1731e1ea03a3Smacallan DE_DRAWMODE_PLANEMASK | DE_DRAWMODE_BYTEMASK | DE_DRAWMODE_ROP); 1732e1ea03a3Smacallan WRITE4(CRIME_DE_PRIMITIVE, DE_PRIM_POINT); 173326dcc2a3Smacallan SYNC; 1734e1ea03a3Smacallan for (nBox = REGION_NUM_RECTS (pGC->pCompositeClip), 1735e1ea03a3Smacallan pBox = REGION_RECTS (pGC->pCompositeClip); 1736e1ea03a3Smacallan nBox--; pBox++) { 1737e1ea03a3Smacallan 1738e1ea03a3Smacallan pts = pptInit; 1739e1ea03a3Smacallan for (i = 0; i < npt; i++) { 1740e1ea03a3Smacallan x1 = pBox->x1; 1741e1ea03a3Smacallan y1 = pBox->y1; 1742e1ea03a3Smacallan x2 = pBox->x2; 1743e1ea03a3Smacallan y2 = pBox->y2; 1744e1ea03a3Smacallan x = pts->x + pDraw->x; 1745e1ea03a3Smacallan y = pts->y + pDraw->y; 1746e1ea03a3Smacallan if (x1 <= x && x < x2 && y1 <= y && y < y2) { 1747e1ea03a3Smacallan 174826dcc2a3Smacallan MAKE_ROOM(1); 1749e1ea03a3Smacallan WRITE4ST(CRIME_DE_X_VERTEX_0, 1750e1ea03a3Smacallan (x << 16) | y); 1751e1ea03a3Smacallan } 1752e1ea03a3Smacallan pts++; 1753e1ea03a3Smacallan } 1754e1ea03a3Smacallan } 1755e1ea03a3Smacallan} 1756e1ea03a3Smacallan 1757e1ea03a3Smacallanstatic void 1758e1ea03a3SmacallanCrimeValidatePolyPoint( 1759e1ea03a3Smacallan GCPtr pGC, 1760e1ea03a3Smacallan unsigned long changes, 1761e1ea03a3Smacallan DrawablePtr pDraw ) 1762e1ea03a3Smacallan{ 1763e1ea03a3Smacallan 1764e1ea03a3Smacallan if ((pDraw->type == DRAWABLE_WINDOW) || 1765e1ea03a3Smacallan IS_OFFSCREEN_PIXMAP(pDraw)) { 1766e1ea03a3Smacallan pGC->ops->PolyPoint = CrimePolyPoint; 1767e1ea03a3Smacallan } else 1768e1ea03a3Smacallan xf86Msg(X_ERROR, "boo\n"); 1769e1ea03a3Smacallan} 177034c4e112Smacallanstatic void 177134c4e112SmacallanCrimePolyArc(DrawablePtr pDraw, 177234c4e112Smacallan GCPtr pGC, 177334c4e112Smacallan int narcs, 177434c4e112Smacallan xArc *parcs) 177534c4e112Smacallan{ 177634c4e112Smacallan xArc *arc; 177734c4e112Smacallan BoxRec box; 177834c4e112Smacallan int i, x2, y2; 177934c4e112Smacallan RegionPtr cclip; 178034c4e112Smacallan 178134c4e112Smacallan cclip = pGC->pCompositeClip; 178234c4e112Smacallan 178334c4e112Smacallan if(!REGION_NUM_RECTS(cclip)) 178434c4e112Smacallan return; 178534c4e112Smacallan 178634c4e112Smacallan for (arc = parcs, i = narcs; --i >= 0; arc++) { 178734c4e112Smacallan if (miCanZeroArc(arc)) { 178834c4e112Smacallan box.x1 = arc->x + pDraw->x; 178934c4e112Smacallan box.y1 = arc->y + pDraw->y; 179034c4e112Smacallan x2 = box.x1 + (int)arc->width + 1; 179134c4e112Smacallan box.x2 = x2; 179234c4e112Smacallan y2 = box.y1 + (int)arc->height + 1; 179334c4e112Smacallan box.y2 = y2; 179434c4e112Smacallan if ( (x2 <= SHRT_MAX) && (y2 <= SHRT_MAX) && 179534c4e112Smacallan (RECT_IN_REGION(pDraw->pScreen, cclip, &box) == rgnIN) ) 179634c4e112Smacallan miZeroPolyArc(pDraw, pGC, 1, arc); 179734c4e112Smacallan } 179834c4e112Smacallan else 179934c4e112Smacallan miPolyArc(pDraw, pGC, 1, arc); 180034c4e112Smacallan } 180134c4e112Smacallan} 180234c4e112Smacallan 180334c4e112Smacallanstatic void 180434c4e112SmacallanCrimeValidatePolyArc(GCPtr pGC, 180534c4e112Smacallan unsigned long changes, 180634c4e112Smacallan DrawablePtr pDraw) 180734c4e112Smacallan{ 180834c4e112Smacallan if ((pDraw->type == DRAWABLE_WINDOW) || 180934c4e112Smacallan IS_OFFSCREEN_PIXMAP(pDraw)) { 181034c4e112Smacallan pGC->ops->PolyPoint = CrimePolyPoint; 181134c4e112Smacallan /*pGC->ops->PolyArc = miPolyArc;*/ 181234c4e112Smacallan pGC->ops->PolyArc = CrimePolyArc; 181334c4e112Smacallan } else 181434c4e112Smacallan { 181534c4e112Smacallan pGC->ops->PolyPoint = XAAGetFallbackOps()->PolyPoint; 181634c4e112Smacallan pGC->ops->PolyArc = XAAGetFallbackOps()->PolyArc; 181734c4e112Smacallan } 181834c4e112Smacallan} 1819e1ea03a3Smacallan 182026dcc2a3Smacallanstatic void copyRGBAtoARGB(uint32_t *dest, uint32_t *src, int len) 182126dcc2a3Smacallan{ 182226dcc2a3Smacallan while (len > 0) { 182326dcc2a3Smacallan *dest = *src >> 8; 182426dcc2a3Smacallan dest++; 182526dcc2a3Smacallan src++; 182626dcc2a3Smacallan len--; 182726dcc2a3Smacallan } 182826dcc2a3Smacallan} 182926dcc2a3Smacallan 183034c4e112Smacallanstatic void 183134c4e112SmacallanCrimeReadPixmap(ScrnInfoPtr pScrn, 183234c4e112Smacallan int x, 183334c4e112Smacallan int y, 183434c4e112Smacallan int w, 183534c4e112Smacallan int h, 183634c4e112Smacallan unsigned char *dst, 183734c4e112Smacallan int dstwidth, 183834c4e112Smacallan int bpp, 183934c4e112Smacallan int depth) 184034c4e112Smacallan{ 184126dcc2a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 184226dcc2a3Smacallan int bufno = 0; 184326dcc2a3Smacallan int nextbuf, i, len = w << 2; 184426dcc2a3Smacallan int mx = x << 2, offset; 184526dcc2a3Smacallan 184626dcc2a3Smacallan offset = mx & 0x3f; 184726dcc2a3Smacallan mx &= ~0x3f; 184826dcc2a3Smacallan len = (len + offset + 0x3f) & ~0x3f; 184926dcc2a3Smacallan 185026dcc2a3Smacallan LOG(CRIME_DEBUG_IMAGEREAD); 185126dcc2a3Smacallan 185226dcc2a3Smacallan#ifdef CRIME_DEBUG_LOUD 185326dcc2a3Smacallan xf86Msg(X_ERROR, "%s: %d %d %d %d\n", __func__, x, y, w, h); 185426dcc2a3Smacallan#endif 185526dcc2a3Smacallan 185626dcc2a3Smacallan MAKE_ROOM(3); 185726dcc2a3Smacallan 185826dcc2a3Smacallan /* 185926dcc2a3Smacallan * apparently all MTE coordinates are in bytes, not pixels 186026dcc2a3Smacallan * also, the MTE has some crazy alignment requirements - if 186126dcc2a3Smacallan * we don't do as above the thing will deadlock sooner or later 186226dcc2a3Smacallan * We use the MTE here because I couldn't get the rendering engine 186326dcc2a3Smacallan * to actually transfer anything into a linear buffer. The other 186426dcc2a3Smacallan * way around works just fine though. Shouldn't make much of a 186526dcc2a3Smacallan * difference, transfer times should be dominated by copying 186626dcc2a3Smacallan * data in and out of the DMA buffer anyway 186726dcc2a3Smacallan */ 186826dcc2a3Smacallan WRITE4(CRIME_MTE_MODE, (MTE_TLB_LIN_A << MTE_DST_TLB_SHIFT) | 186926dcc2a3Smacallan (MTE_TLB_A << MTE_SRC_TLB_SHIFT) | 187026dcc2a3Smacallan (MTE_DEPTH_8 << MTE_DEPTH_SHIFT) | 187126dcc2a3Smacallan MTE_MODE_DST_ECC | MTE_MODE_COPY); 187226dcc2a3Smacallan WRITE4(CRIME_MTE_SRC_Y_STEP, 1); 187326dcc2a3Smacallan WRITE4(CRIME_MTE_DST_Y_STEP, 1); 187426dcc2a3Smacallan SYNCMTE; 187526dcc2a3Smacallan WRITE4(CRIME_MTE_SRC0, (mx << 16) | y); 187626dcc2a3Smacallan WRITE4(CRIME_MTE_SRC1, ((mx + len) << 16) | y); 187726dcc2a3Smacallan WRITE4(CRIME_MTE_DST0, (bufno << 13)); 187826dcc2a3Smacallan WRITE4ST(CRIME_MTE_DST1, (bufno << 13) + len); 187926dcc2a3Smacallan for (i = y + 1; i < y + h; i++) { 188026dcc2a3Smacallan nextbuf = (bufno + 1) & 7; 188126dcc2a3Smacallan SYNCMTE; 188226dcc2a3Smacallan WRITE4(CRIME_MTE_SRC0, (mx << 16) | i); 188326dcc2a3Smacallan WRITE4(CRIME_MTE_SRC1, ((mx + len) << 16) | i); 188426dcc2a3Smacallan WRITE4(CRIME_MTE_DST0, (nextbuf << 13)); 188526dcc2a3Smacallan WRITE4ST(CRIME_MTE_DST1, (nextbuf << 13) + len); 188626dcc2a3Smacallan copyRGBAtoARGB((uint32_t *)dst, 188726dcc2a3Smacallan (uint32_t *)(fPtr->buffers[bufno] + offset), w); 188826dcc2a3Smacallan dst += dstwidth; 188926dcc2a3Smacallan bufno = nextbuf; 189026dcc2a3Smacallan } 189126dcc2a3Smacallan SYNCMTE; 189226dcc2a3Smacallan copyRGBAtoARGB((uint32_t *)dst, 189326dcc2a3Smacallan (uint32_t *)(fPtr->buffers[bufno] + offset), w); 189426dcc2a3Smacallan DONE(CRIME_DEBUG_IMAGEREAD); 189526dcc2a3Smacallan 189634c4e112Smacallan} 1897e1ea03a3Smacallanint 1898e1ea03a3SmacallanCrimeAccelInit(ScrnInfoPtr pScrn) 1899e1ea03a3Smacallan{ 1900e1ea03a3Smacallan CrimePtr fPtr = CRIMEPTR(pScrn); 1901e1ea03a3Smacallan XAAInfoRecPtr pXAAInfo = fPtr->pXAA; 1902e1ea03a3Smacallan int i; 1903e1ea03a3Smacallan 1904e1ea03a3Smacallan for (i = 0; i < 0x1000; i++) regcache[i] = 0x12345678; 1905e1ea03a3Smacallan LOG(CRIME_DEBUG_ALL); 1906e1ea03a3Smacallan SYNC; 1907e1ea03a3Smacallan WRITE4(CRIME_DE_MODE_DST, DE_MODE_TLB_A | DE_MODE_BUFDEPTH_32 | 1908e1ea03a3Smacallan DE_MODE_TYPE_RGBA | DE_MODE_PIXDEPTH_32); 1909e1ea03a3Smacallan 1910e1ea03a3Smacallan WRITE4(CRIME_DE_XFER_STEP_Y, 1); 191126dcc2a3Smacallan WRITE4(CRIME_DE_XFER_STRD_DST, 4); 1912e1ea03a3Smacallan WRITE4(CRIME_DE_XFER_STRD_SRC, 1); 1913e1ea03a3Smacallan 1914e1ea03a3Smacallan WRITE4(CRIME_MTE_BYTEMASK, 0xffffffff); 1915e1ea03a3Smacallan WRITE4(CRIME_MTE_SRC_Y_STEP, 4); 1916e1ea03a3Smacallan WRITE4(CRIME_MTE_DST_Y_STEP, 4); 191726dcc2a3Smacallan SYNC; 1918e1ea03a3Smacallan 1919e1ea03a3Smacallan /* blit the screen black */ 1920e1ea03a3Smacallan WRITE4(CRIME_DE_DRAWMODE, 1921e1ea03a3Smacallan DE_DRAWMODE_PLANEMASK | DE_DRAWMODE_BYTEMASK | DE_DRAWMODE_ROP); 1922e1ea03a3Smacallan WRITE4(CRIME_DE_ROP, 3); 1923e1ea03a3Smacallan WRITE4(CRIME_DE_PRIMITIVE, DE_PRIM_RECTANGLE | DE_PRIM_LR | DE_PRIM_TB); 1924e1ea03a3Smacallan WRITE4(CRIME_DE_FG, 0); 1925e1ea03a3Smacallan WRITE4(CRIME_DE_X_VERTEX_0, 0); 1926e1ea03a3Smacallan WRITE4ST(CRIME_DE_X_VERTEX_1, 1927e1ea03a3Smacallan fPtr->info.width << 16 | fPtr->info.height); 1928e1ea03a3Smacallan SYNC; 1929e1ea03a3Smacallan 193034c4e112Smacallan pXAAInfo->Flags = /*LINEAR_FRAMEBUFFER |*/ PIXMAP_CACHE | OFFSCREEN_PIXMAPS; 1931e1ea03a3Smacallan pXAAInfo->maxOffPixWidth = fPtr->info.width; 1932e1ea03a3Smacallan pXAAInfo->maxOffPixHeight = 2048; 1933e1ea03a3Smacallan 1934e1ea03a3Smacallan /* Sync */ 1935e1ea03a3Smacallan pXAAInfo->Sync = CrimeSync; 1936e1ea03a3Smacallan 19378e5567ffSmacallan CrimeDisableClipping(pScrn); 19388e5567ffSmacallan 1939e1ea03a3Smacallan /* Screen-to-screen copy */ 1940e1ea03a3Smacallan pXAAInfo->ScreenToScreenCopyFlags = NO_TRANSPARENCY; 1941e1ea03a3Smacallan pXAAInfo->SetupForScreenToScreenCopy = CrimeSetupForScreenToScreenCopy; 1942e1ea03a3Smacallan pXAAInfo->SubsequentScreenToScreenCopy = 1943e1ea03a3Smacallan CrimeSubsequentScreenToScreenCopy; 1944e1ea03a3Smacallan 1945e1ea03a3Smacallan /* rectangle fills */ 1946e1ea03a3Smacallan pXAAInfo->SetupForSolidFill = CrimeSetupForSolidFill; 1947e1ea03a3Smacallan pXAAInfo->SubsequentSolidFillRect = CrimeSubsequentSolidFillRect; 1948e1ea03a3Smacallan 1949e1ea03a3Smacallan /* image writes */ 1950e1ea03a3Smacallan pXAAInfo->ScanlineImageWriteFlags = 1951e1ea03a3Smacallan NO_TRANSPARENCY | LEFT_EDGE_CLIPPING | 1952e1ea03a3Smacallan LEFT_EDGE_CLIPPING_NEGATIVE_X | 1953e1ea03a3Smacallan CPU_TRANSFER_PAD_DWORD | SCANLINE_PAD_DWORD; 1954e1ea03a3Smacallan pXAAInfo->NumScanlineImageWriteBuffers = 8; 1955e1ea03a3Smacallan for (i = 0; i < 8; i++) 1956e1ea03a3Smacallan fPtr->buffers[i] = fPtr->linear + (i * 8192); 1957e1ea03a3Smacallan pXAAInfo->ScanlineImageWriteBuffers = fPtr->buffers; 1958e1ea03a3Smacallan pXAAInfo->SetupForScanlineImageWrite = 1959e1ea03a3Smacallan CrimeSetupForScanlineImageWrite; 1960e1ea03a3Smacallan pXAAInfo->SubsequentScanlineImageWriteRect = 1961e1ea03a3Smacallan CrimeSubsequentImageWriteRect; 1962e1ea03a3Smacallan pXAAInfo->SubsequentImageWriteScanline = 1963e1ea03a3Smacallan CrimeSubsequentImageWriteScanline; 1964e1ea03a3Smacallan 196534c4e112Smacallan /* read pixmap */ 196634c4e112Smacallan pXAAInfo->ReadPixmapFlags = 0 196734c4e112Smacallan | CPU_TRANSFER_PAD_DWORD 196834c4e112Smacallan ; 196934c4e112Smacallan pXAAInfo->ReadPixmap = CrimeReadPixmap; 197034c4e112Smacallan 1971e1ea03a3Smacallan /* colour expansion */ 1972e1ea03a3Smacallan pXAAInfo->ScanlineCPUToScreenColorExpandFillFlags = 1973e1ea03a3Smacallan LEFT_EDGE_CLIPPING; 1974e1ea03a3Smacallan pXAAInfo->NumScanlineColorExpandBuffers = 1; 1975e1ea03a3Smacallan fPtr->expandbuffers[0] = (uint8_t *)fPtr->expand; 1976e1ea03a3Smacallan pXAAInfo->ScanlineColorExpandBuffers = (void *)&fPtr->expandbuffers; 1977e1ea03a3Smacallan pXAAInfo->SetupForScanlineCPUToScreenColorExpandFill = 1978e1ea03a3Smacallan CrimeSetupForCPUToScreenColorExpandFill; 1979e1ea03a3Smacallan pXAAInfo->SubsequentScanlineCPUToScreenColorExpandFill = 1980e1ea03a3Smacallan CrimeSubsequentScanlineCPUToScreenColorExpandFill; 1981e1ea03a3Smacallan pXAAInfo->SubsequentColorExpandScanline = 1982e1ea03a3Smacallan CrimeSubsequentColorExpandScanline; 1983e1ea03a3Smacallan 1984e1ea03a3Smacallan /* clipping */ 1985e1ea03a3Smacallan pXAAInfo->ClippingFlags = HARDWARE_CLIP_SCREEN_TO_SCREEN_COPY | 19865b2650b9Smacallan HARDWARE_CLIP_SOLID_FILL | HARDWARE_CLIP_SOLID_LINE | 19875b2650b9Smacallan HARDWARE_CLIP_MONO_8x8_FILL | HARDWARE_CLIP_DASHED_LINE; 1988e1ea03a3Smacallan pXAAInfo->SetClippingRectangle = CrimeSetClippingRectangle; 1989e1ea03a3Smacallan pXAAInfo->DisableClipping = CrimeDisableClipping; 1990e1ea03a3Smacallan 1991e1ea03a3Smacallan /* solid line drawing */ 1992e1ea03a3Smacallan pXAAInfo->SetupForSolidLine = CrimeSetupForSolidLine; 1993e1ea03a3Smacallan pXAAInfo->SubsequentSolidTwoPointLine = 1994e1ea03a3Smacallan CrimeSubsequentSolidTwoPointLine; 19955b2650b9Smacallan pXAAInfo->SolidLineFlags = 0; 1996e1ea03a3Smacallan 1997e1ea03a3Smacallan /* dashed line drawing */ 1998e1ea03a3Smacallan pXAAInfo->SetupForDashedLine = CrimeSetupForDashedLine; 1999e1ea03a3Smacallan pXAAInfo->SubsequentDashedTwoPointLine = 2000e1ea03a3Smacallan CrimeSubsequentDashedTwoPointLine; 2001e1ea03a3Smacallan pXAAInfo->DashedLineFlags = LINE_PATTERN_MSBFIRST_MSBJUSTIFIED; 2002e1ea03a3Smacallan pXAAInfo->DashPatternMaxLength = 32; 2003e1ea03a3Smacallan 20045b2650b9Smacallan /* mono pattern fills */ 20055b2650b9Smacallan pXAAInfo->Mono8x8PatternFillFlags = HARDWARE_PATTERN_PROGRAMMED_BITS | 20065b2650b9Smacallan HARDWARE_PATTERN_PROGRAMMED_ORIGIN | BIT_ORDER_IN_BYTE_MSBFIRST; 20075b2650b9Smacallan pXAAInfo->SetupForMono8x8PatternFill = CrimeSetupForMono8x8PatternFill; 20085b2650b9Smacallan pXAAInfo->SubsequentMono8x8PatternFillRect = 20095b2650b9Smacallan CrimeSubsequentMono8x8PatternFillRect; 20105b2650b9Smacallan 2011e1ea03a3Smacallan /* XRender acceleration */ 2012e1ea03a3Smacallan#ifdef RENDER 2013e1ea03a3Smacallan pXAAInfo->CPUToScreenAlphaTextureFlags = 0; 2014e1ea03a3Smacallan pXAAInfo->SetupForCPUToScreenAlphaTexture = 2015e1ea03a3Smacallan CrimeSetupForCPUToScreenAlphaTexture; 2016e1ea03a3Smacallan pXAAInfo->SubsequentCPUToScreenAlphaTexture = 2017e1ea03a3Smacallan CrimeSubsequentCPUToScreenAlphaTexture; 2018e1ea03a3Smacallan pXAAInfo->CPUToScreenAlphaTextureFormats = CrimeAlphaTextureFormats; 2019e1ea03a3Smacallan 2020e1ea03a3Smacallan pXAAInfo->SetupForCPUToScreenTexture = CrimeSetupForCPUToScreenTexture; 2021e1ea03a3Smacallan pXAAInfo->SubsequentCPUToScreenTexture = 2022e1ea03a3Smacallan CrimeSubsequentCPUToScreenTexture; 2023e1ea03a3Smacallan pXAAInfo->CPUToScreenTextureFlags = 0; 2024e1ea03a3Smacallan pXAAInfo->CPUToScreenTextureFormats = CrimeTextureFormats; 2025e1ea03a3Smacallan pXAAInfo->Composite = CrimeComposite; 2026e1ea03a3Smacallan#endif 2027e1ea03a3Smacallan pXAAInfo->ValidatePolyPoint = CrimeValidatePolyPoint; 2028e1ea03a3Smacallan pXAAInfo->PolyPointMask = GCFunction; 202934c4e112Smacallan pXAAInfo->ValidatePolyArc = CrimeValidatePolyArc; 203034c4e112Smacallan pXAAInfo->PolyArcMask = GCFunction | GCLineWidth; 2031e1ea03a3Smacallan 2032e1ea03a3Smacallan return -1; 2033e1ea03a3Smacallan} 2034