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