mga_storm.c revision fe5e51b7
1/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_storm.c,v 1.99tsi Exp $ */ 2 3#define PSZ 8 4 5#ifdef HAVE_CONFIG_H 6#include "config.h" 7#endif 8 9/* All drivers should typically include these */ 10#include "xf86.h" 11#include "xf86_OSproc.h" 12 13/* For correct __inline__ usage */ 14#include "compiler.h" 15 16/* Drivers that need to access the PCI config space directly need this */ 17#include "xf86Pci.h" 18 19/* Drivers for PCI hardware need this */ 20#include "xf86PciInfo.h" 21 22/* Drivers that use XAA need this */ 23#include "xaa.h" 24#include "xaalocal.h" 25#include "xf86fbman.h" 26#include "miline.h" 27#include "servermd.h" 28 29#ifdef XF86DRI 30#include "cfb.h" 31#include "GL/glxtokens.h" 32#endif 33 34#include "mga.h" 35#include "mga_reg.h" 36#include "mga_macros.h" 37 38#ifdef XF86DRI 39#include "mga_dri.h" 40#endif 41 42#define REPLICATE_8(r) (((r) & 0x0ff) | (((r) & 0x0ff) << 8) \ 43 | (((r) & 0x0ff) << 16) | (((r) & 0x0ff) << 24)) 44#define REPLICATE_16(r) (((r) & 0x0000ffff) | (((r) & 0x0000ffff) << 16)) 45#define REPLICATE_24(r) (((r) & 0x00ffffff) | (((r) & 0x00ffffff) << 24)) 46#define REPLICATE_32(r) (r) 47 48 49#define SET_FOREGROUND_REPLICATED(c, rep_c) \ 50 if((c) != pMga->FgColor) { \ 51 pMga->FgColor = (c); \ 52 OUTREG(MGAREG_FCOL,(rep_c)); \ 53 } 54 55#define SET_BACKGROUND_REPLICATED(c, rep_c) \ 56 if((c) != pMga->BgColor) { \ 57 pMga->BgColor = (c); \ 58 OUTREG(MGAREG_BCOL,(rep_c)); \ 59 } 60 61 62#define MGAMoveDWORDS(d,s,c) \ 63do { \ 64 write_mem_barrier(); \ 65 XAAMoveDWORDS((d),(s),(c)); \ 66} while (0) 67 68static void mgaSetupForSolidFill( ScrnInfoPtr pScrn, int color, 69 int rop, unsigned int planemask ); 70 71static void mgaSetupForScreenToScreenCopy( ScrnInfoPtr pScrn, 72 int xdir, int ydir, int rop, unsigned int planemask, int trans ); 73 74static void mgaSubsequentScreenToScreenCopy( ScrnInfoPtr pScrn, 75 int srcX, int srcY, int dstX, int dstY, int w, int h ); 76 77static void mgaSubsequentScreenToScreenCopy_FastBlit( ScrnInfoPtr pScrn, 78 int srcX, int srcY, int dstX, int dstY, int w, int h ); 79 80static void mgaSetupForScanlineCPUToScreenColorExpandFill( ScrnInfoPtr pScrn, 81 int fg, int bg, int rop, unsigned int planemask ); 82 83static void mgaSubsequentScanlineCPUToScreenColorExpandFill( ScrnInfoPtr pScrn, 84 int x, int y, int w, int h, int skipleft ); 85 86static void mgaSubsequentColorExpandScanline( ScrnInfoPtr pScrn, int bufno ); 87 88static void mgaSubsequentColorExpandScanlineIndirect( ScrnInfoPtr pScrn, 89 int bufno ); 90 91static void mgaSubsequentSolidFillRect( ScrnInfoPtr pScrn, int x, int y, 92 int w, int h ); 93 94static void mgaSubsequentSolidFillTrap( ScrnInfoPtr pScrn, int y, int h, 95 int left, int dxL, int dyL, int eL, int right, int dxR, int dyR, int eR ); 96 97static void mgaSubsequentSolidHorVertLine( ScrnInfoPtr pScrn, int x, int y, 98 int len, int dir ); 99 100static void mgaSubsequentSolidTwoPointLine( ScrnInfoPtr pScrn, int x1, int y1, 101 int x2, int y2, int flags ); 102 103static void mgaSetupForMono8x8PatternFill( ScrnInfoPtr pScrn, 104 int patx, int paty, int fg, int bg, int rop, unsigned int planemask ); 105 106static void mgaSubsequentMono8x8PatternFillRect( ScrnInfoPtr pScrn, 107 int patx, int paty, int x, int y, int w, int h ); 108 109static void mgaSubsequentMono8x8PatternFillRect_Additional( ScrnInfoPtr pScrn, 110 int patx, int paty, int x, int y, int w, int h ); 111 112static void mgaSubsequentMono8x8PatternFillTrap( ScrnInfoPtr pScrn, 113 int patx, int paty, int y, int h, int left, int dxL, int dyL, int eL, 114 int right, int dxR, int dyR, int eR ); 115 116static void mgaSetupForScanlineImageWrite( ScrnInfoPtr pScrn, int rop, 117 unsigned int planemask, int transparency_color, int bpp, int depth ); 118 119static void mgaSubsequentScanlineImageWriteRect( ScrnInfoPtr pScrn, 120 int x, int y, int w, int h, int skipleft ); 121 122static void mgaSubsequentImageWriteScanline( ScrnInfoPtr pScrn, int num ); 123 124static void mgaSetupForPlanarScreenToScreenColorExpandFill( ScrnInfoPtr pScrn, 125 int fg, int bg, int rop, unsigned int planemask ); 126 127static void mgaSubsequentPlanarScreenToScreenColorExpandFill( ScrnInfoPtr pScrn, 128 int x, int y, int w, int h, int srcx, int srcy, int skipleft ); 129 130static void mgaSetupForScreenToScreenColorExpandFill( ScrnInfoPtr pScrn, 131 int fg, int bg, int rop, unsigned int planemask ); 132 133static void mgaSubsequentScreenToScreenColorExpandFill( ScrnInfoPtr pScrn, 134 int x, int y, int w, int h, int srcx, int srcy, int skipleft ); 135 136#if X_BYTE_ORDER == X_LITTLE_ENDIAN 137static void mgaSetupForDashedLine( ScrnInfoPtr pScrn, int fg, int bg, 138 int rop, unsigned int planemask, int length, unsigned char *pattern ); 139 140static void mgaSubsequentDashedTwoPointLine( ScrnInfoPtr pScrn, 141 int x1, int y1, int x2, int y2, int flags, int phase ); 142#endif 143 144static void mgaRestoreAccelState( ScrnInfoPtr pScrn ); 145 146static void MGASetClippingRectangle(ScrnInfoPtr pScrn, int x1, int y1, 147 int x2, int y2); 148static void MGADisableClipping(ScrnInfoPtr pScrn); 149static void MGAFillSolidRectsDMA(ScrnInfoPtr pScrn, int fg, int rop, 150 unsigned int planemask, int nBox, BoxPtr pBox); 151static void MGAFillSolidSpansDMA(ScrnInfoPtr pScrn, int fg, int rop, 152 unsigned int planemask, int n, DDXPointPtr ppt, 153 int *pwidth, int fSorted); 154static void MGAFillMono8x8PatternRectsTwoPass(ScrnInfoPtr pScrn, int fg, int bg, 155 int rop, unsigned int planemask, int nBox, 156 BoxPtr pBox, int pattern0, int pattern1, 157 int xorigin, int yorigin); 158static void MGAValidatePolyArc(GCPtr, unsigned long, DrawablePtr); 159static void MGAValidatePolyPoint(GCPtr, unsigned long, DrawablePtr); 160static void MGAFillCacheBltRects(ScrnInfoPtr, int, unsigned int, int, BoxPtr, 161 int, int, XAACacheInfoPtr); 162 163 164static __inline__ void 165common_replicate_colors_and_mask( unsigned int fg, unsigned int bg, 166 unsigned int pm, 167 unsigned int bpp, 168 unsigned int * rep_fg, 169 unsigned int * rep_bg, 170 unsigned int * rep_pm ) 171{ 172 switch( bpp ) { 173 case 8: 174 *rep_fg = REPLICATE_8( fg ); 175 *rep_bg = REPLICATE_8( bg ); 176 *rep_pm = REPLICATE_8( pm ); 177 break; 178 case 16: 179 *rep_fg = REPLICATE_16( fg ); 180 *rep_bg = REPLICATE_16( bg ); 181 *rep_pm = REPLICATE_16( pm ); 182 break; 183 case 24: 184 *rep_fg = REPLICATE_24( fg ); 185 *rep_bg = REPLICATE_24( bg ); 186 *rep_pm = REPLICATE_24( pm ); 187 break; 188 case 32: 189 *rep_fg = REPLICATE_32( fg ); 190 *rep_bg = REPLICATE_32( bg ); 191 *rep_pm = REPLICATE_32( pm ); 192 break; 193 } 194} 195 196 197#ifdef RENDER 198 199static Bool MGASetupForCPUToScreenAlphaTexture(ScrnInfoPtr pScrn, int op, 200 CARD16 red, CARD16 green, CARD16 blue, CARD16 alpha, int alphaType, 201 CARD8 *alphaPtr, int alphaPitch, int width, int height, int flags); 202 203static Bool MGASetupForCPUToScreenAlphaTextureFaked(ScrnInfoPtr Scrn, int op, 204 CARD16 red, CARD16 green, CARD16 blue, CARD16 alpha, int alphaType, 205 CARD8 *alphaPtr, int alphaPitch, int width, int height, int flags); 206 207static Bool MGASetupForCPUToScreenTexture(ScrnInfoPtr pScrn, int op, 208 int texType, CARD8 *texPtr, int texPitch, int width, int height, 209 int flags); 210 211static void MGASubsequentCPUToScreenTexture(ScrnInfoPtr pScrn, int dstx, 212 int dsty, int srcx, int srcy, int width, int height); 213 214#include "mipict.h" 215#include "dixstruct.h" 216 217static CARD32 MGAAlphaTextureFormats[2] = {PICT_a8, 0}; 218static CARD32 MGATextureFormats[2] = {PICT_a8r8g8b8, 0}; 219 220static void 221RemoveLinear (FBLinearPtr linear) 222{ 223 MGAPtr pMga = (MGAPtr)(linear->devPrivate.ptr); 224 225 pMga->LinearScratch = NULL; /* just lost our scratch */ 226} 227 228static void 229RenderCallback (ScrnInfoPtr pScrn) 230{ 231 MGAPtr pMga = MGAPTR(pScrn); 232 233 if((currentTime.milliseconds > pMga->RenderTime) && pMga->LinearScratch) { 234 xf86FreeOffscreenLinear(pMga->LinearScratch); 235 pMga->LinearScratch = NULL; 236 } 237 238 if(!pMga->LinearScratch) 239 pMga->RenderCallback = NULL; 240} 241 242#define RENDER_DELAY 15000 243 244static Bool 245AllocateLinear ( 246 ScrnInfoPtr pScrn, 247 int sizeNeeded 248){ 249 MGAPtr pMga = MGAPTR(pScrn); 250 251 pMga->RenderTime = currentTime.milliseconds + RENDER_DELAY; 252 pMga->RenderCallback = RenderCallback; 253 254 if(pMga->LinearScratch) { 255 if(pMga->LinearScratch->size >= sizeNeeded) 256 return TRUE; 257 else { 258 if(xf86ResizeOffscreenLinear(pMga->LinearScratch, sizeNeeded)) 259 return TRUE; 260 261 xf86FreeOffscreenLinear(pMga->LinearScratch); 262 pMga->LinearScratch = NULL; 263 } 264 } 265 266 pMga->LinearScratch = xf86AllocateOffscreenLinear( 267 pScrn->pScreen, sizeNeeded, 32, 268 NULL, RemoveLinear, pMga); 269 270 return (pMga->LinearScratch != NULL); 271} 272 273static int 274GetPowerOfTwo(int w) 275{ 276 int Pof2 = 0; 277 int i = 12; 278 279 while(--i) { 280 if(w & (1 << i)) { 281 Pof2 = i; 282 if(w & ((1 << i) - 1)) 283 Pof2++; 284 break; 285 } 286 } 287 return Pof2; 288} 289 290 291static int tex_padw, tex_padh; 292 293Bool MGASetupForCPUToScreenAlphaTextureFaked( ScrnInfoPtr pScrn, int op, 294 CARD16 red, CARD16 green, 295 CARD16 blue, CARD16 alpha, 296 int alphaType, CARD8 *alphaPtr, 297 int alphaPitch, int width, 298 int height, int flags ) 299{ 300 int log2w, log2h, pitch, sizeNeeded, offset; 301 unsigned int texctl, dwgctl, alphactrl; 302 MGAPtr pMga = MGAPTR(pScrn); 303 304 if(op != PictOpOver) /* only one tested */ 305 return FALSE; 306 307 if((width > 2048) || (height > 2048)) 308 return FALSE; 309 310 log2w = GetPowerOfTwo(width); 311 log2h = GetPowerOfTwo(height); 312 313 CHECK_DMA_QUIESCENT(pMga, pScrn); 314 315 if(pMga->Overlay8Plus24) { 316 WAITFIFO(1); 317 SET_PLANEMASK_REPLICATED( 0x00ffffff, 0xffffffff, 32 ); 318 } 319 320 pitch = (width + 15) & ~15; 321 sizeNeeded = pitch * height; 322 if(pScrn->bitsPerPixel == 16) 323 sizeNeeded <<= 1; 324 325 if(!AllocateLinear(pScrn, sizeNeeded)) 326 return FALSE; 327 328 offset = pMga->LinearScratch->offset << 1; 329 if(pScrn->bitsPerPixel == 32) 330 offset <<= 1; 331 332 if(pMga->AccelInfoRec->NeedToSync) 333 MGAStormSync(pScrn); 334 335 XAA_888_plus_PICT_a8_to_8888( 336 (blue >> 8) | (green & 0xff00) | ((red & 0xff00) << 8), 337 alphaPtr, alphaPitch, (CARD32*)(pMga->FbStart + offset), 338 pitch, width, height); 339 340 tex_padw = 1 << log2w; 341 tex_padh = 1 << log2h; 342 343 WAITFIFO(15); 344 OUTREG(MGAREG_TMR0, (1 << 20) / tex_padw); /* sx inc */ 345 OUTREG(MGAREG_TMR1, 0); /* sy inc */ 346 OUTREG(MGAREG_TMR2, 0); /* tx inc */ 347 OUTREG(MGAREG_TMR3, (1 << 20) / tex_padh); /* ty inc */ 348 OUTREG(MGAREG_TMR4, 0x00000000); 349 OUTREG(MGAREG_TMR5, 0x00000000); 350 OUTREG(MGAREG_TMR8, 0x00010000); 351 OUTREG(MGAREG_TEXORG, offset); 352 OUTREG(MGAREG_TEXWIDTH, log2w | (((8 - log2w) & 63) << 9) | 353 ((width - 1) << 18)); 354 OUTREG(MGAREG_TEXHEIGHT, log2h | (((8 - log2h) & 63) << 9) | 355 ((height - 1) << 18)); 356 357 texctl = MGA_TW32 | MGA_PITCHLIN | MGA_TAKEY | MGA_CLAMPUV | 358 ((pitch & 0x07FF) << 9); 359 dwgctl = MGADWG_TEXTURE_TRAP | MGADWG_I | MGADWG_ARZERO | 360 MGADWG_SGNZERO | MGADWG_SHIFTZERO | 0xc0000; 361 alphactrl = MGA_SRC_ALPHA | MGA_DST_ONE_MINUS_SRC_ALPHA | 362 MGA_ALPHACHANNEL; 363 364 OUTREG(MGAREG_TEXCTL, texctl); 365 OUTREG(MGAREG_TEXCTL2, MGA_TC2_DECALDIS | MGA_TC2_CKSTRANSDIS); 366 OUTREG(MGAREG_DWGCTL, dwgctl); 367 OUTREG(MGAREG_TEXFILTER, ((0x1e << 20) | MGA_MAG_BILIN)); 368 OUTREG(MGAREG_ALPHACTRL, alphactrl); 369 370 return TRUE; 371} 372 373Bool 374MGASetupForCPUToScreenAlphaTexture ( 375 ScrnInfoPtr pScrn, 376 int op, 377 CARD16 red, 378 CARD16 green, 379 CARD16 blue, 380 CARD16 alpha, 381 int alphaType, 382 CARD8 *alphaPtr, 383 int alphaPitch, 384 int width, 385 int height, 386 int flags 387){ 388 int log2w, log2h, i, pitch, sizeNeeded, offset; 389 unsigned int texctl, dwgctl, alphactrl; 390 CARD8 *dst; 391 MGAPtr pMga = MGAPTR(pScrn); 392 393 if(op != PictOpOver) /* only one tested */ 394 return FALSE; 395 396 if((width > 2048) || (height > 2048)) 397 return FALSE; 398 399 log2w = GetPowerOfTwo(width); 400 log2h = GetPowerOfTwo(height); 401 402 CHECK_DMA_QUIESCENT(pMga, pScrn); 403 404 if(pMga->Overlay8Plus24) { 405 WAITFIFO(1); 406 SET_PLANEMASK_REPLICATED( 0x00ffffff, 0xffffffff, 32 ); 407 } 408 409 pitch = (width + 15) & ~15; 410 sizeNeeded = (pitch * height) >> 1; 411 if(pScrn->bitsPerPixel == 32) 412 sizeNeeded >>= 1; 413 414 if(!AllocateLinear(pScrn, sizeNeeded)) 415 return FALSE; 416 417 offset = pMga->LinearScratch->offset << 1; 418 if(pScrn->bitsPerPixel == 32) 419 offset <<= 1; 420 421 if(pMga->AccelInfoRec->NeedToSync) 422 MGAStormSync(pScrn); 423 424 i = height; 425 dst = pMga->FbStart + offset; 426 while(i--) { 427 memcpy(dst, alphaPtr, width); 428 dst += pitch; 429 alphaPtr += alphaPitch; 430 } 431 432 tex_padw = 1 << log2w; 433 tex_padh = 1 << log2h; 434 435 436 WAITFIFO(12); 437 OUTREG(MGAREG_DR4, red << 7); /* red start */ 438 OUTREG(MGAREG_DR6, 0); 439 OUTREG(MGAREG_DR7, 0); 440 OUTREG(MGAREG_DR8, green << 7); /* green start */ 441 OUTREG(MGAREG_DR10, 0); 442 OUTREG(MGAREG_DR11, 0); 443 OUTREG(MGAREG_DR12, blue << 7); /* blue start */ 444 OUTREG(MGAREG_DR14, 0); 445 OUTREG(MGAREG_DR15, 0); 446 OUTREG(MGAREG_ALPHASTART, alpha << 7); /* alpha start */ 447 OUTREG(MGAREG_ALPHAXINC, 0); 448 OUTREG(MGAREG_ALPHAYINC, 0); 449 450 WAITFIFO(15); 451 OUTREG(MGAREG_TMR0, (1 << 20) / tex_padw); /* sx inc */ 452 OUTREG(MGAREG_TMR1, 0); /* sy inc */ 453 OUTREG(MGAREG_TMR2, 0); /* tx inc */ 454 OUTREG(MGAREG_TMR3, (1 << 20) / tex_padh); /* ty inc */ 455 OUTREG(MGAREG_TMR4, 0x00000000); 456 OUTREG(MGAREG_TMR5, 0x00000000); 457 OUTREG(MGAREG_TMR8, 0x00010000); 458 OUTREG(MGAREG_TEXORG, offset); 459 OUTREG(MGAREG_TEXWIDTH, log2w | (((8 - log2w) & 63) << 9) | 460 ((width - 1) << 18)); 461 OUTREG(MGAREG_TEXHEIGHT, log2h | (((8 - log2h) & 63) << 9) | 462 ((height - 1) << 18)); 463 464 texctl = MGA_TW8A | MGA_PITCHLIN | MGA_TAKEY | MGA_CLAMPUV | 465 MGA_TEXMODULATE | 466 ((pitch & 0x07FF) << 9); 467 dwgctl = MGADWG_TEXTURE_TRAP | MGADWG_I | MGADWG_ARZERO | 468 MGADWG_SGNZERO | MGADWG_SHIFTZERO | 0xc0000; 469 alphactrl = MGA_SRC_ONE | MGA_DST_ONE_MINUS_SRC_ALPHA | 470 MGA_ALPHACHANNEL | MGA_MODULATEDALPHA; 471 472 OUTREG(MGAREG_TEXCTL, texctl); 473 OUTREG(MGAREG_TEXCTL2, MGA_TC2_DECALDIS | MGA_TC2_CKSTRANSDIS); 474 OUTREG(MGAREG_DWGCTL, dwgctl); 475 OUTREG(MGAREG_TEXFILTER, ((0x1e << 20) | MGA_MAG_BILIN)); 476 OUTREG(MGAREG_ALPHACTRL, alphactrl); 477 478 return TRUE; 479} 480 481 482Bool 483MGASetupForCPUToScreenTexture ( 484 ScrnInfoPtr pScrn, 485 int op, 486 int texType, 487 CARD8 *texPtr, 488 int texPitch, 489 int width, 490 int height, 491 int flags 492){ 493 int log2w, log2h, i, pitch, sizeNeeded, offset; 494 unsigned int texctl, dwgctl, alphactrl; 495 MGAPtr pMga = MGAPTR(pScrn); 496 497 if(op != PictOpOver) /* only one tested */ 498 return FALSE; 499 500 if((width > 2048) || (height > 2048)) 501 return FALSE; 502 503 log2w = GetPowerOfTwo(width); 504 log2h = GetPowerOfTwo(height); 505 506 CHECK_DMA_QUIESCENT(pMga, pScrn); 507 508 if(pMga->Overlay8Plus24) { 509 WAITFIFO(1); 510 SET_PLANEMASK_REPLICATED( 0x00ffffff, 0xffffffff, 32 ); 511 } 512 513 pitch = (width + 15) & ~15; 514 sizeNeeded = pitch * height; 515 if(pScrn->bitsPerPixel == 16) 516 sizeNeeded <<= 1; 517 518 if(!AllocateLinear(pScrn, sizeNeeded)) 519 return FALSE; 520 521 offset = pMga->LinearScratch->offset << 1; 522 if(pScrn->bitsPerPixel == 32) 523 offset <<= 1; 524 525 if(pMga->AccelInfoRec->NeedToSync) 526 MGAStormSync(pScrn); 527 528 { 529 CARD8 *dst = (CARD8*)(pMga->FbStart + offset); 530 i = height; 531 while(i--) { 532 memcpy(dst, texPtr, width << 2); 533 texPtr += texPitch; 534 dst += pitch << 2; 535 } 536 } 537 538 tex_padw = 1 << log2w; 539 tex_padh = 1 << log2h; 540 541 WAITFIFO(15); 542 OUTREG(MGAREG_TMR0, (1 << 20) / tex_padw); /* sx inc */ 543 OUTREG(MGAREG_TMR1, 0); /* sy inc */ 544 OUTREG(MGAREG_TMR2, 0); /* tx inc */ 545 OUTREG(MGAREG_TMR3, (1 << 20) / tex_padh); /* ty inc */ 546 OUTREG(MGAREG_TMR4, 0x00000000); 547 OUTREG(MGAREG_TMR5, 0x00000000); 548 OUTREG(MGAREG_TMR8, 0x00010000); 549 OUTREG(MGAREG_TEXORG, offset); 550 OUTREG(MGAREG_TEXWIDTH, log2w | (((8 - log2w) & 63) << 9) | 551 ((width - 1) << 18)); 552 OUTREG(MGAREG_TEXHEIGHT, log2h | (((8 - log2h) & 63) << 9) | 553 ((height - 1) << 18)); 554 555 texctl = MGA_TW32 | MGA_PITCHLIN | MGA_TAKEY | MGA_CLAMPUV | 556 ((pitch & 0x07FF) << 9); 557 dwgctl = MGADWG_TEXTURE_TRAP | MGADWG_I | MGADWG_ARZERO | 558 MGADWG_SGNZERO | MGADWG_SHIFTZERO | 0xc0000; 559 alphactrl = MGA_SRC_ONE | MGA_DST_ONE_MINUS_SRC_ALPHA | 560 MGA_ALPHACHANNEL; 561 562 OUTREG(MGAREG_TEXCTL, texctl); 563 OUTREG(MGAREG_TEXCTL2, MGA_TC2_DECALDIS | MGA_TC2_CKSTRANSDIS); 564 OUTREG(MGAREG_DWGCTL, dwgctl); 565 OUTREG(MGAREG_TEXFILTER, ((0x1e << 20) | MGA_MAG_BILIN)); 566 OUTREG(MGAREG_ALPHACTRL, alphactrl); 567 568 return TRUE; 569} 570void 571MGASubsequentCPUToScreenTexture ( 572 ScrnInfoPtr pScrn, 573 int dstx, 574 int dsty, 575 int srcx, 576 int srcy, 577 int width, 578 int height 579){ 580 MGAPtr pMga = MGAPTR(pScrn); 581 582 WAITFIFO(4); 583 OUTREG(MGAREG_TMR6, (srcx << 20) / tex_padw); 584 OUTREG(MGAREG_TMR7, (srcy << 20) / tex_padh); 585 OUTREG(MGAREG_FXBNDRY, ((dstx + width) << 16) | (dstx & 0xffff)); 586 OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (dsty << 16) | height); 587 588 pMga->AccelInfoRec->NeedToSync = TRUE; 589} 590 591 592#endif /* defined(RENDER) */ 593 594Bool mgaAccelInit( ScreenPtr pScreen ) 595{ 596 XAAInfoRecPtr infoPtr; 597 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 598 MGAPtr pMga = MGAPTR(pScrn); 599 int maxFastBlitMem, maxlines; 600 Bool doRender = FALSE; 601 BoxRec AvailFBArea; 602 int i; 603 604 pMga->ScratchBuffer = xalloc(((pScrn->displayWidth * pMga->CurrentLayout.bitsPerPixel) + 127) >> 3); 605 if(!pMga->ScratchBuffer) return FALSE; 606 607 pMga->AccelInfoRec = infoPtr = XAACreateInfoRec(); 608 if(!infoPtr) return FALSE; 609 610 pMga->RenderTime = 0; 611 pMga->LinearScratch = 0; 612 613 pMga->MaxFastBlitY = 0; 614 pMga->MaxBlitDWORDS = 0x40000 >> 5; 615 616 617 /* Set initial acceleration flags. 618 */ 619 pMga->AccelFlags = pMga->chip_attribs->accel_flags; 620 621 if ((pMga->FbMapSize > 8*1024*1024) && (pScrn->depth == 8)) { 622 pMga->AccelFlags |= LARGE_ADDRESSES; 623 } 624 625 if (pMga->CurrentLayout.bitsPerPixel == 24) { 626 pMga->AccelFlags |= MGA_NO_PLANEMASK; 627 } 628 629 if (pMga->SecondCrtc) { 630 pMga->HasFBitBlt = FALSE; 631 } 632 633 if(pMga->HasSDRAM) { 634 pMga->Atype = pMga->AtypeNoBLK = MGAAtypeNoBLK; 635 pMga->AccelFlags &= ~TWO_PASS_COLOR_EXPAND; 636 } else { 637 pMga->Atype = MGAAtype; 638 pMga->AtypeNoBLK = MGAAtypeNoBLK; 639 } 640 641 /* fill out infoPtr here */ 642 infoPtr->Flags = PIXMAP_CACHE | 643 OFFSCREEN_PIXMAPS | 644 LINEAR_FRAMEBUFFER | 645 MICROSOFT_ZERO_LINE_BIAS; 646 647 /* sync */ 648 infoPtr->Sync = MGAStormSync; 649 650 /* screen to screen copy */ 651 infoPtr->ScreenToScreenCopyFlags = NO_TRANSPARENCY; 652 infoPtr->SetupForScreenToScreenCopy = 653 mgaSetupForScreenToScreenCopy; 654 infoPtr->SubsequentScreenToScreenCopy = mgaSubsequentScreenToScreenCopy; 655 656 if(pMga->HasFBitBlt) { 657 infoPtr->FillCacheBltRects = MGAFillCacheBltRects; 658 infoPtr->FillCacheBltRectsFlags = NO_TRANSPARENCY; 659 } 660 /* solid fills */ 661 infoPtr->SetupForSolidFill = mgaSetupForSolidFill; 662 infoPtr->SubsequentSolidFillRect = mgaSubsequentSolidFillRect; 663 infoPtr->SubsequentSolidFillTrap = mgaSubsequentSolidFillTrap; 664 665 /* solid lines */ 666 infoPtr->SetupForSolidLine = infoPtr->SetupForSolidFill; 667 infoPtr->SubsequentSolidHorVertLine = mgaSubsequentSolidHorVertLine; 668 infoPtr->SubsequentSolidTwoPointLine = mgaSubsequentSolidTwoPointLine; 669 670 /* clipping */ 671 infoPtr->SetClippingRectangle = MGASetClippingRectangle; 672 infoPtr->DisableClipping = MGADisableClipping; 673 infoPtr->ClippingFlags = HARDWARE_CLIP_SOLID_LINE | 674 HARDWARE_CLIP_DASHED_LINE | 675 HARDWARE_CLIP_SOLID_FILL | 676 HARDWARE_CLIP_MONO_8x8_FILL; 677 678#if X_BYTE_ORDER == X_LITTLE_ENDIAN 679 /* dashed lines */ 680 infoPtr->DashedLineFlags = LINE_PATTERN_MSBFIRST_LSBJUSTIFIED; 681 infoPtr->SetupForDashedLine = mgaSetupForDashedLine; 682 infoPtr->SubsequentDashedTwoPointLine = mgaSubsequentDashedTwoPointLine; 683 infoPtr->DashPatternMaxLength = 128; 684#endif 685 686 /* 8x8 mono patterns */ 687 infoPtr->Mono8x8PatternFillFlags = HARDWARE_PATTERN_PROGRAMMED_BITS | 688 HARDWARE_PATTERN_PROGRAMMED_ORIGIN | 689 HARDWARE_PATTERN_SCREEN_ORIGIN | 690 BIT_ORDER_IN_BYTE_MSBFIRST; 691 infoPtr->SetupForMono8x8PatternFill = mgaSetupForMono8x8PatternFill; 692 infoPtr->SubsequentMono8x8PatternFillRect = 693 mgaSubsequentMono8x8PatternFillRect; 694 infoPtr->SubsequentMono8x8PatternFillTrap = 695 mgaSubsequentMono8x8PatternFillTrap; 696 697 /* cpu to screen color expansion */ 698 infoPtr->ScanlineCPUToScreenColorExpandFillFlags = 699 CPU_TRANSFER_PAD_DWORD | 700 SCANLINE_PAD_DWORD | 701#if X_BYTE_ORDER == X_BIG_ENDIAN 702 BIT_ORDER_IN_BYTE_MSBFIRST | 703#else 704 BIT_ORDER_IN_BYTE_LSBFIRST | 705#endif 706 LEFT_EDGE_CLIPPING | 707 LEFT_EDGE_CLIPPING_NEGATIVE_X; 708 709 if(pMga->ILOADBase) { 710 pMga->ColorExpandBase = pMga->ILOADBase; 711 } else { 712 pMga->ColorExpandBase = pMga->IOBase; 713 } 714 infoPtr->SetupForScanlineCPUToScreenColorExpandFill = 715 mgaSetupForScanlineCPUToScreenColorExpandFill; 716 infoPtr->SubsequentScanlineCPUToScreenColorExpandFill = 717 mgaSubsequentScanlineCPUToScreenColorExpandFill; 718 infoPtr->SubsequentColorExpandScanline = mgaSubsequentColorExpandScanline; 719 infoPtr->NumScanlineColorExpandBuffers = 1; 720 infoPtr->ScanlineColorExpandBuffers = &(pMga->ColorExpandBase); 721 722 /* screen to screen color expansion */ 723 if(pMga->AccelFlags & USE_LINEAR_EXPANSION) { 724 infoPtr->ScreenToScreenColorExpandFillFlags = 725 BIT_ORDER_IN_BYTE_LSBFIRST; 726 infoPtr->SetupForScreenToScreenColorExpandFill = 727 mgaSetupForScreenToScreenColorExpandFill; 728 infoPtr->SubsequentScreenToScreenColorExpandFill = 729 mgaSubsequentScreenToScreenColorExpandFill; 730 } 731 else if ( pMga->CurrentLayout.bitsPerPixel != 24 ) { 732 /* Alternate (but slower) planar expansions */ 733 infoPtr->SetupForScreenToScreenColorExpandFill = 734 mgaSetupForPlanarScreenToScreenColorExpandFill; 735 infoPtr->SubsequentScreenToScreenColorExpandFill = 736 mgaSubsequentPlanarScreenToScreenColorExpandFill; 737 infoPtr->CacheColorExpandDensity = pMga->CurrentLayout.bitsPerPixel; 738 infoPtr->CacheMonoStipple = XAAGetCachePlanarMonoStipple(); 739 740 /* It's faster to blit the stipples if you have fastbilt 741 */ 742 if(pMga->HasFBitBlt) 743 infoPtr->ScreenToScreenColorExpandFillFlags = TRANSPARENCY_ONLY; 744 } 745 746 /* image writes */ 747 infoPtr->ScanlineImageWriteFlags = CPU_TRANSFER_PAD_DWORD | 748 SCANLINE_PAD_DWORD | 749 LEFT_EDGE_CLIPPING | 750 LEFT_EDGE_CLIPPING_NEGATIVE_X | 751 NO_TRANSPARENCY | 752 NO_GXCOPY; 753 754 infoPtr->SetupForScanlineImageWrite = mgaSetupForScanlineImageWrite; 755 infoPtr->SubsequentScanlineImageWriteRect = 756 mgaSubsequentScanlineImageWriteRect; 757 infoPtr->SubsequentImageWriteScanline = mgaSubsequentImageWriteScanline; 758 infoPtr->NumScanlineImageWriteBuffers = 1; 759 infoPtr->ScanlineImageWriteBuffers = &(pMga->ScratchBuffer); 760 761 762 /* midrange replacements */ 763 764 if(pMga->ILOADBase && pMga->UsePCIRetry && infoPtr->SetupForSolidFill) { 765 infoPtr->FillSolidRects = MGAFillSolidRectsDMA; 766 infoPtr->FillSolidSpans = MGAFillSolidSpansDMA; 767 } 768 769 if(pMga->AccelFlags & TWO_PASS_COLOR_EXPAND) { 770 if(infoPtr->SetupForMono8x8PatternFill) 771 infoPtr->FillMono8x8PatternRects = 772 MGAFillMono8x8PatternRectsTwoPass; 773 } 774 775 if(infoPtr->SetupForSolidFill) { 776 infoPtr->ValidatePolyArc = MGAValidatePolyArc; 777 infoPtr->PolyArcMask = GCFunction | GCLineWidth | GCPlaneMask | 778 GCLineStyle | GCFillStyle; 779 infoPtr->ValidatePolyPoint = MGAValidatePolyPoint; 780 infoPtr->PolyPointMask = GCFunction | GCPlaneMask; 781 } 782 if(pMga->AccelFlags & MGA_NO_PLANEMASK) { 783 infoPtr->ScanlineImageWriteFlags |= NO_PLANEMASK; 784 infoPtr->ScreenToScreenCopyFlags |= NO_PLANEMASK; 785 infoPtr->ScanlineCPUToScreenColorExpandFillFlags |= NO_PLANEMASK; 786 infoPtr->SolidFillFlags |= NO_PLANEMASK; 787 infoPtr->SolidLineFlags |= NO_PLANEMASK; 788#if X_BYTE_ORDER == X_LITTLE_ENDIAN 789 infoPtr->DashedLineFlags |= NO_PLANEMASK; 790#endif 791 infoPtr->Mono8x8PatternFillFlags |= NO_PLANEMASK; 792 infoPtr->ScreenToScreenColorExpandFillFlags |= NO_PLANEMASK; 793 infoPtr->FillSolidRectsFlags |= NO_PLANEMASK; 794 infoPtr->FillSolidSpansFlags |= NO_PLANEMASK; 795 infoPtr->FillMono8x8PatternRectsFlags |= NO_PLANEMASK; 796 infoPtr->FillCacheBltRectsFlags |= NO_PLANEMASK; 797 } 798 799 800 maxFastBlitMem = (pMga->Interleave ? 4096 : 2048) * 1024; 801 802 if(pMga->FbMapSize > maxFastBlitMem) { 803 pMga->MaxFastBlitY = maxFastBlitMem / (pScrn->displayWidth * pMga->CurrentLayout.bitsPerPixel / 8); 804 } 805 806 switch (pMga->Chipset) { 807 case PCI_CHIP_MGAG200_SE_A_PCI: 808 case PCI_CHIP_MGAG200_SE_B_PCI: 809 maxlines = (min(pMga->FbUsableSize, 1*1024*1024)) / 810 (pScrn->displayWidth * pMga->CurrentLayout.bitsPerPixel / 8); 811 break; 812 default: 813 maxlines = (min(pMga->FbUsableSize, 16*1024*1024)) / 814 (pScrn->displayWidth * pMga->CurrentLayout.bitsPerPixel / 8); 815 break; 816 } 817 818#ifdef XF86DRI 819 if ( pMga->directRenderingEnabled ) { 820 MGADRIServerPrivatePtr pMGADRIServer = pMga->DRIServerInfo; 821 BoxRec MemBox; 822 int cpp = pScrn->bitsPerPixel / 8; 823 int widthBytes = pScrn->displayWidth * cpp; 824 int bufferSize = ((pScrn->virtualY * widthBytes + MGA_BUFFER_ALIGN) 825 & ~MGA_BUFFER_ALIGN); 826 int scanlines; 827 828 pMGADRIServer->frontOffset = 0; 829 pMGADRIServer->frontPitch = widthBytes; 830 831 /* Try for front, back, depth, and two framebuffers worth of 832 * pixmap cache. Should be enough for a fullscreen background 833 * image plus some leftovers. 834 */ 835 pMGADRIServer->textureSize = pMga->FbMapSize - 5 * bufferSize; 836 837 /* If that gives us less than half the available memory, let's 838 * be greedy and grab some more. Sorry, I care more about 3D 839 * performance than playing nicely, and you'll get around a full 840 * framebuffer's worth of pixmap cache anyway. 841 */ 842 if ( pMGADRIServer->textureSize < (int)pMga->FbMapSize / 2 ) { 843 pMGADRIServer->textureSize = pMga->FbMapSize - 4 * bufferSize; 844 } 845 846 /* Check to see if there is more room available after the maximum 847 * scanline for textures. 848 */ 849 if ( (int)pMga->FbMapSize - maxlines * widthBytes - bufferSize * 2 850 > pMGADRIServer->textureSize ) { 851 pMGADRIServer->textureSize = (pMga->FbMapSize - 852 maxlines * widthBytes - 853 bufferSize * 2); 854 } 855 856 /* Set a minimum usable local texture heap size. This will fit 857 * two 256x256x32bpp textures. 858 */ 859 if ( pMGADRIServer->textureSize < 512 * 1024 ) { 860 pMGADRIServer->textureOffset = 0; 861 pMGADRIServer->textureSize = 0; 862 } 863 864 /* Reserve space for textures */ 865 pMGADRIServer->textureOffset = (pMga->FbMapSize - 866 pMGADRIServer->textureSize + 867 MGA_BUFFER_ALIGN) & ~MGA_BUFFER_ALIGN; 868 869 /* Reserve space for the shared depth buffer */ 870 pMGADRIServer->depthOffset = (pMGADRIServer->textureOffset - 871 bufferSize + 872 MGA_BUFFER_ALIGN) & ~MGA_BUFFER_ALIGN; 873 pMGADRIServer->depthPitch = widthBytes; 874 875 /* Reserve space for the shared back buffer */ 876 pMGADRIServer->backOffset = (pMGADRIServer->depthOffset - bufferSize + 877 MGA_BUFFER_ALIGN) & ~MGA_BUFFER_ALIGN; 878 pMGADRIServer->backPitch = widthBytes; 879 880 scanlines = pMGADRIServer->backOffset / widthBytes - 1; 881 if ( scanlines > maxlines ) scanlines = maxlines; 882 883 MemBox.x1 = 0; 884 MemBox.y1 = 0; 885 MemBox.x2 = pScrn->displayWidth; 886 MemBox.y2 = scanlines; 887 888 if ( !xf86InitFBManager( pScreen, &MemBox ) ) { 889 xf86DrvMsg( pScrn->scrnIndex, X_ERROR, 890 "Memory manager initialization to (%d,%d) (%d,%d) failed\n", 891 MemBox.x1, MemBox.y1, MemBox.x2, MemBox.y2 ); 892 return FALSE; 893 } else { 894 int width, height; 895 896 xf86DrvMsg( pScrn->scrnIndex, X_INFO, 897 "Memory manager initialized to (%d,%d) (%d,%d)\n", 898 MemBox.x1, MemBox.y1, MemBox.x2, MemBox.y2 ); 899 900 if ( xf86QueryLargestOffscreenArea( pScreen, &width, 901 &height, 0, 0, 0 ) ) { 902 xf86DrvMsg( pScrn->scrnIndex, X_INFO, 903 "Largest offscreen area available: %d x %d\n", 904 width, height ); 905 } 906 } 907 908 xf86DrvMsg( pScrn->scrnIndex, X_INFO, 909 "Reserved back buffer at offset 0x%x\n", 910 pMGADRIServer->backOffset ); 911 xf86DrvMsg( pScrn->scrnIndex, X_INFO, 912 "Reserved depth buffer at offset 0x%x\n", 913 pMGADRIServer->depthOffset ); 914 xf86DrvMsg( pScrn->scrnIndex, X_INFO, 915 "Reserved %d kb for textures at offset 0x%x\n", 916 pMGADRIServer->textureSize/1024, 917 pMGADRIServer->textureOffset ); 918 } 919 else 920#endif /* defined(XF86DRI) */ 921 { 922 AvailFBArea.x1 = 0; 923 AvailFBArea.x2 = pScrn->displayWidth; 924 AvailFBArea.y1 = 0; 925 AvailFBArea.y2 = maxlines; 926 927 /* 928 * Need to keep a strip of memory to the right of screen to workaround 929 * a display problem with the second CRTC. 930 */ 931 if (pMga->SecondCrtc) 932 AvailFBArea.x2 = pScrn->virtualX; 933 934 xf86InitFBManager(pScreen, &AvailFBArea); 935 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using %d lines for offscreen " 936 "memory.\n", 937 maxlines - pScrn->virtualY); 938 939 } 940 941 for (i = 0; i < pScrn->numEntities; i++) { 942 if (xf86IsEntityShared(pScrn->entityList[i])) { 943 infoPtr->RestoreAccelState = mgaRestoreAccelState; 944 break; 945 } 946 } 947 948#ifdef RENDER 949 if(doRender && ((pScrn->bitsPerPixel == 32) || (pScrn->bitsPerPixel == 16))) 950 { 951 if(pMga->Chipset == PCI_CHIP_MGAG400 || pMga->Chipset == PCI_CHIP_MGAG550) { 952 infoPtr->CPUToScreenAlphaTextureFlags = XAA_RENDER_NO_TILE; 953 infoPtr->SetupForCPUToScreenAlphaTexture = 954 MGASetupForCPUToScreenAlphaTexture; 955 } else { 956 infoPtr->CPUToScreenAlphaTextureFlags = XAA_RENDER_NO_TILE | 957 XAA_RENDER_NO_SRC_ALPHA; 958 infoPtr->SetupForCPUToScreenAlphaTexture = 959 MGASetupForCPUToScreenAlphaTextureFaked; 960 } 961 infoPtr->SubsequentCPUToScreenAlphaTexture = 962 MGASubsequentCPUToScreenTexture; 963 infoPtr->CPUToScreenAlphaTextureFormats = MGAAlphaTextureFormats; 964 965 infoPtr->SetupForCPUToScreenTexture = MGASetupForCPUToScreenTexture; 966 infoPtr->SubsequentCPUToScreenTexture = MGASubsequentCPUToScreenTexture; 967 infoPtr->CPUToScreenTextureFlags = XAA_RENDER_NO_TILE; 968 infoPtr->CPUToScreenTextureFormats = MGATextureFormats; 969 } 970#endif /* defined(RENDER) */ 971 972 return(XAAInit(pScreen, infoPtr)); 973} 974 975 976/* Support for multiscreen */ 977static void mgaRestoreAccelState(ScrnInfoPtr pScrn) 978{ 979 MGAPtr pMga = MGAPTR(pScrn); 980 MGAFBLayout *pLayout = &pMga->CurrentLayout; 981 unsigned int replicate_fg = 0; 982 unsigned int replicate_bg = 0; 983 unsigned int replicate_pm = 0; 984 985 MGAStormSync(pScrn); 986 WAITFIFO(12); 987 pMga->SrcOrg = 0; 988 OUTREG(MGAREG_MACCESS, pMga->MAccess); 989 OUTREG(MGAREG_PITCH, pLayout->displayWidth); 990 OUTREG(MGAREG_YDSTORG, pMga->YDstOrg); 991 992 993 common_replicate_colors_and_mask( pMga->FgColor, pMga->BgColor, 994 pMga->PlaneMask, pLayout->bitsPerPixel, 995 & replicate_fg, & replicate_bg, 996 & replicate_pm ); 997 998 if( (pLayout->bitsPerPixel != 24) 999 && ((pMga->AccelFlags & MGA_NO_PLANEMASK) == 0) ) { 1000 OUTREG( MGAREG_PLNWT, replicate_pm ); 1001 } 1002 1003 OUTREG( MGAREG_BCOL, replicate_bg ); 1004 OUTREG( MGAREG_FCOL, replicate_fg ); 1005 1006 OUTREG(MGAREG_SRCORG, pMga->realSrcOrg); 1007 OUTREG(MGAREG_DSTORG, pMga->DstOrg); 1008#if X_BYTE_ORDER == X_LITTLE_ENDIAN 1009 OUTREG(MGAREG_OPMODE, MGAOPM_DMA_BLIT ); 1010#else 1011 OUTREG(MGAREG_OPMODE, MGAOPM_DMA_BLIT | 0x10000); 1012#endif 1013 OUTREG(MGAREG_CXBNDRY, 0xFFFF0000); /* (maxX << 16) | minX */ 1014 OUTREG(MGAREG_YTOP, 0x00000000); /* minPixelPointer */ 1015 OUTREG(MGAREG_YBOT, 0x007FFFFF); /* maxPixelPointer */ 1016 pMga->AccelFlags &= ~CLIPPER_ON; 1017} 1018 1019 1020CARD32 MGAAtype[16] = { 1021 MGADWG_RPL | 0x00000000, MGADWG_RSTR | 0x00080000, 1022 MGADWG_RSTR | 0x00040000, MGADWG_BLK | 0x000c0000, 1023 MGADWG_RSTR | 0x00020000, MGADWG_RSTR | 0x000a0000, 1024 MGADWG_RSTR | 0x00060000, MGADWG_RSTR | 0x000e0000, 1025 MGADWG_RSTR | 0x00010000, MGADWG_RSTR | 0x00090000, 1026 MGADWG_RSTR | 0x00050000, MGADWG_RSTR | 0x000d0000, 1027 MGADWG_RPL | 0x00030000, MGADWG_RSTR | 0x000b0000, 1028 MGADWG_RSTR | 0x00070000, MGADWG_RPL | 0x000f0000 1029}; 1030 1031 1032CARD32 MGAAtypeNoBLK[16] = { 1033 MGADWG_RPL | 0x00000000, MGADWG_RSTR | 0x00080000, 1034 MGADWG_RSTR | 0x00040000, MGADWG_RPL | 0x000c0000, 1035 MGADWG_RSTR | 0x00020000, MGADWG_RSTR | 0x000a0000, 1036 MGADWG_RSTR | 0x00060000, MGADWG_RSTR | 0x000e0000, 1037 MGADWG_RSTR | 0x00010000, MGADWG_RSTR | 0x00090000, 1038 MGADWG_RSTR | 0x00050000, MGADWG_RSTR | 0x000d0000, 1039 MGADWG_RPL | 0x00030000, MGADWG_RSTR | 0x000b0000, 1040 MGADWG_RSTR | 0x00070000, MGADWG_RPL | 0x000f0000 1041}; 1042 1043 1044Bool 1045MGAStormAccelInit(ScreenPtr pScreen) 1046{ 1047 return mgaAccelInit( pScreen ); 1048} 1049 1050 1051 1052void 1053MGAStormSync(ScrnInfoPtr pScrn) 1054{ 1055 MGAPtr pMga = MGAPTR(pScrn); 1056 1057 CHECK_DMA_QUIESCENT(pMga, pScrn); 1058 1059 /* MGAISBUSY() reportedly causes a freeze for Mystique revisions 0 and 1 */ 1060 if (!(pMga->Chipset == PCI_CHIP_MGA1064 && (pMga->ChipRev >= 0 && pMga->ChipRev <= 1))) 1061 while(MGAISBUSY()); 1062 /* flush cache before a read (mga-1064g 5.1.6) */ 1063 OUTREG8(MGAREG_CRTC_INDEX, 0); 1064 if(pMga->AccelFlags & CLIPPER_ON) { 1065 pMga->AccelFlags &= ~CLIPPER_ON; 1066 OUTREG(MGAREG_CXBNDRY, 0xFFFF0000); 1067 } 1068} 1069 1070 1071void MGAStormEngineInit( ScrnInfoPtr pScrn ) 1072{ 1073 long maccess = 0; 1074 MGAPtr pMga = MGAPTR(pScrn); 1075 MGAFBLayout *pLayout = &pMga->CurrentLayout; 1076 CARD32 opmode; 1077 static const unsigned int maccess_table[5] = { 1078 /* bpp: 8 16 24 32 */ 1079 0, 0, 1, 3, 2 1080 }; 1081 static const unsigned int opmode_table[5] = { 1082 /* bpp: 8 16 24 32 */ 1083 0x00000, 0x00000, 0x10000, 0x20000, 0x20000 1084 }; 1085 1086 CHECK_DMA_QUIESCENT(pMga, pScrn); 1087 1088 if ((pMga->Chipset == PCI_CHIP_MGAG100) 1089 || (pMga->Chipset == PCI_CHIP_MGAG100_PCI)) 1090 maccess = 1 << 14; 1091 1092 opmode = INREG(MGAREG_OPMODE); 1093 1094 maccess |= maccess_table[ pLayout->bitsPerPixel / 8 ]; 1095 if ( pLayout->depth == 15 ) { 1096 maccess |= (1 << 31); 1097 } 1098 1099 opmode |= opmode_table[ pLayout->bitsPerPixel / 8 ]; 1100#if X_BYTE_ORDER == X_LITTLE_ENDIAN 1101 opmode &= ~0x30000; 1102#endif 1103 1104 pMga->SetupForSolidFill = mgaSetupForSolidFill; 1105 pMga->SubsequentSolidFillRect = mgaSubsequentSolidFillRect; 1106 pMga->RestoreAccelState = mgaRestoreAccelState; 1107 1108 1109 pMga->fifoCount = 0; 1110 1111 while(MGAISBUSY()); 1112 1113 if(!pMga->FifoSize) { 1114 pMga->FifoSize = INREG8(MGAREG_FIFOSTATUS); 1115 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "%i DWORD fifo\n", 1116 pMga->FifoSize); 1117 } 1118 1119 OUTREG(MGAREG_PITCH, pLayout->displayWidth); 1120 OUTREG(MGAREG_YDSTORG, pMga->YDstOrg); 1121 OUTREG(MGAREG_MACCESS, maccess); 1122 pMga->MAccess = maccess; 1123 pMga->PlaneMask = ~0; 1124 /* looks like this doesn't apply to mga g100 pci */ 1125 1126 if ((pMga->Chipset != PCI_CHIP_MGAG100) 1127 && (pMga->Chipset != PCI_CHIP_MGAG100_PCI)) 1128 OUTREG(MGAREG_PLNWT, pMga->PlaneMask); 1129 1130 pMga->FgColor = 0; 1131 OUTREG(MGAREG_FCOL, pMga->FgColor); 1132 pMga->BgColor = 0; 1133 OUTREG(MGAREG_BCOL, pMga->BgColor); 1134 OUTREG(MGAREG_OPMODE, MGAOPM_DMA_BLIT | opmode); 1135 1136 /* put clipping in a known state */ 1137 OUTREG(MGAREG_CXBNDRY, 0xFFFF0000); /* (maxX << 16) | minX */ 1138 OUTREG(MGAREG_YTOP, 0x00000000); /* minPixelPointer */ 1139 OUTREG(MGAREG_YBOT, 0x007FFFFF); /* maxPixelPointer */ 1140 pMga->AccelFlags &= ~CLIPPER_ON; 1141 1142 switch(pMga->Chipset) { 1143 case PCI_CHIP_MGAG550: 1144 case PCI_CHIP_MGAG400: 1145 case PCI_CHIP_MGAG200: 1146 case PCI_CHIP_MGAG200_PCI: 1147 case PCI_CHIP_MGAG200_SE_A_PCI: 1148 case PCI_CHIP_MGAG200_SE_B_PCI: 1149 pMga->SrcOrg = 0; 1150 OUTREG(MGAREG_SRCORG, pMga->realSrcOrg); 1151 OUTREG(MGAREG_DSTORG, pMga->DstOrg); 1152 break; 1153 default: 1154 break; 1155 } 1156 1157 xf86SetLastScrnFlag(pScrn->entityList[0], pScrn->scrnIndex); 1158} 1159 1160 1161static void 1162MGASetClippingRectangle( 1163 ScrnInfoPtr pScrn, 1164 int x1, int y1, int x2, int y2 1165){ 1166 MGAPtr pMga = MGAPTR(pScrn); 1167 1168 CHECK_DMA_QUIESCENT(pMga, pScrn); 1169 1170 WAITFIFO(3); 1171 OUTREG(MGAREG_CXBNDRY,(x2 << 16) | x1); 1172 OUTREG(MGAREG_YTOP, (y1 * pScrn->displayWidth) + pMga->YDstOrg); 1173 OUTREG(MGAREG_YBOT, (y2 * pScrn->displayWidth) + pMga->YDstOrg); 1174 pMga->AccelFlags |= CLIPPER_ON; 1175} 1176 1177static void 1178MGADisableClipping(ScrnInfoPtr pScrn) 1179{ 1180 MGAPtr pMga = MGAPTR(pScrn); 1181 1182 CHECK_DMA_QUIESCENT(pMga, pScrn); 1183 1184 WAITFIFO(3); 1185 OUTREG(MGAREG_CXBNDRY, 0xFFFF0000); /* (maxX << 16) | minX */ 1186 OUTREG(MGAREG_YTOP, 0x00000000); /* minPixelPointer */ 1187 OUTREG(MGAREG_YBOT, 0x007FFFFF); /* maxPixelPointer */ 1188 pMga->AccelFlags &= ~CLIPPER_ON; 1189} 1190 1191 1192static CARD32 1193common_setup_for_pattern_fill( MGAPtr pMga, int fg, int bg, int rop, 1194 int planemask, 1195 CARD32 * reg_data, unsigned int count, 1196 CARD32 cmd ) 1197{ 1198 unsigned int replicate_fg = 0; 1199 unsigned int replicate_bg = 0; 1200 unsigned int replicate_pm = 0; 1201 unsigned int i; 1202 1203 1204 common_replicate_colors_and_mask( fg, bg, planemask, 1205 pMga->CurrentLayout.bitsPerPixel, 1206 & replicate_fg, & replicate_bg, 1207 & replicate_pm ); 1208 1209 1210 if( bg == -1 ) { 1211 if ( (pMga->CurrentLayout.bitsPerPixel == 24) && !RGBEQUAL(fg) ) { 1212 cmd |= MGADWG_TRANSC | pMga->AtypeNoBLK[rop]; 1213 } 1214 else { 1215 cmd |= MGADWG_TRANSC | pMga->Atype[rop]; 1216 } 1217 1218 WAITFIFO( count + 3 ); 1219 } 1220 else { 1221 /* (Packed) 24-bit is a funky mode. We only use the Atype table in 1222 * 24-bit if the components of the foreground color and the components 1223 * of the background color are the same (e.g., fg = 0xf8f8f8 and bg = 1224 * 0x131313). 1225 */ 1226 1227 if( ((pMga->AccelFlags & BLK_OPAQUE_EXPANSION) != 0) 1228 && ((pMga->CurrentLayout.bitsPerPixel != 24) 1229 || (RGBEQUAL(fg) && RGBEQUAL(bg))) ) { 1230 cmd |= pMga->Atype[rop]; 1231 } 1232 else { 1233 cmd |= pMga->AtypeNoBLK[rop]; 1234 } 1235 1236 WAITFIFO( count + 4 ); 1237 SET_BACKGROUND_REPLICATED( bg, replicate_bg ); 1238 } 1239 1240 SET_FOREGROUND_REPLICATED( fg, replicate_fg ); 1241 SET_PLANEMASK_REPLICATED( planemask, replicate_pm, 1242 pMga->CurrentLayout.bitsPerPixel ); 1243 1244 /* FIXME: Is this the right order? */ 1245 1246 for ( i = 0 ; i < count ; i++ ) { 1247 OUTREG( reg_data[0], reg_data[1] ); 1248 reg_data += 2; 1249 } 1250 1251 OUTREG(MGAREG_DWGCTL, cmd); 1252 1253 return cmd; 1254} 1255 1256 1257 /*********************************************\ 1258 | Screen-to-Screen Copy | 1259 \*********************************************/ 1260 1261#define BLIT_LEFT 1 1262#define BLIT_UP 4 1263 1264void mgaDoSetupForScreenToScreenCopy( ScrnInfoPtr pScrn, int xdir, int ydir, 1265 int rop, unsigned int planemask, 1266 int trans, unsigned bpp ) 1267{ 1268 MGAPtr pMga = MGAPTR(pScrn); 1269 CARD32 dwgctl = pMga->AtypeNoBLK[rop] | MGADWG_SHIFTZERO | 1270 MGADWG_BITBLT | MGADWG_BFCOL; 1271 unsigned int tmp; 1272 unsigned int replicated_trans = 0; 1273 unsigned int replicated_mask = 0; 1274 1275 1276 CHECK_DMA_QUIESCENT(pMga, pScrn); 1277 1278 pMga->AccelInfoRec->SubsequentScreenToScreenCopy = 1279 mgaSubsequentScreenToScreenCopy; 1280 1281 pMga->BltScanDirection = 0; 1282 if(ydir == -1) pMga->BltScanDirection |= BLIT_UP; 1283 if(xdir == -1) 1284 pMga->BltScanDirection |= BLIT_LEFT; 1285 else if(pMga->HasFBitBlt && (rop == GXcopy) && !pMga->DrawTransparent) 1286 pMga->AccelInfoRec->SubsequentScreenToScreenCopy = 1287 mgaSubsequentScreenToScreenCopy_FastBlit; 1288 1289 1290 common_replicate_colors_and_mask( trans, 0, planemask, bpp, 1291 & replicated_trans, & tmp, 1292 & replicated_mask ); 1293 1294 if(pMga->DrawTransparent) { 1295 dwgctl |= MGADWG_TRANSC; 1296 WAITFIFO(2); 1297 1298 SET_FOREGROUND_REPLICATED( trans, replicated_trans ); 1299 SET_BACKGROUND_REPLICATED( ~0, ~0 ); 1300 } 1301 1302 WAITFIFO(4); 1303 OUTREG(MGAREG_DWGCTL, dwgctl); 1304 OUTREG(MGAREG_SGN, pMga->BltScanDirection); 1305 1306 SET_PLANEMASK_REPLICATED( planemask, replicated_mask, bpp ); 1307 OUTREG(MGAREG_AR5, ydir * pMga->CurrentLayout.displayWidth); 1308} 1309 1310 1311void mgaSetupForScreenToScreenCopy( ScrnInfoPtr pScrn, int xdir, int ydir, 1312 int rop, unsigned int planemask, 1313 int trans ) 1314{ 1315 MGAPtr pMga = MGAPTR(pScrn); 1316 1317 mgaDoSetupForScreenToScreenCopy( pScrn, xdir, ydir, rop, planemask, trans, 1318 pMga->CurrentLayout.bitsPerPixel ); 1319} 1320 1321 1322void mgaSubsequentScreenToScreenCopy( ScrnInfoPtr pScrn, 1323 int srcX, int srcY, int dstX, int dstY, 1324 int w, int h ) 1325{ 1326 int start, end, SrcOrg = 0, DstOrg = 0; 1327 MGAPtr pMga = MGAPTR(pScrn); 1328 1329 if (pMga->AccelFlags & LARGE_ADDRESSES) { 1330 const unsigned int display_bit_width = 1331 (pMga->CurrentLayout.displayWidth * pMga->CurrentLayout.bitsPerPixel); 1332 1333 SrcOrg = ((srcY & ~1023) * display_bit_width) >> 9; 1334 DstOrg = ((dstY & ~1023) * display_bit_width) >> 9; 1335 dstY &= 1023; 1336 } 1337 1338 if(pMga->BltScanDirection & BLIT_UP) { 1339 srcY += h - 1; 1340 dstY += h - 1; 1341 } 1342 1343 w--; 1344 start = end = XYADDRESS(srcX, srcY); 1345 1346 if(pMga->BltScanDirection & BLIT_LEFT) start += w; 1347 else end += w; 1348 1349 if (pMga->AccelFlags & LARGE_ADDRESSES) { 1350 WAITFIFO(7); 1351 if(DstOrg) 1352 OUTREG(MGAREG_DSTORG, (DstOrg << 6) + pMga->DstOrg); 1353 if(SrcOrg != pMga->SrcOrg) { 1354 pMga->SrcOrg = SrcOrg; 1355 OUTREG(MGAREG_SRCORG, (SrcOrg << 6) + pMga->realSrcOrg); 1356 } 1357 if(SrcOrg) { 1358 SrcOrg = (SrcOrg << 9) / pMga->CurrentLayout.bitsPerPixel; 1359 end -= SrcOrg; 1360 start -= SrcOrg; 1361 } 1362 OUTREG(MGAREG_AR0, end); 1363 OUTREG(MGAREG_AR3, start); 1364 OUTREG(MGAREG_FXBNDRY, ((dstX + w) << 16) | (dstX & 0xffff)); 1365 OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (dstY << 16) | h); 1366 if(DstOrg) 1367 OUTREG(MGAREG_DSTORG, pMga->DstOrg); 1368 } else { 1369 WAITFIFO(4); 1370 OUTREG(MGAREG_AR0, end); 1371 OUTREG(MGAREG_AR3, start); 1372 OUTREG(MGAREG_FXBNDRY, ((dstX + w) << 16) | (dstX & 0xffff)); 1373 OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (dstY << 16) | h); 1374 } 1375} 1376 1377 1378void mgaSubsequentScreenToScreenCopy_FastBlit( ScrnInfoPtr pScrn, 1379 int srcX, int srcY, 1380 int dstX, int dstY, 1381 int w, int h ) 1382{ 1383 int start, end; 1384 MGAPtr pMga = MGAPTR(pScrn); 1385 static const unsigned int masks[5] = { 1386 0, 0x07f, 0x03f, 0x7f, 0x1f 1387 }; 1388 1389 if(pMga->BltScanDirection & BLIT_UP) { 1390 srcY += h - 1; 1391 dstY += h - 1; 1392 } 1393 1394 w--; 1395 start = XYADDRESS(srcX, srcY); 1396 end = start + w; 1397 1398 /* we assume the driver asserts screen pitches such that 1399 we can always use fastblit for scrolling */ 1400 if(((srcX ^ dstX) & masks[ pMga->CurrentLayout.bitsPerPixel / 8 ]) == 0) { 1401 if(pMga->MaxFastBlitY) { 1402 if(pMga->BltScanDirection & BLIT_UP) { 1403 if((srcY >= pMga->MaxFastBlitY) || 1404 (dstY >= pMga->MaxFastBlitY)) 1405 goto FASTBLIT_BAILOUT; 1406 } else { 1407 if(((srcY + h) > pMga->MaxFastBlitY) || 1408 ((dstY + h) > pMga->MaxFastBlitY)) 1409 goto FASTBLIT_BAILOUT; 1410 } 1411 } 1412 1413 /* Millennium 1 fastblit bug fix */ 1414 if(pMga->AccelFlags & FASTBLT_BUG) { 1415 int fxright = dstX + w; 1416 int tmp_dstX = dstX; 1417 int tmp_fxright = fxright; 1418 static const unsigned shift_tab[5] = { 1419 0, 6, 5, 6, 4 1420 }; 1421 const unsigned shift = shift_tab[pMga->CurrentLayout.bitsPerPixel / 8]; 1422 1423 if (pMga->CurrentLayout.bitsPerPixel == 24) { 1424 tmp_dstX *= 3; 1425 tmp_fxright = fxright * 3 + 2; 1426 } 1427 1428 if( (tmp_dstX & (1 << shift)) 1429 && (((tmp_fxright >> shift) - (tmp_dstX >> shift)) & 7) == 7) { 1430 fxright = (tmp_fxright | (1 << shift)); 1431 if (pMga->CurrentLayout.bitsPerPixel == 24) { 1432 fxright /= 3; 1433 } 1434 1435 WAITFIFO(8); 1436 OUTREG(MGAREG_CXRIGHT, dstX + w); 1437 OUTREG(MGAREG_DWGCTL, 0x040A400C); 1438 OUTREG(MGAREG_AR0, end); 1439 OUTREG(MGAREG_AR3, start); 1440 OUTREG(MGAREG_FXBNDRY, (fxright << 16) | (dstX & 0xffff)); 1441 OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (dstY << 16) | h); 1442 OUTREG(MGAREG_DWGCTL, pMga->AtypeNoBLK[GXcopy] | 1443 MGADWG_SHIFTZERO | MGADWG_BITBLT | MGADWG_BFCOL); 1444 OUTREG(MGAREG_CXRIGHT, 0xFFFF); 1445 return; 1446 } 1447 } 1448 1449 WAITFIFO(6); 1450 OUTREG(MGAREG_DWGCTL, 0x040A400C); 1451 OUTREG(MGAREG_AR0, end); 1452 OUTREG(MGAREG_AR3, start); 1453 OUTREG(MGAREG_FXBNDRY, ((dstX + w) << 16) | (dstX & 0xffff)); 1454 OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (dstY << 16) | h); 1455 OUTREG(MGAREG_DWGCTL, pMga->AtypeNoBLK[GXcopy] | MGADWG_SHIFTZERO | 1456 MGADWG_BITBLT | MGADWG_BFCOL); 1457 return; 1458 } 1459 1460FASTBLIT_BAILOUT: 1461 1462 WAITFIFO(4); 1463 OUTREG(MGAREG_AR0, end); 1464 OUTREG(MGAREG_AR3, start); 1465 OUTREG(MGAREG_FXBNDRY, ((dstX + w) << 16) | (dstX & 0xffff)); 1466 OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (dstY << 16) | h); 1467} 1468 1469 /******************\ 1470 | Solid Fills | 1471 \******************/ 1472 1473void mgaDoSetupForSolidFill( ScrnInfoPtr pScrn, int color, int rop, 1474 unsigned int planemask, unsigned int bpp ) 1475{ 1476 MGAPtr pMga = MGAPTR(pScrn); 1477 unsigned int tmp; 1478 unsigned int replicated_color = 0; 1479 unsigned int replicated_planemask = 0; 1480 1481 common_replicate_colors_and_mask( color, 0, planemask, bpp, 1482 & replicated_color, & tmp, 1483 & replicated_planemask ); 1484 1485 CHECK_DMA_QUIESCENT(pMga, pScrn); 1486 1487 if ( (bpp == 24) && !RGBEQUAL(color) ) { 1488 pMga->FilledRectCMD = MGADWG_TRAP | MGADWG_SOLID | MGADWG_ARZERO | 1489 MGADWG_SGNZERO | MGADWG_SHIFTZERO | 1490 MGADWG_BMONOLEF | pMga->AtypeNoBLK[rop]; 1491 } 1492 else { 1493 pMga->FilledRectCMD = MGADWG_TRAP | MGADWG_SOLID | MGADWG_ARZERO | 1494 MGADWG_SGNZERO | MGADWG_SHIFTZERO | 1495 MGADWG_BMONOLEF | pMga->Atype[rop]; 1496 } 1497 1498 pMga->SolidLineCMD = MGADWG_SOLID | MGADWG_SHIFTZERO | MGADWG_BFCOL | 1499 pMga->AtypeNoBLK[rop]; 1500 1501 if(pMga->AccelFlags & TRANSC_SOLID_FILL) 1502 pMga->FilledRectCMD |= MGADWG_TRANSC; 1503 1504 WAITFIFO(3); 1505 if ( color != pMga->FgColor ) { 1506 pMga->FgColor = color; 1507 OUTREG( MGAREG_FCOL, replicated_color ); 1508 } 1509 1510 if ( (bpp != 24) 1511 && !(pMga->AccelFlags & MGA_NO_PLANEMASK) 1512 && (planemask != pMga->PlaneMask) ) { 1513 pMga->PlaneMask = planemask; 1514 OUTREG( MGAREG_PLNWT, replicated_planemask ); 1515 } 1516 1517 OUTREG(MGAREG_DWGCTL, pMga->FilledRectCMD); 1518} 1519 1520void mgaSetupForSolidFill( ScrnInfoPtr pScrn, int color, int rop, 1521 unsigned int planemask ) 1522{ 1523 MGAPtr pMga = MGAPTR(pScrn); 1524 1525 mgaDoSetupForSolidFill( pScrn, color, rop, planemask, 1526 pMga->CurrentLayout.bitsPerPixel ); 1527} 1528 1529void mgaSubsequentSolidFillRect( ScrnInfoPtr pScrn, 1530 int x, int y, int w, int h ) 1531{ 1532 MGAPtr pMga = MGAPTR(pScrn); 1533 1534 WAITFIFO(2); 1535 OUTREG(MGAREG_FXBNDRY, ((x + w) << 16) | (x & 0xffff)); 1536 OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (y << 16) | h); 1537} 1538 1539void mgaSubsequentSolidFillTrap( ScrnInfoPtr pScrn, int y, int h, 1540 int left, int dxL, int dyL, int eL, 1541 int right, int dxR, int dyR, int eR ) 1542{ 1543 MGAPtr pMga = MGAPTR(pScrn); 1544 int sdxl = (dxL < 0); 1545 int ar2 = sdxl? dxL : -dxL; 1546 int sdxr = (dxR < 0); 1547 int ar5 = sdxr? dxR : -dxR; 1548 1549 WAITFIFO(11); 1550 OUTREG(MGAREG_DWGCTL, 1551 pMga->FilledRectCMD & ~(MGADWG_ARZERO | MGADWG_SGNZERO)); 1552 OUTREG(MGAREG_AR0, dyL); 1553 OUTREG(MGAREG_AR1, ar2 - eL); 1554 OUTREG(MGAREG_AR2, ar2); 1555 OUTREG(MGAREG_AR4, ar5 - eR); 1556 OUTREG(MGAREG_AR5, ar5); 1557 OUTREG(MGAREG_AR6, dyR); 1558 OUTREG(MGAREG_SGN, (sdxl << 1) | (sdxr << 5)); 1559 OUTREG(MGAREG_FXBNDRY, ((right + 1) << 16) | (left & 0xffff)); 1560 OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (y << 16) | h); 1561 OUTREG(MGAREG_DWGCTL, pMga->FilledRectCMD); 1562} 1563 1564 1565 /***************\ 1566 | Solid Lines | 1567 \***************/ 1568 1569void mgaSubsequentSolidHorVertLine( ScrnInfoPtr pScrn, int x, int y, 1570 int len, int dir ) 1571{ 1572 MGAPtr pMga = MGAPTR(pScrn); 1573 1574 if(dir == DEGREES_0) { 1575 WAITFIFO(2); 1576 OUTREG(MGAREG_FXBNDRY, ((x + len) << 16) | (x & 0xffff)); 1577 OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (y << 16) | 1); 1578 } else if(pMga->AccelFlags & USE_RECTS_FOR_LINES) { 1579 WAITFIFO(2); 1580 OUTREG(MGAREG_FXBNDRY, ((x + 1) << 16) | (x & 0xffff)); 1581 OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (y << 16) | len); 1582 } else { 1583 WAITFIFO(4); 1584 OUTREG(MGAREG_DWGCTL, pMga->SolidLineCMD | MGADWG_AUTOLINE_OPEN); 1585 OUTREG(MGAREG_XYSTRT, (y << 16) | (x & 0xffff)); 1586 OUTREG(MGAREG_XYEND + MGAREG_EXEC, ((y + len) << 16) | (x & 0xffff)); 1587 OUTREG(MGAREG_DWGCTL, pMga->FilledRectCMD); 1588 } 1589} 1590 1591 1592void mgaSubsequentSolidTwoPointLine( ScrnInfoPtr pScrn, int x1, int y1, 1593 int x2, int y2, int flags ) 1594{ 1595 MGAPtr pMga = MGAPTR(pScrn); 1596 1597 WAITFIFO(4); 1598 OUTREG(MGAREG_DWGCTL, pMga->SolidLineCMD | 1599 ((flags & OMIT_LAST) ? MGADWG_AUTOLINE_OPEN : MGADWG_AUTOLINE_CLOSE)); 1600 OUTREG(MGAREG_XYSTRT, (y1 << 16) | (x1 & 0xFFFF)); 1601 OUTREG(MGAREG_XYEND + MGAREG_EXEC, (y2 << 16) | (x2 & 0xFFFF)); 1602 OUTREG(MGAREG_DWGCTL, pMga->FilledRectCMD); 1603} 1604 1605 1606 /***************************\ 1607 | 8x8 Mono Pattern Fills | 1608 \***************************/ 1609 1610 1611void mgaSetupForMono8x8PatternFill( ScrnInfoPtr pScrn, 1612 int patx, int paty, int fg, int bg, 1613 int rop, unsigned int planemask ) 1614{ 1615 MGAPtr pMga = MGAPTR(pScrn); 1616 XAAInfoRecPtr infoRec = pMga->AccelInfoRec; 1617 CARD32 regs[4]; 1618 1619 CHECK_DMA_QUIESCENT(pMga, pScrn); 1620 1621 infoRec->SubsequentMono8x8PatternFillRect = 1622 mgaSubsequentMono8x8PatternFillRect; 1623 1624 regs[0] = MGAREG_PAT0; 1625 regs[1] = patx; 1626 regs[2] = MGAREG_PAT1; 1627 regs[3] = paty; 1628 1629 pMga->PatternRectCMD = common_setup_for_pattern_fill( pMga, fg, bg, rop, 1630 planemask, regs, 2, 1631 (MGADWG_TRAP 1632 | MGADWG_ARZERO 1633 | MGADWG_SGNZERO 1634 | MGADWG_BMONOLEF) ); 1635} 1636 1637 1638void mgaSubsequentMono8x8PatternFillRect( ScrnInfoPtr pScrn, 1639 int patx, int paty, 1640 int x, int y, int w, int h ) 1641{ 1642 MGAPtr pMga = MGAPTR(pScrn); 1643 1644 WAITFIFO(3); 1645 OUTREG(MGAREG_SHIFT, (paty << 4) | patx); 1646 OUTREG(MGAREG_FXBNDRY, ((x + w) << 16) | (x & 0xffff)); 1647 OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (y << 16) | h); 1648 pMga->AccelInfoRec->SubsequentMono8x8PatternFillRect = 1649 mgaSubsequentMono8x8PatternFillRect_Additional; 1650} 1651 1652static void mgaSubsequentMono8x8PatternFillRect_Additional( ScrnInfoPtr pScrn, 1653 int patx, int paty, 1654 int x, int y, 1655 int w, int h ) 1656{ 1657 MGAPtr pMga = MGAPTR(pScrn); 1658 1659 WAITFIFO(2); 1660 OUTREG(MGAREG_FXBNDRY, ((x + w) << 16) | (x & 0xffff)); 1661 OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (y << 16) | h); 1662} 1663 1664 1665void mgaSubsequentMono8x8PatternFillTrap( ScrnInfoPtr pScrn, 1666 int patx, int paty, 1667 int y, int h, 1668 int left, int dxL, int dyL, int eL, 1669 int right, int dxR, int dyR, int eR ) 1670{ 1671 MGAPtr pMga = MGAPTR(pScrn); 1672 1673 int sdxl = (dxL < 0) ? (1<<1) : 0; 1674 int ar2 = sdxl? dxL : -dxL; 1675 int sdxr = (dxR < 0) ? (1<<5) : 0; 1676 int ar5 = sdxr? dxR : -dxR; 1677 1678 WAITFIFO(12); 1679 OUTREG(MGAREG_SHIFT, (paty << 4) | patx); 1680 OUTREG(MGAREG_DWGCTL, 1681 pMga->PatternRectCMD & ~(MGADWG_ARZERO | MGADWG_SGNZERO)); 1682 OUTREG(MGAREG_AR0, dyL); 1683 OUTREG(MGAREG_AR1, ar2 - eL); 1684 OUTREG(MGAREG_AR2, ar2); 1685 OUTREG(MGAREG_AR4, ar5 - eR); 1686 OUTREG(MGAREG_AR5, ar5); 1687 OUTREG(MGAREG_AR6, dyR); 1688 OUTREG(MGAREG_SGN, sdxl | sdxr); 1689 OUTREG(MGAREG_FXBNDRY, ((right + 1) << 16) | (left & 0xffff)); 1690 OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (y << 16) | h); 1691 OUTREG(MGAREG_DWGCTL, pMga->PatternRectCMD); 1692} 1693 1694 /***********************\ 1695 | Color Expand Rect | 1696 \***********************/ 1697 1698 1699void mgaSetupForScanlineCPUToScreenColorExpandFill( ScrnInfoPtr pScrn, 1700 int fg, int bg, 1701 int rop, 1702 unsigned int planemask ) 1703{ 1704 MGAPtr pMga = MGAPTR(pScrn); 1705 1706 1707 CHECK_DMA_QUIESCENT(pMga, pScrn); 1708 1709 (void) common_setup_for_pattern_fill( pMga, fg, bg, rop, 1710 planemask, NULL, 0, 1711 MGADWG_ILOAD | MGADWG_LINEAR 1712 | MGADWG_SGNZERO | MGADWG_SHIFTZERO 1713 | MGADWG_BMONOLEF ); 1714} 1715 1716 1717void mgaSubsequentScanlineCPUToScreenColorExpandFill( ScrnInfoPtr pScrn, 1718 int x, int y, int w, int h, 1719 int skipleft ) 1720{ 1721 MGAPtr pMga = MGAPTR(pScrn); 1722 1723 pMga->AccelFlags |= CLIPPER_ON; 1724 pMga->expandDWORDs = (w + 31) >> 5; 1725 if((pMga->expandDWORDs * h) > pMga->MaxBlitDWORDS) { 1726 pMga->expandHeight = pMga->MaxBlitDWORDS / pMga->expandDWORDs; 1727 pMga->expandRemaining = h / pMga->expandHeight; 1728 if(!(h = h % pMga->expandHeight)) { 1729 pMga->expandRemaining--; 1730 h = pMga->expandHeight; 1731 } 1732 pMga->expandY = y + h; 1733 } else 1734 pMga->expandRemaining = 0; 1735 pMga->expandRows = h; 1736 1737 WAITFIFO(5); 1738 OUTREG(MGAREG_CXBNDRY, ((x + w - 1) << 16) | ((x + skipleft) & 0xFFFF)); 1739 w = pMga->expandDWORDs << 5; /* source is dword padded */ 1740 OUTREG(MGAREG_AR0, (w * h) - 1); 1741 OUTREG(MGAREG_AR3, 0); /* crashes occasionally without this */ 1742 OUTREG(MGAREG_FXBNDRY, ((x + w - 1) << 16) | (x & 0xFFFF)); 1743 OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (y << 16) | h); 1744 1745#if defined(__alpha__) 1746 if(1) /* force indirect always on Alpha */ 1747#else 1748 if(pMga->expandDWORDs > pMga->FifoSize) 1749#endif 1750 { 1751 pMga->AccelInfoRec->SubsequentColorExpandScanline = 1752 mgaSubsequentColorExpandScanlineIndirect; 1753 pMga->AccelInfoRec->ScanlineColorExpandBuffers = 1754 (unsigned char**)(&pMga->ScratchBuffer); 1755 } else { 1756 pMga->AccelInfoRec->SubsequentColorExpandScanline = 1757 mgaSubsequentColorExpandScanline; 1758 pMga->AccelInfoRec->ScanlineColorExpandBuffers = 1759 (unsigned char**)(&pMga->ColorExpandBase); 1760 WAITFIFO(pMga->expandDWORDs); 1761 } 1762} 1763 1764 1765void mgaSubsequentColorExpandScanlineIndirect( ScrnInfoPtr pScrn, 1766 int bufno ) 1767{ 1768 MGAPtr pMga = MGAPTR(pScrn); 1769 int dwords = pMga->expandDWORDs; 1770 CARD32 *src = (CARD32*)(pMga->ScratchBuffer); 1771 1772 while(dwords > pMga->FifoSize) { 1773 WAITFIFO(pMga->FifoSize); 1774 MGAMoveDWORDS((CARD32*)(pMga->ColorExpandBase), src, pMga->FifoSize); 1775 src += pMga->FifoSize; 1776 dwords -= pMga->FifoSize; 1777 } 1778 1779 WAITFIFO(dwords); 1780 MGAMoveDWORDS((CARD32*)(pMga->ColorExpandBase), src, dwords); 1781 1782 if(!(--pMga->expandRows)) { 1783 if(pMga->expandRemaining) { 1784 WAITFIFO(3); 1785 OUTREG(MGAREG_AR0,((pMga->expandDWORDs<< 5)*pMga->expandHeight)-1); 1786 OUTREG(MGAREG_AR3, 0); /* crashes occasionally without this */ 1787 OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (pMga->expandY << 16) | 1788 pMga->expandHeight); 1789 pMga->expandY += pMga->expandHeight; 1790 pMga->expandRows = pMga->expandHeight; 1791 pMga->expandRemaining--; 1792 } else { 1793 DISABLE_CLIP(); 1794 } 1795 } 1796} 1797 1798 1799void mgaSubsequentColorExpandScanline( ScrnInfoPtr pScrn, 1800 int bufno ) 1801{ 1802 MGAPtr pMga = MGAPTR(pScrn); 1803 1804 if(--pMga->expandRows) { 1805 WAITFIFO(pMga->expandDWORDs); 1806 } else if(pMga->expandRemaining) { 1807 WAITFIFO(3); 1808 OUTREG(MGAREG_AR0,((pMga->expandDWORDs<<5)*pMga->expandHeight)-1); 1809 OUTREG(MGAREG_AR3, 0); /* crashes occasionally without this */ 1810 OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (pMga->expandY << 16) | 1811 pMga->expandHeight); 1812 pMga->expandY += pMga->expandHeight; 1813 pMga->expandRows = pMga->expandHeight; 1814 pMga->expandRemaining--; 1815 WAITFIFO(pMga->expandDWORDs); 1816 } else { 1817 DISABLE_CLIP(); 1818 } 1819} 1820 1821 1822 /*******************\ 1823 | Image Writes | 1824 \*******************/ 1825 1826 1827void mgaSetupForScanlineImageWrite( ScrnInfoPtr pScrn, int rop, 1828 unsigned int planemask, 1829 int transparency_color, 1830 int bpp, int depth ) 1831{ 1832 MGAPtr pMga = MGAPTR(pScrn); 1833 unsigned int replicate_pm = 0; 1834 1835 switch( pMga->CurrentLayout.bitsPerPixel ) { 1836 case 8: 1837 replicate_pm = REPLICATE_8( planemask ); 1838 break; 1839 case 16: 1840 replicate_pm = REPLICATE_16( planemask ); 1841 break; 1842 case 24: 1843 replicate_pm = REPLICATE_24( planemask ); 1844 break; 1845 case 32: 1846 replicate_pm = REPLICATE_32( planemask ); 1847 break; 1848 } 1849 1850 CHECK_DMA_QUIESCENT(pMga, pScrn); 1851 1852 WAITFIFO(3); 1853 OUTREG(MGAREG_AR5, 0); 1854 SET_PLANEMASK_REPLICATED( planemask, replicate_pm, 1855 pMga->CurrentLayout.bitsPerPixel ); 1856 OUTREG(MGAREG_DWGCTL, MGADWG_ILOAD | MGADWG_BFCOL | MGADWG_SHIFTZERO | 1857 MGADWG_SGNZERO | pMga->AtypeNoBLK[rop]); 1858} 1859 1860 1861void mgaSubsequentScanlineImageWriteRect( ScrnInfoPtr pScrn, 1862 int x, int y, int w, int h, 1863 int skipleft ) 1864{ 1865 MGAPtr pMga = MGAPTR(pScrn); 1866 1867 pMga->AccelFlags |= CLIPPER_ON; 1868 pMga->expandRows = h; 1869 pMga->expandDWORDs = ((w * pMga->CurrentLayout.bitsPerPixel) + 31) >> 5; 1870 1871 WAITFIFO(5); 1872 OUTREG(MGAREG_CXBNDRY, 0xFFFF0000 | ((x + skipleft) & 0xFFFF)); 1873 OUTREG(MGAREG_AR0, w - 1); 1874 OUTREG(MGAREG_AR3, 0); 1875 OUTREG(MGAREG_FXBNDRY, ((x + w - 1) << 16) | (x & 0xFFFF)); 1876 OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (y << 16) | h); 1877} 1878 1879 1880void mgaSubsequentImageWriteScanline( ScrnInfoPtr pScrn, int bufno ) 1881{ 1882 MGAPtr pMga = MGAPTR(pScrn); 1883 int dwords = pMga->expandDWORDs; 1884 CARD32 *src = (CARD32*)(pMga->ScratchBuffer); 1885 1886 while(dwords > pMga->FifoSize) { 1887 WAITFIFO(pMga->FifoSize); 1888 MGAMoveDWORDS((CARD32*)(pMga->ColorExpandBase), src, pMga->FifoSize); 1889 src += pMga->FifoSize; 1890 dwords -= pMga->FifoSize; 1891 } 1892 1893 WAITFIFO(dwords); 1894 MGAMoveDWORDS((CARD32*)(pMga->ColorExpandBase), src, dwords); 1895 1896 if(!(--pMga->expandRows)) { 1897 DISABLE_CLIP(); 1898 } 1899} 1900 1901 1902#if X_BYTE_ORDER == X_LITTLE_ENDIAN 1903 1904 /***************************\ 1905 | Dashed Lines | 1906 \***************************/ 1907 1908void mgaSetupForDashedLine( ScrnInfoPtr pScrn, 1909 int fg, int bg, int rop, 1910 unsigned int planemask, int length, 1911 unsigned char *pattern ) 1912{ 1913 MGAPtr pMga = MGAPTR(pScrn); 1914 CARD32 *DashPattern = (CARD32*)pattern; 1915 CARD32 NiceDashPattern = DashPattern[0]; 1916 int dwords = (length + 31) >> 5; 1917 unsigned int replicate_fg = 0; 1918 unsigned int replicate_bg = 0; 1919 unsigned int replicate_pm = 0; 1920 1921 1922 common_replicate_colors_and_mask( fg, bg, planemask, 1923 pMga->CurrentLayout.bitsPerPixel, 1924 & replicate_fg, & replicate_bg, 1925 & replicate_pm ); 1926 1927 CHECK_DMA_QUIESCENT(pMga, pScrn); 1928 1929 pMga->DashCMD = MGADWG_BFCOL | pMga->AtypeNoBLK[rop]; 1930 pMga->StyleLen = length - 1; 1931 1932 if(bg == -1) { 1933 pMga->DashCMD |= MGADWG_TRANSC; 1934 WAITFIFO(dwords + 2); 1935 } else { 1936 WAITFIFO(dwords + 3); 1937 SET_BACKGROUND_REPLICATED( bg, replicate_bg ); 1938 } 1939 1940 SET_PLANEMASK_REPLICATED( planemask, replicate_pm, 1941 pMga->CurrentLayout.bitsPerPixel ); 1942 SET_FOREGROUND_REPLICATED( fg, replicate_fg ); 1943 1944 1945 /* We see if we can draw horizontal lines as 8x8 pattern fills. This is 1946 * worthwhile since the pattern fills can use block mode and the default X 1947 * pattern is 8 pixels long. The forward pattern is the top scanline, the 1948 * backwards pattern is the next one. 1949 */ 1950 switch(length) { 1951 case 2: NiceDashPattern |= NiceDashPattern << 2; 1952 case 4: NiceDashPattern |= NiceDashPattern << 4; 1953 case 8: { 1954 NiceDashPattern |= byte_reversed[NiceDashPattern] << 16; 1955 NiceDashPattern |= NiceDashPattern << 8; 1956 pMga->NiceDashCMD = MGADWG_TRAP | MGADWG_ARZERO | 1957 MGADWG_SGNZERO | MGADWG_BMONOLEF; 1958 pMga->AccelFlags |= NICE_DASH_PATTERN; 1959 1960 if( bg == -1 ) { 1961 if ( (pMga->CurrentLayout.bitsPerPixel == 24) && !RGBEQUAL(fg) ) { 1962 pMga->NiceDashCMD |= MGADWG_TRANSC | pMga->AtypeNoBLK[rop]; 1963 } 1964 else { 1965 pMga->NiceDashCMD |= MGADWG_TRANSC | pMga->Atype[rop]; 1966 } 1967 } 1968 else { 1969 /* (Packed) 24-bit is a funky mode. We only use the Atype table 1970 * in 24-bit if the components of the foreground color and the 1971 * components of the background color are the same (e.g., fg = 1972 * 0xf8f8f8 and bg = 0x131313). 1973 */ 1974 1975 if( ((pMga->AccelFlags & BLK_OPAQUE_EXPANSION) != 0) 1976 && ((pMga->CurrentLayout.bitsPerPixel != 24) 1977 || (RGBEQUAL(fg) && RGBEQUAL(bg))) ) { 1978 pMga->NiceDashCMD |= pMga->Atype[rop]; 1979 } 1980 else { 1981 pMga->NiceDashCMD |= pMga->AtypeNoBLK[rop]; 1982 } 1983 } 1984 OUTREG(MGAREG_SRC0, NiceDashPattern); 1985 break; 1986 } 1987 default: { 1988 pMga->AccelFlags &= ~NICE_DASH_PATTERN; 1989 switch (dwords) { 1990 case 4: OUTREG(MGAREG_SRC3, DashPattern[3]); 1991 case 3: OUTREG(MGAREG_SRC2, DashPattern[2]); 1992 case 2: OUTREG(MGAREG_SRC1, DashPattern[1]); 1993 default: OUTREG(MGAREG_SRC0, DashPattern[0]); 1994 } 1995 } 1996 } 1997} 1998 1999 2000void mgaSubsequentDashedTwoPointLine( ScrnInfoPtr pScrn, 2001 int x1, int y1, int x2, int y2, 2002 int flags, int phase ) 2003{ 2004 MGAPtr pMga = MGAPTR(pScrn); 2005 2006 WAITFIFO(4); 2007 if((pMga->AccelFlags & NICE_DASH_PATTERN) && (y1 == y2)) { 2008 OUTREG(MGAREG_DWGCTL, pMga->NiceDashCMD); 2009 if(x2 < x1) { 2010 if(flags & OMIT_LAST) x2++; 2011 OUTREG(MGAREG_SHIFT, ((-y1 & 0x07) << 4) | 2012 ((7 - phase - x1) & 0x07)); 2013 OUTREG(MGAREG_FXBNDRY, ((x1 + 1) << 16) | (x2 & 0xffff)); 2014 } else { 2015 if(!flags) x2++; 2016 OUTREG(MGAREG_SHIFT, (((1 - y1) & 0x07) << 4) | 2017 ((phase - x1) & 0x07)); 2018 OUTREG(MGAREG_FXBNDRY, (x2 << 16) | (x1 & 0xffff)); 2019 } 2020 OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (y1 << 16) | 1); 2021 } else { 2022 OUTREG(MGAREG_SHIFT, (pMga->StyleLen << 16 ) | 2023 (pMga->StyleLen - phase)); 2024 OUTREG(MGAREG_DWGCTL, pMga->DashCMD | ((flags & OMIT_LAST) ? 2025 MGADWG_AUTOLINE_OPEN : MGADWG_AUTOLINE_CLOSE)); 2026 OUTREG(MGAREG_XYSTRT, (y1 << 16) | (x1 & 0xFFFF)); 2027 OUTREG(MGAREG_XYEND + MGAREG_EXEC, (y2 << 16) | (x2 & 0xFFFF)); 2028 } 2029} 2030#endif /* X_BYTE_ORDER == X_LITTLE_ENDIAN */ 2031 2032 2033 /******************************************\ 2034 | Planar Screen to Screen Color Expansion | 2035 \******************************************/ 2036 2037void mgaSetupForPlanarScreenToScreenColorExpandFill( ScrnInfoPtr pScrn, 2038 int fg, int bg, 2039 int rop, 2040 unsigned int planemask ) 2041{ 2042 MGAPtr pMga = MGAPTR(pScrn); 2043 CARD32 mgaCMD = pMga->AtypeNoBLK[rop] | MGADWG_BITBLT | 2044 MGADWG_SGNZERO | MGADWG_BPLAN; 2045 CARD32 regs[2]; 2046 2047 2048 regs[0] = MGAREG_AR5; 2049 regs[1] = pScrn->displayWidth; 2050 2051 CHECK_DMA_QUIESCENT(pMga, pScrn); 2052 2053 (void) common_setup_for_pattern_fill( pMga, fg, bg, 0, planemask, regs, 1, 2054 mgaCMD ); 2055} 2056 2057 2058void mgaSubsequentPlanarScreenToScreenColorExpandFill( ScrnInfoPtr pScrn, 2059 int x, int y, int w, int h, 2060 int srcx, int srcy, 2061 int skipleft ) 2062{ 2063 MGAPtr pMga = MGAPTR(pScrn); 2064 int start, end; 2065 2066 w--; 2067 start = XYADDRESS(srcx, srcy) + skipleft; 2068 end = start + w; 2069 2070 WAITFIFO(4); 2071 OUTREG(MGAREG_AR3, start); 2072 OUTREG(MGAREG_AR0, end); 2073 OUTREG(MGAREG_FXBNDRY, ((x + w) << 16) | (x & 0xffff)); 2074 OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (y << 16) | h); 2075} 2076 2077 2078 /***********************************\ 2079 | Screen to Screen Color Expansion | 2080 \***********************************/ 2081 2082void mgaSetupForScreenToScreenColorExpandFill( ScrnInfoPtr pScrn, 2083 int fg, int bg, 2084 int rop, 2085 unsigned int planemask ) 2086{ 2087 MGAPtr pMga = MGAPTR(pScrn); 2088 CARD32 regs[2]; 2089 2090 regs[0] = MGAREG_AR5; 2091 regs[1] = pScrn->displayWidth * pMga->CurrentLayout.bitsPerPixel; 2092 2093 CHECK_DMA_QUIESCENT(pMga, pScrn); 2094 2095 (void) common_setup_for_pattern_fill( pMga, fg, bg, rop, planemask, 2096 regs, 1, 2097 MGADWG_BITBLT | MGADWG_SGNZERO 2098 | MGADWG_SHIFTZERO ); 2099} 2100 2101 2102void mgaSubsequentScreenToScreenColorExpandFill( ScrnInfoPtr pScrn, 2103 int x, int y, int w, int h, 2104 int srcx, int srcy, 2105 int skipleft ) 2106{ 2107 MGAPtr pMga = MGAPTR(pScrn); 2108 const unsigned int display_bit_width = 2109 (pMga->CurrentLayout.displayWidth * pMga->CurrentLayout.bitsPerPixel); 2110 int start, end, next, num; 2111 Bool resetDstOrg = FALSE; 2112 2113 if (pMga->AccelFlags & LARGE_ADDRESSES) { 2114 const int DstOrg = ((y & ~1023) * display_bit_width) >> 9; 2115 const int SrcOrg = ((srcy & ~1023) * display_bit_width) >> 9; 2116 2117 y &= 1023; 2118 srcy &= 1023; 2119 2120 WAITFIFO(2); 2121 if(DstOrg) { 2122 OUTREG(MGAREG_DSTORG, (DstOrg << 6) + pMga->DstOrg); 2123 resetDstOrg = TRUE; 2124 } 2125 if(SrcOrg != pMga->SrcOrg) { 2126 pMga->SrcOrg = SrcOrg; 2127 OUTREG(MGAREG_SRCORG, (SrcOrg << 6) + pMga->realSrcOrg); 2128 } 2129 } 2130 2131 w--; 2132 start = (XYADDRESS(srcx, srcy) * pMga->CurrentLayout.bitsPerPixel) 2133 + skipleft; 2134 end = start + w + (display_bit_width * (h - 1)); 2135 2136 /* src cannot split a 2 Meg boundary from SrcOrg */ 2137 if(!((start ^ end) & 0xff000000)) { 2138 WAITFIFO(4); 2139 OUTREG(MGAREG_AR3, start); 2140 OUTREG(MGAREG_AR0, start + w); 2141 OUTREG(MGAREG_FXBNDRY, ((x + w) << 16) | (x & 0xffff)); 2142 OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (y << 16) | h); 2143 } else { 2144 while(h) { 2145 next = (start + 0x00ffffff) & 0xff000000; 2146 if(next <= (start + w)) { 2147 num = next - start - 1; 2148 2149 WAITFIFO(7); 2150 OUTREG(MGAREG_AR3, start); 2151 OUTREG(MGAREG_AR0, start + num); 2152 OUTREG(MGAREG_FXBNDRY, ((x + num) << 16) | (x & 0xffff)); 2153 OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (y << 16) | 1); 2154 2155 OUTREG(MGAREG_AR3, next); 2156 OUTREG(MGAREG_AR0, start + w ); 2157 OUTREG(MGAREG_FXBNDRY + MGAREG_EXEC, ((x + w) << 16) | 2158 ((x + num + 1) & 0xffff)); 2159 start += display_bit_width; 2160 h--; y++; 2161 } else { 2162 num = ((next - start - w)/display_bit_width) + 1; 2163 if(num > h) num = h; 2164 2165 WAITFIFO(4); 2166 OUTREG(MGAREG_AR3, start); 2167 OUTREG(MGAREG_AR0, start + w); 2168 OUTREG(MGAREG_FXBNDRY, ((x + w) << 16) | (x & 0xffff)); 2169 OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (y << 16) | num); 2170 2171 start += num * display_bit_width; 2172 h -= num; y += num; 2173 } 2174 } 2175 } 2176 2177 if(resetDstOrg) { 2178 WAITFIFO(1); 2179 OUTREG(MGAREG_DSTORG, pMga->DstOrg); 2180 } 2181} 2182 2183 2184static void 2185MGAFillSolidRectsDMA( 2186 ScrnInfoPtr pScrn, 2187 int fg, int rop, 2188 unsigned int planemask, 2189 int nBox, /* number of rectangles to fill */ 2190 BoxPtr pBox /* Pointer to first rectangle to fill */ 2191){ 2192 MGAPtr pMga = MGAPTR(pScrn); 2193 XAAInfoRecPtr infoRec = pMga->AccelInfoRec; 2194 CARD32 *base = (CARD32*)pMga->ILOADBase; 2195 2196 CHECK_DMA_QUIESCENT(pMga, pScrn); 2197 2198 SET_SYNC_FLAG(infoRec); 2199 (*infoRec->SetupForSolidFill)(pScrn, fg, rop, planemask); 2200 2201 if(nBox & 1) { 2202 OUTREG(MGAREG_FXBNDRY, ((pBox->x2) << 16) | (pBox->x1 & 0xffff)); 2203 OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, 2204 (pBox->y1 << 16) | (pBox->y2 - pBox->y1)); 2205 nBox--; pBox++; 2206 } 2207 2208 if(!nBox) return; 2209 2210 OUTREG(MGAREG_OPMODE, MGAOPM_DMA_GENERAL); 2211 while(nBox) { 2212 base[0] = DMAINDICES(MGAREG_FXBNDRY, MGAREG_YDSTLEN + MGAREG_EXEC, 2213 MGAREG_FXBNDRY, MGAREG_YDSTLEN + MGAREG_EXEC); 2214 base[1] = ((pBox->x2) << 16) | (pBox->x1 & 0xffff); 2215 base[2] = (pBox->y1 << 16) | (pBox->y2 - pBox->y1); 2216 pBox++; 2217 base[3] = ((pBox->x2) << 16) | (pBox->x1 & 0xffff); 2218 base[4] = (pBox->y1 << 16) | (pBox->y2 - pBox->y1); 2219 pBox++; 2220 base += 5; nBox -= 2; 2221 } 2222 OUTREG(MGAREG_OPMODE, MGAOPM_DMA_BLIT); 2223} 2224 2225static void 2226MGAFillSolidSpansDMA( 2227 ScrnInfoPtr pScrn, 2228 int fg, int rop, 2229 unsigned int planemask, 2230 int n, 2231 DDXPointPtr ppt, 2232 int *pwidth, int fSorted 2233){ 2234 MGAPtr pMga = MGAPTR(pScrn); 2235 XAAInfoRecPtr infoRec = pMga->AccelInfoRec; 2236 CARD32 *base = (CARD32*)pMga->ILOADBase; 2237 2238 CHECK_DMA_QUIESCENT(pMga, pScrn); 2239 SET_SYNC_FLAG(infoRec); 2240 2241 if(infoRec->ClipBox) { 2242 OUTREG(MGAREG_CXBNDRY, 2243 ((infoRec->ClipBox->x2 - 1) << 16) | infoRec->ClipBox->x1); 2244 OUTREG(MGAREG_YTOP, 2245 (infoRec->ClipBox->y1 * pScrn->displayWidth) + pMga->YDstOrg); 2246 OUTREG(MGAREG_YBOT, 2247 ((infoRec->ClipBox->y2 - 1) * pScrn->displayWidth) + pMga->YDstOrg); 2248 } 2249 2250 (*infoRec->SetupForSolidFill)(pScrn, fg, rop, planemask); 2251 2252 if(n & 1) { 2253 OUTREG(MGAREG_FXBNDRY, ((ppt->x + *pwidth) << 16) | (ppt->x & 0xffff)); 2254 OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (ppt->y << 16) | 1); 2255 ppt++; pwidth++; n--; 2256 } 2257 2258 if(n) { 2259 if(n > 838860) n = 838860; /* maximum number we have room for */ 2260 2261 OUTREG(MGAREG_OPMODE, MGAOPM_DMA_GENERAL); 2262 while(n) { 2263 base[0] = DMAINDICES(MGAREG_FXBNDRY, MGAREG_YDSTLEN + MGAREG_EXEC, 2264 MGAREG_FXBNDRY, MGAREG_YDSTLEN + MGAREG_EXEC); 2265 base[1] = ((ppt->x + *(pwidth++)) << 16) | (ppt->x & 0xffff); 2266 base[2] = (ppt->y << 16) | 1; 2267 ppt++; 2268 base[3] = ((ppt->x + *(pwidth++)) << 16) | (ppt->x & 0xffff); 2269 base[4] = (ppt->y << 16) | 1; 2270 ppt++; 2271 base += 5; n -= 2; 2272 } 2273 OUTREG(MGAREG_OPMODE, MGAOPM_DMA_BLIT); 2274 } 2275 2276 if(infoRec->ClipBox) { 2277 OUTREG(MGAREG_CXBNDRY, 0xFFFF0000); /* (maxX << 16) | minX */ 2278 OUTREG(MGAREG_YTOP, 0x00000000); /* minPixelPointer */ 2279 OUTREG(MGAREG_YBOT, 0x007FFFFF); /* maxPixelPointer */ 2280 } 2281} 2282 2283 2284static void 2285MGAFillMono8x8PatternRectsTwoPass( 2286 ScrnInfoPtr pScrn, 2287 int fg, int bg, int rop, 2288 unsigned int planemask, 2289 int nBoxInit, 2290 BoxPtr pBoxInit, 2291 int pattern0, int pattern1, 2292 int xorg, int yorg 2293){ 2294 MGAPtr pMga = MGAPTR(pScrn); 2295 XAAInfoRecPtr infoRec = pMga->AccelInfoRec; 2296 int nBox, SecondPassColor; 2297 BoxPtr pBox; 2298 2299 CHECK_DMA_QUIESCENT(pMga, pScrn); 2300 2301 if((rop == GXcopy) && (bg != -1)) { 2302 SecondPassColor = bg; 2303 bg = -1; 2304 } else SecondPassColor = -1; 2305 2306 WAITFIFO(1); 2307 OUTREG(MGAREG_SHIFT, (((-yorg) & 0x07) << 4) | ((-xorg) & 0x07)); 2308 2309SECOND_PASS: 2310 2311 nBox = nBoxInit; 2312 pBox = pBoxInit; 2313 2314 (*infoRec->SetupForMono8x8PatternFill)(pScrn, pattern0, pattern1, 2315 fg, bg, rop, planemask); 2316 2317 while(nBox--) { 2318 WAITFIFO(2); 2319 OUTREG(MGAREG_FXBNDRY, ((pBox->x2) << 16) | (pBox->x1 & 0xffff)); 2320 OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, 2321 (pBox->y1 << 16) | (pBox->y2 - pBox->y1)); 2322 pBox++; 2323 } 2324 2325 if(SecondPassColor != -1) { 2326 fg = SecondPassColor; 2327 SecondPassColor = -1; 2328 pattern0 = ~pattern0; 2329 pattern1 = ~pattern1; 2330 goto SECOND_PASS; 2331 } 2332 2333 SET_SYNC_FLAG(infoRec); 2334} 2335 2336 2337static void 2338MGAValidatePolyArc( 2339 GCPtr pGC, 2340 unsigned long changes, 2341 DrawablePtr pDraw 2342){ 2343 ScrnInfoPtr pScrn = xf86Screens[pGC->pScreen->myNum]; 2344 MGAPtr pMga = MGAPTR(pScrn); 2345 Bool fullPlanemask = TRUE; 2346 2347 if((pGC->planemask & pMga->AccelInfoRec->FullPlanemask) != 2348 pMga->AccelInfoRec->FullPlanemask) 2349 { 2350 if(pMga->AccelFlags & MGA_NO_PLANEMASK) return; 2351 fullPlanemask = FALSE; 2352 } 2353 2354 if(!pGC->lineWidth && 2355 (pGC->fillStyle == FillSolid) && 2356 (pGC->lineStyle == LineSolid) && 2357 ((pGC->alu != GXcopy) || !fullPlanemask)) 2358 { 2359 pGC->ops->PolyArc = MGAPolyArcThinSolid; 2360 } 2361} 2362 2363static void 2364MGAPolyPoint ( 2365 DrawablePtr pDraw, 2366 GCPtr pGC, 2367 int mode, 2368 int npt, 2369 xPoint *ppt 2370){ 2371 int numRects = REGION_NUM_RECTS(pGC->pCompositeClip); 2372 XAAInfoRecPtr infoRec; 2373 BoxPtr pbox; 2374 MGAPtr pMga; 2375 int xorg, yorg; 2376 ScrnInfoPtr pScrn; 2377 2378 if(!numRects) return; 2379 2380 if(numRects != 1) { 2381 XAAGetFallbackOps()->PolyPoint(pDraw, pGC, mode, npt, ppt); 2382 return; 2383 } 2384 2385 infoRec = GET_XAAINFORECPTR_FROM_GC(pGC); 2386 pScrn = infoRec->pScrn; 2387 pMga = MGAPTR(pScrn); 2388 xorg = pDraw->x; 2389 yorg = pDraw->y; 2390 2391 pbox = REGION_RECTS(pGC->pCompositeClip); 2392 2393 (*infoRec->SetClippingRectangle)(infoRec->pScrn, 2394 pbox->x1, pbox->y1, pbox->x2 - 1, pbox->y2 - 1); 2395 (*infoRec->SetupForSolidFill)(infoRec->pScrn, pGC->fgPixel, pGC->alu, 2396 pGC->planemask); 2397 2398 if(mode == CoordModePrevious) { 2399 while(npt--) { 2400 xorg += ppt->x; 2401 yorg += ppt->y; 2402 WAITFIFO(2); 2403 OUTREG(MGAREG_FXBNDRY, ((xorg + 1) << 16) | (xorg & 0xffff)); 2404 OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (yorg << 16) | 1); 2405 ppt++; 2406 } 2407 } else { 2408 int x; 2409 while(npt--) { 2410 x = ppt->x + xorg; 2411 WAITFIFO(2); 2412 OUTREG(MGAREG_FXBNDRY, ((x + 1) << 16) | (x & 0xffff)); 2413 OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, ((ppt->y + yorg) << 16) | 1); 2414 ppt++; 2415 } 2416 } 2417 2418 (*infoRec->DisableClipping)(infoRec->pScrn); 2419 2420 SET_SYNC_FLAG(infoRec); 2421} 2422 2423 2424static void 2425MGAValidatePolyPoint( 2426 GCPtr pGC, 2427 unsigned long changes, 2428 DrawablePtr pDraw 2429){ 2430 ScrnInfoPtr pScrn = xf86Screens[pGC->pScreen->myNum]; 2431 MGAPtr pMga = MGAPTR(pScrn); 2432 Bool fullPlanemask = TRUE; 2433 2434 pGC->ops->PolyPoint = XAAGetFallbackOps()->PolyPoint; 2435 2436 if((pGC->planemask & pMga->AccelInfoRec->FullPlanemask) != 2437 pMga->AccelInfoRec->FullPlanemask) 2438 { 2439 if(pMga->AccelFlags & MGA_NO_PLANEMASK) return; 2440 fullPlanemask = FALSE; 2441 } 2442 2443 if((pGC->alu != GXcopy) || !fullPlanemask) 2444 pGC->ops->PolyPoint = MGAPolyPoint; 2445} 2446 2447 2448static void 2449MGAFillCacheBltRects( 2450 ScrnInfoPtr pScrn, 2451 int rop, 2452 unsigned int planemask, 2453 int nBox, 2454 BoxPtr pBox, 2455 int xorg, int yorg, 2456 XAACacheInfoPtr pCache 2457){ 2458 XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn); 2459 int x, y, phaseY, phaseX, skipleft, height, width, w, blit_w, blit_h, start; 2460 2461 CHECK_DMA_QUIESCENT(MGAPTR(pScrn), pScrn); 2462 2463 (*infoRec->SetupForScreenToScreenCopy)(pScrn, 1, 1, rop, planemask, 2464 pCache->trans_color); 2465 2466 while(nBox--) { 2467 y = pBox->y1; 2468 phaseY = (y - yorg) % pCache->orig_h; 2469 if(phaseY < 0) phaseY += pCache->orig_h; 2470 phaseX = (pBox->x1 - xorg) % pCache->orig_w; 2471 if(phaseX < 0) phaseX += pCache->orig_w; 2472 height = pBox->y2 - y; 2473 width = pBox->x2 - pBox->x1; 2474 start = phaseY ? (pCache->orig_h - phaseY) : 0; 2475 2476 /* This is optimized for WRAM */ 2477 2478 if ((rop == GXcopy) && (height >= (pCache->orig_h + start))) { 2479 w = width; skipleft = phaseX; x = pBox->x1; 2480 blit_h = pCache->orig_h; 2481 2482 while(1) { 2483 blit_w = pCache->w - skipleft; 2484 if(blit_w > w) blit_w = w; 2485 (*infoRec->SubsequentScreenToScreenCopy)(pScrn, 2486 pCache->x + skipleft, pCache->y, 2487 x, y + start, blit_w, blit_h); 2488 w -= blit_w; 2489 if(!w) break; 2490 x += blit_w; 2491 skipleft = (skipleft + blit_w) % pCache->orig_w; 2492 } 2493 height -= blit_h; 2494 2495 if(start) { 2496 (*infoRec->SubsequentScreenToScreenCopy)(pScrn, 2497 pBox->x1, y + blit_h, pBox->x1, y, width, start); 2498 height -= start; 2499 y += start; 2500 } 2501 start = blit_h; 2502 2503 while(height) { 2504 if(blit_h > height) blit_h = height; 2505 (*infoRec->SubsequentScreenToScreenCopy)(pScrn, 2506 pBox->x1, y, 2507 pBox->x1, y + start, width, blit_h); 2508 height -= blit_h; 2509 start += blit_h; 2510 blit_h <<= 1; 2511 } 2512 } else { 2513 while(1) { 2514 w = width; skipleft = phaseX; x = pBox->x1; 2515 blit_h = pCache->h - phaseY; 2516 if(blit_h > height) blit_h = height; 2517 2518 while(1) { 2519 blit_w = pCache->w - skipleft; 2520 if(blit_w > w) blit_w = w; 2521 (*infoRec->SubsequentScreenToScreenCopy)(pScrn, 2522 pCache->x + skipleft, pCache->y + phaseY, 2523 x, y, blit_w, blit_h); 2524 w -= blit_w; 2525 if(!w) break; 2526 x += blit_w; 2527 skipleft = (skipleft + blit_w) % pCache->orig_w; 2528 } 2529 height -= blit_h; 2530 if(!height) break; 2531 y += blit_h; 2532 phaseY = (phaseY + blit_h) % pCache->orig_h; 2533 } 2534 } 2535 pBox++; 2536 } 2537 2538 SET_SYNC_FLAG(infoRec); 2539} 2540