crime_accel.c revision 29406fd8
1/* $NetBSD: crime_accel.c,v 1.13 2009/10/21 03:28:40 macallan Exp $ */ 2/* 3 * Copyright (c) 2008 Michael Lorenz 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 10 * - Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * - Redistributions in binary form must reproduce the above 13 * copyright notice, this list of conditions and the following 14 * disclaimer in the documentation and/or other materials provided 15 * with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 20 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 21 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 23 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 27 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * POSSIBILITY OF SUCH DAMAGE. 29 * 30 */ 31 32/* a driver for the CRIME rendering engine foundin SGI O2 workstations */ 33 34#include "crime.h" 35#include "picturestr.h" 36#include "xaalocal.h" 37#include "xaa.h" 38#include "mipict.h" 39 40uint32_t regcache[0x1000]; 41 42#define CRIMEREG(p) (volatile uint32_t *)(fPtr->engine + p) 43#define WBFLUSH __asm("sync") 44#if 0 45#define WRITE4(r, v) {if (regcache[r >> 2] != v) { \ 46 *CRIMEREG(r) = v; \ 47 regcache[r >> 2] = v; } } 48#else 49#define WRITE4(r, v) { *CRIMEREG(r) = v; } 50#endif 51#define WRITE4ST(r, v) {WBFLUSH; *CRIMEREG(r + CRIME_DE_START) = v; WBFLUSH;} 52#ifdef CRIME_DEBUG 53#define SYNC { int bail = 0; do {bail++; } \ 54 while(((*CRIMEREG(0x4000) & CRIME_DE_IDLE) == 0) && (bail < 10000000)); \ 55 if (bail == 10000000) { \ 56 xf86Msg(X_ERROR, "sync timeout\n"); \ 57 WRITE4ST(CRIME_MTE_FLUSH, 0); \ 58 WRITE4ST(CRIME_DE_FLUSH, 0); \ 59 } \ 60 } 61#else 62#define SYNC do {} while ((*CRIMEREG(0x4000) & CRIME_DE_IDLE) == 0) 63#endif 64#define SYNCMTE do {} while ((*CRIMEREG(0x4000) & CRIME_DE_MTE_IDLE) == 0) 65#define MAKE_ROOM(x) do {} while ((16 - \ 66 CRIME_PIPE_LEVEL(*CRIMEREG(0x4000))) < x); 67 68#define MAX(a, b) (a > b ? a : b) 69#define MIN(a, b) (a < b ? a : b) 70 71CARD32 CrimeAlphaTextureFormats[] = {PICT_a8, 0}; 72CARD32 CrimeTextureFormats[] = {PICT_a8b8g8r8, PICT_a8r8g8b8, 0}; 73 74void 75CrimeSync(ScrnInfoPtr pScrn) 76{ 77 CrimePtr fPtr = CRIMEPTR(pScrn); 78#if defined(CRIME_DEBUG_LOUD) && (CRIME_DEBUG_MASK & CRIME_DEBUG_SYNC) 79 volatile uint32_t *status = CRIMEREG(CRIME_DE_STATUS); 80 81 xf86Msg(X_ERROR, "%s: %08x\n", __func__, *status); 82#endif 83 LOG(CRIME_DEBUG_SYNC); 84 SYNC; 85} 86 87static void 88CrimeSetupForScreenToScreenCopy( 89 ScrnInfoPtr pScrn, 90 int xdir, 91 int ydir, 92 int rop, 93 unsigned int planemask, 94 int TransparencyColour 95) 96{ 97 CrimePtr fPtr = CRIMEPTR(pScrn); 98 99 LOG(CRIME_DEBUG_BITBLT); 100 MAKE_ROOM(9); 101 if ((rop == GXcopy) && (planemask == 0xffffffff) && (xdir > 0)) { 102 /* use the MTE */ 103 WRITE4(CRIME_MTE_MODE, MTE_MODE_DST_ECC | 104 MTE_TLB_A << MTE_DST_TLB_SHIFT | 105 MTE_TLB_A << MTE_SRC_TLB_SHIFT | 106 MTE_DEPTH_32 << MTE_DEPTH_SHIFT | 107 MTE_MODE_COPY); 108 fPtr->use_mte = 1; 109 if (ydir > 0) { 110 WRITE4(CRIME_MTE_DST_Y_STEP, 1); 111 WRITE4(CRIME_MTE_SRC_Y_STEP, 1); 112 } else { 113 WRITE4(CRIME_MTE_DST_Y_STEP, -1); 114 WRITE4(CRIME_MTE_SRC_Y_STEP, -1); 115 } 116 } else 117 fPtr->use_mte = 0; 118 119 WRITE4(CRIME_DE_XFER_STEP_X, 1); 120 WRITE4(CRIME_DE_PLANEMASK, planemask); 121 WRITE4(CRIME_DE_ROP, rop); 122 WRITE4(CRIME_DE_DRAWMODE, 123 DE_DRAWMODE_PLANEMASK | DE_DRAWMODE_BYTEMASK | 124 DE_DRAWMODE_ROP | DE_DRAWMODE_XFER_EN); 125 WRITE4(CRIME_DE_MODE_SRC, DE_MODE_TLB_A | DE_MODE_BUFDEPTH_32 | 126 DE_MODE_TYPE_RGBA | DE_MODE_PIXDEPTH_32); 127 WRITE4(CRIME_DE_MODE_DST, DE_MODE_TLB_A | DE_MODE_BUFDEPTH_32 | 128 DE_MODE_TYPE_RGBA | DE_MODE_PIXDEPTH_32); 129 fPtr->xdir = xdir; 130 fPtr->ydir = ydir; 131 SYNC; 132 DONE(CRIME_DEBUG_BITBLT); 133} 134 135static void 136CrimeSubsequentScreenToScreenCopy 137( 138 ScrnInfoPtr pScrn, 139 int xSrc, 140 int ySrc, 141 int xDst, 142 int yDst, 143 int w, 144 int h 145) 146{ 147 CrimePtr fPtr = CRIMEPTR(pScrn); 148 uint32_t prim = DE_PRIM_RECTANGLE; 149 uint32_t rxa, rya, rxe, rye, rxs, rys, rxd, ryd, rxde, ryde; 150 151 LOG(CRIME_DEBUG_BITBLT); 152#if defined(CRIME_DEBUG_LOUD) && (CRIME_DEBUG_MASK & CRIME_DEBUG_BITBLT) 153 xf86Msg(X_ERROR, "%s: %d, %d; %d x %d -> %d %d\n", __func__, 154 xSrc, ySrc, w, h, xDst, yDst); 155#endif 156 if ((fPtr->use_mte) && (w > 64) && (abs(ySrc - yDst) > 4) && 157 ((xSrc & 15) == (xDst & 15))) { 158 if (fPtr->ydir == -1) { 159 /* bottom to top */ 160 rye = ySrc; 161 rya = ySrc + h - 1; 162 ryd = yDst + h - 1; 163 ryde = yDst; 164 } else { 165 /* top to bottom */ 166 rye = ySrc + h - 1; 167 rya = ySrc; 168 ryd = yDst; 169 ryde = yDst + h - 1; 170 } 171 rxa = xSrc << 2; 172 rxe = ((xSrc + w) << 2) - 1; 173 rxd = xDst << 2; 174 rxde = ((xDst + w) << 2) - 1; 175 MAKE_ROOM(4); 176 WRITE4(CRIME_MTE_SRC0, (rxa << 16) | rya); 177 WRITE4(CRIME_MTE_SRC1, (rxe << 16) | rye); 178 WRITE4(CRIME_MTE_DST0, (rxd << 16) | ryd); 179 WRITE4ST(CRIME_MTE_DST1, (rxde << 16) | ryde); 180 181 } else { 182 if (fPtr->xdir == -1) { 183 prim |= DE_PRIM_RL; 184 rxe = xDst; 185 rxa = xDst + w - 1; 186 rxs = xSrc + w - 1; 187 } else { 188 prim |= DE_PRIM_LR; 189 rxe = xDst + w - 1; 190 rxa = xDst; 191 rxs = xSrc; 192 } 193 if (fPtr->ydir == -1) { 194 prim |= DE_PRIM_BT; 195 rye = yDst; 196 rya = yDst + h - 1; 197 rys = ySrc + h - 1; 198 } else { 199 prim |= DE_PRIM_TB; 200 rye = yDst + h - 1; 201 rya = yDst; 202 rys = ySrc; 203 } 204 205 MAKE_ROOM(4); 206 WRITE4(CRIME_DE_PRIMITIVE, prim); 207 WRITE4(CRIME_DE_XFER_ADDR_SRC,(rxs << 16) | (rys & 0xffff)); 208 WRITE4(CRIME_DE_X_VERTEX_0, (rxa << 16) | (rya & 0xffff)); 209 WRITE4ST(CRIME_DE_X_VERTEX_1, (rxe << 16) | (rye & 0xffff)); 210 } 211 DONE(CRIME_DEBUG_BITBLT); 212} 213 214static void 215CrimeSetupForSolidFill 216( 217 ScrnInfoPtr pScrn, 218 int colour, 219 int rop, 220 unsigned int planemask 221) 222{ 223 CrimePtr fPtr = CRIMEPTR(pScrn); 224 int i; 225 226 LOG(CRIME_DEBUG_RECTFILL); 227#ifdef MTE_DRAW_RECT 228 if (rop == GXcopy) { 229 fPtr->use_mte = 1; 230 MAKE_ROOM(3); 231 WRITE4(CRIME_MTE_MODE, MTE_MODE_DST_ECC | 232 MTE_TLB_A << MTE_DST_TLB_SHIFT | 233 MTE_TLB_A << MTE_SRC_TLB_SHIFT | 234 MTE_DEPTH_32 << MTE_DEPTH_SHIFT); 235 WRITE4(CRIME_MTE_DST_Y_STEP, 1); 236 WRITE4(CRIME_MTE_BG, colour << 8); 237 SYNCMTE; 238 } else 239#endif 240 { 241 fPtr->use_mte = 0; 242 MAKE_ROOM(7); 243 WRITE4(CRIME_DE_PLANEMASK, planemask); 244 WRITE4(CRIME_DE_ROP, rop); 245 WRITE4(CRIME_DE_FG, colour << 8); 246 WRITE4(CRIME_DE_DRAWMODE, 247 DE_DRAWMODE_PLANEMASK | DE_DRAWMODE_BYTEMASK | 248 DE_DRAWMODE_ROP |\ 249 DE_DRAWMODE_SCISSOR_EN); 250 WRITE4(CRIME_DE_PRIMITIVE, 251 DE_PRIM_RECTANGLE | DE_PRIM_LR | DE_PRIM_TB); 252 WRITE4(CRIME_DE_MODE_DST, DE_MODE_TLB_A | DE_MODE_BUFDEPTH_32 | 253 DE_MODE_TYPE_RGBA | DE_MODE_PIXDEPTH_32); 254 SYNC; 255 } 256 DONE(CRIME_DEBUG_RECTFILL); 257} 258 259static void 260CrimeSubsequentSolidFillRect 261( 262 ScrnInfoPtr pScrn, 263 int x, 264 int y, 265 int w, 266 int h 267) 268{ 269 CrimePtr fPtr = CRIMEPTR(pScrn); 270 int xa, xe, ya, ye; 271 272 LOG(CRIME_DEBUG_RECTFILL); 273#ifdef MTE_DRAW_RECT 274 if (fPtr->use_mte) { 275 276 /* 277 * the MTE doesn't support clipping so we have to do it 278 * ourselves - luckily it's trivial with rectangles 279 */ 280 xa = MAX(fPtr->cxa, x); 281 ya = MAX(fPtr->cya, y); 282 xe = MIN(fPtr->cxe, x + w); 283 ye = MIN(fPtr->cye, y + h); 284 if ((xa < xe) && (ya < ye)) { 285 MAKE_ROOM(2); 286 WRITE4(CRIME_MTE_DST0, (xa << 18) | (ya & 0xffff)); 287 WRITE4ST(CRIME_MTE_DST1, 288 (((xe << 2) - 1 ) << 16) | ((ye - 1) & 0xffff)); 289 } 290 } else 291#endif 292 { 293 MAKE_ROOM(2); 294 WRITE4(CRIME_DE_X_VERTEX_0, (x << 16) | (y & 0xffff)); 295 WRITE4ST(CRIME_DE_X_VERTEX_1, 296 ((x + w - 1) << 16) | ((y + h - 1) & 0xffff)); 297 } 298 DONE(CRIME_DEBUG_RECTFILL); 299} 300 301static void 302CrimeSetupForMono8x8PatternFill(ScrnInfoPtr pScrn, int patx, int paty, 303 int fg, int bg, int rop, unsigned int planemask) 304{ 305 CrimePtr fPtr = CRIMEPTR(pScrn); 306 uint32_t pat; 307 308 LOG(CRIME_DEBUG_RECTFILL); 309 MAKE_ROOM(7); 310 WRITE4(CRIME_DE_PLANEMASK, planemask); 311 WRITE4(CRIME_DE_ROP, rop); 312 WRITE4(CRIME_DE_FG, fg << 8); 313 if (bg == -1) { 314 WRITE4(CRIME_DE_DRAWMODE, 315 DE_DRAWMODE_PLANEMASK | DE_DRAWMODE_BYTEMASK | 316 DE_DRAWMODE_ROP | DE_DRAWMODE_POLY_STIP | 317 DE_DRAWMODE_SCISSOR_EN); 318 } else { 319 WRITE4(CRIME_DE_BG, bg << 8); 320 WRITE4(CRIME_DE_DRAWMODE, 321 DE_DRAWMODE_PLANEMASK | DE_DRAWMODE_BYTEMASK | 322 DE_DRAWMODE_ROP | DE_DRAWMODE_POLY_STIP | 323 DE_DRAWMODE_OPAQUE_STIP | DE_DRAWMODE_SCISSOR_EN); 324 } 325 WRITE4(CRIME_DE_PRIMITIVE, 326 DE_PRIM_RECTANGLE | DE_PRIM_LR | DE_PRIM_TB); 327 WRITE4(CRIME_DE_MODE_DST, DE_MODE_TLB_A | DE_MODE_BUFDEPTH_32 | 328 DE_MODE_TYPE_RGBA | DE_MODE_PIXDEPTH_32); 329 330 /* 331 * we need to store the pattern so we can just hammer it into the 332 * stipple register later on 333 */ 334 pat = patx & 0xff000000; 335 pat |= pat >> 8; 336 fPtr->pattern[0] = pat | (pat >> 16); 337 pat = patx & 0x00ff0000; 338 pat |= pat << 8; 339 fPtr->pattern[1] = pat | (pat >> 16); 340 pat = patx & 0x0000ff00; 341 pat |= pat >> 8; 342 fPtr->pattern[2] = pat | (pat << 16); 343 pat = patx & 0x000000ff; 344 pat |= pat << 8; 345 fPtr->pattern[3] = pat | (pat << 16); 346 347 pat = paty & 0xff000000; 348 pat |= pat >> 8; 349 fPtr->pattern[4] = pat | (pat >> 16); 350 pat = paty & 0x00ff0000; 351 pat |= pat << 8; 352 fPtr->pattern[5] = pat | (pat >> 16); 353 pat = paty & 0x0000ff00; 354 pat |= pat >> 8; 355 fPtr->pattern[6] = pat | (pat << 16); 356 pat = paty & 0x000000ff; 357 pat |= pat << 8; 358 fPtr->pattern[7] = pat | (pat << 16); 359 SYNC; 360 DONE(CRIME_DEBUG_RECTFILL); 361} 362 363static void 364CrimeSubsequentMono8x8PatternFillRect( ScrnInfoPtr pScrn, 365 int patx, int paty, int x, int y, int w, int h) 366{ 367 CrimePtr fPtr = CRIMEPTR(pScrn); 368 int i, pat; 369 370 LOG(CRIME_DEBUG_RECTFILL); 371 372 /* first setup the stipple stuff */ 373 374 MAKE_ROOM(1); 375 WRITE4(CRIME_DE_STIPPLE_MODE, 0x001f0000 | (patx << 24)); 376 pat = paty; 377 378 for (i = 0; i < h; i++) { 379 MAKE_ROOM(3); 380 WRITE4(CRIME_DE_STIPPLE_PAT, fPtr->pattern[pat]); 381 WRITE4(CRIME_DE_X_VERTEX_0, (x << 16) | ((y + i) & 0xffff)); 382 WRITE4ST(CRIME_DE_X_VERTEX_1, 383 ((x + w - 1) << 16) | ((y + i) & 0xffff)); 384 pat = (pat + 1) & 7; 385 } 386 DONE(CRIME_DEBUG_RECTFILL); 387} 388 389static void 390CrimeSetupForScanlineImageWrite(ScrnInfoPtr pScrn, int rop, 391 unsigned int planemask, int trans_color, 392 int bpp, int depth) 393{ 394 CrimePtr fPtr = CRIMEPTR(pScrn); 395 396 LOG(CRIME_DEBUG_IMAGEWRITE); 397#if defined(CRIME_DEBUG_LOUD) && (CRIME_DEBUG_MASK & CRIME_DEBUG_IMAGEWRITE) 398 if ((bpp == 24) || (depth == 24)) 399 xf86Msg(X_ERROR, "%s: %d %d \n", __func__, bpp, depth); 400#endif 401 MAKE_ROOM(7); 402 WRITE4(CRIME_DE_MODE_SRC, DE_MODE_LIN_A | DE_MODE_BUFDEPTH_32 | 403 DE_MODE_TYPE_RGB | DE_MODE_PIXDEPTH_32); 404 WRITE4(CRIME_DE_MODE_DST, DE_MODE_TLB_A | DE_MODE_BUFDEPTH_32 | 405 DE_MODE_TYPE_RGBA | DE_MODE_PIXDEPTH_32); 406 WRITE4(CRIME_DE_PLANEMASK, planemask); 407 WRITE4(CRIME_DE_XFER_STEP_X, 4); 408 WRITE4(CRIME_DE_ROP, rop); 409 WRITE4(CRIME_DE_DRAWMODE, 410 DE_DRAWMODE_PLANEMASK | DE_DRAWMODE_BYTEMASK | DE_DRAWMODE_ROP | 411 DE_DRAWMODE_XFER_EN); 412 WRITE4(CRIME_DE_PRIMITIVE, 413 DE_PRIM_RECTANGLE | DE_PRIM_LR | DE_PRIM_TB); 414 SYNC; 415 DONE(CRIME_DEBUG_IMAGEWRITE); 416} 417 418static void 419CrimeSubsequentImageWriteRect(ScrnInfoPtr pScrn, 420 int x, int y, int w, int h, int skipleft) 421{ 422 CrimePtr fPtr = CRIMEPTR(pScrn); 423 424 LOG(CRIME_DEBUG_IMAGEWRITE); 425 426#if defined(CRIME_DEBUG_LOUD) && (CRIME_DEBUG_MASK & CRIME_DEBUG_IMAGEWRITE) 427 xf86Msg(X_ERROR, "%s: %d %d %d %d\n", __func__, x, y, w, h); 428#endif 429 430 fPtr->start = skipleft; 431 x += skipleft; 432 w -= skipleft; 433 if (x < 0) { 434 fPtr->ux = 0; 435 w += x; 436 fPtr->start -= x; 437 } else { 438 fPtr->ux = x; 439 } 440 fPtr->uy = y; 441 fPtr->uw = w; 442 fPtr->uh = h; 443 DONE(CRIME_DEBUG_IMAGEWRITE); 444} 445 446static void 447CrimeSubsequentImageWriteScanline(ScrnInfoPtr pScrn, int bufno) 448{ 449 CrimePtr fPtr = CRIMEPTR(pScrn); 450 451 LOG(CRIME_DEBUG_IMAGEWRITE); 452 /* 453 * we need to sync here, otherwise we might queue up more copy 454 * commands than we have buffers 455 */ 456 SYNC; 457 WRITE4(CRIME_DE_XFER_ADDR_SRC, (bufno << 13) + (fPtr->start << 2)); 458 WRITE4(CRIME_DE_X_VERTEX_0, (fPtr->ux << 16) | fPtr->uy); 459 WRITE4ST(CRIME_DE_X_VERTEX_1, 460 ((fPtr->ux + fPtr->uw - 1) << 16) | (fPtr->uy)); 461 fPtr->uy++; 462 DONE(CRIME_DEBUG_IMAGEWRITE); 463} 464 465static void 466CrimeSetupForCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, 467 int fg, int bg, 468 int rop, 469 unsigned int planemask) 470{ 471 CrimePtr fPtr = CRIMEPTR(pScrn); 472 473 LOG(CRIME_DEBUG_COLOUREXPAND); 474 MAKE_ROOM(7); 475 WRITE4(CRIME_DE_MODE_DST, DE_MODE_TLB_A | DE_MODE_BUFDEPTH_32 | 476 DE_MODE_TYPE_RGBA | DE_MODE_PIXDEPTH_32); 477 WRITE4(CRIME_DE_PLANEMASK, planemask); 478 WRITE4(CRIME_DE_ROP, rop); 479 WRITE4(CRIME_DE_FG, fg << 8); 480 if (bg == -1) { 481 /* transparent */ 482 WRITE4(CRIME_DE_DRAWMODE, 483 DE_DRAWMODE_PLANEMASK | DE_DRAWMODE_BYTEMASK | 484 DE_DRAWMODE_ROP | DE_DRAWMODE_POLY_STIP); 485 } else { 486 WRITE4(CRIME_DE_BG, bg << 8); 487 WRITE4(CRIME_DE_DRAWMODE, 488 DE_DRAWMODE_PLANEMASK | DE_DRAWMODE_BYTEMASK | 489 DE_DRAWMODE_ROP | 490 DE_DRAWMODE_OPAQUE_STIP | DE_DRAWMODE_POLY_STIP); 491 } 492 WRITE4(CRIME_DE_PRIMITIVE, 493 DE_PRIM_RECTANGLE | DE_PRIM_LR | DE_PRIM_TB); 494 SYNC; 495 DONE(CRIME_DEBUG_COLOUREXPAND); 496} 497 498static void 499CrimeSubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, 500 int x, int y, int w, int h, 501 int skipleft ) 502{ 503 CrimePtr fPtr = CRIMEPTR(pScrn); 504 505 LOG(CRIME_DEBUG_COLOUREXPAND); 506 507 fPtr->start = skipleft; 508 fPtr->ux = x; 509 fPtr->uy = y; 510 fPtr->uw = w; 511 fPtr->uh = h; 512 DONE(CRIME_DEBUG_COLOUREXPAND); 513} 514 515static void 516CrimeSubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno) 517{ 518 CrimePtr fPtr = CRIMEPTR(pScrn); 519 uint32_t *boo = (uint32_t *)fPtr->expandbuffers[bufno]; 520 int idx = fPtr->uw, x = fPtr->ux; 521 522 LOG(CRIME_DEBUG_COLOUREXPAND); 523 524 MAKE_ROOM(5); 525 WRITE4(CRIME_DE_STIPPLE_MODE, 0x001f0000 | (fPtr->start << 24)); 526 WRITE4(CRIME_DE_STIPPLE_PAT, *boo); 527 boo++; 528 WRITE4(CRIME_DE_X_VERTEX_0, (x + fPtr->start << 16) | fPtr->uy); 529 WRITE4ST(CRIME_DE_X_VERTEX_1, 530 ((x + min(idx, 32) - 1) << 16) | (fPtr->uy)); 531 idx -= 32; 532 x += 32; 533 WRITE4(CRIME_DE_STIPPLE_MODE, 0x001f0000); 534 535 while (idx > 0) { 536 MAKE_ROOM(3); 537 WRITE4(CRIME_DE_STIPPLE_PAT, *boo); 538 boo++; 539 WRITE4(CRIME_DE_X_VERTEX_0, (x << 16) | fPtr->uy); 540 WRITE4ST(CRIME_DE_X_VERTEX_1, 541 ((x + min(idx, 32) - 1) << 16) | (fPtr->uy)); 542 idx -= 32; 543 x += 32; 544 } 545 fPtr->uy++; 546 DONE(CRIME_DEBUG_COLOUREXPAND); 547} 548 549static void 550CrimeSetupForSolidLine(ScrnInfoPtr pScrn, int color, int rop, 551 unsigned int planemask) 552{ 553 CrimePtr fPtr = CRIMEPTR(pScrn); 554 555 LOG(CRIME_DEBUG_LINES); 556 557 MAKE_ROOM(5); 558 WRITE4(CRIME_DE_MODE_DST, DE_MODE_TLB_A | DE_MODE_BUFDEPTH_32 | 559 DE_MODE_TYPE_RGBA | DE_MODE_PIXDEPTH_32); 560 WRITE4(CRIME_DE_PLANEMASK, planemask); 561 WRITE4(CRIME_DE_ROP, rop); 562 WRITE4(CRIME_DE_FG, color << 8); 563 WRITE4(CRIME_DE_DRAWMODE, 564 DE_DRAWMODE_PLANEMASK | DE_DRAWMODE_BYTEMASK | 565 DE_DRAWMODE_ROP | DE_DRAWMODE_SCISSOR_EN); 566 SYNC; 567 DONE(CRIME_DEBUG_LINES); 568} 569 570static void 571CrimeSubsequentSolidTwoPointLine(ScrnInfoPtr pScrn, int x1, int y1, int x2, 572 int y2, int flags) 573{ 574 CrimePtr fPtr = CRIMEPTR(pScrn); 575 576 LOG(CRIME_DEBUG_LINES); 577 MAKE_ROOM(3); 578 if (flags & OMIT_LAST) { 579 WRITE4(CRIME_DE_PRIMITIVE, 580 DE_PRIM_LINE | DE_PRIM_LINE_SKIP_END | 2); 581 } else { 582 WRITE4(CRIME_DE_PRIMITIVE, 583 DE_PRIM_LINE | 2); 584 } 585 WRITE4(CRIME_DE_X_VERTEX_0, (x1 << 16) | y1); 586 WRITE4ST(CRIME_DE_X_VERTEX_1, (x2 << 16) | y2); 587 DONE(CRIME_DEBUG_LINES); 588} 589 590void 591CrimeSetupForDashedLine(ScrnInfoPtr pScrn, 592 int fg, int bg, int rop, unsigned int planemask, 593 int length, unsigned char *pattern) 594{ 595 CrimePtr fPtr = CRIMEPTR(pScrn); 596 uint32_t pat; 597 598 LOG(CRIME_DEBUG_LINES); 599 600 fPtr->uw = length; 601 MAKE_ROOM(7); 602 WRITE4(CRIME_DE_MODE_DST, DE_MODE_TLB_A | DE_MODE_BUFDEPTH_32 | 603 DE_MODE_TYPE_RGBA | DE_MODE_PIXDEPTH_32); 604 WRITE4(CRIME_DE_PLANEMASK, planemask); 605 WRITE4(CRIME_DE_ROP, rop); 606 WRITE4(CRIME_DE_FG, fg << 8); 607 if (bg == -1) { 608 /* transparent */ 609 WRITE4(CRIME_DE_DRAWMODE, 610 DE_DRAWMODE_PLANEMASK | DE_DRAWMODE_BYTEMASK | 611 DE_DRAWMODE_ROP | DE_DRAWMODE_LINE_STIP | 612 DE_DRAWMODE_SCISSOR_EN); 613 } else { 614 WRITE4(CRIME_DE_BG, bg << 8); 615 WRITE4(CRIME_DE_DRAWMODE, 616 DE_DRAWMODE_PLANEMASK | DE_DRAWMODE_BYTEMASK | 617 DE_DRAWMODE_ROP | DE_DRAWMODE_SCISSOR_EN | 618 DE_DRAWMODE_OPAQUE_STIP | DE_DRAWMODE_LINE_STIP); 619 } 620 /* 621 * can we trust the Xserver to always hand us a 32bit aligned 622 * pattern buffer? 623 */ 624 memcpy(&pat, pattern, 4); 625 WRITE4(CRIME_DE_STIPPLE_PAT, pat); 626 SYNC; 627 DONE(CRIME_DEBUG_LINES); 628} 629 630void 631CrimeSubsequentDashedTwoPointLine( ScrnInfoPtr pScrn, 632 int x1, int y1, int x2, int y2, int flags, int phase) 633{ 634 CrimePtr fPtr = CRIMEPTR(pScrn); 635 uint32_t stipmode; 636 637 LOG(CRIME_DEBUG_LINES); 638 MAKE_ROOM(4); 639 640 if (flags & OMIT_LAST) { 641 WRITE4(CRIME_DE_PRIMITIVE, 642 DE_PRIM_LINE | DE_PRIM_LINE_SKIP_END | 2); 643 } else { 644 WRITE4(CRIME_DE_PRIMITIVE, 645 DE_PRIM_LINE | 2); 646 } 647 648 stipmode = ((fPtr->uw - 1) << 16) | (phase << 24); 649 WRITE4(CRIME_DE_STIPPLE_MODE, stipmode); 650 WRITE4(CRIME_DE_X_VERTEX_0, (x1 << 16) | y1); 651 WRITE4ST(CRIME_DE_X_VERTEX_1, (x2 << 16) | y2); 652 DONE(CRIME_DEBUG_LINES); 653} 654 655void 656CrimeSetClippingRectangle ( ScrnInfoPtr pScrn, 657 int left, int top, int right, int bottom) 658{ 659 CrimePtr fPtr = CRIMEPTR(pScrn); 660 661 LOG(CRIME_DEBUG_CLIPPING); 662 MAKE_ROOM(2); 663 WRITE4(CRIME_DE_SCISSOR, (left << 16) | top); 664 WRITE4(CRIME_DE_SCISSOR + 4, ((right + 1) << 16) | (bottom + 1)); 665 fPtr->cxa = left; 666 fPtr->cxe = right; 667 fPtr->cya = top; 668 fPtr->cye = bottom; 669 SYNC; 670 DONE(CRIME_DEBUG_CLIPPING); 671} 672 673void 674CrimeDisableClipping (ScrnInfoPtr pScrn) 675{ 676 CrimePtr fPtr = CRIMEPTR(pScrn); 677 678 LOG(CRIME_DEBUG_CLIPPING); 679 MAKE_ROOM(2); 680 WRITE4(CRIME_DE_SCISSOR, 0); 681 WRITE4(CRIME_DE_SCISSOR + 4, 0x3fff3fff); 682 fPtr->cxa = 0; 683 fPtr->cxe = 2047; 684 fPtr->cya = 0; 685 fPtr->cye = 2047; 686 SYNC; 687 DONE(CRIME_DEBUG_CLIPPING); 688} 689 690static Bool 691CrimeSetupForCPUToScreenAlphaTexture ( 692 ScrnInfoPtr pScrn, 693 int op, 694 CARD16 red, 695 CARD16 green, 696 CARD16 blue, 697 CARD16 alpha, 698 int alphaType, 699 CARD8 *alphaPtr, 700 int alphaPitch, 701 int width, 702 int height, 703 int flags 704) 705{ 706 CrimePtr fPtr = CRIMEPTR(pScrn); 707 708 if (op != PictOpOver) { 709 xf86Msg(X_ERROR, "%s: op %d\n", __func__, op); 710 op = PictOpOver; 711 } 712 713 LOG(CRIME_DEBUG_XRENDER); 714 715 fPtr->alpha_color = ((red & 0xff00) << 16) | 716 ((green & 0xff00) << 8) | 717 (blue & 0xff00); 718 fPtr->uw = width; 719 fPtr->uh = height; 720 fPtr->us = alphaPitch; 721 fPtr->alpha_texture = alphaPtr; 722 fPtr->format = alphaType; 723#ifdef CRIME_DEBUG_LOUD 724 if (alphaType != PICT_a8) { 725 xf86Msg(X_ERROR, "ARGB mask %08x %d\n", (uint32_t)alphaPtr, 726 alphaPitch); 727 } 728 xf86Msg(X_ERROR, "%s: %x %x %x\n", __func__, red, green, blue); 729#endif 730 MAKE_ROOM(7); 731 WRITE4(CRIME_DE_MODE_DST, DE_MODE_TLB_A | DE_MODE_BUFDEPTH_32 | 732 DE_MODE_TYPE_RGBA | DE_MODE_PIXDEPTH_32); 733 /* XXX this register is not where it's supposed to be */ 734 WRITE4(CRIME_DE_ALPHA_COLOR, fPtr->alpha_color); 735 if (alphaType == PICT_a8) { 736 if (fPtr->alpha_color == 0) { 737 WRITE4(CRIME_DE_MODE_SRC, DE_MODE_LIN_A | DE_MODE_BUFDEPTH_8 | 738 DE_MODE_TYPE_RGBA | DE_MODE_PIXDEPTH_32); 739 WRITE4(CRIME_DE_XFER_STEP_X, 1); 740 WRITE4(CRIME_DE_ALPHA_FUNC, 741 DE_ALPHA_ADD | 742 (DE_ALPHA_OP_ZERO << DE_ALPHA_OP_SRC_SHIFT) | 743 (DE_ALPHA_OP_1_MINUS_SRC_ALPHA << DE_ALPHA_OP_DST_SHIFT)); 744 } else { 745 WRITE4(CRIME_DE_MODE_SRC, DE_MODE_LIN_A | DE_MODE_BUFDEPTH_32 | 746 DE_MODE_TYPE_RGBA | DE_MODE_PIXDEPTH_32); 747 WRITE4(CRIME_DE_XFER_STEP_X, 4); 748 WRITE4(CRIME_DE_ALPHA_FUNC, 749 DE_ALPHA_ADD | 750 (DE_ALPHA_OP_SRC_ALPHA << DE_ALPHA_OP_SRC_SHIFT) | 751 (DE_ALPHA_OP_1_MINUS_SRC_ALPHA << DE_ALPHA_OP_DST_SHIFT)); 752 } 753 } else { 754 WRITE4(CRIME_DE_MODE_SRC, DE_MODE_LIN_A | DE_MODE_BUFDEPTH_32 | 755 DE_MODE_TYPE_RGBA | DE_MODE_PIXDEPTH_32); 756 WRITE4(CRIME_DE_XFER_STEP_X, 4); 757 WRITE4(CRIME_DE_ALPHA_FUNC, 758 DE_ALPHA_ADD | 759 (DE_ALPHA_OP_SRC_ALPHA << DE_ALPHA_OP_SRC_SHIFT) | 760 (DE_ALPHA_OP_1_MINUS_SRC_ALPHA << DE_ALPHA_OP_DST_SHIFT)); 761 } 762 WRITE4(CRIME_DE_DRAWMODE, 763 DE_DRAWMODE_BYTEMASK | DE_DRAWMODE_ALPHA_BLEND | 764 DE_DRAWMODE_XFER_EN); 765 WRITE4(CRIME_DE_PRIMITIVE, 766 DE_PRIM_RECTANGLE | DE_PRIM_LR | DE_PRIM_TB); 767 SYNC; 768 DONE(CRIME_DEBUG_XRENDER); 769 return TRUE; 770} 771 772void 773CrimeSubsequentCPUToScreenAlphaTexture ( 774 ScrnInfoPtr pScrn, 775 int dstx, 776 int dsty, 777 int srcx, 778 int srcy, 779 int width, 780 int height 781) 782{ 783 CrimePtr fPtr = CRIMEPTR(pScrn); 784 unsigned char *aptr; 785 uint32_t *dptr, aval; 786 int i, j; 787 int bufnum = 0; 788 789 LOG(CRIME_DEBUG_XRENDER); 790#ifdef CRIME_DEBUG_LOUD 791 xf86Msg(X_ERROR, "%d %d %d %d %d %d\n",srcx, srcy, dstx, dsty, width, 792 height); 793#endif 794 aptr = fPtr->alpha_texture + (fPtr->us * srcy) + srcx; 795 for (i = 0; i < height; i++) { 796 dptr = (uint32_t *)fPtr->buffers[bufnum]; 797 if (fPtr->alpha_color == 0) { 798 memcpy(dptr, aptr, width); 799 } else { 800 for (j = 0; j < width; j++) { 801 aval = aptr[j]; 802 *dptr = aval | fPtr->alpha_color; 803 dptr++; 804 } 805 } 806 MAKE_ROOM(3); 807 WRITE4(CRIME_DE_XFER_ADDR_SRC, bufnum * 8192); 808 WRITE4(CRIME_DE_X_VERTEX_0, dstx << 16 | (dsty + i)); 809 WRITE4ST(CRIME_DE_X_VERTEX_1, 810 ((dstx + width - 1) << 16) | (dsty + i)); 811 bufnum++; 812 if (bufnum == 8) bufnum = 0; 813 aptr += fPtr->us; 814 } 815 DONE(CRIME_DEBUG_XRENDER); 816} 817 818void 819CrimeSubsequentCPUToScreenAlphaTexture32 ( 820 ScrnInfoPtr pScrn, 821 int dstx, 822 int dsty, 823 int srcx, 824 int srcy, 825 int width, 826 int height 827) 828{ 829 CrimePtr fPtr = CRIMEPTR(pScrn); 830 uint8_t *aptr; 831 uint32_t *dptr, *sptr; 832 int i, j; 833 int bufnum = 0; 834 835 LOG(CRIME_DEBUG_XRENDER); 836#ifdef CRIME_DEBUG_LOUD_ 837 xf86Msg(X_ERROR, "%d %d %d %d %d %d\n",srcx, srcy, dstx, dsty, width, 838 height); 839#endif 840 aptr = fPtr->alpha_texture + (fPtr->us * srcy) + (srcx << 2); 841 for (i = 0; i < height; i++) { 842 dptr = (uint32_t *)fPtr->buffers[bufnum]; 843 sptr = (uint32_t *)aptr; 844 for (j = 0; j < width; j++) { 845 *dptr = (*sptr >> 24) | fPtr->alpha_color; 846#ifdef CRIME_DEBUG_LOUD_ 847 xf86Msg(X_ERROR, "%08x %08x\n", *sptr, *dptr); 848#endif 849 sptr++; 850 dptr++; 851 } 852 MAKE_ROOM(3); 853 WRITE4(CRIME_DE_XFER_ADDR_SRC, bufnum * 8192); 854 WRITE4(CRIME_DE_X_VERTEX_0, dstx << 16 | (dsty + i)); 855 WRITE4ST(CRIME_DE_X_VERTEX_1, 856 ((dstx + width - 1) << 16) | (dsty + i)); 857 bufnum++; 858 if (bufnum == 8) bufnum = 0; 859 aptr += fPtr->us; 860 } 861 DONE(CRIME_DEBUG_XRENDER); 862} 863 864static Bool 865CrimeSetupForCPUToScreenTexture ( 866 ScrnInfoPtr pScrn, 867 int op, 868 int texType, 869 CARD8 *texPtr, 870 int texPitch, 871 int width, 872 int height, 873 int flags 874) 875{ 876 CrimePtr fPtr = CRIMEPTR(pScrn); 877 878 if (op != PictOpOver) { 879 xf86Msg(X_ERROR, "%s: op %d\n", __func__, op); 880 op = PictOpOver; 881 } 882 883 LOG(CRIME_DEBUG_XRENDER); 884 885 fPtr->uw = width; 886 fPtr->uh = height; 887 fPtr->us = texPitch; 888 fPtr->alpha_texture = texPtr; 889 MAKE_ROOM(6); 890 WRITE4(CRIME_DE_MODE_DST, DE_MODE_TLB_A | DE_MODE_BUFDEPTH_32 | 891 DE_MODE_TYPE_RGBA | DE_MODE_PIXDEPTH_32); 892 if (texType == PICT_a8b8g8r8) { 893 WRITE4(CRIME_DE_MODE_SRC, DE_MODE_LIN_A | DE_MODE_BUFDEPTH_32 | 894 DE_MODE_TYPE_ABGR | DE_MODE_PIXDEPTH_32); 895 } else { 896 WRITE4(CRIME_DE_MODE_SRC, DE_MODE_LIN_A | DE_MODE_BUFDEPTH_32 | 897 DE_MODE_TYPE_RGBA | DE_MODE_PIXDEPTH_32); 898 } 899 fPtr->format = texType; 900 WRITE4(CRIME_DE_XFER_STEP_X, 4); 901 WRITE4(CRIME_DE_ALPHA_FUNC, 902 DE_ALPHA_ADD | 903 (DE_ALPHA_OP_ONE/*SRC_ALPHA*/ << DE_ALPHA_OP_SRC_SHIFT) | 904 (DE_ALPHA_OP_1_MINUS_SRC_ALPHA << DE_ALPHA_OP_DST_SHIFT)); 905 WRITE4(CRIME_DE_DRAWMODE, 906 DE_DRAWMODE_BYTEMASK | DE_DRAWMODE_ALPHA_BLEND | 907 DE_DRAWMODE_XFER_EN); 908 WRITE4(CRIME_DE_PRIMITIVE, 909 DE_PRIM_RECTANGLE | DE_PRIM_LR | DE_PRIM_TB); 910 SYNC; 911 DONE(CRIME_DEBUG_XRENDER); 912 return TRUE; 913} 914 915void 916CrimeSubsequentCPUToScreenTexture ( 917 ScrnInfoPtr pScrn, 918 int dstx, 919 int dsty, 920 int srcx, 921 int srcy, 922 int width, 923 int height 924) 925{ 926 CrimePtr fPtr = CRIMEPTR(pScrn); 927 unsigned char *aptr, *lptr; 928 uint32_t *dptr, *sptr, aval, pixel; 929 int i, j, k, l, rep = 1, period = fPtr->uw, xoff, lcnt, xa, xe; 930 int bufnum = 0; 931 932 LOG(CRIME_DEBUG_XRENDER); 933#ifdef CRIME_DEBUG_LOUD 934 xf86Msg(X_ERROR, "%s: %d %d %d %d %d %d\n", __func__, 935 srcx, srcy, dstx, dsty, width, height); 936#endif 937 if ((width == 1) || (fPtr->format != PICT_a8r8g8b8)) { 938 xf86Msg(X_ERROR, "%s: %d %d %d %d %d %d %d %d\n", __func__, 939 srcx, srcy, dstx, dsty, width, height, fPtr->uw, fPtr->us); 940 return; 941 } 942 943 aptr = fPtr->alpha_texture + (srcx << 2); 944 lptr = aptr + (fPtr->us * srcy); 945 if ((fPtr->uw < 128) && (fPtr->uw < width)) { 946 rep = 128 / fPtr->uw; 947 period = rep * fPtr->uw; 948 } 949 950 if (fPtr->format == PICT_a8b8g8r8) { 951#ifdef CRIME_DEBUG_LOUD 952 xf86Msg(X_ERROR, "ABGR\n"); 953#endif 954 for (i = 0; i < height; i++) { 955 dptr = (uint32_t *)fPtr->buffers[bufnum]; 956 memcpy(dptr, aptr, fPtr->us); 957 MAKE_ROOM(3); 958 WRITE4(CRIME_DE_XFER_ADDR_SRC, bufnum * 8192); 959 WRITE4(CRIME_DE_X_VERTEX_0, dstx << 16 | (dsty + i)); 960 WRITE4ST(CRIME_DE_X_VERTEX_1, 961 ((dstx + width - 1) << 16) | (dsty + i)); 962 bufnum++; 963 if (bufnum == 8) bufnum = 0; 964 aptr += fPtr->us; 965 } 966 } else { 967#ifdef CRIME_DEBUG_LOUD 968 xf86Msg(X_ERROR, "ARGB %08x %d\n", (uint32_t)aptr, fPtr->uw); 969#endif 970 lcnt = fPtr->uh - srcy; 971 for (i = 0; i < height; i++) { 972 dptr = (uint32_t *)fPtr->buffers[bufnum]; 973 for (k = 0; k < rep; k++) { 974 sptr = (uint32_t *)aptr; 975 for (j = 0; j < fPtr->uw; j++) { 976 pixel = *sptr; 977 *dptr = (pixel << 8) | (pixel >> 24); 978 dptr++; 979 sptr++; 980 } 981 } 982 xoff = 0; 983 MAKE_ROOM(1); 984 WRITE4(CRIME_DE_XFER_ADDR_SRC, bufnum * 8192); 985 while (xoff < width) { 986 xa = dstx + xoff; 987 xe = dstx + min(xoff + period, width) - 1; 988 MAKE_ROOM(2); 989 WRITE4(CRIME_DE_X_VERTEX_0, 990 xa << 16 | (dsty + i)); 991 WRITE4ST(CRIME_DE_X_VERTEX_1, 992 (xe << 16) | (dsty + i)); 993 xoff += period; 994 } 995 bufnum++; 996 if (bufnum == 8) bufnum = 0; 997 lcnt--; 998 if (lcnt == 0) { 999 aptr = lptr; 1000 lcnt = fPtr->uh; 1001 } else 1002 aptr += fPtr->us; 1003 } 1004 } 1005 DONE(CRIME_DEBUG_XRENDER); 1006} 1007 1008static Bool 1009CrimeSetupForCPUToScreenTextureMask( 1010 ScrnInfoPtr pScrn, 1011 int op, 1012 int texType, 1013 CARD8 *srcPtr, 1014 int srcPitch, 1015 CARD8 *mskPtr, 1016 int mskPitch, 1017 int width, 1018 int height, 1019 int flags 1020) 1021{ 1022 CrimePtr fPtr = CRIMEPTR(pScrn); 1023 1024 if (op != PictOpOver) { 1025 xf86Msg(X_ERROR, "%s: op %d\n", __func__, op); 1026 op = PictOpOver; 1027 } 1028 1029 LOG(CRIME_DEBUG_XRENDER); 1030 1031 fPtr->uw = width; 1032 fPtr->uh = height; 1033 fPtr->us = srcPitch >> 2; 1034 if (PICT_FORMAT_BPP(texType) == 32) { 1035 fPtr->um = mskPitch >> 2; 1036 } else 1037 fPtr->um = mskPitch; 1038 fPtr->msk = (uint8_t *)mskPtr; 1039 fPtr->src = (uint8_t *)srcPtr; 1040 fPtr->texture_depth = PICT_FORMAT_BPP(texType); 1041 1042 MAKE_ROOM(6); 1043 /* always expect ARGB for now */ 1044 WRITE4(CRIME_DE_MODE_SRC, DE_MODE_LIN_A | DE_MODE_BUFDEPTH_32 | 1045 DE_MODE_TYPE_RGBA | DE_MODE_PIXDEPTH_32); 1046 WRITE4(CRIME_DE_MODE_DST, DE_MODE_TLB_A | DE_MODE_BUFDEPTH_32 | 1047 DE_MODE_TYPE_RGBA | DE_MODE_PIXDEPTH_32); 1048 fPtr->format = texType; 1049 WRITE4(CRIME_DE_ALPHA_FUNC, 1050 DE_ALPHA_ADD | 1051 (DE_ALPHA_OP_SRC_ALPHA << DE_ALPHA_OP_SRC_SHIFT) | 1052 (DE_ALPHA_OP_1_MINUS_SRC_ALPHA << DE_ALPHA_OP_DST_SHIFT)); 1053 WRITE4(CRIME_DE_XFER_STEP_X, 4); 1054 WRITE4(CRIME_DE_DRAWMODE, 1055 DE_DRAWMODE_BYTEMASK | DE_DRAWMODE_ALPHA_BLEND | 1056 DE_DRAWMODE_XFER_EN); 1057 WRITE4(CRIME_DE_PRIMITIVE, 1058 DE_PRIM_RECTANGLE | DE_PRIM_LR | DE_PRIM_TB); 1059 SYNC; 1060 DONE(CRIME_DEBUG_XRENDER); 1061 return TRUE; 1062} 1063 1064void 1065CrimeSubsequentCPUToScreenTextureMask32( 1066 ScrnInfoPtr pScrn, 1067 int dstx, 1068 int dsty, 1069 int srcx, 1070 int srcy, 1071 int maskx, 1072 int masky, 1073 int width, 1074 int height 1075) 1076{ 1077 CrimePtr fPtr = CRIMEPTR(pScrn); 1078 uint32_t *lsptr, *lmptr, *asptr, *amptr; 1079 uint32_t *dptr, *sptr, *mptr, aval, pixel, mask; 1080 int i, j, k, l, rep = 1, period = fPtr->uw, xoff, lcnt, xa, xe; 1081 int bufnum = 0; 1082 int sr, sg, sb, sa, mr, mg, mb, ma, rr, gg, bb, aa; 1083 1084 LOG(CRIME_DEBUG_XRENDER); 1085#ifdef CRIME_DEBUG_LOUD 1086 xf86Msg(X_ERROR, "%s: %d %d %d %d %d %d; %d %d %d\n", __func__, 1087 srcx, srcy, dstx, dsty, width, height, maskx, masky, fPtr->um); 1088#endif 1089 sptr = fPtr->src + (srcx << 2); 1090 mptr = fPtr->msk + (srcx << 2); 1091 lsptr = sptr + (fPtr->us * srcy); 1092 lmptr = mptr + (fPtr->um * srcy); 1093 if ((fPtr->uw < 128) && (fPtr->uw < width)) { 1094 rep = 128 / fPtr->uw; 1095 period = rep * fPtr->uw; 1096 } 1097 1098#ifdef CRIME_DEBUG_LOUD 1099 xf86Msg(X_ERROR, "ARGB %08x %d\n", (uint32_t)asptr, fPtr->uw); 1100#endif 1101 lcnt = fPtr->uh - srcy; 1102 for (i = 0; i < height; i++) { 1103 dptr = (uint32_t *)fPtr->buffers[bufnum]; 1104 for (k = 0; k < rep; k++) { 1105 asptr = lsptr; 1106 amptr = lmptr; 1107 for (j = 0; j < fPtr->uw; j++) { 1108 pixel = *asptr; 1109 mask = *amptr; 1110 if (mask == 0xffffffff) { 1111 *dptr = (pixel >> 24) | (pixel << 8); 1112 } else if (mask == 0x00000000) { 1113 *dptr = 0; 1114 } else { 1115 /* input is ARGB */ 1116 sb = pixel & 0xff; 1117 sg = (pixel >> 8) & 0xff; 1118 sr = (pixel >> 16) & 0xff; 1119 sa = (pixel >> 24) & 0xff; 1120 mb = mask & 0xff; 1121 mg = (mask >> 8) & 0xff; 1122 mr = (mask >> 16) & 0xff; 1123 ma = (mask >> 24) & 0xff; 1124 1125 /* and here we need an RGBA pixel */ 1126 bb = (((sb * mb) + 0x80) & 0xff00); 1127 gg = (((sg * mg) + 0x80) & 0xff00) << 8; 1128 rr = (((sr * mr) + 0x80) & 0xff00) << 16; 1129 aa = (((sa * ma) + 0x80) & 0xff00) >> 8; 1130 /* 1131 * actually we could let the HW do this stuff 1132 */ 1133 *dptr = aa | rr | gg | bb; 1134 } 1135 dptr++; 1136 asptr++; 1137 amptr++; 1138 } 1139 } 1140 xoff = 0; 1141 MAKE_ROOM(1); 1142 WRITE4(CRIME_DE_XFER_ADDR_SRC, bufnum * 8192); 1143 while (xoff < width) { 1144 xa = dstx + xoff; 1145 xe = dstx + min(xoff + period, width) - 1; 1146 MAKE_ROOM(2); 1147 WRITE4(CRIME_DE_X_VERTEX_0, 1148 xa << 16 | (dsty + i)); 1149 WRITE4ST(CRIME_DE_X_VERTEX_1, 1150 (xe << 16) | (dsty + i)); 1151 xoff += period; 1152 } 1153 bufnum++; 1154 if (bufnum == 8) bufnum = 0; 1155 lcnt--; 1156 if (lcnt == 0) { 1157 /* back to the beginning */ 1158 lsptr = sptr; 1159 lmptr = mptr; 1160 lcnt = fPtr->uh; 1161 } else 1162 /* next line */ 1163 lsptr += fPtr->us; 1164 lmptr += fPtr->um; 1165 } 1166 DONE(CRIME_DEBUG_XRENDER); 1167} 1168 1169void 1170CrimeSubsequentCPUToScreenTextureMask8( 1171 ScrnInfoPtr pScrn, 1172 int dstx, 1173 int dsty, 1174 int srcx, 1175 int srcy, 1176 int maskx, 1177 int masky, 1178 int width, 1179 int height 1180) 1181{ 1182 CrimePtr fPtr = CRIMEPTR(pScrn); 1183 uint32_t *lsptr, *asptr; 1184 uint32_t *dptr, *sptr, aval, pixel, mask; 1185 uint8_t *lmptr, *amptr, *mptr; 1186 int i, j, k, l, rep = 1, period = fPtr->uw, xoff, lcnt, xa, xe; 1187 int bufnum = 0; 1188 int sr, sg, sb, sa, rr, gg, bb, aa; 1189 1190 LOG(CRIME_DEBUG_XRENDER); 1191#ifdef CRIME_DEBUG_LOUD 1192 xf86Msg(X_ERROR, "%s: %d %d %d %d %d %d\n", __func__, 1193 srcx, srcy, dstx, dsty, width, height); 1194#endif 1195 sptr = (uint32_t *)fPtr->src + (fPtr->us * srcy) + (srcx << 2); 1196 mptr = (uint8_t *)fPtr->msk + (fPtr->um * srcy) + srcx; 1197 lsptr = sptr; 1198 lmptr = mptr; 1199 if ((fPtr->uw < 128) && (fPtr->uw < width)) { 1200 rep = 128 / fPtr->uw; 1201 period = rep * fPtr->uw; 1202 } 1203 1204#ifdef CRIME_DEBUG_LOUD 1205 xf86Msg(X_ERROR, "ARGB %08x %d\n", (uint32_t)asptr, fPtr->uw); 1206#endif 1207 lcnt = fPtr->uh; 1208 for (i = 0; i < height; i++) { 1209 dptr = (uint32_t *)fPtr->buffers[bufnum]; 1210 for (k = 0; k < rep; k++) { 1211 asptr = lsptr; 1212 amptr = lmptr; 1213 for (j = 0; j < fPtr->uw; j++) { 1214 pixel = *asptr; 1215 mask = *amptr; 1216 if (mask == 0xff) { 1217 *dptr = (pixel >> 24) | (pixel << 8); 1218 } else if (mask == 0x00) { 1219 *dptr = 0; 1220 } else { 1221 /* input is ARGB */ 1222 sb = pixel & 0xff; 1223 sg = (pixel >> 8) & 0xff; 1224 sr = (pixel >> 16) & 0xff; 1225 sa = (pixel >> 24) & 0xff; 1226 1227 /* and here we need an RGBA pixel */ 1228 bb = (((sb * mask) + 0x80) & 0xff00); 1229 gg = (((sg * mask) + 0x80) & 0xff00) 1230 << 8; 1231 rr = (((sr * mask) + 0x80) & 0xff00) 1232 << 16; 1233 aa = (((sa * mask) + 0x80) & 0xff00) 1234 >> 8; 1235 /* 1236 * actually we could let the HW do this 1237 * stuff 1238 */ 1239 *dptr = aa | rr | gg | bb; 1240 } 1241 dptr++; 1242 asptr++; 1243 amptr++; 1244 } 1245 } 1246 xoff = 0; 1247 MAKE_ROOM(1); 1248 WRITE4(CRIME_DE_XFER_ADDR_SRC, bufnum * 8192); 1249 while (xoff < width) { 1250 xa = dstx + xoff; 1251 xe = dstx + min(xoff + period, width) - 1; 1252 MAKE_ROOM(2); 1253 WRITE4(CRIME_DE_X_VERTEX_0, 1254 xa << 16 | (dsty + i)); 1255 WRITE4ST(CRIME_DE_X_VERTEX_1, 1256 (xe << 16) | (dsty + i)); 1257 xoff += period; 1258 } 1259 bufnum++; 1260 if (bufnum == 8) bufnum = 0; 1261 lcnt--; 1262 if (lcnt == 0) { 1263 /* back to the beginning */ 1264 lsptr = sptr; 1265 lmptr = mptr; 1266 lcnt = fPtr->uh; 1267 } else 1268 /* next line */ 1269 lsptr += fPtr->us; 1270 lmptr += fPtr->um; 1271 } 1272 DONE(CRIME_DEBUG_XRENDER); 1273} 1274 1275static void 1276CrimeDoCPUToScreenComposite( 1277 CARD8 op, 1278 PicturePtr pSrc, 1279 PicturePtr pMask, 1280 PicturePtr pDst, 1281 INT16 xSrc, 1282 INT16 ySrc, 1283 INT16 xMask, 1284 INT16 yMask, 1285 INT16 xDst, 1286 INT16 yDst, 1287 CARD16 width, 1288 CARD16 height 1289) 1290{ 1291 ScreenPtr pScreen = pDst->pDrawable->pScreen; 1292 XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen); 1293 RegionRec region; 1294 CARD32 *formats; 1295 int flags = 0; 1296 BoxPtr pbox; 1297 int nbox, w, h; 1298 1299 LOG(CRIME_DEBUG_XRENDER); 1300 if (pSrc->transform || (pMask && pMask->transform)) { 1301 xf86Msg(X_ERROR, "%s: transform?!\n", __func__); 1302 return; 1303 } 1304 1305 if (pDst->alphaMap || pSrc->alphaMap || (pMask && pMask->alphaMap)) { 1306 xf86Msg(X_ERROR, "%s: alpha-map?!\n", __func__); 1307 return; 1308 } 1309 1310 xDst += pDst->pDrawable->x; 1311 yDst += pDst->pDrawable->y; 1312 xSrc += pSrc->pDrawable->x; 1313 ySrc += pSrc->pDrawable->y; 1314 1315 if(pMask) { 1316 CARD16 red, green, blue, alpha; 1317 CARD32 pixel = 1318 *((CARD32*)(((PixmapPtr)(pSrc->pDrawable))->devPrivate.ptr)); 1319#ifdef CRIME_DEBUG_LOUD 1320 if(pMask->componentAlpha) { 1321 xf86Msg(X_ERROR, "%s: alpha component mask\n", 1322 __func__); 1323 xf86Msg(X_ERROR, "src: %d x %d\n", 1324 pSrc->pDrawable->width, 1325 pSrc->pDrawable->height); 1326 } 1327#endif 1328 if ((pSrc->pDrawable->width == 1) && 1329 (pSrc->pDrawable->height == 1)) { 1330 1331 if(!XAAGetRGBAFromPixel(pixel, &red, &green, &blue, 1332 &alpha, pSrc->format)) { 1333 xf86Msg(X_ERROR, "%s: can't read pixel\n", 1334 __func__); 1335 return; 1336 } 1337#ifdef CRIME_DEBUG_LOUD 1338 xf86Msg(X_ERROR, "RGBA: %d %d %d %d\n", red, green, 1339 blue, alpha); 1340#endif 1341 xMask += pMask->pDrawable->x; 1342 yMask += pMask->pDrawable->y; 1343 1344 /* pull out color expandable operations here */ 1345 if(pMask->format == PICT_a1) { 1346 PixmapPtr pPix = (PixmapPtr)(pMask->pDrawable); 1347 int skipleft; 1348 1349 if (op != PictOpOver) { 1350 xf86Msg(X_ERROR, "!over\n"); 1351 return; 1352 } 1353 if (pMask->repeat) { 1354 xf86Msg(X_ERROR, "mono repeat\n"); 1355 return; 1356 } 1357 if (!miComputeCompositeRegion (®ion, pSrc, 1358 pMask, pDst, xSrc, ySrc, xMask, yMask, xDst, 1359 yDst, width, height)) { 1360 return; 1361 } 1362 1363 nbox = REGION_NUM_RECTS(®ion); 1364 pbox = REGION_RECTS(®ion); 1365 1366 if(!nbox) { 1367 return; 1368 } 1369 1370 XAAGetPixelFromRGBA(&pixel, red, green, blue, 0, 1371 pDst->format); 1372 1373 xMask -= xDst; 1374 yMask -= yDst; 1375 1376 while(nbox--) { 1377 skipleft = pbox->x1 + xMask; 1378 1379 (*infoRec->WriteBitmap)(infoRec->pScrn, pbox->x1, pbox->y1, 1380 pbox->x2 - pbox->x1, 1381 pbox->y2 - pbox->y1, 1382 (unsigned char*) 1383 (pPix->devPrivate.ptr) + 1384 (pPix->devKind * 1385 (pbox->y1 + yMask)) + 1386 ((skipleft >> 3) & ~3), 1387 pPix->devKind, skipleft & 31, pixel, 1388 -1, GXcopy, ~0); 1389 pbox++; 1390 } 1391 1392 /* WriteBitmap sets the Sync flag */ 1393 REGION_UNINIT(pScreen, ®ion); 1394 DONE(CRIME_DEBUG_XRENDER); 1395 return; 1396 } 1397 if((pMask->format == PICT_a8) || 1398 (pMask->format == PICT_a8r8g8b8)) { 1399 1400 w = pMask->pDrawable->width; 1401 h = pMask->pDrawable->height; 1402 1403 if(pMask->repeat) { 1404 flags |= XAA_RENDER_REPEAT; 1405 } 1406 1407 if (!miComputeCompositeRegion (®ion, pSrc, pMask, 1408 pDst, xSrc, ySrc, xMask, yMask, xDst, yDst, 1409 width, height)) { 1410 return; 1411 } 1412 1413 nbox = REGION_NUM_RECTS(®ion); 1414 pbox = REGION_RECTS(®ion); 1415 1416 if(!nbox) { 1417 REGION_UNINIT(pScreen, ®ion); 1418 return; 1419 } 1420 1421 CrimeSetupForCPUToScreenAlphaTexture( 1422 infoRec->pScrn, op, red, green, blue, alpha, 1423 pMask->format, 1424 ((PixmapPtr)(pMask->pDrawable))->devPrivate.ptr, 1425 ((PixmapPtr)(pMask->pDrawable))->devKind, 1426 w, h, flags); 1427 1428 xMask -= xDst; 1429 yMask -= yDst; 1430 1431 if (pMask->format != PICT_a8) { 1432 while(nbox--) { 1433 CrimeSubsequentCPUToScreenAlphaTexture32( 1434 infoRec->pScrn, 1435 pbox->x1, pbox->y1, pbox->x1 + xMask, 1436 pbox->y1 + yMask, pbox->x2 - pbox->x1, 1437 pbox->y2 - pbox->y1); 1438 pbox++; 1439 } 1440 } else { 1441 while(nbox--) { 1442 CrimeSubsequentCPUToScreenAlphaTexture( 1443 infoRec->pScrn, 1444 pbox->x1, pbox->y1, 1445 pbox->x1 + xMask, 1446 pbox->y1 + yMask, 1447 pbox->x2 - pbox->x1, 1448 pbox->y2 - pbox->y1); 1449 pbox++; 1450 } 1451 } 1452 SET_SYNC_FLAG(infoRec); 1453 REGION_UNINIT(pScreen, ®ion); 1454 DONE(CRIME_DEBUG_XRENDER); 1455 return; 1456 } else { 1457 xf86Msg(X_ERROR, "unknown mask %x\n", 1458 pMask->format); 1459 } 1460 REGION_UNINIT(pScreen, ®ion); 1461 DONE(CRIME_DEBUG_XRENDER); 1462 return; 1463 } else { 1464 /* source isn't solid */ 1465 1466 w = pSrc->pDrawable->width; 1467 h = pSrc->pDrawable->height; 1468 1469 if(pSrc->repeat) 1470 flags |= XAA_RENDER_REPEAT; 1471 1472 if (!miComputeCompositeRegion (®ion, pSrc, pMask, 1473 pDst, xSrc, ySrc, xMask, yMask, xDst, yDst, 1474 width, height)) { 1475 return; 1476 } 1477 1478 nbox = REGION_NUM_RECTS(®ion); 1479 pbox = REGION_RECTS(®ion); 1480 1481 if(!nbox) { 1482 REGION_UNINIT(pScreen, ®ion); 1483 return; 1484 } 1485 CrimeSetupForCPUToScreenTextureMask( 1486 infoRec->pScrn, op, pMask->format, 1487 ((PixmapPtr)(pSrc->pDrawable))->devPrivate.ptr, 1488 ((PixmapPtr)(pSrc->pDrawable))->devKind, 1489 ((PixmapPtr)(pMask->pDrawable))->devPrivate.ptr, 1490 ((PixmapPtr)(pMask->pDrawable))->devKind, 1491 w, h, flags); 1492 1493 xSrc -= xDst; 1494 ySrc -= yDst; 1495 1496 if (PICT_FORMAT_BPP(pMask->format) == 32) { 1497 while(nbox--) { 1498 CrimeSubsequentCPUToScreenTextureMask32( 1499 infoRec->pScrn, 1500 pbox->x1, pbox->y1, 1501 pbox->x1 + xSrc, pbox->y1 + ySrc, 1502 xMask, yMask, 1503 pbox->x2 - pbox->x1, 1504 pbox->y2 - pbox->y1); 1505 pbox++; 1506 } 1507 } else { 1508 while(nbox--) { 1509 CrimeSubsequentCPUToScreenTextureMask8( 1510 infoRec->pScrn, 1511 pbox->x1, pbox->y1, pbox->x1 + xSrc, 1512 pbox->y1 + ySrc, 1513 xMask, yMask, 1514 pbox->x2 - pbox->x1, 1515 pbox->y2 - pbox->y1); 1516 pbox++; 1517 } 1518 } 1519 1520 SET_SYNC_FLAG(infoRec); 1521 REGION_UNINIT(pScreen, ®ion); 1522 DONE(CRIME_DEBUG_XRENDER); 1523 return; 1524 } 1525 } else { /* no mask */ 1526 formats = infoRec->CPUToScreenTextureFormats; 1527 1528 w = pSrc->pDrawable->width; 1529 h = pSrc->pDrawable->height; 1530 1531 if(pSrc->repeat) 1532 flags |= XAA_RENDER_REPEAT; 1533 1534 while(*formats != pSrc->format) { 1535 if(!(*formats)) { 1536 xf86Msg(X_ERROR, 1537 "%s: format %x not found\n", 1538 __func__, pSrc->format); 1539 return; 1540 } 1541 formats++; 1542 } 1543 1544 if (!miComputeCompositeRegion (®ion, pSrc, pMask, pDst, 1545 xSrc, ySrc, xMask, yMask, xDst, yDst, 1546 width, height)) { 1547 return; 1548 } 1549 1550 nbox = REGION_NUM_RECTS(®ion); 1551 pbox = REGION_RECTS(®ion); 1552 1553 if(!nbox) { 1554 REGION_UNINIT(pScreen, ®ion); 1555 return; 1556 } 1557 1558 CrimeSetupForCPUToScreenTexture(infoRec->pScrn, 1559 op, pSrc->format, 1560 ((PixmapPtr)(pSrc->pDrawable))->devPrivate.ptr, 1561 ((PixmapPtr)(pSrc->pDrawable))->devKind, 1562 w, h, flags); 1563 1564 xSrc -= xDst; 1565 ySrc -= yDst; 1566 1567 while(nbox--) { 1568 CrimeSubsequentCPUToScreenTexture(infoRec->pScrn, 1569 pbox->x1, pbox->y1, pbox->x1 + xSrc, 1570 pbox->y1 + ySrc, pbox->x2 - pbox->x1, 1571 pbox->y2 - pbox->y1); 1572 pbox++; 1573 } 1574 1575 SET_SYNC_FLAG(infoRec); 1576 REGION_UNINIT(pScreen, ®ion); 1577 DONE(CRIME_DEBUG_XRENDER); 1578 return; 1579 } 1580 xf86Msg(X_ERROR, "%s: shouldn't be here\n", __func__); 1581} 1582 1583static void 1584CrimeDoScreenToScreenComposite( 1585 CARD8 op, 1586 PicturePtr pSrc, 1587 PicturePtr pMask, 1588 PicturePtr pDst, 1589 INT16 xSrc, 1590 INT16 ySrc, 1591 INT16 xMask, 1592 INT16 yMask, 1593 INT16 xDst, 1594 INT16 yDst, 1595 CARD16 width, 1596 CARD16 height 1597) 1598{ 1599 ScreenPtr pScreen = pDst->pDrawable->pScreen; 1600 XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen); 1601 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 1602 CrimePtr fPtr = CRIMEPTR(pScrn); 1603 RegionRec region; 1604 CARD32 *formats; 1605 int flags = 0; 1606 BoxPtr pbox; 1607 int nbox; 1608 int xs, ys, xd, yd, w, h; 1609xf86Msg(X_ERROR, "CRIME screen-to-screen composite\n"); 1610 LOG(CRIME_DEBUG_XRENDER); 1611 if (pSrc->transform || (pMask && pMask->transform)) { 1612 xf86Msg(X_ERROR, "%s: mask?!\n", __func__); 1613 return; 1614 } 1615 xf86Msg(X_ERROR, "%s: %d\n", __func__, op); 1616 if (pDst->alphaMap || pSrc->alphaMap || (pMask && pMask->alphaMap)) { 1617 xf86Msg(X_ERROR, "%s: alpha-map\n", __func__); 1618 return; 1619 } 1620 1621 xDst += pDst->pDrawable->x; 1622 yDst += pDst->pDrawable->y; 1623 xSrc += pSrc->pDrawable->x; 1624 ySrc += pSrc->pDrawable->y; 1625 1626 formats = infoRec->CPUToScreenTextureFormats; 1627 1628 w = pSrc->pDrawable->width; 1629 h = pSrc->pDrawable->height; 1630 1631 if(pSrc->repeat) 1632 flags |= XAA_RENDER_REPEAT; 1633 1634 while(*formats != pSrc->format) { 1635 if(!(*formats)) return; 1636 formats++; 1637 } 1638 1639 if (!miComputeCompositeRegion (®ion, pSrc, pMask, pDst, 1640 xSrc, ySrc, xMask, yMask, xDst, yDst, width, height)) 1641 return; 1642 1643 nbox = REGION_NUM_RECTS(®ion); 1644 pbox = REGION_RECTS(®ion); 1645 1646 if(!nbox) { 1647 REGION_UNINIT(pScreen, ®ion); 1648 return; 1649 } 1650 1651 MAKE_ROOM(6); 1652 WRITE4(CRIME_DE_MODE_SRC, DE_MODE_TLB_A | DE_MODE_BUFDEPTH_32 | 1653 DE_MODE_TYPE_RGBA | DE_MODE_PIXDEPTH_32); 1654 WRITE4(CRIME_DE_MODE_DST, DE_MODE_TLB_A | DE_MODE_BUFDEPTH_32 | 1655 DE_MODE_TYPE_RGBA | DE_MODE_PIXDEPTH_32); 1656 WRITE4(CRIME_DE_XFER_STEP_X, 1); 1657 WRITE4(CRIME_DE_ALPHA_FUNC, 1658 DE_ALPHA_ADD | 1659 (DE_ALPHA_OP_SRC_ALPHA << DE_ALPHA_OP_SRC_SHIFT) | 1660 (DE_ALPHA_OP_1_MINUS_SRC_ALPHA << DE_ALPHA_OP_DST_SHIFT)); 1661 WRITE4(CRIME_DE_DRAWMODE, 1662 DE_DRAWMODE_BYTEMASK | DE_DRAWMODE_ALPHA_BLEND | 1663 DE_DRAWMODE_XFER_EN); 1664 WRITE4(CRIME_DE_PRIMITIVE, 1665 DE_PRIM_RECTANGLE | DE_PRIM_LR | DE_PRIM_TB); 1666 SYNC; 1667 xSrc -= xDst; 1668 ySrc -= yDst; 1669 1670 /* assume no overlap - might bite us in the arse at some point */ 1671 while(nbox--) { 1672 xs = pbox->x1 + xSrc; 1673 ys = pbox->y1 + ySrc; 1674 xd = pbox->x1; 1675 yd = pbox->y1; 1676 w = pbox->x2 - pbox->x1; 1677 h = pbox->y2 - pbox->y1; 1678 MAKE_ROOM(3); 1679 WRITE4(CRIME_DE_XFER_ADDR_SRC,(xs << 16) | (ys & 0xffff)); 1680 WRITE4(CRIME_DE_X_VERTEX_0, (xd << 16) | (yd & 0xffff)); 1681 WRITE4ST(CRIME_DE_X_VERTEX_1, 1682 ((xd + w - 1) << 16) | ((yd + h - 1) & 0xffff)); 1683 pbox++; 1684 } 1685 1686 SET_SYNC_FLAG(infoRec); 1687 REGION_UNINIT(pScreen, ®ion); 1688 return; 1689} 1690 1691static Bool 1692CrimeComposite( 1693 CARD8 op, 1694 PicturePtr pSrc, 1695 PicturePtr pMask, 1696 PicturePtr pDst, 1697 INT16 xSrc, 1698 INT16 ySrc, 1699 INT16 xMask, 1700 INT16 yMask, 1701 INT16 xDst, 1702 INT16 yDst, 1703 CARD16 width, 1704 CARD16 height 1705) 1706{ 1707 ScreenPtr pScreen = pDst->pDrawable->pScreen; 1708 XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen); 1709 1710 LOG(CRIME_DEBUG_XRENDER); 1711 1712 if(!REGION_NUM_RECTS(pDst->pCompositeClip)) { 1713#ifdef CRIME_DEBUG_LOUD 1714 xf86Msg(X_ERROR, "%s: empty clip\n", __func__); 1715#endif 1716 return TRUE; 1717 } 1718 1719 if(!infoRec->pScrn->vtSema) { 1720#ifdef CRIME_DEBUG_LOUD 1721 xf86Msg(X_ERROR, "%s: semaphore\n", __func__); 1722#endif 1723 return FALSE; 1724 } 1725 1726 if((pDst->pDrawable->type == DRAWABLE_WINDOW) || 1727 IS_OFFSCREEN_PIXMAP(pDst->pDrawable) || 1728 PIXMAP_IS_SCREEN(pDst->pDrawable)) { 1729 if ((pSrc->pDrawable->type == DRAWABLE_WINDOW) || 1730 IS_OFFSCREEN_PIXMAP(pSrc->pDrawable) || 1731 PIXMAP_IS_SCREEN(pSrc->pDrawable)) { 1732 /* screen-to-screen */ 1733 CrimeDoScreenToScreenComposite(op, pSrc, pMask, pDst, 1734 xSrc, ySrc, xMask, yMask, 1735 xDst, yDst, width, height); 1736 return TRUE; 1737 } else { 1738 /* CPU-to-screen composite */ 1739 if (op != PictOpOver) 1740 xf86Msg(X_ERROR, "%s: op %d\n", __func__, op); 1741 CrimeDoCPUToScreenComposite(op, pSrc, pMask, pDst, 1742 xSrc, ySrc, xMask, yMask, 1743 xDst, yDst, width, height); 1744 return TRUE; 1745 } 1746 } else { 1747 if ((pSrc->pDrawable->type == DRAWABLE_WINDOW) || 1748 IS_OFFSCREEN_PIXMAP(pSrc->pDrawable) || 1749 PIXMAP_IS_SCREEN(pSrc->pDrawable)) { 1750 /* 1751 * screen-to-RAM 1752 * Download from screen, then composite 1753 */ 1754 xf86Msg(X_ERROR, "%s: screen-to-RAM composite\n", 1755 __func__); 1756 return TRUE; 1757 } else { 1758 /* RAM-to-RAM */ 1759#ifdef CRIME_DEBUG_LOUD 1760 xf86Msg(X_ERROR, "%s: fallback %d, %08x %08x %08x\n", 1761 __func__, op, (uint32_t)pSrc->format, 1762 (uint32_t)pDst->format, 1763 pMask == NULL ? 0 : (uint32_t)pMask->format); 1764#endif 1765#if 0 1766 return FALSE; 1767#else 1768 return fbComposite(op, pSrc, pMask, pDst, xSrc, ySrc, 1769 xMask, yMask, xDst, yDst, width, height); 1770#endif 1771 } 1772 } 1773 xf86Msg(X_ERROR, "composite fucked\n"); 1774} 1775 1776static Bool 1777CrimeGlyphs (CARD8 op, 1778 PicturePtr pSrc, 1779 PicturePtr pDst, 1780 PictFormatPtr maskFormat, 1781 INT16 xSrc, 1782 INT16 ySrc, 1783 int nlist, 1784 GlyphListPtr list, 1785 GlyphPtr *glyphs) 1786{ 1787 ScreenPtr pScreen = pDst->pDrawable->pScreen; 1788 PicturePtr pPicture; 1789 GlyphPtr glyph; 1790 int xDst = list->xOff, yDst = list->yOff; 1791 int x = 0, y = 0, i, n; 1792 1793 while (nlist--) { 1794 x += list->xOff; 1795 y += list->yOff; 1796 n = list->len; 1797 while (n--) { 1798 glyph = *glyphs++; 1799 pPicture = GlyphPicture (glyph)[pScreen->myNum]; 1800 1801 CrimeComposite (op, 1802 pSrc, 1803 pPicture, 1804 pDst, 1805 xSrc + (x - glyph->info.x) - xDst, 1806 ySrc + (y - glyph->info.y) - yDst, 1807 0, 0, 1808 x - glyph->info.x, 1809 y - glyph->info.y, 1810 glyph->info.width, 1811 glyph->info.height); 1812 1813 x += glyph->info.xOff; 1814 y += glyph->info.yOff; 1815 } 1816 list++; 1817 } 1818 return TRUE; 1819} 1820 1821static void 1822CrimePolyPoint( 1823 DrawablePtr pDraw, 1824 GCPtr pGC, 1825 int mode, 1826 int npt, 1827 xPoint *pptInit 1828) 1829{ 1830 ScreenPtr pScreen = pDraw->pScreen; 1831 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 1832 CrimePtr fPtr = CRIMEPTR(pScrn); 1833 BoxPtr pBox; 1834 xPoint *ppt, *pts; 1835 int x1, x2, y1, y2, x, y, i, nBox; 1836 1837 /* make pointlist origin relative */ 1838 ppt = pptInit; 1839 if (mode == CoordModePrevious) { 1840 for (i = 0; i < npt; i++) { 1841 ppt++; 1842 ppt->x += (ppt-1)->x; 1843 ppt->y += (ppt-1)->y; 1844 } 1845 } 1846 MAKE_ROOM(6); 1847 WRITE4(CRIME_DE_MODE_DST, DE_MODE_TLB_A | DE_MODE_BUFDEPTH_32 | 1848 DE_MODE_TYPE_RGBA | DE_MODE_PIXDEPTH_32); 1849 WRITE4(CRIME_DE_FG, pGC->fgPixel << 8); 1850 WRITE4(CRIME_DE_ROP, pGC->alu); 1851 WRITE4(CRIME_DE_PLANEMASK, pGC->planemask); 1852 WRITE4(CRIME_DE_DRAWMODE, 1853 DE_DRAWMODE_PLANEMASK | DE_DRAWMODE_BYTEMASK | DE_DRAWMODE_ROP); 1854 WRITE4(CRIME_DE_PRIMITIVE, DE_PRIM_POINT); 1855 SYNC; 1856 for (nBox = REGION_NUM_RECTS (pGC->pCompositeClip), 1857 pBox = REGION_RECTS (pGC->pCompositeClip); 1858 nBox--; pBox++) { 1859 1860 pts = pptInit; 1861 for (i = 0; i < npt; i++) { 1862 x1 = pBox->x1; 1863 y1 = pBox->y1; 1864 x2 = pBox->x2; 1865 y2 = pBox->y2; 1866 x = pts->x + pDraw->x; 1867 y = pts->y + pDraw->y; 1868 if (x1 <= x && x < x2 && y1 <= y && y < y2) { 1869 1870 MAKE_ROOM(1); 1871 WRITE4ST(CRIME_DE_X_VERTEX_0, 1872 (x << 16) | y); 1873 } 1874 pts++; 1875 } 1876 } 1877} 1878 1879static void 1880CrimeValidatePolyPoint( 1881 GCPtr pGC, 1882 unsigned long changes, 1883 DrawablePtr pDraw ) 1884{ 1885 1886 if ((pDraw->type == DRAWABLE_WINDOW) || 1887 IS_OFFSCREEN_PIXMAP(pDraw)) { 1888 pGC->ops->PolyPoint = CrimePolyPoint; 1889 } else 1890 xf86Msg(X_ERROR, "boo\n"); 1891} 1892static void 1893CrimePolyArc(DrawablePtr pDraw, 1894 GCPtr pGC, 1895 int narcs, 1896 xArc *parcs) 1897{ 1898 xArc *arc; 1899 BoxRec box; 1900 int i, x2, y2; 1901 RegionPtr cclip; 1902 1903 cclip = pGC->pCompositeClip; 1904 1905 if(!REGION_NUM_RECTS(cclip)) 1906 return; 1907 1908 for (arc = parcs, i = narcs; --i >= 0; arc++) { 1909 if (miCanZeroArc(arc)) { 1910 box.x1 = arc->x + pDraw->x; 1911 box.y1 = arc->y + pDraw->y; 1912 x2 = box.x1 + (int)arc->width + 1; 1913 box.x2 = x2; 1914 y2 = box.y1 + (int)arc->height + 1; 1915 box.y2 = y2; 1916 if ( (x2 <= SHRT_MAX) && (y2 <= SHRT_MAX) && 1917 (RECT_IN_REGION(pDraw->pScreen, cclip, &box) == rgnIN) ) 1918 miZeroPolyArc(pDraw, pGC, 1, arc); 1919 } 1920 else 1921 miPolyArc(pDraw, pGC, 1, arc); 1922 } 1923} 1924 1925static void 1926CrimeValidatePolyArc(GCPtr pGC, 1927 unsigned long changes, 1928 DrawablePtr pDraw) 1929{ 1930 if ((pDraw->type == DRAWABLE_WINDOW) || 1931 IS_OFFSCREEN_PIXMAP(pDraw)) { 1932 pGC->ops->PolyPoint = CrimePolyPoint; 1933 /*pGC->ops->PolyArc = miPolyArc;*/ 1934 pGC->ops->PolyArc = CrimePolyArc; 1935 } else 1936 { 1937 pGC->ops->PolyPoint = XAAGetFallbackOps()->PolyPoint; 1938 pGC->ops->PolyArc = XAAGetFallbackOps()->PolyArc; 1939 } 1940} 1941 1942static void copyRGBAtoARGB(uint32_t *dest, uint32_t *src, int len) 1943{ 1944 while (len > 0) { 1945 *dest = *src >> 8; 1946 dest++; 1947 src++; 1948 len--; 1949 } 1950} 1951 1952static void 1953CrimeReadPixmap(ScrnInfoPtr pScrn, 1954 int x, 1955 int y, 1956 int w, 1957 int h, 1958 unsigned char *dst, 1959 int dstwidth, 1960 int bpp, 1961 int depth) 1962{ 1963 CrimePtr fPtr = CRIMEPTR(pScrn); 1964 int bufno = 0; 1965 int nextbuf, i, len = w << 2; 1966 int mx = x << 2, offset; 1967 1968 offset = mx & 0x3f; 1969 mx &= ~0x3f; 1970 len = (len + offset + 0x3f) & ~0x3f; 1971 1972 LOG(CRIME_DEBUG_IMAGEREAD); 1973 1974#ifdef CRIME_DEBUG_LOUD 1975 xf86Msg(X_ERROR, "%s: %d %d %d %d\n", __func__, x, y, w, h); 1976#endif 1977 1978 MAKE_ROOM(3); 1979 1980 /* 1981 * apparently all MTE coordinates are in bytes, not pixels 1982 * also, the MTE has some crazy alignment requirements - if 1983 * we don't do as above the thing will deadlock sooner or later 1984 * We use the MTE here because I couldn't get the rendering engine 1985 * to actually transfer anything into a linear buffer. The other 1986 * way around works just fine though. Shouldn't make much of a 1987 * difference, transfer times should be dominated by copying 1988 * data in and out of the DMA buffer anyway 1989 */ 1990 WRITE4(CRIME_MTE_MODE, (MTE_TLB_LIN_A << MTE_DST_TLB_SHIFT) | 1991 (MTE_TLB_A << MTE_SRC_TLB_SHIFT) | 1992 (MTE_DEPTH_8 << MTE_DEPTH_SHIFT) | 1993 MTE_MODE_DST_ECC | MTE_MODE_COPY); 1994 WRITE4(CRIME_MTE_SRC_Y_STEP, 1); 1995 WRITE4(CRIME_MTE_DST_Y_STEP, 1); 1996 SYNCMTE; 1997 WRITE4(CRIME_MTE_SRC0, (mx << 16) | y); 1998 WRITE4(CRIME_MTE_SRC1, ((mx + len) << 16) | y); 1999 WRITE4(CRIME_MTE_DST0, (bufno << 13)); 2000 WRITE4ST(CRIME_MTE_DST1, (bufno << 13) + len); 2001 for (i = y + 1; i < y + h; i++) { 2002 nextbuf = (bufno + 1) & 7; 2003 SYNCMTE; 2004 WRITE4(CRIME_MTE_SRC0, (mx << 16) | i); 2005 WRITE4(CRIME_MTE_SRC1, ((mx + len) << 16) | i); 2006 WRITE4(CRIME_MTE_DST0, (nextbuf << 13)); 2007 WRITE4ST(CRIME_MTE_DST1, (nextbuf << 13) + len); 2008 copyRGBAtoARGB((uint32_t *)dst, 2009 (uint32_t *)(fPtr->buffers[bufno] + offset), w); 2010 dst += dstwidth; 2011 bufno = nextbuf; 2012 } 2013 SYNCMTE; 2014 copyRGBAtoARGB((uint32_t *)dst, 2015 (uint32_t *)(fPtr->buffers[bufno] + offset), w); 2016 DONE(CRIME_DEBUG_IMAGEREAD); 2017 2018} 2019 2020int 2021CrimeAccelInit(ScrnInfoPtr pScrn) 2022{ 2023 CrimePtr fPtr = CRIMEPTR(pScrn); 2024 XAAInfoRecPtr pXAAInfo = fPtr->pXAA; 2025 int i; 2026 2027 for (i = 0; i < 0x1000; i++) regcache[i] = 0x12345678; 2028 LOG(CRIME_DEBUG_ALL); 2029 SYNC; 2030 WRITE4(CRIME_DE_MODE_DST, DE_MODE_TLB_A | DE_MODE_BUFDEPTH_32 | 2031 DE_MODE_TYPE_RGBA | DE_MODE_PIXDEPTH_32); 2032 2033 WRITE4(CRIME_DE_XFER_STEP_Y, 1); 2034 WRITE4(CRIME_DE_XFER_STRD_DST, 4); 2035 WRITE4(CRIME_DE_XFER_STRD_SRC, 1); 2036 2037 WRITE4(CRIME_MTE_BYTEMASK, 0xffffffff); 2038 WRITE4(CRIME_MTE_SRC_Y_STEP, 4); 2039 WRITE4(CRIME_MTE_DST_Y_STEP, 4); 2040 SYNC; 2041 2042 /* blit the screen black */ 2043 WRITE4(CRIME_DE_DRAWMODE, 2044 DE_DRAWMODE_PLANEMASK | DE_DRAWMODE_BYTEMASK | DE_DRAWMODE_ROP); 2045 WRITE4(CRIME_DE_ROP, 3); 2046 WRITE4(CRIME_DE_PRIMITIVE, DE_PRIM_RECTANGLE | DE_PRIM_LR | DE_PRIM_TB); 2047 WRITE4(CRIME_DE_FG, 0); 2048 WRITE4(CRIME_DE_X_VERTEX_0, 0); 2049 WRITE4ST(CRIME_DE_X_VERTEX_1, 2050 fPtr->info.width << 16 | fPtr->info.height); 2051 SYNC; 2052 2053 pXAAInfo->Flags = /*LINEAR_FRAMEBUFFER |*/ PIXMAP_CACHE | OFFSCREEN_PIXMAPS; 2054 pXAAInfo->maxOffPixWidth = fPtr->info.width; 2055 pXAAInfo->maxOffPixHeight = 2048; 2056 2057 /* Sync */ 2058 pXAAInfo->Sync = CrimeSync; 2059 2060 CrimeDisableClipping(pScrn); 2061 2062 /* Screen-to-screen copy */ 2063 pXAAInfo->ScreenToScreenCopyFlags = NO_TRANSPARENCY; 2064 pXAAInfo->SetupForScreenToScreenCopy = CrimeSetupForScreenToScreenCopy; 2065 pXAAInfo->SubsequentScreenToScreenCopy = 2066 CrimeSubsequentScreenToScreenCopy; 2067 2068 /* rectangle fills */ 2069 pXAAInfo->SetupForSolidFill = CrimeSetupForSolidFill; 2070 pXAAInfo->SubsequentSolidFillRect = CrimeSubsequentSolidFillRect; 2071 2072 /* image writes */ 2073 pXAAInfo->ScanlineImageWriteFlags = 2074 NO_TRANSPARENCY | LEFT_EDGE_CLIPPING | 2075 LEFT_EDGE_CLIPPING_NEGATIVE_X | 2076 CPU_TRANSFER_PAD_DWORD | SCANLINE_PAD_DWORD; 2077 pXAAInfo->NumScanlineImageWriteBuffers = 8; 2078 for (i = 0; i < 8; i++) 2079 fPtr->buffers[i] = fPtr->linear + (i * 8192); 2080 pXAAInfo->ScanlineImageWriteBuffers = fPtr->buffers; 2081 pXAAInfo->SetupForScanlineImageWrite = 2082 CrimeSetupForScanlineImageWrite; 2083 pXAAInfo->SubsequentScanlineImageWriteRect = 2084 CrimeSubsequentImageWriteRect; 2085 pXAAInfo->SubsequentImageWriteScanline = 2086 CrimeSubsequentImageWriteScanline; 2087 2088 /* read pixmap */ 2089 pXAAInfo->ReadPixmapFlags = 0 2090 | CPU_TRANSFER_PAD_DWORD 2091 ; 2092 pXAAInfo->ReadPixmap = CrimeReadPixmap; 2093 2094 /* colour expansion */ 2095 pXAAInfo->ScanlineCPUToScreenColorExpandFillFlags = 2096 LEFT_EDGE_CLIPPING; 2097 pXAAInfo->NumScanlineColorExpandBuffers = 1; 2098 fPtr->expandbuffers[0] = (uint8_t *)fPtr->expand; 2099 pXAAInfo->ScanlineColorExpandBuffers = (void *)&fPtr->expandbuffers; 2100 pXAAInfo->SetupForScanlineCPUToScreenColorExpandFill = 2101 CrimeSetupForCPUToScreenColorExpandFill; 2102 pXAAInfo->SubsequentScanlineCPUToScreenColorExpandFill = 2103 CrimeSubsequentScanlineCPUToScreenColorExpandFill; 2104 pXAAInfo->SubsequentColorExpandScanline = 2105 CrimeSubsequentColorExpandScanline; 2106 2107 /* clipping */ 2108 pXAAInfo->ClippingFlags = HARDWARE_CLIP_SCREEN_TO_SCREEN_COPY | 2109 HARDWARE_CLIP_SOLID_FILL | 2110 HARDWARE_CLIP_SOLID_LINE | 2111 HARDWARE_CLIP_MONO_8x8_FILL | HARDWARE_CLIP_DASHED_LINE; 2112 pXAAInfo->SetClippingRectangle = CrimeSetClippingRectangle; 2113 pXAAInfo->DisableClipping = CrimeDisableClipping; 2114 2115 /* solid line drawing */ 2116 pXAAInfo->SetupForSolidLine = CrimeSetupForSolidLine; 2117 pXAAInfo->SubsequentSolidTwoPointLine = 2118 CrimeSubsequentSolidTwoPointLine; 2119 pXAAInfo->SolidLineFlags = 0; 2120 2121 /* dashed line drawing */ 2122 pXAAInfo->SetupForDashedLine = CrimeSetupForDashedLine; 2123 pXAAInfo->SubsequentDashedTwoPointLine = 2124 CrimeSubsequentDashedTwoPointLine; 2125 pXAAInfo->DashedLineFlags = LINE_PATTERN_MSBFIRST_MSBJUSTIFIED; 2126 pXAAInfo->DashPatternMaxLength = 32; 2127 2128 /* mono pattern fills */ 2129 pXAAInfo->Mono8x8PatternFillFlags = HARDWARE_PATTERN_PROGRAMMED_BITS | 2130 HARDWARE_PATTERN_PROGRAMMED_ORIGIN | BIT_ORDER_IN_BYTE_MSBFIRST; 2131 pXAAInfo->SetupForMono8x8PatternFill = CrimeSetupForMono8x8PatternFill; 2132 pXAAInfo->SubsequentMono8x8PatternFillRect = 2133 CrimeSubsequentMono8x8PatternFillRect; 2134 2135 /* XRender acceleration */ 2136#ifdef RENDER 2137 pXAAInfo->CPUToScreenAlphaTextureFlags = 0; 2138 pXAAInfo->SetupForCPUToScreenAlphaTexture = 2139 CrimeSetupForCPUToScreenAlphaTexture; 2140 pXAAInfo->SubsequentCPUToScreenAlphaTexture = 2141 CrimeSubsequentCPUToScreenAlphaTexture; 2142 pXAAInfo->CPUToScreenAlphaTextureFormats = CrimeAlphaTextureFormats; 2143 2144 pXAAInfo->SetupForCPUToScreenTexture = CrimeSetupForCPUToScreenTexture; 2145 pXAAInfo->SubsequentCPUToScreenTexture = 2146 CrimeSubsequentCPUToScreenTexture; 2147 pXAAInfo->CPUToScreenTextureFlags = 0; 2148 pXAAInfo->CPUToScreenTextureFormats = CrimeTextureFormats; 2149 pXAAInfo->Composite = CrimeComposite; 2150 pXAAInfo->Glyphs = CrimeGlyphs; 2151#endif 2152 pXAAInfo->ValidatePolyPoint = CrimeValidatePolyPoint; 2153 pXAAInfo->PolyPointMask = GCFunction; 2154 pXAAInfo->ValidatePolyArc = CrimeValidatePolyArc; 2155 pXAAInfo->PolyArcMask = GCFunction | GCLineWidth; 2156 2157 return -1; 2158} 2159