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