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