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