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