gx_accel.c revision 44802259
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 GeodeRec *pGeode = GEODEPTR_FROM_PIXMAP(pDst); 1494 char *dst = pGeode->pExa->memoryBase + exaGetPixmapOffset(pDst); 1495 int dst_pitch = exaGetPixmapPitch(pDst); 1496 int bpp = pDst->drawable.bitsPerPixel; 1497 1498 dst += y * dst_pitch + x * (bpp >> 3); 1499 GU2_WAIT_BUSY; 1500 geode_memory_to_screen_blt((unsigned long) src, (unsigned long) dst, 1501 src_pitch, dst_pitch, w, h, bpp); 1502 return TRUE; 1503} 1504 1505static Bool 1506amd_gx_exa_DownloadFromScreen(PixmapPtr pSrc, int x, int y, int w, int h, 1507 char *dst, int dst_pitch) 1508{ 1509 GeodeRec *pGeode = GEODEPTR_FROM_PIXMAP(pSrc); 1510 char *src = pGeode->pExa->memoryBase + exaGetPixmapOffset(pSrc); 1511 int src_pitch = exaGetPixmapPitch(pSrc); 1512 int bpp = pSrc->drawable.bitsPerPixel; 1513 1514 src += (y * src_pitch) + (x * (bpp >> 3)); 1515 GU2_WAIT_BUSY; 1516 geode_memory_to_screen_blt((unsigned long) src, (unsigned long) dst, 1517 src_pitch, dst_pitch, w, h, bpp); 1518 return TRUE; 1519} 1520 1521/* Solid */ 1522 1523static Bool 1524amd_gx_exa_PrepareSolid(PixmapPtr pxMap, int alu, Pixel planemask, Pixel fg) 1525{ 1526 int dstPitch = exaGetPixmapPitch(pxMap); 1527 unsigned int ROP = amd_gx_BppToRasterMode(pxMap->drawable.bitsPerPixel) 1528 | (planemask == ~0U ? SDfn[alu] : SDfn_PM[alu]); 1529 1530 // FIXME: this should go away -- workaround for the blockparty icon corruption 1531 //if (pxMap->drawable.bitsPerPixel == 32) 1532 // return FALSE; 1533 1534 BLT_MODE = ((ROP ^ (ROP >> 2)) & 0x33) == 0 ? MGP_BM_SRC_MONO : 0; 1535 if (((ROP ^ (ROP >> 1)) & 0x55) != 0) 1536 BLT_MODE |= MGP_BM_DST_REQ; 1537 //ErrorF("amd_gx_exa_PrepareSolid(%#x,%#x,%#x - ROP=%x,BLT_MODE=%x)\n", alu, planemask, fg, ROP, BLT_MODE); 1538 GU2_WAIT_PENDING; 1539 WRITE_GP32(MGP_RASTER_MODE, ROP); 1540 WRITE_GP32(MGP_PAT_COLOR_0, planemask); 1541 WRITE_GP32(MGP_SRC_COLOR_FG, fg); 1542 WRITE_GP32(MGP_STRIDE, dstPitch); 1543 return TRUE; 1544} 1545 1546static void 1547amd_gx_exa_Solid(PixmapPtr pxMap, int x1, int y1, int x2, int y2) 1548{ 1549 int bpp = (pxMap->drawable.bitsPerPixel + 7) / 8; 1550 int pitch = exaGetPixmapPitch(pxMap); 1551 unsigned int offset = exaGetPixmapOffset(pxMap) + pitch * y1 + bpp * x1; 1552 unsigned int size = ((x2 - x1) << 16) | (y2 - y1); 1553 1554 //ErrorF("amd_gx_exa_Solid() at %d,%d %d,%d - offset=%d, bpp=%d\n", x1, y1, x2, y2, offset, bpp); 1555 1556 GU2_WAIT_PENDING; 1557 WRITE_GP32(MGP_DST_OFFSET, offset); 1558 WRITE_GP32(MGP_WID_HEIGHT, size); 1559 WRITE_GP32(MGP_BLT_MODE, BLT_MODE); 1560} 1561 1562/* Copy */ 1563 1564static Bool 1565amd_gx_exa_PrepareCopy(PixmapPtr pxSrc, PixmapPtr pxDst, int dx, int dy, 1566 int alu, Pixel planemask) 1567{ 1568 GeodeRec *pGeode = GEODEPTR_FROM_PIXMAP(pxDst); 1569 int dstPitch = exaGetPixmapPitch(pxDst); 1570 unsigned int ROP; 1571 1572 /* Punt if the color formats aren't the same */ 1573 1574 if (pxSrc->drawable.bitsPerPixel != pxDst->drawable.bitsPerPixel) 1575 return FALSE; 1576 1577 //ErrorF("amd_gx_exa_PrepareCopy() dx%d dy%d alu %#x %#x\n", 1578 // dx, dy, alu, planemask); 1579 1580 pGeode->cpySrcOffset = exaGetPixmapOffset(pxSrc); 1581 pGeode->cpySrcPitch = exaGetPixmapPitch(pxSrc); 1582 pGeode->cpySrcBpp = (pxSrc->drawable.bitsPerPixel + 7) / 8; 1583 pGeode->cpyDx = dx; 1584 pGeode->cpyDy = dy; 1585 ROP = amd_gx_BppToRasterMode(pxSrc->drawable.bitsPerPixel) | 1586 (planemask == ~0U ? SDfn[alu] : SDfn_PM[alu]); 1587 1588 BLT_MODE = ((ROP ^ (ROP >> 1)) & 0x55) != 0 ? 1589 MGP_BM_SRC_FB | MGP_BM_DST_REQ : MGP_BM_SRC_FB; 1590 GU2_WAIT_PENDING; 1591 WRITE_GP32(MGP_RASTER_MODE, ROP); 1592 WRITE_GP32(MGP_PAT_COLOR_0, planemask); 1593 WRITE_GP32(MGP_SRC_COLOR_FG, ~0); 1594 WRITE_GP32(MGP_SRC_COLOR_BG, ~0); 1595 WRITE_GP32(MGP_STRIDE, (pGeode->cpySrcPitch << 16) | dstPitch); 1596 return TRUE; 1597} 1598 1599static void 1600amd_gx_exa_Copy(PixmapPtr pxDst, int srcX, int srcY, int dstX, int dstY, 1601 int w, int h) 1602{ 1603 GeodeRec *pGeode = GEODEPTR_FROM_PIXMAP(pxDst); 1604 int dstBpp = (pxDst->drawable.bitsPerPixel + 7) / 8; 1605 int dstPitch = exaGetPixmapPitch(pxDst); 1606 unsigned int srcOffset = 1607 pGeode->cpySrcOffset + (pGeode->cpySrcPitch * srcY) + 1608 (pGeode->cpySrcBpp * srcX); 1609 unsigned int dstOffset = 1610 exaGetPixmapOffset(pxDst) + (dstPitch * dstY) + (dstBpp * dstX); 1611 unsigned int size = (w << 16) | h; 1612 unsigned int blt_mode = BLT_MODE; 1613 1614 //ErrorF("amd_gx_exa_Copy() from %d,%d to %d,%d %dx%d\n", srcX, srcY, 1615 // dstX, dstY, w, h); 1616 1617 if (pGeode->cpyDx < 0) { 1618 srcOffset += w * pGeode->cpySrcBpp - 1; 1619 dstOffset += w * dstBpp - 1; 1620 blt_mode |= MGP_BM_NEG_XDIR; 1621 } 1622 if (pGeode->cpyDy < 0) { 1623 srcOffset += (h - 1) * pGeode->cpySrcPitch; 1624 dstOffset += (h - 1) * dstPitch; 1625 blt_mode |= MGP_BM_NEG_YDIR; 1626 } 1627 GU2_WAIT_PENDING; 1628 WRITE_GP32(MGP_SRC_OFFSET, srcOffset); 1629 WRITE_GP32(MGP_DST_OFFSET, dstOffset); 1630 WRITE_GP32(MGP_WID_HEIGHT, size); 1631 WRITE_GP16(MGP_BLT_MODE, blt_mode); 1632} 1633 1634/* A=SRC, B=DST */ 1635#define SRC_DST 0 1636/* B=SRC, A=DST */ 1637#define DST_SRC MGP_RM_DEST_FROM_CHAN_A 1638/* A*alpha + B*0 */ 1639#define Aa_B0 MGP_RM_ALPHA_TIMES_A 1640/* A*0 + B*(1-alpha) */ 1641#define A0_B1a MGP_RM_BETA_TIMES_B 1642/* A*1 + B*(1-alpha) */ 1643#define A1_B1a MGP_RM_A_PLUS_BETA_B 1644/* A*alpha + B*(1-alpha) */ 1645#define Aa_B1a MGP_RM_ALPHA_A_PLUS_BETA_B 1646/* alpha from A */ 1647#define a_A MGP_RM_SELECT_ALPHA_A 1648/* alpha from B */ 1649#define a_B MGP_RM_SELECT_ALPHA_B 1650/* alpha from const */ 1651#define a_C MGP_RM_SELECT_ALPHA_R 1652/* alpha = 1 */ 1653#define a_1 MGP_RM_SELECT_ALPHA_1 1654 1655#define MGP_RM_ALPHA_TO_ARGB (MGP_RM_ALPHA_TO_ALPHA | MGP_RM_ALPHA_TO_RGB) 1656#define gxPictOpMAX PictOpAdd /* highest accelerated op */ 1657 1658unsigned int amd_gx_exa_alpha_ops[] = 1659/* A B OP AS const = 0 */ 1660{ 1661 (SRC_DST | Aa_B0 | a_C), 0, /* clear (src*0) */ 1662 (SRC_DST | Aa_B0 | a_1), 0, /* src (src*1) */ 1663 (DST_SRC | Aa_B0 | a_1), 0, /* dst (dst*1) */ 1664 (SRC_DST | A1_B1a | a_A), 0, /* src-over (src*1 + dst(1-A)) */ 1665 (DST_SRC | A1_B1a | a_A), 0, /* dst-over (dst*1 + src(1-B)) */ 1666 (SRC_DST | Aa_B0 | a_B), 0, /* src-in (src*B) */ 1667 (DST_SRC | Aa_B0 | a_B), 0, /* dst-in (dst*A) */ 1668 (DST_SRC | A0_B1a | a_A), 0, /* src-out (src*(1-B)) */ 1669 (SRC_DST | A0_B1a | a_A), 0, /* dst-out (dst*(1-A)) */ 1670/* pass1 (SRC=dst DST=scr=src), pass2 (SRC=src, DST=dst) */ 1671 (DST_SRC | Aa_B0 | a_B), /* srcatop (src*B) */ 1672 (SRC_DST | A0_B1a | a_A), /* + (dst(1-A)) */ 1673 (SRC_DST | Aa_B0 | a_B), /* dstatop (dst*A) */ 1674 (DST_SRC | A0_B1a | a_A), /* + (src(1-B) */ 1675 (SRC_DST | A0_B1a | a_A), /* xor (src*(1-B) */ 1676 (SRC_DST | A0_B1a | a_A), /* + (dst(1-A) */ 1677 (SRC_DST | A1_B1a | a_C), 0, /* add (src*1 + dst*1) */ 1678}; 1679 1680typedef struct { 1681 int exa_fmt; 1682 int bpp; 1683 int gx_fmt; 1684 int alpha_bits; 1685} amd_gx_exa_fmt_t; 1686 1687amd_gx_exa_fmt_t amd_gx_exa_fmts[] = { 1688 {PICT_a8r8g8b8, 32, MGP_RM_BPPFMT_8888, 8}, 1689 {PICT_x8r8g8b8, 32, MGP_RM_BPPFMT_8888, 0}, 1690 {PICT_a4r4g4b4, 16, MGP_RM_BPPFMT_4444, 4}, 1691 {PICT_a1r5g5b5, 16, MGP_RM_BPPFMT_1555, 1}, 1692 {PICT_r5g6b5, 16, MGP_RM_BPPFMT_565, 0}, 1693 {PICT_r3g3b2, 8, MGP_RM_BPPFMT_332, 0}, 1694}; 1695 1696static amd_gx_exa_fmt_t * 1697amd_gx_exa_check_format(PicturePtr p) 1698{ 1699 int i; 1700 int bpp = p->pDrawable ? p->pDrawable->bitsPerPixel : 0; 1701 amd_gx_exa_fmt_t *fp = &amd_gx_exa_fmts[0]; 1702 1703 for (i = sizeof(amd_gx_exa_fmts) / sizeof(amd_gx_exa_fmts[0]); --i >= 0; 1704 ++fp) { 1705 if (fp->bpp < bpp) 1706 return NULL; 1707 if (fp->bpp != bpp) 1708 continue; 1709 if (fp->exa_fmt == p->format) 1710 break; 1711 } 1712 return i < 0 ? NULL : fp; 1713} 1714 1715/* Composite */ 1716 1717static Bool 1718amd_gx_exa_CheckComposite(int op, PicturePtr pSrc, PicturePtr pMsk, 1719 PicturePtr pDst) 1720{ 1721 GeodeRec *pGeode = GEODEPTR_FROM_PICTURE(pDst); 1722 1723 if (op > gxPictOpMAX) 1724 return FALSE; 1725 if (pMsk) 1726 return FALSE; 1727 if (usesPasses(op) && pGeode->exaBfrSz == 0) 1728 return FALSE; 1729 if (pSrc->filter != PictFilterNearest && 1730 pSrc->filter != PictFilterFast && 1731 pSrc->filter != PictFilterGood && pSrc->filter != PictFilterBest) 1732 return FALSE; 1733 if (pSrc->repeat) 1734 return FALSE; 1735 if (pSrc->transform) 1736 return FALSE; 1737 return TRUE; 1738} 1739 1740static Bool 1741amd_gx_exa_PrepareComposite(int op, PicturePtr pSrc, PicturePtr pMsk, 1742 PicturePtr pDst, PixmapPtr pxSrc, PixmapPtr pxMsk, 1743 PixmapPtr pxDst) 1744{ 1745 int srcPitch; 1746 if (!pxSrc || !pSrc->pDrawable) return FALSE; 1747 1748 GeodeRec *pGeode = GEODEPTR_FROM_PIXMAP(pxDst); 1749 amd_gx_exa_fmt_t *sfp, *dfp; 1750 1751 //ErrorF("amd_gx_exa_PrepareComposite()\n"); 1752 1753 if ((sfp = amd_gx_exa_check_format(pSrc)) == NULL) 1754 return FALSE; 1755 if (sfp->alpha_bits == 0 && usesSrcAlpha(op)) 1756 return FALSE; 1757 if ((dfp = amd_gx_exa_check_format(pDst)) == NULL) 1758 return FALSE; 1759 if (dfp->alpha_bits == 0 && usesDstAlpha(op)) 1760 return FALSE; 1761 if (sfp->gx_fmt != dfp->gx_fmt) 1762 return FALSE; 1763 srcPitch = exaGetPixmapPitch(pxSrc); 1764 if (usesPasses(op) && srcPitch > pGeode->exaBfrSz) 1765 return FALSE; 1766 pGeode->cmpSrcPitch = srcPitch; 1767 pGeode->cmpOp = op; 1768 pGeode->cmpSrcOffset = exaGetPixmapOffset(pxSrc); 1769 pGeode->cmpSrcBpp = (pxSrc->drawable.bitsPerPixel + 7) / 8; 1770 pGeode->cmpSrcFmt = sfp->gx_fmt; 1771 pGeode->cmpDstFmt = dfp->gx_fmt | (dfp->alpha_bits == 0 ? 1772 MGP_RM_ALPHA_TO_RGB : 1773 MGP_RM_ALPHA_TO_ARGB); 1774 return TRUE; 1775} 1776 1777static void 1778amd_gx_exa_Composite(PixmapPtr pxDst, int srcX, int srcY, int maskX, 1779 int maskY, int dstX, int dstY, int width, int height) 1780{ 1781 int op, current_line, max_lines, lines, pass, scratchPitch; 1782 unsigned int srcOffset, srcOfs = 0, srcPitch, srcPch = 0, srcBpp; 1783 unsigned int dstOffset, dstOfs = 0, dstPitch, dstPch = 0, dstBpp; 1784 unsigned int sizes, strides, blt_mode = 0, rop = 0; 1785 GeodeRec *pGeode = GEODEPTR_FROM_PIXMAP(pxDst); 1786 1787 //ErrorF("amd_gx_exa_Composite() from %d,%d to %d,%d %dx%d\n", 1788 // srcX, srcY, dstX, dstY, width, height); 1789 1790 op = pGeode->cmpOp; 1791 if (usesPasses(op)) { 1792 int cacheLineSz = 32; 1793 int cachelines = 1794 (width * pGeode->cmpSrcBpp + cacheLineSz - 1) / cacheLineSz; 1795 scratchPitch = cachelines * cacheLineSz; 1796 if (scratchPitch > pGeode->cmpSrcPitch) 1797 scratchPitch = pGeode->cmpSrcPitch; 1798 max_lines = pGeode->exaBfrSz / scratchPitch; 1799 } 1800 else { 1801 scratchPitch = 0; 1802 max_lines = height; 1803 } 1804 1805 dstBpp = (pxDst->drawable.bitsPerPixel + 7) / 8; 1806 dstPitch = exaGetPixmapPitch(pxDst); 1807 dstOffset = exaGetPixmapOffset(pxDst) + dstPitch * dstY + dstBpp * dstX; 1808 srcBpp = pGeode->cmpSrcBpp; 1809 srcPitch = pGeode->cmpSrcPitch; 1810 srcOffset = pGeode->cmpSrcOffset + srcPitch * srcY + srcBpp * srcX; 1811 1812 current_line = pass = 0; 1813 while (current_line < height) { 1814 if (usesPasses(op)) { 1815 lines = height - current_line; 1816 if (lines > max_lines) 1817 lines = max_lines; 1818 switch (pass) { 1819 case 0: /* copy src to scratch */ 1820 srcPch = srcPitch; 1821 srcOfs = srcOffset + current_line * srcPch; 1822 dstPch = scratchPitch; 1823 dstOfs = pGeode->exaBfrOffset; 1824 rop = pGeode->cmpSrcFmt | MGP_RM_ALPHA_TO_ARGB; 1825 rop |= amd_gx_exa_alpha_ops[PictOpSrc * 2]; 1826 blt_mode = usesChanB0(PictOpSrc) ? 1827 MGP_BM_SRC_FB | MGP_BM_DST_REQ : MGP_BM_SRC_FB; 1828 ++pass; 1829 break; 1830 case 1: /* pass1 */ 1831 srcPch = dstPitch; 1832 srcOfs = dstOffset + current_line * srcPch; 1833 dstPch = scratchPitch; 1834 dstOfs = pGeode->exaBfrOffset; 1835 rop = pGeode->cmpSrcFmt | MGP_RM_ALPHA_TO_ARGB; 1836 rop |= amd_gx_exa_alpha_ops[op * 2]; 1837 blt_mode = usesChanB1(op) ? 1838 MGP_BM_SRC_FB | MGP_BM_DST_REQ : MGP_BM_SRC_FB; 1839 ++pass; 1840 break; 1841 case 2: /* pass2 */ 1842 srcPch = srcPitch; 1843 srcOfs = srcOffset + current_line * srcPch; 1844 dstPch = dstPitch; 1845 dstOfs = dstOffset + current_line * dstPch; 1846 rop = pGeode->cmpSrcFmt | MGP_RM_ALPHA_TO_ARGB; 1847 rop |= amd_gx_exa_alpha_ops[op * 2 + 1]; 1848 blt_mode = usesChanB2(op) ? 1849 MGP_BM_SRC_FB | MGP_BM_DST_REQ : MGP_BM_SRC_FB; 1850 ++pass; 1851 break; 1852 case 3: /* add */ 1853 srcPch = scratchPitch; 1854 srcOfs = pGeode->exaBfrOffset; 1855 dstPch = dstPitch; 1856 dstOfs = dstOffset + current_line * dstPch; 1857 rop = pGeode->cmpDstFmt; 1858 rop |= amd_gx_exa_alpha_ops[PictOpAdd * 2]; 1859 blt_mode = usesChanB0(PictOpAdd) ? 1860 MGP_BM_SRC_FB | MGP_BM_DST_REQ : MGP_BM_SRC_FB; 1861 current_line += lines; 1862 pass = 0; 1863 break; 1864 } 1865 strides = (srcPch << 16) | dstPch; 1866 } 1867 else { /* not multi pass */ 1868 srcOfs = srcOffset; 1869 dstOfs = dstOffset; 1870 current_line = lines = height; 1871 strides = (srcPitch << 16) | dstPitch; 1872 rop = pGeode->cmpDstFmt | amd_gx_exa_alpha_ops[op * 2]; 1873 blt_mode = usesChanB0(op) ? 1874 MGP_BM_SRC_FB | MGP_BM_DST_REQ : MGP_BM_SRC_FB; 1875 } 1876 sizes = (width << 16) | lines; 1877 if (srcOfs < dstOfs) { 1878 srcOfs += (lines - 1) * srcPitch + width * srcBpp - 1; 1879 dstOfs += (lines - 1) * dstPitch + width * dstBpp - 1; 1880 blt_mode |= MGP_BM_NEG_XDIR | MGP_BM_NEG_YDIR; 1881 } 1882 GU2_WAIT_PENDING; 1883 WRITE_GP32(MGP_RASTER_MODE, rop); 1884 WRITE_GP32(MGP_SRC_OFFSET, srcOfs); 1885 WRITE_GP32(MGP_DST_OFFSET, dstOfs); 1886 WRITE_GP32(MGP_WID_HEIGHT, sizes); 1887 WRITE_GP32(MGP_STRIDE, strides); 1888 WRITE_GP16(MGP_BLT_MODE, blt_mode); 1889 } 1890} 1891#endif /* #if XF86EXA */ 1892 1893/*---------------------------------------------------------------------------- 1894 * GXAccelInit. 1895 * 1896 * Description: This function sets up the supported acceleration routines and 1897 * appropriate flags. 1898 * 1899 * Parameters: 1900 * pScrn: Screeen pointer structure. 1901 * 1902 * Returns: TRUE on success and FALSE on Failure 1903 * 1904 * Comments: This function is called in GXScreenInit in 1905 * geode_driver.c to set * the acceleration. 1906 *---------------------------------------------------------------------------- 1907 */ 1908Bool 1909GXAccelInit(ScreenPtr pScrn) 1910{ 1911 ScrnInfoPtr pScrni = xf86ScreenToScrn(pScrn); 1912 GeodeRec *pGeode = GEODEPTR(pScrni); 1913 1914#if XF86EXA 1915 ExaDriverPtr pExa = pGeode->pExa; 1916#endif 1917 1918 gu2_xshift = pScrni->bitsPerPixel >> 4; 1919 1920 /* XXX - fixme - this will change - we'll need to update it */ 1921 1922 gu2_pitch = pGeode->Pitch; 1923 1924 switch (pGeode->Pitch) { 1925 case 1024: 1926 gu2_yshift = 10; 1927 break; 1928 case 2048: 1929 gu2_yshift = 11; 1930 break; 1931 case 4096: 1932 gu2_yshift = 12; 1933 break; 1934 default: 1935 gu2_yshift = 13; 1936 break; 1937 } 1938 1939#ifdef OPT_ACCEL 1940 ACCEL_STRIDE = (pGeode->Pitch << 16) | pGeode->Pitch; 1941 BPP = amd_gx_BppToRasterMode(pScrni->bitsPerPixel); 1942#endif 1943 1944#if XF86EXA 1945 if (pExa && pGeode->useEXA) { 1946 pExa->exa_major = EXA_VERSION_MAJOR; 1947 pExa->exa_minor = EXA_VERSION_MINOR; 1948 1949 /* Sync */ 1950 pExa->WaitMarker = amd_gx_exa_WaitMarker; 1951 /* UploadToScreen */ 1952 pExa->UploadToScreen = amd_gx_exa_UploadToScreen; 1953 pExa->DownloadFromScreen = amd_gx_exa_DownloadFromScreen; 1954 1955 /* Solid fill */ 1956 pExa->PrepareSolid = amd_gx_exa_PrepareSolid; 1957 pExa->Solid = amd_gx_exa_Solid; 1958 pExa->DoneSolid = amd_gx_exa_Done; 1959 1960 /* Copy */ 1961 pExa->PrepareCopy = amd_gx_exa_PrepareCopy; 1962 pExa->Copy = amd_gx_exa_Copy; 1963 pExa->DoneCopy = amd_gx_exa_Done; 1964 1965 /* Composite */ 1966 pExa->CheckComposite = amd_gx_exa_CheckComposite; 1967 pExa->PrepareComposite = amd_gx_exa_PrepareComposite; 1968 pExa->Composite = amd_gx_exa_Composite; 1969 pExa->DoneComposite = amd_gx_exa_Done; 1970 1971 return exaDriverInit(pScrn, pGeode->pExa); 1972 } 1973#endif 1974 1975#if XF86XAA 1976 1977 /* Getting the pointer for acceleration Inforecord */ 1978 pGeode->AccelInfoRec = localRecPtr = XAACreateInfoRec(); 1979 if (!pGeode->AccelInfoRec) 1980 return FALSE; 1981 1982 /* SET ACCELERATION FLAGS */ 1983 localRecPtr->Flags = PIXMAP_CACHE | OFFSCREEN_PIXMAPS | LINEAR_FRAMEBUFFER; 1984 1985 /* HOOK SYNCRONIZARION ROUTINE */ 1986 localRecPtr->Sync = GXAccelSync; 1987 1988#if GX_FILL_RECT_SUPPORT 1989 /* HOOK FILLED RECTANGLES */ 1990 HOOK(SetupForSolidFill); 1991 HOOK(SubsequentSolidFillRect); 1992 localRecPtr->SolidFillFlags = 0; 1993#endif 1994 1995#if GX_MONO_8X8_PAT_SUPPORT 1996 /* Color expansion */ 1997 HOOK(SetupForMono8x8PatternFill); 1998 HOOK(SubsequentMono8x8PatternFillRect); 1999/* BIT_ORDER_IN_BYTE_MSBFIRST | SCANLINE_PAD_DWORD | NO_TRANSPARENCY | */ 2000 localRecPtr->Mono8x8PatternFillFlags = BIT_ORDER_IN_BYTE_MSBFIRST | 2001 HARDWARE_PATTERN_PROGRAMMED_BITS | HARDWARE_PATTERN_SCREEN_ORIGIN; 2002#endif 2003 2004#if GX_CLREXP_8X8_PAT_SUPPORT 2005 /* Color expansion */ 2006 HOOK(SetupForColor8x8PatternFill); 2007 HOOK(SubsequentColor8x8PatternFillRect); 2008/* BIT_ORDER_IN_BYTE_MSBFIRST | SCANLINE_PAD_DWORD | NO_TRANSPARENCY | */ 2009 localRecPtr->Color8x8PatternFillFlags = 2010 BIT_ORDER_IN_BYTE_MSBFIRST | SCANLINE_PAD_DWORD | 2011 HARDWARE_PATTERN_PROGRAMMED_BITS | HARDWARE_PATTERN_PROGRAMMED_ORIGIN; 2012#endif 2013 2014#if GX_SCR2SCRCPY_SUPPORT 2015 /* HOOK SCREEN TO SCREEN COPIES 2016 * Set flag to only allow copy if transparency is enabled. 2017 */ 2018 HOOK(SetupForScreenToScreenCopy); 2019 HOOK(SubsequentScreenToScreenCopy); 2020 localRecPtr->ScreenToScreenCopyFlags = 2021 BIT_ORDER_IN_BYTE_MSBFIRST | SCANLINE_PAD_DWORD; 2022#endif 2023 2024#if GX_BRES_LINE_SUPPORT 2025 /* HOOK BRESENHAM SOLID LINES */ 2026 localRecPtr->SolidLineFlags = NO_PLANEMASK; 2027 HOOK(SetupForSolidLine); 2028 HOOK(SubsequentSolidBresenhamLine); 2029 HOOK(SubsequentSolidHorVertLine); 2030 HOOK(SubsequentSolidTwoPointLine); 2031 localRecPtr->SolidBresenhamLineErrorTermBits = 15; 2032#endif 2033 2034#if GX_DASH_LINE_SUPPORT 2035 /* HOOK BRESENHAM DASHED LINES */ 2036 HOOK(SetupForDashedLine); 2037 HOOK(SubsequentDashedBresenhamLine); 2038 HOOK(SubsequentDashedTwoPointLine); 2039 localRecPtr->DashedBresenhamLineErrorTermBits = 15; 2040 localRecPtr->DashPatternMaxLength = 64; 2041 localRecPtr->DashedLineFlags = NO_PLANEMASK | /* TRANSPARENCY_ONLY | */ 2042 LINE_PATTERN_POWER_OF_2_ONLY | LINE_PATTERN_MSBFIRST_MSBJUSTIFIED; 2043#endif 2044 2045#if GX_SCR2SCREXP_SUPPORT 2046 /* Color expansion */ 2047 HOOK(SetupForScreenToScreenColorExpandFill); 2048 HOOK(SubsequentScreenToScreenColorExpandFill); 2049 localRecPtr->ScreenToScreenColorExpandFillFlags = 2050 BIT_ORDER_IN_BYTE_MSBFIRST | SCANLINE_PAD_DWORD | NO_TRANSPARENCY; 2051#endif 2052 2053 if (pGeode->AccelImageWriteBuffers) { 2054#if GX_SCANLINE_SUPPORT 2055 localRecPtr->ScanlineImageWriteBuffers = pGeode->AccelImageWriteBuffers; 2056 localRecPtr->NumScanlineImageWriteBuffers = pGeode->NoOfImgBuffers; 2057 HOOK(SetupForScanlineImageWrite); 2058 HOOK(SubsequentScanlineImageWriteRect); 2059 HOOK(SubsequentImageWriteScanline); 2060 localRecPtr->ScanlineImageWriteFlags = NO_PLANEMASK | NO_GXCOPY | 2061 BIT_ORDER_IN_BYTE_MSBFIRST | SCANLINE_PAD_DWORD; 2062#endif 2063 2064 } 2065 else { 2066 localRecPtr->PixmapCacheFlags = DO_NOT_BLIT_STIPPLES; 2067 } 2068 2069 if (pGeode->AccelColorExpandBuffers) { 2070#if GX_CPU2SCREXP_SUPPORT 2071 /* Color expansion */ 2072 localRecPtr->ScanlineColorExpandBuffers = 2073 pGeode->AccelColorExpandBuffers; 2074 localRecPtr->NumScanlineColorExpandBuffers = 2075 pGeode->NoOfColorExpandLines; 2076 HOOK(SetupForScanlineCPUToScreenColorExpandFill); 2077 HOOK(SubsequentScanlineCPUToScreenColorExpandFill); 2078 HOOK(SubsequentColorExpandScanline); 2079 localRecPtr->ScanlineCPUToScreenColorExpandFillFlags = NO_PLANEMASK | 2080 BIT_ORDER_IN_BYTE_MSBFIRST | SCANLINE_PAD_DWORD; 2081#endif 2082 } 2083#if GX_WRITE_PIXMAP_SUPPORT 2084 pGeode->WritePixmap = localRecPtr->WritePixmap; 2085 HOOK(WritePixmap); 2086#endif 2087 2088 return (XAAInit(pScrn, localRecPtr)); 2089#else /* XF86XAA */ 2090 return FALSE; 2091#endif 2092} 2093 2094/* END OF FILE */ 2095