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