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