gx_accel.c revision f29dbc25
1/* Copyright (c) 2003-2005 Advanced Micro Devices, Inc. 2 * 3 * Permission is hereby granted, free of charge, to any person obtaining a copy 4 * of this software and associated documentation files (the "Software"), to 5 * deal in the Software without restriction, including without limitation the 6 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 * sell copies of the Software, and to permit persons to whom the Software is 8 * furnished to do so, subject to the following conditions: 9 * 10 * The above copyright notice and this permission notice shall be included in 11 * all copies or substantial portions of the Software. 12 * 13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 * IN THE SOFTWARE. 20 * 21 * Neither the name of the Advanced Micro Devices, Inc. nor the names of its 22 * contributors may be used to endorse or promote products derived from this 23 * software without specific prior written permission. 24 * */ 25 26/* 27 * File Contents: This file is consists of main Xfree acceleration supported 28 * routines like solid fill used here. 29 * 30 * Project: Geode Xfree Frame buffer device driver. 31 * */ 32 33/* #undef OPT_ACCEL */ 34 35/* Xfree86 header files */ 36#ifdef HAVE_CONFIG_H 37#include "config.h" 38#endif 39 40#include "vgaHW.h" 41#include "xf86.h" 42#include "xaalocal.h" 43#include "xf86fbman.h" 44#include "miline.h" 45#include "xaarop.h" 46#include "servermd.h" 47#include "picture.h" 48#include "xf86.h" 49#include "xf86_OSproc.h" 50#include "xf86Pci.h" 51#include "xf86PciInfo.h" 52#include "geode.h" 53#include "gfx_defs.h" 54#include "gfx_regs.h" 55 56/* Common macros for blend operations are here */ 57 58#include "geode_blend.h" 59 60#undef ulong 61typedef unsigned long ulong; 62 63#undef uint 64typedef unsigned int uint; 65 66#undef ushort 67typedef unsigned short ushort; 68 69#undef uchar 70typedef unsigned char uchar; 71 72#define CALC_FBOFFSET(x, y) \ 73 (((ulong)(y) * gu2_pitch + ((ulong)(x) << gu2_xshift))) 74 75#define FBADDR(x,y) \ 76 ((unsigned char *)pGeode->FBBase + CALC_FBOFFSET(x, y)) 77 78#define OS_UDELAY 0 79#if OS_UDELAY > 0 80#define OS_USLEEP(usec) usleep(usec); 81#else 82#define OS_USLEEP(usec) 83#endif 84 85#ifdef OPT_ACCEL 86static unsigned int BPP; 87static unsigned int BLT_MODE, VEC_MODE; 88static unsigned int ACCEL_STRIDE; 89 90#define GU2_WAIT_PENDING while(READ_GP32(MGP_BLT_STATUS) & MGP_BS_BLT_PENDING) 91#define GU2_WAIT_BUSY while(READ_GP32(MGP_BLT_STATUS) & MGP_BS_BLT_BUSY) 92#endif 93 94#define HOOK(fn) localRecPtr->fn = GX##fn 95 96#define DLOG(l, fmt, args...) ErrorF(fmt, ##args) 97 98/* static storage declarations */ 99 100typedef struct sGBltBox 101{ 102 ulong x, y; 103 ulong w, h; 104 ulong color; 105 int bpp, transparent; 106} GBltBox; 107 108#if GX_SCANLINE_SUPPORT 109static GBltBox giwr; 110#endif 111#if GX_CPU2SCREXP_SUPPORT 112static GBltBox gc2s; 113#endif 114#if GX_CLREXP_8X8_PAT_SUPPORT 115static ulong *gc8x8p; 116#endif 117 118#if GX_DASH_LINE_SUPPORT 119typedef struct sGDashLine 120{ 121 ulong pat[2]; 122 int len; 123 int fg; 124 int bg; 125} GDashLine; 126 127static GDashLine gdln; 128#endif 129 130static unsigned int gu2_xshift, gu2_yshift; 131static unsigned int gu2_pitch; 132 133static XAAInfoRecPtr localRecPtr; 134 135/* pat 0xF0 */ 136/* src 0xCC */ 137/* dst 0xAA */ 138 139/* (src FUNC dst) */ 140 141static const int SDfn[16] = { 142 0x00, 0x88, 0x44, 0xCC, 0x22, 0xAA, 0x66, 0xEE, 143 0x11, 0x99, 0x55, 0xDD, 0x33, 0xBB, 0x77, 0xFF 144}; 145 146/* ((src FUNC dst) AND pat-mask) OR (dst AND (NOT pat-mask)) */ 147 148static const int SDfn_PM[16] = { 149 0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA, 150 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA 151}; 152 153/* (pat FUNC dst) */ 154 155static const int PDfn[16] = { 156 0x00, 0xA0, 0x50, 0xF0, 0x0A, 0xAA, 0x5A, 0xFA, 157 0x05, 0xA5, 0x55, 0xF5, 0x0F, 0xAF, 0x5F, 0xFF 158}; 159 160/* ((pat FUNC dst) AND src-mask) OR (dst AND (NOT src-mask)) */ 161 162static const int PDfn_SM[16] = { 163 0x22, 0xA2, 0x62, 0xE2, 0x2A, 0xAA, 0x6A, 0xEA, 164 0x26, 0xA6, 0x66, 0xE6, 0x2E, 0xAE, 0x6E, 0xEE 165}; 166 167#ifdef OPT_ACCEL 168static inline CARD32 169amd_gx_BppToRasterMode(int bpp) 170{ 171 switch (bpp) { 172 case 16: 173 return MGP_RM_BPPFMT_565; 174 case 32: 175 return MGP_RM_BPPFMT_8888; 176 case 8: 177 return MGP_RM_BPPFMT_332; 178 default: 179 return 0; 180 } 181} 182#endif /* OPT_ACCEL */ 183 184/*---------------------------------------------------------------------------- 185 * GXAccelSync. 186 * 187 * Description :This function is called to synchronize with the graphics 188 * engine and it waits the graphic engine is idle. This is 189 * required before allowing direct access to the framebuffer. 190 * 191 * Arg Type Comment 192 * pScrni ScrnInfoPtr pointer to Screeen info 193 * 194 * Returns :none 195 *---------------------------------------------------------------------------*/ 196void 197GXAccelSync(ScrnInfoPtr pScrni) 198{ 199 //ErrorF("GXAccelSync()\n"); 200#ifndef OPT_ACCEL 201 gfx_wait_until_idle(); 202#else 203 GU2_WAIT_BUSY; 204#endif 205} 206 207#if GX_FILL_RECT_SUPPORT 208/*---------------------------------------------------------------------------- 209 * GXSetupForSolidFill. 210 * 211 * Description :The SetupFor and Subsequent SolidFill(Rect) provide 212 * filling rectangular areas of the screen with a 213 * foreground color. 214 * 215 * Parameters. 216 * Arg Type Comment 217 * pScrni ScrnInfoPtr pointer to Screeen info 218 * color int foreground fill color 219 * rop int unmapped raster op 220 * planemask uint -1 (fill) or pattern data 221 * 222 * Returns :none 223 *--------------------------------------------------------------------------*/ 224static void 225GXSetupForSolidFill(ScrnInfoPtr pScrni, 226 int color, int rop, unsigned int planemask) 227{ 228 //ErrorF("GXSetupForSolidFill(%#x,%#x,%#x)\n", color, rop, planemask); 229 rop &= 0x0F; 230#ifndef OPT_ACCEL 231 gfx_set_solid_pattern(planemask); 232 gfx_set_solid_source(color); 233 gfx_set_raster_operation(planemask == ~0U ? SDfn[rop] : SDfn_PM[rop]); 234#else 235 { 236 unsigned int ROP = 237 BPP | (planemask == ~0U ? SDfn[rop] : SDfn_PM[rop]); 238 BLT_MODE = ((ROP ^ (ROP >> 2)) & 0x33) == 0 ? MGP_BM_SRC_MONO : 0; 239 if (((ROP ^ (ROP >> 1)) & 0x55) != 0) 240 BLT_MODE |= MGP_BM_DST_REQ; 241 GU2_WAIT_PENDING; 242 WRITE_GP32(MGP_RASTER_MODE, ROP); 243 WRITE_GP32(MGP_PAT_COLOR_0, planemask); 244 WRITE_GP32(MGP_SRC_COLOR_FG, color); 245 WRITE_GP32(MGP_STRIDE, ACCEL_STRIDE); 246 } 247#endif 248} 249 250/*---------------------------------------------------------------------------- 251 * GXSubsequentSolidFillRect. 252 * 253 * Description :see GXSetupForSolidFill. 254 * 255 * Parameters. 256 * Arg Type Comment 257 * pScrni ScrnInfoPtr pointer to Screeen info 258 * x int destination x offset 259 * y int destination y offset 260 * w int fill area width (pixels) 261 * h int fill area height (pixels) 262 * 263 * Returns :none 264 * 265 * Sample application uses: 266 * - Window backgrounds. 267 * - pull down highlighting. 268 * - x11perf: rectangle tests (-rect500). 269 * - x11perf: fill trapezoid tests (-trap100). 270 * - x11perf: horizontal line segments (-hseg500). 271 *----------------------------------------------------------------------------*/ 272static void 273GXSubsequentSolidFillRect(ScrnInfoPtr pScrni, int x, int y, int w, int h) 274{ 275 //ErrorF("GXSubsequentSolidFillRect() at %d,%d %dx%d\n", x, y, w, h); 276#ifndef OPT_ACCEL 277 gfx_pattern_fill(x, y, w, h); 278#else 279 { 280 unsigned int offset = CALC_FBOFFSET(x, y); 281 unsigned int size = (w << 16) | h; 282 283 GU2_WAIT_PENDING; 284 WRITE_GP32(MGP_DST_OFFSET, offset); 285 WRITE_GP32(MGP_WID_HEIGHT, size); 286 WRITE_GP32(MGP_BLT_MODE, BLT_MODE); 287 } 288#endif 289} 290 291#endif /* if GX_FILL_RECT_SUPPORT */ 292 293#if GX_CLREXP_8X8_PAT_SUPPORT 294/*---------------------------------------------------------------------------- 295 * GXSetupForColor8x8PatternFill 296 * 297 * Description :8x8 color pattern data is 64 pixels of full color data 298 * stored linearly in offscreen video memory. These patterns 299 * are useful as a substitute for 8x8 mono patterns when tiling, 300 * doing opaque stipples, or regular stipples. 301 * 302 * Arg Type Comment 303 * pScrni ScrnInfoPtr pointer to Screeen info 304 * patx int x offset to pattern data 305 * paty int y offset to pattern data 306 * rop int unmapped raster operation 307 * planemask uint -1 (copy) or pattern data 308 * trans_color int -1 (copy) or transparent color (not enabled) 309 * trans color only supported on source channel 310 * or in monochrome pattern channel 311 * 312 * Returns :none. 313 * 314 *---------------------------------------------------------------------------*/ 315 316static void 317GXSetupForColor8x8PatternFill(ScrnInfoPtr pScrni, int patx, int paty, int rop, 318 uint planemask, int trans_color) 319{ 320 GeodeRec *pGeode = GEODEPTR(pScrni); 321 322 //ErrorF("GXSetupForColor8x8PatternFill() pat %#x,%#x rop %#x %#x %#x\n", 323 // patx, paty, rop, planemask, trans_color); 324 rop &= 0x0F; 325 gc8x8p = (unsigned long *)FBADDR(patx, paty); 326 /* gfx_set_solid_pattern is needed to clear src/pat transparency */ 327 gfx_set_solid_pattern(0); 328 gfx_set_raster_operation(planemask == ~0U ? PDfn[rop] : 329 (gfx_set_solid_source(planemask), PDfn_SM[rop])); 330 gfx2_set_source_stride(pGeode->Pitch); 331 gfx2_set_destination_stride(pGeode->Pitch); 332 if (trans_color == -1) 333 gfx2_set_source_transparency(0, 0); 334 else 335 gfx2_set_source_transparency(trans_color, ~0); 336} 337 338/*---------------------------------------------------------------------------- 339 * GXSubsequentColor8x8PatternFillRect 340 * 341 * Description :see GXSetupForColor8x8PatternFill. 342 * 343 * Arg Type Comment 344 * pScrni ScrnInfoPtr pointer to Screeen info 345 * patx int pattern phase x offset 346 * paty int pattern phase y offset 347 * x int destination x offset 348 * y int destination y offset 349 * w int fill area width (pixels) 350 * h int fill area height (pixels) 351 * 352 * Returns :none 353 * 354 * Sample application uses: 355 * - Patterned desktops 356 * - x11perf: stippled rectangle tests (-srect500). 357 * - x11perf: opaque stippled rectangle tests (-osrect500). 358 *--------------------------------------------------------------------------*/ 359static void 360GXSubsequentColor8x8PatternFillRect(ScrnInfoPtr pScrni, int patx, int paty, 361 int x, int y, int w, int h) 362{ 363 //ErrorF( 364 // "GXSubsequentColor8x8PatternFillRect() patxy %d,%d at %d,%d %dsx%d\n", 365 // patx, paty, x, y, w, h); 366 gfx2_set_pattern_origin(patx, paty); 367 gfx2_color_pattern_fill(CALC_FBOFFSET(x, y), w, h, gc8x8p); 368} 369 370/* GX_CLREXP_8X8_PAT_SUPPORT */ 371#endif 372 373#if GX_MONO_8X8_PAT_SUPPORT 374/*---------------------------------------------------------------------------- 375 * GXSetupForMono8x8PatternFill 376 * 377 * Description :8x8 mono pattern data is 64 bits of color expansion data 378 * with ones indicating the foreground color and zeros 379 * indicating the background color. These patterns are 380 * useful when tiling, doing opaque stipples, or regular 381 * stipples. 382 * 383 * Arg Type Comment 384 * pScrni ScrnInfoPtr pointer to Screeen info 385 * patx int x offset to pattern data 386 * paty int y offset to pattern data 387 * fg int foreground color 388 * bg int -1 (transparent) or background color 389 * rop int unmapped raster operation 390 * planemask uint -1 (copy) or pattern data 391 * 392 * Returns :none. 393 * 394 * Comments :none. 395 * 396 *--------------------------------------------------------------------------*/ 397static void 398GXSetupForMono8x8PatternFill(ScrnInfoPtr pScrni, int patx, int paty, 399 int fg, int bg, int rop, uint planemask) 400{ 401 //ErrorF( 402 //"GXSetupForMono8x8PatternFill() pat %#x,%#x fg %#x bg %#x %#x %#x\n", 403 //patx, paty, fg, bg, rop, planemask); 404 rop &= 0x0F; 405#ifndef OPT_ACCEL 406 gfx_set_mono_pattern(bg, fg, patx, paty, bg == -1 ? 1 : 0); 407 gfx_set_raster_operation(planemask == ~0U ? PDfn[rop] : 408 (gfx_set_solid_source(planemask), PDfn_SM[rop])); 409#else 410 { 411 unsigned int ROP = BPP | 412 (bg == 413 -1 ? MGP_RM_PAT_MONO | MGP_RM_PAT_TRANS : MGP_RM_PAT_MONO) | 414 (planemask == ~0U ? PDfn[rop] : PDfn_SM[rop]); 415 BLT_MODE = ((ROP ^ (ROP >> 2)) & 0x33) == 0 ? MGP_BM_SRC_MONO : 0; 416 if (((ROP ^ (ROP >> 1)) & 0x55) != 0) 417 BLT_MODE |= MGP_BM_DST_REQ; 418 GU2_WAIT_PENDING; 419 WRITE_GP32(MGP_RASTER_MODE, ROP); 420 WRITE_GP32(MGP_SRC_COLOR_FG, planemask); 421 WRITE_GP32(MGP_PAT_COLOR_0, bg); 422 WRITE_GP32(MGP_PAT_COLOR_1, fg); 423 WRITE_GP32(MGP_PAT_DATA_0, patx); 424 WRITE_GP32(MGP_PAT_DATA_1, paty); 425 WRITE_GP32(MGP_STRIDE, ACCEL_STRIDE); 426 } 427#endif 428} 429 430/*---------------------------------------------------------------------------- 431 * GXSubsequentMono8x8PatternFillRect 432 * 433 * Description :see GXSetupForMono8x8PatternFill 434 * 435 * Arg Type Comment 436 * pScrni ScrnInfoPtr pointer to Screeen info 437 * patx int pattern phase x offset 438 * paty int pattern phase y offset 439 * x int destination x offset 440 * y int destination y offset 441 * w int fill area width (pixels) 442 * h int fill area height (pixels) 443 444 * Returns :none 445 * 446 * Sample application uses: 447 * - Patterned desktops 448 * - x11perf: stippled rectangle tests (-srect500). 449 * - x11perf: opaque stippled rectangle tests (-osrect500). 450 *--------------------------------------------------------------------------*/ 451static void 452GXSubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrni, int patx, int paty, 453 int x, int y, int w, int h) 454{ 455 DEBUGMSG(1, (0, X_INFO, "%s() pat %#x,%#x at %d,%d %dx%d\n", 456 __func__, patx, paty, x, y, w, h)); 457#ifndef OPT_ACCEL 458 gfx_pattern_fill(x, y, w, h); 459#else 460 { 461 unsigned int offset = 462 CALC_FBOFFSET(x, y) | ((x & 7) << 26) | ((y & 7) << 29); 463 unsigned int size = (w << 16) | h; 464 465 GU2_WAIT_PENDING; 466 WRITE_GP32(MGP_DST_OFFSET, offset); 467 WRITE_GP32(MGP_WID_HEIGHT, size); 468 WRITE_GP32(MGP_BLT_MODE, BLT_MODE); 469 } 470#endif 471} 472 473#endif /* GX_MONO_8X8_PAT_SUPPORT */ 474 475#if GX_SCR2SCRCPY_SUPPORT 476/*---------------------------------------------------------------------------- 477 * GXSetupForScreenToScreenCopy 478 * 479 * Description :SetupFor and Subsequent ScreenToScreenCopy functions 480 * provide an interface for copying rectangular areas from 481 * video memory to video memory. 482 * 483 * Arg Type Comment 484 * pScrni ScrnInfoPtr pointer to Screeen info 485 * xdir int x copy direction (up/dn) 486 * ydir int y copy direction (up/dn) 487 * rop int unmapped raster operation 488 * planemask uint -1 (copy) or pattern data 489 * trans_color int -1 (copy) or transparent color 490 * 491 * Returns :none 492 *---------------------------------------------------------------------------*/ 493static void 494GXSetupForScreenToScreenCopy(ScrnInfoPtr pScrni, int xdir, int ydir, int rop, 495 uint planemask, int trans_color) 496{ 497 DEBUGMSG(1, (0, X_INFO, "%s() xd%d yd%d rop %#x %#x %#x\n", 498 __func__, xdir, ydir, rop, planemask, trans_color)); 499 rop &= 0x0F; 500#ifndef OPT_ACCEL 501 { 502 GeodeRec *pGeode = GEODEPTR(pScrni); 503 504 gfx_set_solid_pattern(planemask); 505 /* transparency is a parameter to set_rop, but set...pattern clears 506 * transparency */ 507 if (trans_color == -1) 508 gfx2_set_source_transparency(0, 0); 509 else 510 gfx2_set_source_transparency(trans_color, ~0); 511 gfx_set_raster_operation(planemask == ~0U ? SDfn[rop] : SDfn_PM[rop]); 512 gfx2_set_source_stride(pGeode->Pitch); 513 gfx2_set_destination_stride(pGeode->Pitch); 514 } 515#else 516 { 517 unsigned int ROP = 518 BPP | (planemask == ~0U ? SDfn[rop] : SDfn_PM[rop]); 519 if (trans_color != -1) 520 ROP |= MGP_RM_SRC_TRANS; 521 BLT_MODE = ((ROP ^ (ROP >> 1)) & 0x55) != 0 ? 522 MGP_BM_SRC_FB | MGP_BM_DST_REQ : MGP_BM_SRC_FB; 523 GU2_WAIT_PENDING; 524 WRITE_GP32(MGP_RASTER_MODE, ROP); 525 WRITE_GP32(MGP_PAT_COLOR_0, planemask); 526 WRITE_GP32(MGP_SRC_COLOR_FG, trans_color); 527 WRITE_GP32(MGP_SRC_COLOR_BG, ~0); 528 WRITE_GP32(MGP_STRIDE, ACCEL_STRIDE); 529 } 530#endif 531} 532 533/*---------------------------------------------------------------------------- 534 * GXSubsquentScreenToScreenCopy 535 * 536 * Description :see GXSetupForScreenToScreenCopy. 537 * 538 * Arg Type Comment 539 * pScrni ScrnInfoPtr pointer to Screeen info 540 * x1 int source x offset 541 * y1 int source y offset 542 * x2 int destination x offset 543 * y2 int destination y offset 544 * w int copy area width (pixels) 545 * h int copy area height (pixels) 546 * 547 * Returns :none 548 * 549 * Sample application uses (non-transparent): 550 * - Moving windows. 551 * - x11perf: scroll tests (-scroll500). 552 * - x11perf: copy from window to window (-copywinwin500). 553 *---------------------------------------------------------------------------*/ 554static void 555GXSubsequentScreenToScreenCopy(ScrnInfoPtr pScrni, 556 int x1, int y1, int x2, int y2, int w, int h) 557{ 558 DEBUGMSG(1, (0, X_INFO, "%s() from %d,%d to %d,%d %dx%d\n", 559 __func__, x1, y1, x2, y2, w, h)); 560#ifndef OPT_ACCEL 561 { 562 int flags = 0; 563 564 if (x2 > x1) 565 flags |= 1; 566 if (y2 > y1) 567 flags |= 2; 568 gfx2_screen_to_screen_blt(CALC_FBOFFSET(x1, y1), CALC_FBOFFSET(x2, 569 y2), w, h, flags); 570 } 571#else 572 { 573 GeodeRec *pGeode = GEODEPTR(pScrni); 574 unsigned int src = CALC_FBOFFSET(x1, y1); 575 unsigned int dst = CALC_FBOFFSET(x2, y2); 576 unsigned int size = (w << 16) | h; 577 unsigned int blt_mode = BLT_MODE; 578 579 if (x2 > x1) { 580 int n = (w << gu2_xshift) - 1; 581 582 src += n; 583 dst += n; 584 blt_mode |= MGP_BM_NEG_XDIR; 585 } 586 if (y2 > y1) { 587 int n = (h - 1) * pGeode->Pitch; 588 589 src += n; 590 dst += n; 591 blt_mode |= MGP_BM_NEG_YDIR; 592 } 593 GU2_WAIT_PENDING; 594 WRITE_GP32(MGP_SRC_OFFSET, src); 595 WRITE_GP32(MGP_DST_OFFSET, dst); 596 WRITE_GP32(MGP_WID_HEIGHT, size); 597 WRITE_GP16(MGP_BLT_MODE, blt_mode); 598 } 599#endif 600} 601 602#endif /* if GX_SCR2SCRCPY_SUPPORT */ 603 604#if GX_SCANLINE_SUPPORT 605/*---------------------------------------------------------------------------- 606 * GXSetupForScanlineImageWrite 607 * 608 * Description :SetupFor/Subsequent ScanlineImageWrite and ImageWriteScanline 609 * transfer full color pixel data from system memory to video 610 * memory. This is useful for dealing with alignment issues and 611 * performing raster ops on the data. 612 * 613 * Arg Type Comment 614 * pScrni ScrnInfoPtr pointer to Screeen info 615 * rop int unmapped raster operation 616 * planemask uint -1 (copy) or pattern data 617 * bpp int bits per pixel (unused) 618 * depth int color depth (unused) 619 * 620 * Returns :none 621 * 622 * x11perf -putimage10 623 * x11perf -putimage100 624 * x11perf -putimage500 625 *---------------------------------------------------------------------------- 626 */ 627static void 628GXSetupForScanlineImageWrite(ScrnInfoPtr pScrni, int rop, uint planemask, 629 int trans_color, int bpp, int depth) 630{ 631 GeodeRec *pGeode = GEODEPTR(pScrni); 632 633 DEBUGMSG(1, (0, X_INFO, "%s() rop %#x %#x %#x %d %d\n", 634 __func__, rop, planemask, trans_color, bpp, depth)); 635 rop &= 0x0F; 636 /* transparency is a parameter to set_rop, but set...pattern clears 637 * transparency */ 638 gfx_set_solid_pattern(planemask); 639 if (trans_color == -1) 640 gfx2_set_source_transparency(0, 0); 641 else 642 gfx2_set_source_transparency(trans_color, ~0); 643 gfx_set_raster_operation(planemask == ~0U ? SDfn[rop] : SDfn_PM[rop]); 644 gfx2_set_source_stride(pGeode->Pitch); 645 gfx2_set_destination_stride(pGeode->Pitch); 646} 647 648/*---------------------------------------------------------------------------- 649 * GXSubsequentScanlineImageWriteRect 650 * 651 * Description : see GXSetupForScanlineImageWrite. 652 * 653 * Arg Type Comment 654 * pScrni ScrnInfoPtr pointer to Screeen info 655 * x int destination x offset 656 * y int destination y offset 657 * w int copy area width (pixels) 658 * h int copy area height (pixels) 659 * skipleft int x margin (pixels) to skip (not enabled) 660 * 661 * Returns :none 662 *---------------------------------------------------------------------------*/ 663static void 664GXSubsequentScanlineImageWriteRect(ScrnInfoPtr pScrni, 665 int x, int y, int w, int h, int skipleft) 666{ 667 DEBUGMSG(1, (0, X_INFO, "%s() rop %d,%d %dx%d %d\n", 668 __func__, x, y, w, h, skipleft)); 669 giwr.x = x; 670 giwr.y = y; 671 giwr.w = w; 672 giwr.h = h; 673#if !GX_USE_OFFSCRN_MEM 674#if !GX_ONE_LINE_AT_A_TIME 675 GXAccelSync(pScrni); 676#endif 677#endif 678} 679 680/*---------------------------------------------------------------------------- 681 * GXSubsquentImageWriteScanline 682 * 683 * Description : see GXSetupForScanlineImageWrite. 684 * 685 * Arg Type Comment 686 * pScrni ScrnInfoPtr pointer to Screeen info 687 * bufno int scanline number in write group 688 * 689 * Returns :none 690 * 691 * Sample application uses (non-transparent): 692 * - Moving windows. 693 * - x11perf: scroll tests (-scroll500). 694 * - x11perf: copy from window to window (-copywinwin500). 695 * 696 *---------------------------------------------------------------------------*/ 697static void 698GXSubsequentImageWriteScanline(ScrnInfoPtr pScrni, int bufno) 699{ 700 GeodeRec *pGeode = GEODEPTR(pScrni); 701 702#if !GX_USE_OFFSCRN_MEM 703 unsigned long offset; 704#endif 705 706#if GX_ONE_LINE_AT_A_TIME 707 DEBUGMSG(1, (0, X_INFO, "%s() %d\n", __func__, bufno)); 708#if !GX_USE_OFFSCRN_MEM 709 offset = pGeode->AccelImageWriteBuffers[bufno] - pGeode->FBBase; 710 gfx2_screen_to_screen_blt(offset, CALC_FBOFFSET(giwr.x, giwr.y), giwr.w, 711 1, 0); 712#else /* if !GX_USE_OFFSCRN_MEM */ 713 gfx2_color_bitmap_to_screen_blt(0, 0, CALC_FBOFFSET(giwr.x, giwr.y), 714 giwr.w, 1, pGeode->AccelImageWriteBuffers[bufno], pGeode->Pitch); 715#endif /* if !GX_USE_OFFSCRN_MEM */ 716 ++giwr.y; 717#else /* if GX_ONE_LINE_AT_A_TIME */ 718 int blt_height; 719 720 DEBUGMSG(1, (0, X_INFO, "%s() %d\n", __func__, bufno)); 721 722 if ((blt_height = pGeode->NoOfImgBuffers) > giwr.h) 723 blt_height = giwr.h; 724 if (++bufno < blt_height) 725 return; 726#if !GX_USE_OFFSCRN_MEM 727 offset = pGeode->AccelImageWriteBuffers[0] - pGeode->FBBase; 728 gfx2_screen_to_screen_blt(offset, CALC_FBOFFSET(giwr.x, giwr.y), giwr.w, 729 blt_height, 0); 730 GXAccelSync(pScrni); 731#else /* if !GX_USE_OFFSCRN_MEM */ 732 gfx2_color_bitmap_to_screen_blt(0, 0, CALC_FBOFFSET(giwr.x, giwr.y), 733 giwr.w, blt_height, pGeode->AccelImageWriteBuffers[0], pGeode->Pitch); 734#endif /* if !GX_USE_OFFSCRN_MEM */ 735 giwr.h -= blt_height; 736 giwr.y += blt_height; 737#endif /* if GX_ONE_LINE_AT_A_TIME */ 738} 739#endif /* GX_SCANLINE_SUPPORT */ 740 741#if GX_CPU2SCREXP_SUPPORT 742/*---------------------------------------------------------------------------- 743 * GXSetupForScanlineCPUToScreenColorExpandFill 744 * 745 * Description :SetupFor/Subsequent CPUToScreenColorExpandFill and 746 * ColorExpandScanline routines provide an interface for 747 * doing expansion blits from source patterns stored in 748 * system memory. 749 * 750 * Arg Type Comment 751 * pScrni ScrnInfoPtr pointer to Screeen info 752 * fg int foreground color 753 * bg int -1 (transparent) or background color 754 * rop int unmapped raster operation 755 * planemask uint -1 (copy) or pattern data 756 * 757 * Returns :none. 758 *---------------------------------------------------------------------------*/ 759 760static void 761GXSetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrni, 762 int fg, int bg, int rop, uint planemask) 763{ 764 GeodeRec *pGeode = GEODEPTR(pScrni); 765 ulong srcpitch; 766 767 DEBUGMSG(1, (0, X_INFO, "%s() fg %#x bg %#x rop %#x %#x\n", 768 __func__, fg, bg, rop, planemask)); 769 rop &= 0x0F; 770 srcpitch = ((pGeode->Pitch + 31) >> 5) << 2; 771#ifndef OPT_ACCEL 772 gfx_set_solid_pattern(planemask); 773 gfx_set_mono_source(bg, fg, bg == -1 ? 1 : 0); 774 gfx_set_raster_operation(planemask == ~0U ? SDfn[rop] : SDfn_PM[rop]); 775 gfx2_set_source_stride(srcpitch); 776 gfx2_set_destination_stride(pGeode->Pitch); 777#else 778 { 779 unsigned int stride = (srcpitch << 16) | pGeode->Pitch; 780 unsigned int ROP = 781 BPP | (planemask == ~0U ? SDfn[rop] : SDfn_PM[rop]); 782 if (bg == -1) 783 ROP |= MGP_RM_SRC_TRANS; 784 BLT_MODE = ((ROP ^ (ROP >> 1)) & 0x55) != 0 ? 785 MGP_BM_SRC_MONO | MGP_BM_SRC_FB | MGP_BM_DST_REQ : 786 MGP_BM_SRC_MONO | MGP_BM_SRC_FB; 787 GU2_WAIT_PENDING; 788 WRITE_GP32(MGP_RASTER_MODE, ROP); 789 WRITE_GP32(MGP_PAT_COLOR_0, planemask); 790 WRITE_GP32(MGP_SRC_COLOR_BG, bg); 791 WRITE_GP32(MGP_SRC_COLOR_FG, fg); 792 WRITE_GP32(MGP_STRIDE, stride); 793 } 794#endif 795} 796 797/*---------------------------------------------------------------------------- 798 * GXSubsequentScanlineCPUToScreenColorExpandFill 799 * 800 Description :see GXSetupForScanlineCPUToScreenColorExpandFill 801 * 802 * Parameters: 803 * Arg Type Comment 804 * pScrni ScrnInfoPtr pointer to Screeen info 805 * x int destination x offset 806 * y int destination y offset 807 * w int fill area width (pixels) 808 * h int fill area height (pixels) 809 * 810 * Returns :none 811 * 812 *---------------------------------------------------------------------------*/ 813static void 814GXSubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrni, 815 int x, int y, int w, int h, int skipleft) 816{ 817 DEBUGMSG(1, (0, X_INFO, "%s() %d,%d %dx%d %d\n", 818 __func__, x, y, w, h, skipleft)); 819 gc2s.x = x; 820 gc2s.y = y; 821 gc2s.w = w; 822 gc2s.h = h; 823#ifdef OPT_ACCEL 824 { 825#if GX_ONE_LINE_AT_A_TIME 826 unsigned int size = (gc2s.w << 16) | 1; 827 828 GU2_WAIT_PENDING; 829 WRITE_GP32(MGP_WID_HEIGHT, size); 830#else 831 GeodeRec *pGeode = GEODEPTR(pScrni); 832 unsigned int src = 833 pGeode->AccelColorExpandBuffers[0] - pGeode->FBBase; 834 GU2_WAIT_PENDING; 835 WRITE_GP32(MGP_SRC_OFFSET, src); 836#endif 837 } 838#endif 839} 840 841/*---------------------------------------------------------------------------- 842 * GXSubsequentColorExpandScanline 843 * 844 * Description :see GXSetupForScanlineCPUToScreenColorExpandFill 845 * 846 * Arg Type Comment 847 * pScrni ScrnInfoPtr pointer to Screeen info 848 * bufno int scanline number in write group 849 * 850 * Returns :none 851 *---------------------------------------------------------------------------- 852 */ 853static void 854GXSubsequentColorExpandScanline(ScrnInfoPtr pScrni, int bufno) 855{ 856 GeodeRec *pGeode = GEODEPTR(pScrni); 857 858 DEBUGMSG(1, (0, X_INFO, "%s() %d\n", __func__, bufno)); 859#ifndef OPT_ACCEL 860 { 861#if GX_ONE_LINE_AT_A_TIME 862 ulong offset = 863 pGeode->AccelColorExpandBuffers[bufno] - pGeode->FBBase; 864 gfx2_mono_expand_blt(offset, 0, 0, CALC_FBOFFSET(gc2s.x, gc2s.y), 865 gc2s.w, 1, 0); 866 ++gc2s.y; 867#else /* if GX_ONE_LINE_AT_A_TIME */ 868 ulong srcpitch; 869 int blt_height; 870 871 if ((blt_height = pGeode->NoOfImgBuffers) > gc2s.h) 872 blt_height = gc2s.h; 873 if (++bufno < blt_height) 874 return; 875 876 /* convert from bits to dwords */ 877 srcpitch = ((pGeode->Pitch + 31) >> 5) << 2; 878 gfx2_mono_bitmap_to_screen_blt(0, 0, CALC_FBOFFSET(gc2s.x, gc2s.y), 879 gc2s.w, blt_height, pGeode->AccelColorExpandBuffers[0], srcpitch); 880 gc2s.h -= blt_height; 881 gc2s.y += blt_height; 882#endif /* if GX_ONE_LINE_AT_A_TIME */ 883 } 884#else /* ifndef OPT_ACCEL */ 885 { 886#if GX_ONE_LINE_AT_A_TIME 887 unsigned int src = 888 pGeode->AccelColorExpandBuffers[bufno] - pGeode->FBBase; 889 unsigned int dst = CALC_FBOFFSET(gc2s.x, gc2s.y); 890 891 ++gc2s.y; 892 GU2_WAIT_PENDING; 893 WRITE_GP32(MGP_SRC_OFFSET, src); 894 WRITE_GP32(MGP_DST_OFFSET, dst); 895 WRITE_GP16(MGP_BLT_MODE, BLT_MODE); 896#else /* if GX_ONE_LINE_AT_A_TIME */ 897 unsigned int dst, size; 898 int blt_height; 899 900 GU2_WAIT_BUSY; 901 if ((blt_height = pGeode->NoOfImgBuffers) > gc2s.h) 902 blt_height = gc2s.h; 903 if (++bufno < blt_height) 904 return; 905 dst = CALC_FBOFFSET(gc2s.x, gc2s.y); 906 size = (gc2s.w << 16) | blt_height; 907 gc2s.h -= blt_height; 908 gc2s.y += blt_height; 909 GU2_WAIT_PENDING; 910 WRITE_GP32(MGP_DST_OFFSET, dst); 911 WRITE_GP32(MGP_WID_HEIGHT, size); 912 WRITE_GP16(MGP_BLT_MODE, BLT_MODE); 913#endif /* if GX_ONE_LINE_AT_A_TIME */ 914 } 915#endif /* ifndef OPT_ACCEL */ 916} 917#endif /* GX_CPU2SCREXP_SUPPORT */ 918 919#if GX_SCR2SCREXP_SUPPORT 920/*---------------------------------------------------------------------------- 921 * GXSetupForScreenToScreenColorExpandFill 922 * 923 * Description :SetupFor/Subsequent ScreenToScreenColorExpandFill and 924 * ColorExpandScanline routines provide an interface for 925 * doing expansion blits from source patterns stored in 926 * video memory. 927 * 928 * Arg Type Comment 929 * pScrni ScrnInfoPtr pointer to Screeen info 930 * fg int foreground color 931 * bg int -1 (transparent) or background color 932 * rop int unmapped raster operation 933 * planemask uint -1 (copy) or pattern data 934 * 935 * Returns :none. 936 *---------------------------------------------------------------------------*/ 937 938static void 939GXSetupForScreenToScreenColorExpandFill(ScrnInfoPtr pScrni, int fg, int bg, 940 int rop, uint planemask) 941{ 942 DEBUGMSG(1, (0, X_INFO, "%s() fg %#x bg %#x rop %#x %#x\n", 943 __func__, fg, bg, rop, planemask)); 944 rop &= 0x0F; 945#ifndef OPT_ACCEL 946 { 947 GeodeRec *pGeode = GEODEPTR(pScrni); 948 949 gfx_set_solid_pattern(planemask); 950 gfx_set_mono_source(bg, fg, bg == -1 ? 1 : 0); 951 gfx_set_raster_operation(planemask == ~0U ? SDfn[rop] : SDfn_PM[rop]); 952 gfx2_set_source_stride(pGeode->Pitch); 953 gfx2_set_destination_stride(pGeode->Pitch); 954 } 955#else 956 { 957 unsigned int ROP = 958 BPP | (planemask == ~0U ? SDfn[rop] : SDfn_PM[rop]); 959 if (bg == -1) 960 ROP |= MGP_RM_SRC_TRANS; 961 BLT_MODE = ((ROP ^ (ROP >> 1)) & 0x55) != 0 ? 962 MGP_BM_SRC_MONO | MGP_BM_SRC_FB | MGP_BM_DST_REQ : 963 MGP_BM_SRC_MONO | MGP_BM_SRC_FB; 964 GU2_WAIT_PENDING; 965 WRITE_GP32(MGP_RASTER_MODE, ROP); 966 WRITE_GP32(MGP_PAT_COLOR_0, planemask); 967 WRITE_GP32(MGP_SRC_COLOR_BG, bg); 968 WRITE_GP32(MGP_SRC_COLOR_FG, fg); 969 WRITE_GP32(MGP_STRIDE, ACCEL_STRIDE); 970 } 971#endif 972} 973 974/*---------------------------------------------------------------------------- 975 * GXSubsequentScreenToScreenColorExpandFill 976 * 977 * Description :see GXSetupForScreenToScreenColorExpandFill 978 * 979 * Parameters: 980 * Arg Type Comment 981 * pScrni ScrnInfoPtr pointer to Screeen info 982 * x int destination x offset 983 * y int destination y offset 984 * w int fill area width (pixels) 985 * h int fill area height (pixels) 986 * offset int initial x offset 987 * 988 * Returns :none 989 * 990 *---------------------------------------------------------------------------*/ 991static void 992GXSubsequentScreenToScreenColorExpandFill(ScrnInfoPtr pScrni, 993 int x, int y, int w, int h, int srcx, int srcy, int offset) 994{ 995 DEBUGMSG(1, (0, X_INFO, "%s() %d,%d %dx%d %d,%d %d\n", 996 __func__, x, y, w, h, srcx, srcy, offset)); 997#ifndef OPT_ACCEL 998 gfx2_mono_expand_blt(CALC_FBOFFSET(srcx, srcy), offset, 0, 999 CALC_FBOFFSET(x, y), w, h, 0); 1000#else 1001 { 1002 unsigned int src = (CALC_FBOFFSET(srcx, 1003 srcy) + (offset >> 3)) | ((offset & 7) << 26); 1004 unsigned int dst = CALC_FBOFFSET(x, y); 1005 unsigned int size = (w << 16) | h; 1006 1007 GU2_WAIT_PENDING; 1008 WRITE_GP32(MGP_SRC_OFFSET, src); 1009 WRITE_GP32(MGP_DST_OFFSET, dst); 1010 WRITE_GP32(MGP_WID_HEIGHT, size); 1011 WRITE_GP16(MGP_BLT_MODE, BLT_MODE); 1012 } 1013#endif 1014} 1015#endif /* GX_SCR2SCREXP_SUPPORT */ 1016 1017#define VM_MAJOR_DEC 0 1018#define VM_MINOR_DEC 0 1019 1020static unsigned short vmode[] = { 1021 VM_X_MAJOR | VM_MAJOR_INC | VM_MINOR_INC, 1022 /* !XDECREASING !YDECREASING !YMAJOR */ 1023 VM_Y_MAJOR | VM_MAJOR_INC | VM_MINOR_INC, 1024 /* !XDECREASING !YDECREASING YMAJOR */ 1025 VM_X_MAJOR | VM_MAJOR_INC | VM_MINOR_DEC, 1026 /* !XDECREASING YDECREASING !YMAJOR */ 1027 VM_Y_MAJOR | VM_MAJOR_DEC | VM_MINOR_INC, 1028 /* !XDECREASING YDECREASING YMAJOR */ 1029 VM_X_MAJOR | VM_MAJOR_DEC | VM_MINOR_INC, 1030 /* XDECREASING !YDECREASING !YMAJOR */ 1031 VM_Y_MAJOR | VM_MAJOR_INC | VM_MINOR_DEC, 1032 /* XDECREASING !YDECREASING YMAJOR */ 1033 VM_X_MAJOR | VM_MAJOR_DEC | VM_MINOR_DEC, 1034 /* XDECREASING YDECREASING !YMAJOR */ 1035 VM_Y_MAJOR | VM_MAJOR_DEC | VM_MINOR_DEC, 1036 /* XDECREASING YDECREASING YMAJOR */ 1037}; 1038 1039#if GX_BRES_LINE_SUPPORT 1040/*---------------------------------------------------------------------------- 1041 * GXSetupForSolidLine 1042 * 1043 * Description :SetupForSolidLine and Subsequent HorVertLine TwoPointLine 1044 * BresenhamLine provides an interface for drawing thin 1045 * solid lines. 1046 * 1047 * Arg Type Comment 1048 * pScrni ScrnInfoPtr pointer to Screeen info 1049 * color int foreground fill color 1050 * rop int unmapped raster op 1051 * planemask uint -1 (fill) or pattern data (not enabled) 1052 * 1053 * Returns :none 1054 *---------------------------------------------------------------------------*/ 1055static void 1056GXSetupForSolidLine(ScrnInfoPtr pScrni, int color, int rop, uint planemask) 1057{ 1058 DEBUGMSG(1, (0, X_INFO, "%s() %#x %#x %#x\n", 1059 __func__, color, rop, planemask)); 1060 rop &= 0x0F; 1061#ifndef OPT_ACCEL 1062 gfx_set_solid_pattern(color); 1063 gfx_set_raster_operation(planemask == ~0U ? PDfn[rop] : 1064 (gfx_set_solid_source(planemask), PDfn_SM[rop])); 1065#else 1066 { 1067 unsigned int ROP = 1068 BPP | (planemask == ~0U ? PDfn[rop] : PDfn_SM[rop]); 1069 BLT_MODE = ((ROP ^ (ROP >> 2)) & 0x33) == 0 ? MGP_BM_SRC_MONO : 0; 1070 VEC_MODE = ((ROP ^ (ROP >> 1)) & 0x55) != 0 ? ((BLT_MODE |= 1071 MGP_BM_DST_REQ), MGP_VM_DST_REQ) : 0; 1072 GU2_WAIT_PENDING; 1073 WRITE_GP32(MGP_RASTER_MODE, ROP); 1074 WRITE_GP32(MGP_PAT_COLOR_0, color); 1075 WRITE_GP32(MGP_SRC_COLOR_FG, planemask); 1076 WRITE_GP32(MGP_STRIDE, ACCEL_STRIDE); 1077 } 1078#endif 1079} 1080 1081/*--------------------------------------------------------------------------- 1082 * GXSubsequentSolidBresenhamLine 1083 * 1084 * Description :see GXSetupForSolidLine 1085 * 1086 * Arg Type Comment 1087 * pScrni ScrnInfoPtr pointer to Screeen info 1088 * x1 int destination x offset 1089 * y1 int destination y offset 1090 * absmaj int Bresenman absolute major 1091 * absmin int Bresenman absolute minor 1092 * err int Bresenman initial error term 1093 * len int length of the vector (pixels) 1094 * octant int specifies sign and magnitude relationships 1095 * used to determine axis of magor rendering 1096 * and direction of vector progress. 1097 * 1098 * Returns :none 1099 * 1100 * - Window outlines on window move. 1101 * - x11perf: line segments (-line500). 1102 * - x11perf: line segments (-seg500). 1103 *---------------------------------------------------------------------------*/ 1104static void 1105GXSubsequentSolidBresenhamLine(ScrnInfoPtr pScrni, int x1, int y1, 1106 int absmaj, int absmin, int err, int len, int octant) 1107{ 1108 long axial, diagn; 1109 1110 DEBUGMSG(1, (0, X_INFO, "%s() %d,%d %d %d, %d %d, %d\n", 1111 __func__, x1, y1, absmaj, absmin, err, len, octant)); 1112 if (len <= 0) 1113 return; 1114 axial = absmin; 1115 err += axial; 1116 diagn = absmin - absmaj; 1117#ifndef OPT_ACCEL 1118 gfx_bresenham_line(x1, y1, len, err, axial, diagn, vmode[octant]); 1119#else 1120 { 1121 unsigned int offset = CALC_FBOFFSET(x1, y1); 1122 unsigned int vec_err = (axial << 16) | (unsigned short)diagn; 1123 unsigned int vec_len = (len << 16) | (unsigned short)err; 1124 unsigned int vec_mode = VEC_MODE | vmode[octant]; 1125 1126 GU2_WAIT_PENDING; 1127 WRITE_GP32(MGP_DST_OFFSET, offset); 1128 WRITE_GP32(MGP_VEC_ERR, vec_err); 1129 WRITE_GP32(MGP_VEC_LEN, vec_len); 1130 WRITE_GP32(MGP_VECTOR_MODE, vec_mode); 1131 } 1132#endif 1133} 1134 1135/*--------------------------------------------------------------------------- 1136 * GXSubsequentSolidTwoPointLine 1137 * 1138 * Description :see GXSetupForSolidLine 1139 * 1140 * Arg Type Comment 1141 * pScrni ScrnInfoPtr pointer to Screeen info 1142 * x0 int destination x start offset 1143 * y0 int destination y start offset 1144 * x1 int destination x end offset 1145 * y1 int destination y end offset 1146 * flags int OMIT_LAST, dont draw last pixel (not used) 1147 * 1148 * Returns :none 1149 *---------------------------------------------------------------------------*/ 1150static void 1151GXSubsequentSolidTwoPointLine(ScrnInfoPtr pScrni, int x0, int y0, 1152 int x1, int y1, int flags) 1153{ 1154 long dx, dy, dmaj, dmin, octant, bias; 1155 long axial, diagn, err, len; 1156 1157 DEBUGMSG(1, (0, X_INFO, "%s() %d,%d %d,%d, %#x\n", 1158 __func__, x0, y0, x1, y1, flags)); 1159 1160 if ((dx = x1 - x0) < 0) 1161 dx = -dx; 1162 if ((dy = y1 - y0) < 0) 1163 dy = -dy; 1164 if (dy >= dx) { 1165 dmaj = dy; 1166 dmin = dx; 1167 octant = YMAJOR; 1168 } else { 1169 dmaj = dx; 1170 dmin = dy; 1171 octant = 0; 1172 } 1173 len = dmaj; 1174 if ((flags & OMIT_LAST) == 0) 1175 ++len; 1176 if (len <= 0) 1177 return; 1178 if (x1 < x0) 1179 octant |= XDECREASING; 1180 if (y1 < y0) 1181 octant |= YDECREASING; 1182 1183 axial = dmin << 1; 1184 bias = miGetZeroLineBias(pScrni->pScreen); 1185 err = axial - dmaj - ((bias >> octant) & 1); 1186 diagn = (dmin - dmaj) << 1; 1187 1188#ifndef OPT_ACCEL 1189 gfx_bresenham_line(x0, y0, len, err, axial, diagn, vmode[octant]); 1190#else 1191 { 1192 unsigned int offset = CALC_FBOFFSET(x0, y0); 1193 unsigned int vec_err = (axial << 16) | (unsigned short)diagn; 1194 unsigned int vec_len = (len << 16) | (unsigned short)err; 1195 unsigned int vec_mode = VEC_MODE | vmode[octant]; 1196 1197 GU2_WAIT_PENDING; 1198 WRITE_GP32(MGP_DST_OFFSET, offset); 1199 WRITE_GP32(MGP_VEC_ERR, vec_err); 1200 WRITE_GP32(MGP_VEC_LEN, vec_len); 1201 WRITE_GP32(MGP_VECTOR_MODE, vec_mode); 1202 } 1203#endif 1204} 1205 1206/*--------------------------------------------------------------------------- 1207 * GXSubsequentSolidHorVertLine 1208 * 1209 * Description :see GXSetupForSolidLine 1210 * 1211 * Arg Type Comment 1212 * pScrni ScrnInfoPtr pointer to Screeen info 1213 * x int destination x offset 1214 * y int destination y offset 1215 * len int length of the vector (pixels) 1216 * dir int DEGREES_270 or DEGREES_0 line direction 1217 * 1218 * Sample application uses: 1219 * - Window outlines on window move. 1220 * - x11perf: line segments (-hseg500). 1221 * - x11perf: line segments (-vseg500). 1222 *--------------------------------------------------------------------------- 1223 */ 1224static void 1225GXSubsequentSolidHorVertLine(ScrnInfoPtr pScrni, 1226 int x, int y, int len, int dir) 1227{ 1228 DEBUGMSG(1, (0, X_INFO, "%s() %d,%d %d %d\n", __func__, x, y, len, dir)); 1229#ifndef OPT_ACCEL 1230 if (dir == DEGREES_0) 1231 gfx_pattern_fill(x, y, len, 1); 1232 else 1233 gfx_pattern_fill(x, y, 1, len); 1234#else 1235 { 1236 unsigned int offset = CALC_FBOFFSET(x, y); 1237 unsigned int size = 1238 dir == DEGREES_0 ? (len << 16) | 1 : (1 << 16) | len; 1239 GU2_WAIT_PENDING; 1240 WRITE_GP32(MGP_DST_OFFSET, offset); 1241 WRITE_GP32(MGP_WID_HEIGHT, size); 1242 WRITE_GP32(MGP_BLT_MODE, BLT_MODE); 1243 } 1244#endif 1245} 1246#endif /* GX_BRES_LINE_SUPPORT */ 1247 1248#if GX_DASH_LINE_SUPPORT 1249/*---------------------------------------------------------------------------- 1250 * GXSetupForDashedLine 1251 * 1252 * Description :SetupForDashedLine and Subsequent TwoPointLine 1253 * BresenhamLine provides an interface for drawing thin 1254 * dashed lines. 1255 * 1256 * Arg Type Comment 1257 * pScrni ScrnInfoPtr pointer to Screeen info 1258 * fg int foreground fill color 1259 * bg int -1 (transp) or background fill color 1260 * rop int unmapped raster op 1261 * planemask uint -1 (fill) or pattern data (not enabled) 1262 * length int pattern length (bits) 1263 * pattern uchar* dash pattern mask 1264 * 1265 * Returns :none 1266 *---------------------------------------------------------------------------*/ 1267static void 1268GXSetupForDashedLine(ScrnInfoPtr pScrn, int fg, int bg, int rop, 1269 unsigned int planemask, int length, unsigned char *pattern) 1270{ 1271 int i, l, n, m; 1272 CARD32 pat = *pattern; 1273 CARD32 pat8x8[2]; 1274 1275 if (length <= 0) 1276 return; 1277 i = l = m = 0; 1278 while (i < 2) { 1279 m |= pat >> l; 1280 l += length; 1281 if ((n = l - 32) >= 0) { 1282 pat8x8[i++] = m; 1283 m = pat << (length - n); 1284 l = n; 1285 } 1286 } 1287 gdln.pat[0] = pat8x8[0]; 1288 gdln.pat[1] = pat8x8[1]; 1289 gdln.len = length; 1290 gdln.fg = fg; 1291 gdln.bg = bg; 1292 rop &= 0x0F; 1293 gfx_set_solid_pattern(0); 1294 gfx_set_raster_operation(planemask == ~0U ? PDfn[rop] : 1295 (gfx_set_solid_source(planemask), PDfn_SM[rop])); 1296} 1297 1298/*--------------------------------------------------------------------------- 1299 * GXSubsequentDashedBresenhamLine 1300 * 1301 * Description: This function is used to render a vector using the 1302 * specified bresenham parameters. 1303 * 1304 * Parameters: 1305 * pScrni: Screen handler pointer having screen information. 1306 * x1: Specifies the starting x position 1307 * y1: Specifies starting y possition 1308 * absmaj: Specfies the Bresenman absolute major. 1309 * absmin: Specfies the Bresenman absolute minor. 1310 * err: Specifies the bresenham err term. 1311 * len: Specifies the length of the vector interms of pixels. 1312 * octant: not used in this function,may be added for standard 1313 * interface. 1314 * 1315 * Returns: none 1316 * 1317 * Comments: none 1318 * 1319 * Sample application uses: 1320 * - Window outlines on window move. 1321 * - x11perf: line segments (-line500). 1322 * - x11perf: line segments (-seg500). 1323 *---------------------------------------------------------------------------- 1324 */ 1325static void 1326GXSubsequentDashedBresenhamLine(ScrnInfoPtr pScrni, 1327 int x1, int y1, int absmaj, int absmin, 1328 int err, int len, int octant, int phase) 1329{ 1330 int i, n; 1331 int axial, diagn; 1332 int trans = (gdln.bg == -1); 1333 unsigned long pat8x8[2]; 1334 1335 //ErrorF("BLine %d, %d, %d, %d, %d, %d, %d\n" x1, y1, absmaj, absmin, 1336 //err, len, octant); 1337 1338 i = phase >= 32 ? (phase -= 32, 1) : 0; 1339 n = 32 - phase; 1340 pat8x8[0] = 1341 ((gdln.pat[i] >> phase) & ((1UL << n) - 1)) | (gdln.pat[1 - i] << n); 1342 pat8x8[1] = 1343 ((gdln.pat[1 - i] >> phase) & ((1UL << n) - 1)) | (gdln.pat[i] << n); 1344 axial = absmin; 1345 err += axial; 1346 diagn = absmin - absmaj; 1347 gfx_set_mono_pattern(gdln.bg, gdln.fg, pat8x8[0], pat8x8[1], trans); 1348 gfx2_set_pattern_origin(x1, y1); 1349 gfx2_bresenham_line(CALC_FBOFFSET(x1, y1), len, err, axial, diagn, 1350 vmode[octant]); 1351} 1352 1353/*--------------------------------------------------------------------------- 1354 * GXSubsequentDashedTwoPointLine 1355 * 1356 * Description :see GXSetupForDashedLine 1357 * 1358 * Arg Type Comment 1359 * pScrni ScrnInfoPtr pointer to Screeen info 1360 * x0 int destination x start offset 1361 * y0 int destination y start offset 1362 * x1 int destination x end offset 1363 * y1 int destination y end offset 1364 * flags int OMIT_LAST, dont draw last pixel (not used) 1365 * phase int initial pattern offset at x1,y1 1366 * 1367 * Returns :none 1368 *---------------------------------------------------------------------------*/ 1369static void 1370GXSubsequentDashedTwoPointLine(ScrnInfoPtr pScrni, int x0, int y0, 1371 int x1, int y1, int flags, int phase) 1372{ 1373 int i, n; 1374 long dx, dy, dmaj, dmin, octant, bias; 1375 long axial, diagn, err, len, pat8x8[2]; 1376 1377 //ErrorF("GXSubsequentDashedTwoPointLine() %d,%d %d,%d, %#x %d\n", 1378 // x0, y0, x1, y1, flags, phase); 1379 1380 i = phase >= 32 ? (phase -= 32, 1) : 0; 1381 n = 32 - phase; 1382 pat8x8[0] = 1383 ((gdln.pat[i] >> phase) & ((1UL << n) - 1)) | (gdln.pat[1 - i] << n); 1384 pat8x8[1] = 1385 ((gdln.pat[1 - i] >> phase) & ((1UL << n) - 1)) | (gdln.pat[i] << n); 1386 1387 if ((dx = x1 - x0) < 0) 1388 dx = -dx; 1389 if ((dy = y1 - y0) < 0) 1390 dy = -dy; 1391 if (dy >= dx) { 1392 dmaj = dy; 1393 dmin = dx; 1394 octant = YMAJOR; 1395 } else { 1396 dmaj = dx; 1397 dmin = dy; 1398 octant = 0; 1399 } 1400 len = dmaj; 1401 if ((flags & OMIT_LAST) == 0) 1402 ++len; 1403 if (len <= 0) 1404 return; 1405 if (x1 < x0) 1406 octant |= XDECREASING; 1407 if (y1 < y0) 1408 octant |= YDECREASING; 1409 1410 axial = dmin << 1; 1411 bias = miGetZeroLineBias(pScrni->pScreen); 1412 err = axial - dmaj - ((bias >> octant) & 1); 1413 diagn = (dmin - dmaj) << 1; 1414 1415 gfx2_set_pattern_origin(x0, y0); 1416 gfx2_bresenham_line(CALC_FBOFFSET(x0, y0), len, err, axial, diagn, 1417 vmode[octant]); 1418 1419} 1420#endif /* GX_DASH_LINE_SUPPORT */ 1421 1422#if GX_WRITE_PIXMAP_SUPPORT 1423static void 1424GXWritePixmap(ScrnInfoPtr pScrni, int x, int y, int w, int h, 1425 unsigned char *src, int srcwidth, int rop, unsigned int planemask, 1426 int trans, int bpp, int depth) 1427{ 1428 GeodeRec *pGeode = GEODEPTR(pScrni); 1429 1430 //ErrorF("GXWritePixmap() %d,%d %dx%d, s%#x sp%d %#x %#x %#x %d %d\n", 1431 // x, y, w, h, src, srcwidth, rop, planemask, trans, bpp, depth); 1432 1433 if (bpp == pScrni->bitsPerPixel) { 1434 rop &= 0x0F; 1435 if (rop == GXcopy && trans == -1) { 1436 gfx_wait_until_idle(); 1437 geode_memory_to_screen_blt((unsigned long)src, 1438 (unsigned long)FBADDR(x, y), srcwidth, pGeode->Pitch, w, 1439 h, bpp); 1440 } else { 1441 gfx_set_solid_pattern(planemask); 1442 gfx_set_raster_operation(planemask == 1443 ~0U ? SDfn[rop] : SDfn_PM[rop]); 1444 if (trans != -1) 1445 gfx_color_bitmap_to_screen_xblt(0, 0, x, y, w, h, src, 1446 srcwidth, trans); 1447 else 1448 gfx_color_bitmap_to_screen_blt(0, 0, x, y, w, h, src, 1449 srcwidth); 1450 SET_SYNC_FLAG(pGeode->AccelInfoRec); 1451 } 1452 } else 1453 pGeode->WritePixmap(pScrni, x, y, w, h, src, srcwidth, rop, planemask, 1454 trans, bpp, depth); 1455} 1456#endif /* if GX_WRITE_PIXMAP_SUPPORT */ 1457 1458#if XF86EXA 1459 1460static void 1461amd_gx_exa_WaitMarker(ScreenPtr pScreen, int Marker) 1462{ 1463 GU2_WAIT_BUSY; 1464} 1465 1466static void 1467amd_gx_exa_Done(PixmapPtr p) 1468{ 1469} 1470 1471static Bool 1472amd_gx_exa_UploadToScreen(PixmapPtr pDst, int x, int y, int w, int h, 1473 char *src, int src_pitch) 1474{ 1475 char *dst = pDst->devPrivate.ptr; 1476 int dst_pitch = exaGetPixmapPitch(pDst); 1477 int bpp = pDst->drawable.bitsPerPixel; 1478 1479 dst += y * dst_pitch + x * (bpp >> 3); 1480 GU2_WAIT_BUSY; 1481 geode_memory_to_screen_blt((unsigned long)src, (unsigned long)dst, 1482 src_pitch, dst_pitch, w, h, bpp); 1483 return TRUE; 1484} 1485 1486static Bool 1487amd_gx_exa_DownloadFromScreen(PixmapPtr pSrc, int x, int y, int w, int h, 1488 char *dst, int dst_pitch) 1489{ 1490 char *src = pSrc->devPrivate.ptr; 1491 int src_pitch = exaGetPixmapPitch(pSrc); 1492 int bpp = pSrc->drawable.bitsPerPixel; 1493 1494 src += (y * src_pitch) + (x * (bpp >> 3)); 1495 GU2_WAIT_BUSY; 1496 geode_memory_to_screen_blt((unsigned long)src, (unsigned long)dst, 1497 src_pitch, dst_pitch, w, h, bpp); 1498 return TRUE; 1499} 1500 1501/* Solid */ 1502 1503static Bool 1504amd_gx_exa_PrepareSolid(PixmapPtr pxMap, int alu, Pixel planemask, Pixel fg) 1505{ 1506 int dstPitch = exaGetPixmapPitch(pxMap); 1507 unsigned int ROP = amd_gx_BppToRasterMode(pxMap->drawable.bitsPerPixel) 1508 | (planemask == ~0U ? SDfn[alu] : SDfn_PM[alu]); 1509 1510 // FIXME: this should go away -- workaround for the blockparty icon corruption 1511 //if (pxMap->drawable.bitsPerPixel == 32) 1512 // return FALSE; 1513 1514 BLT_MODE = ((ROP ^ (ROP >> 2)) & 0x33) == 0 ? MGP_BM_SRC_MONO : 0; 1515 if (((ROP ^ (ROP >> 1)) & 0x55) != 0) 1516 BLT_MODE |= MGP_BM_DST_REQ; 1517 //ErrorF("amd_gx_exa_PrepareSolid(%#x,%#x,%#x - ROP=%x,BLT_MODE=%x)\n", alu, planemask, fg, ROP, BLT_MODE); 1518 GU2_WAIT_PENDING; 1519 WRITE_GP32(MGP_RASTER_MODE, ROP); 1520 WRITE_GP32(MGP_PAT_COLOR_0, planemask); 1521 WRITE_GP32(MGP_SRC_COLOR_FG, fg); 1522 WRITE_GP32(MGP_STRIDE, dstPitch); 1523 return TRUE; 1524} 1525 1526static void 1527amd_gx_exa_Solid(PixmapPtr pxMap, int x1, int y1, int x2, int y2) 1528{ 1529 int bpp = (pxMap->drawable.bitsPerPixel + 7) / 8; 1530 int pitch = exaGetPixmapPitch(pxMap); 1531 unsigned int offset = exaGetPixmapOffset(pxMap) + pitch * y1 + bpp * x1; 1532 unsigned int size = ((x2 - x1) << 16) | (y2 - y1); 1533 1534 //ErrorF("amd_gx_exa_Solid() at %d,%d %d,%d - offset=%d, bpp=%d\n", x1, y1, x2, y2, offset, bpp); 1535 1536 GU2_WAIT_PENDING; 1537 WRITE_GP32(MGP_DST_OFFSET, offset); 1538 WRITE_GP32(MGP_WID_HEIGHT, size); 1539 WRITE_GP32(MGP_BLT_MODE, BLT_MODE); 1540} 1541 1542/* Copy */ 1543 1544static Bool 1545amd_gx_exa_PrepareCopy(PixmapPtr pxSrc, PixmapPtr pxDst, int dx, int dy, 1546 int alu, Pixel planemask) 1547{ 1548 GeodeRec *pGeode = GEODEPTR_FROM_PIXMAP(pxDst); 1549 int dstPitch = exaGetPixmapPitch(pxDst); 1550 unsigned int ROP; 1551 1552 /* Punt if the color formats aren't the same */ 1553 1554 if (pxSrc->drawable.bitsPerPixel != pxDst->drawable.bitsPerPixel) 1555 return FALSE; 1556 1557 //ErrorF("amd_gx_exa_PrepareCopy() dx%d dy%d alu %#x %#x\n", 1558 // dx, dy, alu, planemask); 1559 1560 pGeode->cpySrcOffset = exaGetPixmapOffset(pxSrc); 1561 pGeode->cpySrcPitch = exaGetPixmapPitch(pxSrc); 1562 pGeode->cpySrcBpp = (pxSrc->drawable.bitsPerPixel + 7) / 8; 1563 pGeode->cpyDx = dx; 1564 pGeode->cpyDy = dy; 1565 ROP = amd_gx_BppToRasterMode(pxSrc->drawable.bitsPerPixel) | 1566 (planemask == ~0U ? SDfn[alu] : SDfn_PM[alu]); 1567 1568 BLT_MODE = ((ROP ^ (ROP >> 1)) & 0x55) != 0 ? 1569 MGP_BM_SRC_FB | MGP_BM_DST_REQ : MGP_BM_SRC_FB; 1570 GU2_WAIT_PENDING; 1571 WRITE_GP32(MGP_RASTER_MODE, ROP); 1572 WRITE_GP32(MGP_PAT_COLOR_0, planemask); 1573 WRITE_GP32(MGP_SRC_COLOR_FG, ~0); 1574 WRITE_GP32(MGP_SRC_COLOR_BG, ~0); 1575 WRITE_GP32(MGP_STRIDE, (pGeode->cpySrcPitch << 16) | dstPitch); 1576 return TRUE; 1577} 1578 1579static void 1580amd_gx_exa_Copy(PixmapPtr pxDst, int srcX, int srcY, int dstX, int dstY, 1581 int w, int h) 1582{ 1583 GeodeRec *pGeode = GEODEPTR_FROM_PIXMAP(pxDst); 1584 int dstBpp = (pxDst->drawable.bitsPerPixel + 7) / 8; 1585 int dstPitch = exaGetPixmapPitch(pxDst); 1586 unsigned int srcOffset = 1587 pGeode->cpySrcOffset + (pGeode->cpySrcPitch * srcY) + 1588 (pGeode->cpySrcBpp * srcX); 1589 unsigned int dstOffset = 1590 exaGetPixmapOffset(pxDst) + (dstPitch * dstY) + (dstBpp * dstX); 1591 unsigned int size = (w << 16) | h; 1592 unsigned int blt_mode = BLT_MODE; 1593 1594 //ErrorF("amd_gx_exa_Copy() from %d,%d to %d,%d %dx%d\n", srcX, srcY, 1595 // dstX, dstY, w, h); 1596 1597 if (pGeode->cpyDx < 0) { 1598 srcOffset += w * pGeode->cpySrcBpp - 1; 1599 dstOffset += w * dstBpp - 1; 1600 blt_mode |= MGP_BM_NEG_XDIR; 1601 } 1602 if (pGeode->cpyDy < 0) { 1603 srcOffset += (h - 1) * pGeode->cpySrcPitch; 1604 dstOffset += (h - 1) * dstPitch; 1605 blt_mode |= MGP_BM_NEG_YDIR; 1606 } 1607 GU2_WAIT_PENDING; 1608 WRITE_GP32(MGP_SRC_OFFSET, srcOffset); 1609 WRITE_GP32(MGP_DST_OFFSET, dstOffset); 1610 WRITE_GP32(MGP_WID_HEIGHT, size); 1611 WRITE_GP16(MGP_BLT_MODE, blt_mode); 1612} 1613 1614/* A=SRC, B=DST */ 1615#define SRC_DST 0 1616/* B=SRC, A=DST */ 1617#define DST_SRC MGP_RM_DEST_FROM_CHAN_A 1618/* A*alpha + B*0 */ 1619#define Aa_B0 MGP_RM_ALPHA_TIMES_A 1620/* A*0 + B*(1-alpha) */ 1621#define A0_B1a MGP_RM_BETA_TIMES_B 1622/* A*1 + B*(1-alpha) */ 1623#define A1_B1a MGP_RM_A_PLUS_BETA_B 1624/* A*alpha + B*(1-alpha) */ 1625#define Aa_B1a MGP_RM_ALPHA_A_PLUS_BETA_B 1626/* alpha from A */ 1627#define a_A MGP_RM_SELECT_ALPHA_A 1628/* alpha from B */ 1629#define a_B MGP_RM_SELECT_ALPHA_B 1630/* alpha from const */ 1631#define a_C MGP_RM_SELECT_ALPHA_R 1632/* alpha = 1 */ 1633#define a_1 MGP_RM_SELECT_ALPHA_1 1634 1635#define MGP_RM_ALPHA_TO_ARGB (MGP_RM_ALPHA_TO_ALPHA | MGP_RM_ALPHA_TO_RGB) 1636#define gxPictOpMAX PictOpAdd /* highest accelerated op */ 1637 1638unsigned int amd_gx_exa_alpha_ops[] = 1639/* A B OP AS const = 0 */ 1640{ 1641 (SRC_DST | Aa_B0 | a_C), 0, /* clear (src*0) */ 1642 (SRC_DST | Aa_B0 | a_1), 0, /* src (src*1) */ 1643 (DST_SRC | Aa_B0 | a_1), 0, /* dst (dst*1) */ 1644 (SRC_DST | A1_B1a | a_A), 0, /* src-over (src*1 + dst(1-A)) */ 1645 (DST_SRC | A1_B1a | a_A), 0, /* dst-over (dst*1 + src(1-B)) */ 1646 (SRC_DST | Aa_B0 | a_B), 0, /* src-in (src*B) */ 1647 (DST_SRC | Aa_B0 | a_B), 0, /* dst-in (dst*A) */ 1648 (DST_SRC | A0_B1a | a_A), 0, /* src-out (src*(1-B)) */ 1649 (SRC_DST | A0_B1a | a_A), 0, /* dst-out (dst*(1-A)) */ 1650/* pass1 (SRC=dst DST=scr=src), pass2 (SRC=src, DST=dst) */ 1651 (DST_SRC | Aa_B0 | a_B), /* srcatop (src*B) */ 1652 (SRC_DST | A0_B1a | a_A), /* + (dst(1-A)) */ 1653 (SRC_DST | Aa_B0 | a_B), /* dstatop (dst*A) */ 1654 (DST_SRC | A0_B1a | a_A), /* + (src(1-B) */ 1655 (SRC_DST | A0_B1a | a_A), /* xor (src*(1-B) */ 1656 (SRC_DST | A0_B1a | a_A), /* + (dst(1-A) */ 1657 (SRC_DST | A1_B1a | a_C), 0, /* add (src*1 + dst*1) */ 1658}; 1659 1660typedef struct 1661{ 1662 int exa_fmt; 1663 int bpp; 1664 int gx_fmt; 1665 int alpha_bits; 1666} amd_gx_exa_fmt_t; 1667 1668amd_gx_exa_fmt_t amd_gx_exa_fmts[] = { 1669 {PICT_a8r8g8b8, 32, MGP_RM_BPPFMT_8888, 8}, 1670 {PICT_x8r8g8b8, 32, MGP_RM_BPPFMT_8888, 0}, 1671 {PICT_a4r4g4b4, 16, MGP_RM_BPPFMT_4444, 4}, 1672 {PICT_a1r5g5b5, 16, MGP_RM_BPPFMT_1555, 1}, 1673 {PICT_r5g6b5, 16, MGP_RM_BPPFMT_565, 0}, 1674 {PICT_r3g3b2, 8, MGP_RM_BPPFMT_332, 0}, 1675}; 1676 1677static amd_gx_exa_fmt_t * 1678amd_gx_exa_check_format(PicturePtr p) 1679{ 1680 int i; 1681 int bpp = p->pDrawable ? p->pDrawable->bitsPerPixel : 0; 1682 amd_gx_exa_fmt_t *fp = &amd_gx_exa_fmts[0]; 1683 1684 for (i = sizeof(amd_gx_exa_fmts) / sizeof(amd_gx_exa_fmts[0]); --i >= 0; 1685 ++fp) { 1686 if (fp->bpp < bpp) 1687 return NULL; 1688 if (fp->bpp != bpp) 1689 continue; 1690 if (fp->exa_fmt == p->format) 1691 break; 1692 } 1693 return i < 0 ? NULL : fp; 1694} 1695 1696/* Composite */ 1697 1698static Bool 1699amd_gx_exa_CheckComposite(int op, PicturePtr pSrc, PicturePtr pMsk, 1700 PicturePtr pDst) 1701{ 1702 GeodeRec *pGeode = GEODEPTR_FROM_PICTURE(pDst); 1703 1704 if (op > gxPictOpMAX) 1705 return FALSE; 1706 if (pMsk) 1707 return FALSE; 1708 if (usesPasses(op) && pGeode->exaBfrSz == 0) 1709 return FALSE; 1710 if (pSrc->filter != PictFilterNearest && 1711 pSrc->filter != PictFilterFast && 1712 pSrc->filter != PictFilterGood && pSrc->filter != PictFilterBest) 1713 return FALSE; 1714 if (pSrc->repeat) 1715 return FALSE; 1716 if (pSrc->transform) 1717 return FALSE; 1718 return TRUE; 1719} 1720 1721static Bool 1722amd_gx_exa_PrepareComposite(int op, PicturePtr pSrc, PicturePtr pMsk, 1723 PicturePtr pDst, PixmapPtr pxSrc, PixmapPtr pxMsk, PixmapPtr pxDst) 1724{ 1725 int srcPitch; 1726 1727 GeodeRec *pGeode = GEODEPTR_FROM_PIXMAP(pxDst); 1728 amd_gx_exa_fmt_t *sfp, *dfp; 1729 1730 //ErrorF("amd_gx_exa_PrepareComposite()\n"); 1731 1732 if ((sfp = amd_gx_exa_check_format(pSrc)) == NULL) 1733 return FALSE; 1734 if (sfp->alpha_bits == 0 && usesSrcAlpha(op)) 1735 return FALSE; 1736 if ((dfp = amd_gx_exa_check_format(pDst)) == NULL) 1737 return FALSE; 1738 if (dfp->alpha_bits == 0 && usesDstAlpha(op)) 1739 return FALSE; 1740 if (sfp->gx_fmt != dfp->gx_fmt) 1741 return FALSE; 1742 srcPitch = exaGetPixmapPitch(pxSrc); 1743 if (usesPasses(op) && srcPitch > pGeode->exaBfrSz) 1744 return FALSE; 1745 pGeode->cmpSrcPitch = srcPitch; 1746 pGeode->cmpOp = op; 1747 pGeode->cmpSrcOffset = exaGetPixmapOffset(pxSrc); 1748 pGeode->cmpSrcBpp = (pxSrc->drawable.bitsPerPixel + 7) / 8; 1749 pGeode->cmpSrcFmt = sfp->gx_fmt; 1750 pGeode->cmpDstFmt = dfp->gx_fmt | (dfp->alpha_bits == 0 ? 1751 MGP_RM_ALPHA_TO_RGB : MGP_RM_ALPHA_TO_ARGB); 1752 return TRUE; 1753} 1754 1755static void 1756amd_gx_exa_Composite(PixmapPtr pxDst, int srcX, int srcY, int maskX, 1757 int maskY, int dstX, int dstY, int width, int height) 1758{ 1759 int op, current_line, max_lines, lines, pass, scratchPitch; 1760 unsigned int srcOffset, srcOfs = 0, srcPitch, srcPch = 0, srcBpp; 1761 unsigned int dstOffset, dstOfs = 0, dstPitch, dstPch = 0, dstBpp; 1762 unsigned int sizes, strides, blt_mode = 0, rop = 0; 1763 GeodeRec *pGeode = GEODEPTR_FROM_PIXMAP(pxDst); 1764 1765 //ErrorF("amd_gx_exa_Composite() from %d,%d to %d,%d %dx%d\n", 1766 // srcX, srcY, dstX, dstY, width, height); 1767 1768 op = pGeode->cmpOp; 1769 if (usesPasses(op)) { 1770 int cacheLineSz = 32; 1771 int cachelines = 1772 (width * pGeode->cmpSrcBpp + cacheLineSz - 1) / cacheLineSz; 1773 scratchPitch = cachelines * cacheLineSz; 1774 if (scratchPitch > pGeode->cmpSrcPitch) 1775 scratchPitch = pGeode->cmpSrcPitch; 1776 max_lines = pGeode->exaBfrSz / scratchPitch; 1777 } else { 1778 scratchPitch = 0; 1779 max_lines = height; 1780 } 1781 1782 dstBpp = (pxDst->drawable.bitsPerPixel + 7) / 8; 1783 dstPitch = exaGetPixmapPitch(pxDst); 1784 dstOffset = exaGetPixmapOffset(pxDst) + dstPitch * dstY + dstBpp * dstX; 1785 srcBpp = pGeode->cmpSrcBpp; 1786 srcPitch = pGeode->cmpSrcPitch; 1787 srcOffset = pGeode->cmpSrcOffset + srcPitch * srcY + srcBpp * srcX; 1788 1789 current_line = pass = 0; 1790 while (current_line < height) { 1791 if (usesPasses(op)) { 1792 lines = height - current_line; 1793 if (lines > max_lines) 1794 lines = max_lines; 1795 switch (pass) { 1796 case 0: /* copy src to scratch */ 1797 srcPch = srcPitch; 1798 srcOfs = srcOffset + current_line * srcPch; 1799 dstPch = scratchPitch; 1800 dstOfs = pGeode->exaBfrOffset; 1801 rop = pGeode->cmpSrcFmt | MGP_RM_ALPHA_TO_ARGB; 1802 rop |= amd_gx_exa_alpha_ops[PictOpSrc * 2]; 1803 blt_mode = usesChanB0(PictOpSrc) ? 1804 MGP_BM_SRC_FB | MGP_BM_DST_REQ : MGP_BM_SRC_FB; 1805 ++pass; 1806 break; 1807 case 1: /* pass1 */ 1808 srcPch = dstPitch; 1809 srcOfs = dstOffset + current_line * srcPch; 1810 dstPch = scratchPitch; 1811 dstOfs = pGeode->exaBfrOffset; 1812 rop = pGeode->cmpSrcFmt | MGP_RM_ALPHA_TO_ARGB; 1813 rop |= amd_gx_exa_alpha_ops[op * 2]; 1814 blt_mode = usesChanB1(op) ? 1815 MGP_BM_SRC_FB | MGP_BM_DST_REQ : MGP_BM_SRC_FB; 1816 ++pass; 1817 break; 1818 case 2: /* pass2 */ 1819 srcPch = srcPitch; 1820 srcOfs = srcOffset + current_line * srcPch; 1821 dstPch = dstPitch; 1822 dstOfs = dstOffset + current_line * dstPch; 1823 rop = pGeode->cmpSrcFmt | MGP_RM_ALPHA_TO_ARGB; 1824 rop |= amd_gx_exa_alpha_ops[op * 2 + 1]; 1825 blt_mode = usesChanB2(op) ? 1826 MGP_BM_SRC_FB | MGP_BM_DST_REQ : MGP_BM_SRC_FB; 1827 ++pass; 1828 break; 1829 case 3: /* add */ 1830 srcPch = scratchPitch; 1831 srcOfs = pGeode->exaBfrOffset; 1832 dstPch = dstPitch; 1833 dstOfs = dstOffset + current_line * dstPch; 1834 rop = pGeode->cmpDstFmt; 1835 rop |= amd_gx_exa_alpha_ops[PictOpAdd * 2]; 1836 blt_mode = usesChanB0(PictOpAdd) ? 1837 MGP_BM_SRC_FB | MGP_BM_DST_REQ : MGP_BM_SRC_FB; 1838 current_line += lines; 1839 pass = 0; 1840 break; 1841 } 1842 strides = (srcPch << 16) | dstPch; 1843 } else { /* not multi pass */ 1844 srcOfs = srcOffset; 1845 dstOfs = dstOffset; 1846 current_line = lines = height; 1847 strides = (srcPitch << 16) | dstPitch; 1848 rop = pGeode->cmpDstFmt | amd_gx_exa_alpha_ops[op * 2]; 1849 blt_mode = usesChanB0(op) ? 1850 MGP_BM_SRC_FB | MGP_BM_DST_REQ : MGP_BM_SRC_FB; 1851 } 1852 sizes = (width << 16) | lines; 1853 if (srcOfs < dstOfs) { 1854 srcOfs += (lines - 1) * srcPitch + width * srcBpp - 1; 1855 dstOfs += (lines - 1) * dstPitch + width * dstBpp - 1; 1856 blt_mode |= MGP_BM_NEG_XDIR | MGP_BM_NEG_YDIR; 1857 } 1858 GU2_WAIT_PENDING; 1859 WRITE_GP32(MGP_RASTER_MODE, rop); 1860 WRITE_GP32(MGP_SRC_OFFSET, srcOfs); 1861 WRITE_GP32(MGP_DST_OFFSET, dstOfs); 1862 WRITE_GP32(MGP_WID_HEIGHT, sizes); 1863 WRITE_GP32(MGP_STRIDE, strides); 1864 WRITE_GP16(MGP_BLT_MODE, blt_mode); 1865 } 1866} 1867#endif /* #if XF86EXA */ 1868 1869/*---------------------------------------------------------------------------- 1870 * GXAccelInit. 1871 * 1872 * Description: This function sets up the supported acceleration routines and 1873 * appropriate flags. 1874 * 1875 * Parameters: 1876 * pScrn: Screeen pointer structure. 1877 * 1878 * Returns: TRUE on success and FALSE on Failure 1879 * 1880 * Comments: This function is called in GXScreenInit in 1881 * geode_driver.c to set * the acceleration. 1882 *---------------------------------------------------------------------------- 1883 */ 1884Bool 1885GXAccelInit(ScreenPtr pScrn) 1886{ 1887 ScrnInfoPtr pScrni = xf86Screens[pScrn->myNum]; 1888 GeodeRec *pGeode = GEODEPTR(pScrni); 1889 1890#if XF86EXA 1891 ExaDriverPtr pExa = pGeode->pExa; 1892#endif 1893 1894 gu2_xshift = pScrni->bitsPerPixel >> 4; 1895 1896 /* XXX - fixme - this will change - we'll need to update it */ 1897 1898 gu2_pitch = pGeode->Pitch; 1899 1900 switch (pGeode->Pitch) { 1901 case 1024: 1902 gu2_yshift = 10; 1903 break; 1904 case 2048: 1905 gu2_yshift = 11; 1906 break; 1907 case 4096: 1908 gu2_yshift = 12; 1909 break; 1910 default: 1911 gu2_yshift = 13; 1912 break; 1913 } 1914 1915#ifdef OPT_ACCEL 1916 ACCEL_STRIDE = (pGeode->Pitch << 16) | pGeode->Pitch; 1917 BPP = amd_gx_BppToRasterMode(pScrni->bitsPerPixel); 1918#endif 1919 1920#if XF86EXA 1921 if (pExa && pGeode->useEXA) { 1922 pExa->exa_major = EXA_VERSION_MAJOR; 1923 pExa->exa_minor = EXA_VERSION_MINOR; 1924 1925 /* Sync */ 1926 pExa->WaitMarker = amd_gx_exa_WaitMarker; 1927 /* UploadToScreen */ 1928 pExa->UploadToScreen = amd_gx_exa_UploadToScreen; 1929 pExa->DownloadFromScreen = amd_gx_exa_DownloadFromScreen; 1930 1931 /* Solid fill */ 1932 pExa->PrepareSolid = amd_gx_exa_PrepareSolid; 1933 pExa->Solid = amd_gx_exa_Solid; 1934 pExa->DoneSolid = amd_gx_exa_Done; 1935 1936 /* Copy */ 1937 pExa->PrepareCopy = amd_gx_exa_PrepareCopy; 1938 pExa->Copy = amd_gx_exa_Copy; 1939 pExa->DoneCopy = amd_gx_exa_Done; 1940 1941 /* Composite */ 1942 pExa->CheckComposite = amd_gx_exa_CheckComposite; 1943 pExa->PrepareComposite = amd_gx_exa_PrepareComposite; 1944 pExa->Composite = amd_gx_exa_Composite; 1945 pExa->DoneComposite = amd_gx_exa_Done; 1946 1947 return exaDriverInit(pScrn, pGeode->pExa); 1948 } 1949#endif 1950 1951 /* Getting the pointer for acceleration Inforecord */ 1952 pGeode->AccelInfoRec = localRecPtr = XAACreateInfoRec(); 1953 if (!pGeode->AccelInfoRec) 1954 return FALSE; 1955 1956 /* SET ACCELERATION FLAGS */ 1957 localRecPtr->Flags = 1958 PIXMAP_CACHE | OFFSCREEN_PIXMAPS | LINEAR_FRAMEBUFFER; 1959 1960 /* HOOK SYNCRONIZARION ROUTINE */ 1961 localRecPtr->Sync = GXAccelSync; 1962 1963#if GX_FILL_RECT_SUPPORT 1964 /* HOOK FILLED RECTANGLES */ 1965 HOOK(SetupForSolidFill); 1966 HOOK(SubsequentSolidFillRect); 1967 localRecPtr->SolidFillFlags = 0; 1968#endif 1969 1970#if GX_MONO_8X8_PAT_SUPPORT 1971 /* Color expansion */ 1972 HOOK(SetupForMono8x8PatternFill); 1973 HOOK(SubsequentMono8x8PatternFillRect); 1974/* BIT_ORDER_IN_BYTE_MSBFIRST | SCANLINE_PAD_DWORD | NO_TRANSPARENCY | */ 1975 localRecPtr->Mono8x8PatternFillFlags = BIT_ORDER_IN_BYTE_MSBFIRST | 1976 HARDWARE_PATTERN_PROGRAMMED_BITS | HARDWARE_PATTERN_SCREEN_ORIGIN; 1977#endif 1978 1979#if GX_CLREXP_8X8_PAT_SUPPORT 1980 /* Color expansion */ 1981 HOOK(SetupForColor8x8PatternFill); 1982 HOOK(SubsequentColor8x8PatternFillRect); 1983/* BIT_ORDER_IN_BYTE_MSBFIRST | SCANLINE_PAD_DWORD | NO_TRANSPARENCY | */ 1984 localRecPtr->Color8x8PatternFillFlags = 1985 BIT_ORDER_IN_BYTE_MSBFIRST | SCANLINE_PAD_DWORD | 1986 HARDWARE_PATTERN_PROGRAMMED_BITS | HARDWARE_PATTERN_PROGRAMMED_ORIGIN; 1987#endif 1988 1989#if GX_SCR2SCRCPY_SUPPORT 1990 /* HOOK SCREEN TO SCREEN COPIES 1991 * Set flag to only allow copy if transparency is enabled. 1992 */ 1993 HOOK(SetupForScreenToScreenCopy); 1994 HOOK(SubsequentScreenToScreenCopy); 1995 localRecPtr->ScreenToScreenCopyFlags = 1996 BIT_ORDER_IN_BYTE_MSBFIRST | SCANLINE_PAD_DWORD; 1997#endif 1998 1999#if GX_BRES_LINE_SUPPORT 2000 /* HOOK BRESENHAM SOLID LINES */ 2001 localRecPtr->SolidLineFlags = NO_PLANEMASK; 2002 HOOK(SetupForSolidLine); 2003 HOOK(SubsequentSolidBresenhamLine); 2004 HOOK(SubsequentSolidHorVertLine); 2005 HOOK(SubsequentSolidTwoPointLine); 2006 localRecPtr->SolidBresenhamLineErrorTermBits = 15; 2007#endif 2008 2009#if GX_DASH_LINE_SUPPORT 2010 /* HOOK BRESENHAM DASHED LINES */ 2011 HOOK(SetupForDashedLine); 2012 HOOK(SubsequentDashedBresenhamLine); 2013 HOOK(SubsequentDashedTwoPointLine); 2014 localRecPtr->DashedBresenhamLineErrorTermBits = 15; 2015 localRecPtr->DashPatternMaxLength = 64; 2016 localRecPtr->DashedLineFlags = NO_PLANEMASK | /* TRANSPARENCY_ONLY | */ 2017 LINE_PATTERN_POWER_OF_2_ONLY | LINE_PATTERN_MSBFIRST_MSBJUSTIFIED; 2018#endif 2019 2020#if GX_SCR2SCREXP_SUPPORT 2021 /* Color expansion */ 2022 HOOK(SetupForScreenToScreenColorExpandFill); 2023 HOOK(SubsequentScreenToScreenColorExpandFill); 2024 localRecPtr->ScreenToScreenColorExpandFillFlags = 2025 BIT_ORDER_IN_BYTE_MSBFIRST | SCANLINE_PAD_DWORD | NO_TRANSPARENCY; 2026#endif 2027 2028 if (pGeode->AccelImageWriteBuffers) { 2029#if GX_SCANLINE_SUPPORT 2030 localRecPtr->ScanlineImageWriteBuffers = 2031 pGeode->AccelImageWriteBuffers; 2032 localRecPtr->NumScanlineImageWriteBuffers = pGeode->NoOfImgBuffers; 2033 HOOK(SetupForScanlineImageWrite); 2034 HOOK(SubsequentScanlineImageWriteRect); 2035 HOOK(SubsequentImageWriteScanline); 2036 localRecPtr->ScanlineImageWriteFlags = NO_PLANEMASK | NO_GXCOPY | 2037 BIT_ORDER_IN_BYTE_MSBFIRST | SCANLINE_PAD_DWORD; 2038#endif 2039 2040 } else { 2041 localRecPtr->PixmapCacheFlags = DO_NOT_BLIT_STIPPLES; 2042 } 2043 2044 if (pGeode->AccelColorExpandBuffers) { 2045#if GX_CPU2SCREXP_SUPPORT 2046 /* Color expansion */ 2047 localRecPtr->ScanlineColorExpandBuffers = 2048 pGeode->AccelColorExpandBuffers; 2049 localRecPtr->NumScanlineColorExpandBuffers = 2050 pGeode->NoOfColorExpandLines; 2051 HOOK(SetupForScanlineCPUToScreenColorExpandFill); 2052 HOOK(SubsequentScanlineCPUToScreenColorExpandFill); 2053 HOOK(SubsequentColorExpandScanline); 2054 localRecPtr->ScanlineCPUToScreenColorExpandFillFlags = NO_PLANEMASK | 2055 BIT_ORDER_IN_BYTE_MSBFIRST | SCANLINE_PAD_DWORD; 2056#endif 2057 } 2058#if GX_WRITE_PIXMAP_SUPPORT 2059 pGeode->WritePixmap = localRecPtr->WritePixmap; 2060 HOOK(WritePixmap); 2061#endif 2062 2063 return (XAAInit(pScrn, localRecPtr)); 2064} 2065 2066/* END OF FILE */ 2067