mga_storm.c revision eda3803b
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 pMga->SrcOrg = 0; 1134 OUTREG(MGAREG_SRCORG, pMga->realSrcOrg); 1135 OUTREG(MGAREG_DSTORG, pMga->DstOrg); 1136 break; 1137 default: 1138 break; 1139 } 1140 1141 if (pMga->is_G200WB) 1142 { 1143 CARD32 dwgctl = MGADWG_RSTR | 0x00060000 | MGADWG_SHIFTZERO | 1144 MGADWG_BITBLT | MGADWG_BFCOL; 1145 WAITFIFO(7); 1146 OUTREG(MGAREG_DWGCTL, dwgctl); 1147 OUTREG(MGAREG_SGN, 0); 1148 OUTREG(MGAREG_AR5, 1); 1149 OUTREG(MGAREG_AR0, 1); 1150 OUTREG(MGAREG_AR3, 0); 1151 OUTREG(MGAREG_FXBNDRY, (1 << 16) | (1 & 0xffff)); 1152 OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (1 << 16) | 1); 1153 } 1154 1155 xf86SetLastScrnFlag(pScrn->entityList[0], pScrn->scrnIndex); 1156} 1157 1158 1159static void 1160MGASetClippingRectangle( 1161 ScrnInfoPtr pScrn, 1162 int x1, int y1, int x2, int y2 1163){ 1164 MGAPtr pMga = MGAPTR(pScrn); 1165 1166 CHECK_DMA_QUIESCENT(pMga, pScrn); 1167 1168 WAITFIFO(3); 1169 OUTREG(MGAREG_CXBNDRY,(x2 << 16) | x1); 1170 OUTREG(MGAREG_YTOP, (y1 * pScrn->displayWidth) + pMga->YDstOrg); 1171 OUTREG(MGAREG_YBOT, (y2 * pScrn->displayWidth) + pMga->YDstOrg); 1172 pMga->AccelFlags |= CLIPPER_ON; 1173} 1174 1175static void 1176MGADisableClipping(ScrnInfoPtr pScrn) 1177{ 1178 MGAPtr pMga = MGAPTR(pScrn); 1179 1180 CHECK_DMA_QUIESCENT(pMga, pScrn); 1181 1182 WAITFIFO(3); 1183 OUTREG(MGAREG_CXBNDRY, 0xFFFF0000); /* (maxX << 16) | minX */ 1184 OUTREG(MGAREG_YTOP, 0x00000000); /* minPixelPointer */ 1185 OUTREG(MGAREG_YBOT, 0x007FFFFF); /* maxPixelPointer */ 1186 pMga->AccelFlags &= ~CLIPPER_ON; 1187} 1188 1189 1190static CARD32 1191common_setup_for_pattern_fill( MGAPtr pMga, int fg, int bg, int rop, 1192 int planemask, 1193 CARD32 * reg_data, unsigned int count, 1194 CARD32 cmd ) 1195{ 1196 unsigned int replicate_fg = 0; 1197 unsigned int replicate_bg = 0; 1198 unsigned int replicate_pm = 0; 1199 unsigned int i; 1200 1201 1202 common_replicate_colors_and_mask( fg, bg, planemask, 1203 pMga->CurrentLayout.bitsPerPixel, 1204 & replicate_fg, & replicate_bg, 1205 & replicate_pm ); 1206 1207 1208 if( bg == -1 ) { 1209 if ( (pMga->CurrentLayout.bitsPerPixel == 24) && !RGBEQUAL(fg) ) { 1210 cmd |= MGADWG_TRANSC | pMga->AtypeNoBLK[rop]; 1211 } 1212 else { 1213 cmd |= MGADWG_TRANSC | pMga->Atype[rop]; 1214 } 1215 1216 WAITFIFO( count + 3 ); 1217 } 1218 else { 1219 /* (Packed) 24-bit is a funky mode. We only use the Atype table in 1220 * 24-bit if the components of the foreground color and the components 1221 * of the background color are the same (e.g., fg = 0xf8f8f8 and bg = 1222 * 0x131313). 1223 */ 1224 1225 if( ((pMga->AccelFlags & BLK_OPAQUE_EXPANSION) != 0) 1226 && ((pMga->CurrentLayout.bitsPerPixel != 24) 1227 || (RGBEQUAL(fg) && RGBEQUAL(bg))) ) { 1228 cmd |= pMga->Atype[rop]; 1229 } 1230 else { 1231 cmd |= pMga->AtypeNoBLK[rop]; 1232 } 1233 1234 WAITFIFO( count + 4 ); 1235 SET_BACKGROUND_REPLICATED( bg, replicate_bg ); 1236 } 1237 1238 SET_FOREGROUND_REPLICATED( fg, replicate_fg ); 1239 SET_PLANEMASK_REPLICATED( planemask, replicate_pm, 1240 pMga->CurrentLayout.bitsPerPixel ); 1241 1242 /* FIXME: Is this the right order? */ 1243 1244 for ( i = 0 ; i < count ; i++ ) { 1245 OUTREG( reg_data[0], reg_data[1] ); 1246 reg_data += 2; 1247 } 1248 1249 OUTREG(MGAREG_DWGCTL, cmd); 1250 1251 return cmd; 1252} 1253 1254 1255 /*********************************************\ 1256 | Screen-to-Screen Copy | 1257 \*********************************************/ 1258 1259#define BLIT_LEFT 1 1260#define BLIT_UP 4 1261 1262void mgaDoSetupForScreenToScreenCopy( ScrnInfoPtr pScrn, int xdir, int ydir, 1263 int rop, unsigned int planemask, 1264 int trans, unsigned bpp ) 1265{ 1266 MGAPtr pMga = MGAPTR(pScrn); 1267 CARD32 dwgctl = pMga->AtypeNoBLK[rop] | MGADWG_SHIFTZERO | 1268 MGADWG_BITBLT | MGADWG_BFCOL; 1269 unsigned int tmp; 1270 unsigned int replicated_trans = 0; 1271 unsigned int replicated_mask = 0; 1272 1273 1274 CHECK_DMA_QUIESCENT(pMga, pScrn); 1275 1276 pMga->AccelInfoRec->SubsequentScreenToScreenCopy = 1277 mgaSubsequentScreenToScreenCopy; 1278 1279 pMga->BltScanDirection = 0; 1280 if(ydir == -1) pMga->BltScanDirection |= BLIT_UP; 1281 if(xdir == -1) 1282 pMga->BltScanDirection |= BLIT_LEFT; 1283 else if(pMga->HasFBitBlt && (rop == GXcopy) && !pMga->DrawTransparent) 1284 pMga->AccelInfoRec->SubsequentScreenToScreenCopy = 1285 mgaSubsequentScreenToScreenCopy_FastBlit; 1286 1287 1288 common_replicate_colors_and_mask( trans, 0, planemask, bpp, 1289 & replicated_trans, & tmp, 1290 & replicated_mask ); 1291 1292 if(pMga->DrawTransparent) { 1293 dwgctl |= MGADWG_TRANSC; 1294 WAITFIFO(2); 1295 1296 SET_FOREGROUND_REPLICATED( trans, replicated_trans ); 1297 SET_BACKGROUND_REPLICATED( ~0, ~0 ); 1298 } 1299 1300 WAITFIFO(4); 1301 OUTREG(MGAREG_DWGCTL, dwgctl); 1302 OUTREG(MGAREG_SGN, pMga->BltScanDirection); 1303 1304 SET_PLANEMASK_REPLICATED( planemask, replicated_mask, bpp ); 1305 OUTREG(MGAREG_AR5, ydir * pMga->CurrentLayout.displayWidth); 1306} 1307 1308 1309void mgaSetupForScreenToScreenCopy( ScrnInfoPtr pScrn, int xdir, int ydir, 1310 int rop, unsigned int planemask, 1311 int trans ) 1312{ 1313 MGAPtr pMga = MGAPTR(pScrn); 1314 1315 mgaDoSetupForScreenToScreenCopy( pScrn, xdir, ydir, rop, planemask, trans, 1316 pMga->CurrentLayout.bitsPerPixel ); 1317} 1318 1319 1320void mgaSubsequentScreenToScreenCopy( ScrnInfoPtr pScrn, 1321 int srcX, int srcY, int dstX, int dstY, 1322 int w, int h ) 1323{ 1324 int start, end, SrcOrg = 0, DstOrg = 0; 1325 MGAPtr pMga = MGAPTR(pScrn); 1326 1327 if (pMga->AccelFlags & LARGE_ADDRESSES) { 1328 const unsigned int display_bit_width = 1329 (pMga->CurrentLayout.displayWidth * pMga->CurrentLayout.bitsPerPixel); 1330 1331 SrcOrg = ((srcY & ~1023) * display_bit_width) >> 9; 1332 DstOrg = ((dstY & ~1023) * display_bit_width) >> 9; 1333 dstY &= 1023; 1334 } 1335 1336 if(pMga->BltScanDirection & BLIT_UP) { 1337 srcY += h - 1; 1338 dstY += h - 1; 1339 } 1340 1341 w--; 1342 start = end = XYADDRESS(srcX, srcY); 1343 1344 if(pMga->BltScanDirection & BLIT_LEFT) start += w; 1345 else end += w; 1346 1347 if (pMga->AccelFlags & LARGE_ADDRESSES) { 1348 WAITFIFO(7); 1349 if(DstOrg) 1350 OUTREG(MGAREG_DSTORG, (DstOrg << 6) + pMga->DstOrg); 1351 if(SrcOrg != pMga->SrcOrg) { 1352 pMga->SrcOrg = SrcOrg; 1353 OUTREG(MGAREG_SRCORG, (SrcOrg << 6) + pMga->realSrcOrg); 1354 } 1355 if(SrcOrg) { 1356 SrcOrg = (SrcOrg << 9) / pMga->CurrentLayout.bitsPerPixel; 1357 end -= SrcOrg; 1358 start -= SrcOrg; 1359 } 1360 OUTREG(MGAREG_AR0, end); 1361 OUTREG(MGAREG_AR3, start); 1362 OUTREG(MGAREG_FXBNDRY, ((dstX + w) << 16) | (dstX & 0xffff)); 1363 OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (dstY << 16) | h); 1364 if(DstOrg) 1365 OUTREG(MGAREG_DSTORG, pMga->DstOrg); 1366 } else { 1367 WAITFIFO(4); 1368 OUTREG(MGAREG_AR0, end); 1369 OUTREG(MGAREG_AR3, start); 1370 OUTREG(MGAREG_FXBNDRY, ((dstX + w) << 16) | (dstX & 0xffff)); 1371 OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (dstY << 16) | h); 1372 } 1373} 1374 1375 1376void mgaSubsequentScreenToScreenCopy_FastBlit( ScrnInfoPtr pScrn, 1377 int srcX, int srcY, 1378 int dstX, int dstY, 1379 int w, int h ) 1380{ 1381 int start, end; 1382 MGAPtr pMga = MGAPTR(pScrn); 1383 static const unsigned int masks[5] = { 1384 0, 0x07f, 0x03f, 0x7f, 0x1f 1385 }; 1386 1387 if(pMga->BltScanDirection & BLIT_UP) { 1388 srcY += h - 1; 1389 dstY += h - 1; 1390 } 1391 1392 w--; 1393 start = XYADDRESS(srcX, srcY); 1394 end = start + w; 1395 1396 /* we assume the driver asserts screen pitches such that 1397 we can always use fastblit for scrolling */ 1398 if(((srcX ^ dstX) & masks[ pMga->CurrentLayout.bitsPerPixel / 8 ]) == 0) { 1399 if(pMga->MaxFastBlitY) { 1400 if(pMga->BltScanDirection & BLIT_UP) { 1401 if((srcY >= pMga->MaxFastBlitY) || 1402 (dstY >= pMga->MaxFastBlitY)) 1403 goto FASTBLIT_BAILOUT; 1404 } else { 1405 if(((srcY + h) > pMga->MaxFastBlitY) || 1406 ((dstY + h) > pMga->MaxFastBlitY)) 1407 goto FASTBLIT_BAILOUT; 1408 } 1409 } 1410 1411 /* Millennium 1 fastblit bug fix */ 1412 if(pMga->AccelFlags & FASTBLT_BUG) { 1413 int fxright = dstX + w; 1414 int tmp_dstX = dstX; 1415 int tmp_fxright = fxright; 1416 static const unsigned shift_tab[5] = { 1417 0, 6, 5, 6, 4 1418 }; 1419 const unsigned shift = shift_tab[pMga->CurrentLayout.bitsPerPixel / 8]; 1420 1421 if (pMga->CurrentLayout.bitsPerPixel == 24) { 1422 tmp_dstX *= 3; 1423 tmp_fxright = fxright * 3 + 2; 1424 } 1425 1426 if( (tmp_dstX & (1 << shift)) 1427 && (((tmp_fxright >> shift) - (tmp_dstX >> shift)) & 7) == 7) { 1428 fxright = (tmp_fxright | (1 << shift)); 1429 if (pMga->CurrentLayout.bitsPerPixel == 24) { 1430 fxright /= 3; 1431 } 1432 1433 WAITFIFO(8); 1434 OUTREG(MGAREG_CXRIGHT, dstX + w); 1435 OUTREG(MGAREG_DWGCTL, 0x040A400C); 1436 OUTREG(MGAREG_AR0, end); 1437 OUTREG(MGAREG_AR3, start); 1438 OUTREG(MGAREG_FXBNDRY, (fxright << 16) | (dstX & 0xffff)); 1439 OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (dstY << 16) | h); 1440 OUTREG(MGAREG_DWGCTL, pMga->AtypeNoBLK[GXcopy] | 1441 MGADWG_SHIFTZERO | MGADWG_BITBLT | MGADWG_BFCOL); 1442 OUTREG(MGAREG_CXRIGHT, 0xFFFF); 1443 return; 1444 } 1445 } 1446 1447 WAITFIFO(6); 1448 OUTREG(MGAREG_DWGCTL, 0x040A400C); 1449 OUTREG(MGAREG_AR0, end); 1450 OUTREG(MGAREG_AR3, start); 1451 OUTREG(MGAREG_FXBNDRY, ((dstX + w) << 16) | (dstX & 0xffff)); 1452 OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (dstY << 16) | h); 1453 OUTREG(MGAREG_DWGCTL, pMga->AtypeNoBLK[GXcopy] | MGADWG_SHIFTZERO | 1454 MGADWG_BITBLT | MGADWG_BFCOL); 1455 return; 1456 } 1457 1458FASTBLIT_BAILOUT: 1459 1460 WAITFIFO(4); 1461 OUTREG(MGAREG_AR0, end); 1462 OUTREG(MGAREG_AR3, start); 1463 OUTREG(MGAREG_FXBNDRY, ((dstX + w) << 16) | (dstX & 0xffff)); 1464 OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (dstY << 16) | h); 1465} 1466 1467 /******************\ 1468 | Solid Fills | 1469 \******************/ 1470 1471void mgaDoSetupForSolidFill( ScrnInfoPtr pScrn, int color, int rop, 1472 unsigned int planemask, unsigned int bpp ) 1473{ 1474 MGAPtr pMga = MGAPTR(pScrn); 1475 unsigned int tmp; 1476 unsigned int replicated_color = 0; 1477 unsigned int replicated_planemask = 0; 1478 1479 common_replicate_colors_and_mask( color, 0, planemask, bpp, 1480 & replicated_color, & tmp, 1481 & replicated_planemask ); 1482 1483 CHECK_DMA_QUIESCENT(pMga, pScrn); 1484 1485 if ( (bpp == 24) && !RGBEQUAL(color) ) { 1486 pMga->FilledRectCMD = MGADWG_TRAP | MGADWG_SOLID | MGADWG_ARZERO | 1487 MGADWG_SGNZERO | MGADWG_SHIFTZERO | 1488 MGADWG_BMONOLEF | pMga->AtypeNoBLK[rop]; 1489 } 1490 else { 1491 pMga->FilledRectCMD = MGADWG_TRAP | MGADWG_SOLID | MGADWG_ARZERO | 1492 MGADWG_SGNZERO | MGADWG_SHIFTZERO | 1493 MGADWG_BMONOLEF | pMga->Atype[rop]; 1494 } 1495 1496 pMga->SolidLineCMD = MGADWG_SOLID | MGADWG_SHIFTZERO | MGADWG_BFCOL | 1497 pMga->AtypeNoBLK[rop]; 1498 1499 if(pMga->AccelFlags & TRANSC_SOLID_FILL) 1500 pMga->FilledRectCMD |= MGADWG_TRANSC; 1501 1502 WAITFIFO(3); 1503 if ( color != pMga->FgColor ) { 1504 pMga->FgColor = color; 1505 OUTREG( MGAREG_FCOL, replicated_color ); 1506 } 1507 1508 if ( (bpp != 24) 1509 && !(pMga->AccelFlags & MGA_NO_PLANEMASK) 1510 && (planemask != pMga->PlaneMask) ) { 1511 pMga->PlaneMask = planemask; 1512 OUTREG( MGAREG_PLNWT, replicated_planemask ); 1513 } 1514 1515 OUTREG(MGAREG_DWGCTL, pMga->FilledRectCMD); 1516} 1517 1518void mgaSetupForSolidFill( ScrnInfoPtr pScrn, int color, int rop, 1519 unsigned int planemask ) 1520{ 1521 MGAPtr pMga = MGAPTR(pScrn); 1522 1523 mgaDoSetupForSolidFill( pScrn, color, rop, planemask, 1524 pMga->CurrentLayout.bitsPerPixel ); 1525} 1526 1527void mgaSubsequentSolidFillRect( ScrnInfoPtr pScrn, 1528 int x, int y, int w, int h ) 1529{ 1530 MGAPtr pMga = MGAPTR(pScrn); 1531 1532 WAITFIFO(2); 1533 OUTREG(MGAREG_FXBNDRY, ((x + w) << 16) | (x & 0xffff)); 1534 OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (y << 16) | h); 1535} 1536 1537void mgaSubsequentSolidFillTrap( ScrnInfoPtr pScrn, int y, int h, 1538 int left, int dxL, int dyL, int eL, 1539 int right, int dxR, int dyR, int eR ) 1540{ 1541 MGAPtr pMga = MGAPTR(pScrn); 1542 int sdxl = (dxL < 0); 1543 int ar2 = sdxl? dxL : -dxL; 1544 int sdxr = (dxR < 0); 1545 int ar5 = sdxr? dxR : -dxR; 1546 1547 WAITFIFO(11); 1548 OUTREG(MGAREG_DWGCTL, 1549 pMga->FilledRectCMD & ~(MGADWG_ARZERO | MGADWG_SGNZERO)); 1550 OUTREG(MGAREG_AR0, dyL); 1551 OUTREG(MGAREG_AR1, ar2 - eL); 1552 OUTREG(MGAREG_AR2, ar2); 1553 OUTREG(MGAREG_AR4, ar5 - eR); 1554 OUTREG(MGAREG_AR5, ar5); 1555 OUTREG(MGAREG_AR6, dyR); 1556 OUTREG(MGAREG_SGN, (sdxl << 1) | (sdxr << 5)); 1557 OUTREG(MGAREG_FXBNDRY, ((right + 1) << 16) | (left & 0xffff)); 1558 OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (y << 16) | h); 1559 OUTREG(MGAREG_DWGCTL, pMga->FilledRectCMD); 1560} 1561 1562 1563 /***************\ 1564 | Solid Lines | 1565 \***************/ 1566 1567void mgaSubsequentSolidHorVertLine( ScrnInfoPtr pScrn, int x, int y, 1568 int len, int dir ) 1569{ 1570 MGAPtr pMga = MGAPTR(pScrn); 1571 1572 if(dir == DEGREES_0) { 1573 WAITFIFO(2); 1574 OUTREG(MGAREG_FXBNDRY, ((x + len) << 16) | (x & 0xffff)); 1575 OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (y << 16) | 1); 1576 } else if(pMga->AccelFlags & USE_RECTS_FOR_LINES) { 1577 WAITFIFO(2); 1578 OUTREG(MGAREG_FXBNDRY, ((x + 1) << 16) | (x & 0xffff)); 1579 OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (y << 16) | len); 1580 } else { 1581 WAITFIFO(4); 1582 OUTREG(MGAREG_DWGCTL, pMga->SolidLineCMD | MGADWG_AUTOLINE_OPEN); 1583 OUTREG(MGAREG_XYSTRT, (y << 16) | (x & 0xffff)); 1584 OUTREG(MGAREG_XYEND + MGAREG_EXEC, ((y + len) << 16) | (x & 0xffff)); 1585 OUTREG(MGAREG_DWGCTL, pMga->FilledRectCMD); 1586 } 1587} 1588 1589 1590void mgaSubsequentSolidTwoPointLine( ScrnInfoPtr pScrn, int x1, int y1, 1591 int x2, int y2, int flags ) 1592{ 1593 MGAPtr pMga = MGAPTR(pScrn); 1594 1595 WAITFIFO(4); 1596 OUTREG(MGAREG_DWGCTL, pMga->SolidLineCMD | 1597 ((flags & OMIT_LAST) ? MGADWG_AUTOLINE_OPEN : MGADWG_AUTOLINE_CLOSE)); 1598 OUTREG(MGAREG_XYSTRT, (y1 << 16) | (x1 & 0xFFFF)); 1599 OUTREG(MGAREG_XYEND + MGAREG_EXEC, (y2 << 16) | (x2 & 0xFFFF)); 1600 OUTREG(MGAREG_DWGCTL, pMga->FilledRectCMD); 1601} 1602 1603 1604 /***************************\ 1605 | 8x8 Mono Pattern Fills | 1606 \***************************/ 1607 1608 1609void mgaSetupForMono8x8PatternFill( ScrnInfoPtr pScrn, 1610 int patx, int paty, int fg, int bg, 1611 int rop, unsigned int planemask ) 1612{ 1613 MGAPtr pMga = MGAPTR(pScrn); 1614 XAAInfoRecPtr infoRec = pMga->AccelInfoRec; 1615 CARD32 regs[4]; 1616 1617 CHECK_DMA_QUIESCENT(pMga, pScrn); 1618 1619 infoRec->SubsequentMono8x8PatternFillRect = 1620 mgaSubsequentMono8x8PatternFillRect; 1621 1622 regs[0] = MGAREG_PAT0; 1623 regs[1] = patx; 1624 regs[2] = MGAREG_PAT1; 1625 regs[3] = paty; 1626 1627 pMga->PatternRectCMD = common_setup_for_pattern_fill( pMga, fg, bg, rop, 1628 planemask, regs, 2, 1629 (MGADWG_TRAP 1630 | MGADWG_ARZERO 1631 | MGADWG_SGNZERO 1632 | MGADWG_BMONOLEF) ); 1633} 1634 1635 1636void mgaSubsequentMono8x8PatternFillRect( ScrnInfoPtr pScrn, 1637 int patx, int paty, 1638 int x, int y, int w, int h ) 1639{ 1640 MGAPtr pMga = MGAPTR(pScrn); 1641 1642 WAITFIFO(3); 1643 OUTREG(MGAREG_SHIFT, (paty << 4) | patx); 1644 OUTREG(MGAREG_FXBNDRY, ((x + w) << 16) | (x & 0xffff)); 1645 OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (y << 16) | h); 1646 pMga->AccelInfoRec->SubsequentMono8x8PatternFillRect = 1647 mgaSubsequentMono8x8PatternFillRect_Additional; 1648} 1649 1650static void mgaSubsequentMono8x8PatternFillRect_Additional( ScrnInfoPtr pScrn, 1651 int patx, int paty, 1652 int x, int y, 1653 int w, int h ) 1654{ 1655 MGAPtr pMga = MGAPTR(pScrn); 1656 1657 WAITFIFO(2); 1658 OUTREG(MGAREG_FXBNDRY, ((x + w) << 16) | (x & 0xffff)); 1659 OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (y << 16) | h); 1660} 1661 1662 1663void mgaSubsequentMono8x8PatternFillTrap( ScrnInfoPtr pScrn, 1664 int patx, int paty, 1665 int y, int h, 1666 int left, int dxL, int dyL, int eL, 1667 int right, int dxR, int dyR, int eR ) 1668{ 1669 MGAPtr pMga = MGAPTR(pScrn); 1670 1671 int sdxl = (dxL < 0) ? (1<<1) : 0; 1672 int ar2 = sdxl? dxL : -dxL; 1673 int sdxr = (dxR < 0) ? (1<<5) : 0; 1674 int ar5 = sdxr? dxR : -dxR; 1675 1676 WAITFIFO(12); 1677 OUTREG(MGAREG_SHIFT, (paty << 4) | patx); 1678 OUTREG(MGAREG_DWGCTL, 1679 pMga->PatternRectCMD & ~(MGADWG_ARZERO | MGADWG_SGNZERO)); 1680 OUTREG(MGAREG_AR0, dyL); 1681 OUTREG(MGAREG_AR1, ar2 - eL); 1682 OUTREG(MGAREG_AR2, ar2); 1683 OUTREG(MGAREG_AR4, ar5 - eR); 1684 OUTREG(MGAREG_AR5, ar5); 1685 OUTREG(MGAREG_AR6, dyR); 1686 OUTREG(MGAREG_SGN, sdxl | sdxr); 1687 OUTREG(MGAREG_FXBNDRY, ((right + 1) << 16) | (left & 0xffff)); 1688 OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (y << 16) | h); 1689 OUTREG(MGAREG_DWGCTL, pMga->PatternRectCMD); 1690} 1691 1692 /***********************\ 1693 | Color Expand Rect | 1694 \***********************/ 1695 1696 1697void mgaSetupForScanlineCPUToScreenColorExpandFill( ScrnInfoPtr pScrn, 1698 int fg, int bg, 1699 int rop, 1700 unsigned int planemask ) 1701{ 1702 MGAPtr pMga = MGAPTR(pScrn); 1703 1704 1705 CHECK_DMA_QUIESCENT(pMga, pScrn); 1706 1707 (void) common_setup_for_pattern_fill( pMga, fg, bg, rop, 1708 planemask, NULL, 0, 1709 MGADWG_ILOAD | MGADWG_LINEAR 1710 | MGADWG_SGNZERO | MGADWG_SHIFTZERO 1711 | MGADWG_BMONOLEF ); 1712} 1713 1714 1715void mgaSubsequentScanlineCPUToScreenColorExpandFill( ScrnInfoPtr pScrn, 1716 int x, int y, int w, int h, 1717 int skipleft ) 1718{ 1719 MGAPtr pMga = MGAPTR(pScrn); 1720 1721 pMga->AccelFlags |= CLIPPER_ON; 1722 pMga->expandDWORDs = (w + 31) >> 5; 1723 if((pMga->expandDWORDs * h) > pMga->MaxBlitDWORDS) { 1724 pMga->expandHeight = pMga->MaxBlitDWORDS / pMga->expandDWORDs; 1725 pMga->expandRemaining = h / pMga->expandHeight; 1726 if(!(h = h % pMga->expandHeight)) { 1727 pMga->expandRemaining--; 1728 h = pMga->expandHeight; 1729 } 1730 pMga->expandY = y + h; 1731 } else 1732 pMga->expandRemaining = 0; 1733 pMga->expandRows = h; 1734 1735 WAITFIFO(5); 1736 OUTREG(MGAREG_CXBNDRY, ((x + w - 1) << 16) | ((x + skipleft) & 0xFFFF)); 1737 w = pMga->expandDWORDs << 5; /* source is dword padded */ 1738 OUTREG(MGAREG_AR0, (w * h) - 1); 1739 OUTREG(MGAREG_AR3, 0); /* crashes occasionally without this */ 1740 OUTREG(MGAREG_FXBNDRY, ((x + w - 1) << 16) | (x & 0xFFFF)); 1741 OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (y << 16) | h); 1742 1743#if defined(__alpha__) 1744 if(1) /* force indirect always on Alpha */ 1745#else 1746 if(pMga->expandDWORDs > pMga->FifoSize) 1747#endif 1748 { 1749 pMga->AccelInfoRec->SubsequentColorExpandScanline = 1750 mgaSubsequentColorExpandScanlineIndirect; 1751 pMga->AccelInfoRec->ScanlineColorExpandBuffers = 1752 (unsigned char**)(&pMga->ScratchBuffer); 1753 } else { 1754 pMga->AccelInfoRec->SubsequentColorExpandScanline = 1755 mgaSubsequentColorExpandScanline; 1756 pMga->AccelInfoRec->ScanlineColorExpandBuffers = 1757 (unsigned char**)(&pMga->ColorExpandBase); 1758 WAITFIFO(pMga->expandDWORDs); 1759 } 1760} 1761 1762 1763void mgaSubsequentColorExpandScanlineIndirect( ScrnInfoPtr pScrn, 1764 int bufno ) 1765{ 1766 MGAPtr pMga = MGAPTR(pScrn); 1767 int dwords = pMga->expandDWORDs; 1768 CARD32 *src = (CARD32*)(pMga->ScratchBuffer); 1769 1770 while(dwords > pMga->FifoSize) { 1771 WAITFIFO(pMga->FifoSize); 1772 MGAMoveDWORDS((CARD32*)(pMga->ColorExpandBase), src, pMga->FifoSize); 1773 src += pMga->FifoSize; 1774 dwords -= pMga->FifoSize; 1775 } 1776 1777 WAITFIFO(dwords); 1778 MGAMoveDWORDS((CARD32*)(pMga->ColorExpandBase), src, dwords); 1779 1780 if(!(--pMga->expandRows)) { 1781 if(pMga->expandRemaining) { 1782 WAITFIFO(3); 1783 OUTREG(MGAREG_AR0,((pMga->expandDWORDs<< 5)*pMga->expandHeight)-1); 1784 OUTREG(MGAREG_AR3, 0); /* crashes occasionally without this */ 1785 OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (pMga->expandY << 16) | 1786 pMga->expandHeight); 1787 pMga->expandY += pMga->expandHeight; 1788 pMga->expandRows = pMga->expandHeight; 1789 pMga->expandRemaining--; 1790 } else { 1791 DISABLE_CLIP(); 1792 } 1793 } 1794} 1795 1796 1797void mgaSubsequentColorExpandScanline( ScrnInfoPtr pScrn, 1798 int bufno ) 1799{ 1800 MGAPtr pMga = MGAPTR(pScrn); 1801 1802 if(--pMga->expandRows) { 1803 WAITFIFO(pMga->expandDWORDs); 1804 } else if(pMga->expandRemaining) { 1805 WAITFIFO(3); 1806 OUTREG(MGAREG_AR0,((pMga->expandDWORDs<<5)*pMga->expandHeight)-1); 1807 OUTREG(MGAREG_AR3, 0); /* crashes occasionally without this */ 1808 OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (pMga->expandY << 16) | 1809 pMga->expandHeight); 1810 pMga->expandY += pMga->expandHeight; 1811 pMga->expandRows = pMga->expandHeight; 1812 pMga->expandRemaining--; 1813 WAITFIFO(pMga->expandDWORDs); 1814 } else { 1815 DISABLE_CLIP(); 1816 } 1817} 1818 1819 1820 /*******************\ 1821 | Image Writes | 1822 \*******************/ 1823 1824 1825void mgaSetupForScanlineImageWrite( ScrnInfoPtr pScrn, int rop, 1826 unsigned int planemask, 1827 int transparency_color, 1828 int bpp, int depth ) 1829{ 1830 MGAPtr pMga = MGAPTR(pScrn); 1831 unsigned int replicate_pm = 0; 1832 1833 switch( pMga->CurrentLayout.bitsPerPixel ) { 1834 case 8: 1835 replicate_pm = REPLICATE_8( planemask ); 1836 break; 1837 case 16: 1838 replicate_pm = REPLICATE_16( planemask ); 1839 break; 1840 case 24: 1841 replicate_pm = REPLICATE_24( planemask ); 1842 break; 1843 case 32: 1844 replicate_pm = REPLICATE_32( planemask ); 1845 break; 1846 } 1847 1848 CHECK_DMA_QUIESCENT(pMga, pScrn); 1849 1850 WAITFIFO(3); 1851 OUTREG(MGAREG_AR5, 0); 1852 SET_PLANEMASK_REPLICATED( planemask, replicate_pm, 1853 pMga->CurrentLayout.bitsPerPixel ); 1854 OUTREG(MGAREG_DWGCTL, MGADWG_ILOAD | MGADWG_BFCOL | MGADWG_SHIFTZERO | 1855 MGADWG_SGNZERO | pMga->AtypeNoBLK[rop]); 1856} 1857 1858 1859void mgaSubsequentScanlineImageWriteRect( ScrnInfoPtr pScrn, 1860 int x, int y, int w, int h, 1861 int skipleft ) 1862{ 1863 MGAPtr pMga = MGAPTR(pScrn); 1864 1865 pMga->AccelFlags |= CLIPPER_ON; 1866 pMga->expandRows = h; 1867 pMga->expandDWORDs = ((w * pMga->CurrentLayout.bitsPerPixel) + 31) >> 5; 1868 1869 WAITFIFO(5); 1870 OUTREG(MGAREG_CXBNDRY, 0xFFFF0000 | ((x + skipleft) & 0xFFFF)); 1871 OUTREG(MGAREG_AR0, w - 1); 1872 OUTREG(MGAREG_AR3, 0); 1873 OUTREG(MGAREG_FXBNDRY, ((x + w - 1) << 16) | (x & 0xFFFF)); 1874 OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (y << 16) | h); 1875} 1876 1877 1878void mgaSubsequentImageWriteScanline( ScrnInfoPtr pScrn, int bufno ) 1879{ 1880 MGAPtr pMga = MGAPTR(pScrn); 1881 int dwords = pMga->expandDWORDs; 1882 CARD32 *src = (CARD32*)(pMga->ScratchBuffer); 1883 1884 while(dwords > pMga->FifoSize) { 1885 WAITFIFO(pMga->FifoSize); 1886 MGAMoveDWORDS((CARD32*)(pMga->ColorExpandBase), src, pMga->FifoSize); 1887 src += pMga->FifoSize; 1888 dwords -= pMga->FifoSize; 1889 } 1890 1891 WAITFIFO(dwords); 1892 MGAMoveDWORDS((CARD32*)(pMga->ColorExpandBase), src, dwords); 1893 1894 if(!(--pMga->expandRows)) { 1895 DISABLE_CLIP(); 1896 } 1897} 1898 1899 1900#if X_BYTE_ORDER == X_LITTLE_ENDIAN 1901 1902 /***************************\ 1903 | Dashed Lines | 1904 \***************************/ 1905 1906void mgaSetupForDashedLine( ScrnInfoPtr pScrn, 1907 int fg, int bg, int rop, 1908 unsigned int planemask, int length, 1909 unsigned char *pattern ) 1910{ 1911 MGAPtr pMga = MGAPTR(pScrn); 1912 CARD32 *DashPattern = (CARD32*)pattern; 1913 CARD32 NiceDashPattern = DashPattern[0]; 1914 int dwords = (length + 31) >> 5; 1915 unsigned int replicate_fg = 0; 1916 unsigned int replicate_bg = 0; 1917 unsigned int replicate_pm = 0; 1918 1919 1920 common_replicate_colors_and_mask( fg, bg, planemask, 1921 pMga->CurrentLayout.bitsPerPixel, 1922 & replicate_fg, & replicate_bg, 1923 & replicate_pm ); 1924 1925 CHECK_DMA_QUIESCENT(pMga, pScrn); 1926 1927 pMga->DashCMD = MGADWG_BFCOL | pMga->AtypeNoBLK[rop]; 1928 pMga->StyleLen = length - 1; 1929 1930 if(bg == -1) { 1931 pMga->DashCMD |= MGADWG_TRANSC; 1932 WAITFIFO(dwords + 2); 1933 } else { 1934 WAITFIFO(dwords + 3); 1935 SET_BACKGROUND_REPLICATED( bg, replicate_bg ); 1936 } 1937 1938 SET_PLANEMASK_REPLICATED( planemask, replicate_pm, 1939 pMga->CurrentLayout.bitsPerPixel ); 1940 SET_FOREGROUND_REPLICATED( fg, replicate_fg ); 1941 1942 1943 /* We see if we can draw horizontal lines as 8x8 pattern fills. This is 1944 * worthwhile since the pattern fills can use block mode and the default X 1945 * pattern is 8 pixels long. The forward pattern is the top scanline, the 1946 * backwards pattern is the next one. 1947 */ 1948 switch(length) { 1949 case 2: NiceDashPattern |= NiceDashPattern << 2; 1950 case 4: NiceDashPattern |= NiceDashPattern << 4; 1951 case 8: { 1952 NiceDashPattern |= byte_reversed[NiceDashPattern] << 16; 1953 NiceDashPattern |= NiceDashPattern << 8; 1954 pMga->NiceDashCMD = MGADWG_TRAP | MGADWG_ARZERO | 1955 MGADWG_SGNZERO | MGADWG_BMONOLEF; 1956 pMga->AccelFlags |= NICE_DASH_PATTERN; 1957 1958 if( bg == -1 ) { 1959 if ( (pMga->CurrentLayout.bitsPerPixel == 24) && !RGBEQUAL(fg) ) { 1960 pMga->NiceDashCMD |= MGADWG_TRANSC | pMga->AtypeNoBLK[rop]; 1961 } 1962 else { 1963 pMga->NiceDashCMD |= MGADWG_TRANSC | pMga->Atype[rop]; 1964 } 1965 } 1966 else { 1967 /* (Packed) 24-bit is a funky mode. We only use the Atype table 1968 * in 24-bit if the components of the foreground color and the 1969 * components of the background color are the same (e.g., fg = 1970 * 0xf8f8f8 and bg = 0x131313). 1971 */ 1972 1973 if( ((pMga->AccelFlags & BLK_OPAQUE_EXPANSION) != 0) 1974 && ((pMga->CurrentLayout.bitsPerPixel != 24) 1975 || (RGBEQUAL(fg) && RGBEQUAL(bg))) ) { 1976 pMga->NiceDashCMD |= pMga->Atype[rop]; 1977 } 1978 else { 1979 pMga->NiceDashCMD |= pMga->AtypeNoBLK[rop]; 1980 } 1981 } 1982 OUTREG(MGAREG_SRC0, NiceDashPattern); 1983 break; 1984 } 1985 default: { 1986 pMga->AccelFlags &= ~NICE_DASH_PATTERN; 1987 switch (dwords) { 1988 case 4: OUTREG(MGAREG_SRC3, DashPattern[3]); 1989 case 3: OUTREG(MGAREG_SRC2, DashPattern[2]); 1990 case 2: OUTREG(MGAREG_SRC1, DashPattern[1]); 1991 default: OUTREG(MGAREG_SRC0, DashPattern[0]); 1992 } 1993 } 1994 } 1995} 1996 1997 1998void mgaSubsequentDashedTwoPointLine( ScrnInfoPtr pScrn, 1999 int x1, int y1, int x2, int y2, 2000 int flags, int phase ) 2001{ 2002 MGAPtr pMga = MGAPTR(pScrn); 2003 2004 WAITFIFO(4); 2005 if((pMga->AccelFlags & NICE_DASH_PATTERN) && (y1 == y2)) { 2006 OUTREG(MGAREG_DWGCTL, pMga->NiceDashCMD); 2007 if(x2 < x1) { 2008 if(flags & OMIT_LAST) x2++; 2009 OUTREG(MGAREG_SHIFT, ((-y1 & 0x07) << 4) | 2010 ((7 - phase - x1) & 0x07)); 2011 OUTREG(MGAREG_FXBNDRY, ((x1 + 1) << 16) | (x2 & 0xffff)); 2012 } else { 2013 if(!flags) x2++; 2014 OUTREG(MGAREG_SHIFT, (((1 - y1) & 0x07) << 4) | 2015 ((phase - x1) & 0x07)); 2016 OUTREG(MGAREG_FXBNDRY, (x2 << 16) | (x1 & 0xffff)); 2017 } 2018 OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (y1 << 16) | 1); 2019 } else { 2020 OUTREG(MGAREG_SHIFT, (pMga->StyleLen << 16 ) | 2021 (pMga->StyleLen - phase)); 2022 OUTREG(MGAREG_DWGCTL, pMga->DashCMD | ((flags & OMIT_LAST) ? 2023 MGADWG_AUTOLINE_OPEN : MGADWG_AUTOLINE_CLOSE)); 2024 OUTREG(MGAREG_XYSTRT, (y1 << 16) | (x1 & 0xFFFF)); 2025 OUTREG(MGAREG_XYEND + MGAREG_EXEC, (y2 << 16) | (x2 & 0xFFFF)); 2026 } 2027} 2028#endif /* X_BYTE_ORDER == X_LITTLE_ENDIAN */ 2029 2030 2031 /******************************************\ 2032 | Planar Screen to Screen Color Expansion | 2033 \******************************************/ 2034 2035void mgaSetupForPlanarScreenToScreenColorExpandFill( ScrnInfoPtr pScrn, 2036 int fg, int bg, 2037 int rop, 2038 unsigned int planemask ) 2039{ 2040 MGAPtr pMga = MGAPTR(pScrn); 2041 CARD32 mgaCMD = pMga->AtypeNoBLK[rop] | MGADWG_BITBLT | 2042 MGADWG_SGNZERO | MGADWG_BPLAN; 2043 CARD32 regs[2]; 2044 2045 2046 regs[0] = MGAREG_AR5; 2047 regs[1] = pScrn->displayWidth; 2048 2049 CHECK_DMA_QUIESCENT(pMga, pScrn); 2050 2051 (void) common_setup_for_pattern_fill( pMga, fg, bg, 0, planemask, regs, 1, 2052 mgaCMD ); 2053} 2054 2055 2056void mgaSubsequentPlanarScreenToScreenColorExpandFill( ScrnInfoPtr pScrn, 2057 int x, int y, int w, int h, 2058 int srcx, int srcy, 2059 int skipleft ) 2060{ 2061 MGAPtr pMga = MGAPTR(pScrn); 2062 int start, end; 2063 2064 w--; 2065 start = XYADDRESS(srcx, srcy) + skipleft; 2066 end = start + w; 2067 2068 WAITFIFO(4); 2069 OUTREG(MGAREG_AR3, start); 2070 OUTREG(MGAREG_AR0, end); 2071 OUTREG(MGAREG_FXBNDRY, ((x + w) << 16) | (x & 0xffff)); 2072 OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (y << 16) | h); 2073} 2074 2075 2076 /***********************************\ 2077 | Screen to Screen Color Expansion | 2078 \***********************************/ 2079 2080void mgaSetupForScreenToScreenColorExpandFill( ScrnInfoPtr pScrn, 2081 int fg, int bg, 2082 int rop, 2083 unsigned int planemask ) 2084{ 2085 MGAPtr pMga = MGAPTR(pScrn); 2086 CARD32 regs[2]; 2087 2088 regs[0] = MGAREG_AR5; 2089 regs[1] = pScrn->displayWidth * pMga->CurrentLayout.bitsPerPixel; 2090 2091 CHECK_DMA_QUIESCENT(pMga, pScrn); 2092 2093 (void) common_setup_for_pattern_fill( pMga, fg, bg, rop, planemask, 2094 regs, 1, 2095 MGADWG_BITBLT | MGADWG_SGNZERO 2096 | MGADWG_SHIFTZERO ); 2097} 2098 2099 2100void mgaSubsequentScreenToScreenColorExpandFill( ScrnInfoPtr pScrn, 2101 int x, int y, int w, int h, 2102 int srcx, int srcy, 2103 int skipleft ) 2104{ 2105 MGAPtr pMga = MGAPTR(pScrn); 2106 const unsigned int display_bit_width = 2107 (pMga->CurrentLayout.displayWidth * pMga->CurrentLayout.bitsPerPixel); 2108 int start, end, next, num; 2109 Bool resetDstOrg = FALSE; 2110 2111 if (pMga->AccelFlags & LARGE_ADDRESSES) { 2112 const int DstOrg = ((y & ~1023) * display_bit_width) >> 9; 2113 const int SrcOrg = ((srcy & ~1023) * display_bit_width) >> 9; 2114 2115 y &= 1023; 2116 srcy &= 1023; 2117 2118 WAITFIFO(2); 2119 if(DstOrg) { 2120 OUTREG(MGAREG_DSTORG, (DstOrg << 6) + pMga->DstOrg); 2121 resetDstOrg = TRUE; 2122 } 2123 if(SrcOrg != pMga->SrcOrg) { 2124 pMga->SrcOrg = SrcOrg; 2125 OUTREG(MGAREG_SRCORG, (SrcOrg << 6) + pMga->realSrcOrg); 2126 } 2127 } 2128 2129 w--; 2130 start = (XYADDRESS(srcx, srcy) * pMga->CurrentLayout.bitsPerPixel) 2131 + skipleft; 2132 end = start + w + (display_bit_width * (h - 1)); 2133 2134 /* src cannot split a 2 Meg boundary from SrcOrg */ 2135 if(!((start ^ end) & 0xff000000)) { 2136 WAITFIFO(4); 2137 OUTREG(MGAREG_AR3, start); 2138 OUTREG(MGAREG_AR0, start + w); 2139 OUTREG(MGAREG_FXBNDRY, ((x + w) << 16) | (x & 0xffff)); 2140 OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (y << 16) | h); 2141 } else { 2142 while(h) { 2143 next = (start + 0x00ffffff) & 0xff000000; 2144 if(next <= (start + w)) { 2145 num = next - start - 1; 2146 2147 WAITFIFO(7); 2148 OUTREG(MGAREG_AR3, start); 2149 OUTREG(MGAREG_AR0, start + num); 2150 OUTREG(MGAREG_FXBNDRY, ((x + num) << 16) | (x & 0xffff)); 2151 OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (y << 16) | 1); 2152 2153 OUTREG(MGAREG_AR3, next); 2154 OUTREG(MGAREG_AR0, start + w ); 2155 OUTREG(MGAREG_FXBNDRY + MGAREG_EXEC, ((x + w) << 16) | 2156 ((x + num + 1) & 0xffff)); 2157 start += display_bit_width; 2158 h--; y++; 2159 } else { 2160 num = ((next - start - w)/display_bit_width) + 1; 2161 if(num > h) num = h; 2162 2163 WAITFIFO(4); 2164 OUTREG(MGAREG_AR3, start); 2165 OUTREG(MGAREG_AR0, start + w); 2166 OUTREG(MGAREG_FXBNDRY, ((x + w) << 16) | (x & 0xffff)); 2167 OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (y << 16) | num); 2168 2169 start += num * display_bit_width; 2170 h -= num; y += num; 2171 } 2172 } 2173 } 2174 2175 if(resetDstOrg) { 2176 WAITFIFO(1); 2177 OUTREG(MGAREG_DSTORG, pMga->DstOrg); 2178 } 2179} 2180 2181 2182static void 2183MGAFillSolidRectsDMA( 2184 ScrnInfoPtr pScrn, 2185 int fg, int rop, 2186 unsigned int planemask, 2187 int nBox, /* number of rectangles to fill */ 2188 BoxPtr pBox /* Pointer to first rectangle to fill */ 2189){ 2190 MGAPtr pMga = MGAPTR(pScrn); 2191 XAAInfoRecPtr infoRec = pMga->AccelInfoRec; 2192 CARD32 *base = (CARD32*)pMga->ILOADBase; 2193 2194 CHECK_DMA_QUIESCENT(pMga, pScrn); 2195 2196 SET_SYNC_FLAG(infoRec); 2197 (*infoRec->SetupForSolidFill)(pScrn, fg, rop, planemask); 2198 2199 if(nBox & 1) { 2200 OUTREG(MGAREG_FXBNDRY, ((pBox->x2) << 16) | (pBox->x1 & 0xffff)); 2201 OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, 2202 (pBox->y1 << 16) | (pBox->y2 - pBox->y1)); 2203 nBox--; pBox++; 2204 } 2205 2206 if(!nBox) return; 2207 2208 OUTREG(MGAREG_OPMODE, MGAOPM_DMA_GENERAL); 2209 while(nBox) { 2210 base[0] = DMAINDICES(MGAREG_FXBNDRY, MGAREG_YDSTLEN + MGAREG_EXEC, 2211 MGAREG_FXBNDRY, MGAREG_YDSTLEN + MGAREG_EXEC); 2212 base[1] = ((pBox->x2) << 16) | (pBox->x1 & 0xffff); 2213 base[2] = (pBox->y1 << 16) | (pBox->y2 - pBox->y1); 2214 pBox++; 2215 base[3] = ((pBox->x2) << 16) | (pBox->x1 & 0xffff); 2216 base[4] = (pBox->y1 << 16) | (pBox->y2 - pBox->y1); 2217 pBox++; 2218 base += 5; nBox -= 2; 2219 } 2220 OUTREG(MGAREG_OPMODE, MGAOPM_DMA_BLIT); 2221} 2222 2223static void 2224MGAFillSolidSpansDMA( 2225 ScrnInfoPtr pScrn, 2226 int fg, int rop, 2227 unsigned int planemask, 2228 int n, 2229 DDXPointPtr ppt, 2230 int *pwidth, int fSorted 2231){ 2232 MGAPtr pMga = MGAPTR(pScrn); 2233 XAAInfoRecPtr infoRec = pMga->AccelInfoRec; 2234 CARD32 *base = (CARD32*)pMga->ILOADBase; 2235 2236 CHECK_DMA_QUIESCENT(pMga, pScrn); 2237 SET_SYNC_FLAG(infoRec); 2238 2239 if(infoRec->ClipBox) { 2240 OUTREG(MGAREG_CXBNDRY, 2241 ((infoRec->ClipBox->x2 - 1) << 16) | infoRec->ClipBox->x1); 2242 OUTREG(MGAREG_YTOP, 2243 (infoRec->ClipBox->y1 * pScrn->displayWidth) + pMga->YDstOrg); 2244 OUTREG(MGAREG_YBOT, 2245 ((infoRec->ClipBox->y2 - 1) * pScrn->displayWidth) + pMga->YDstOrg); 2246 } 2247 2248 (*infoRec->SetupForSolidFill)(pScrn, fg, rop, planemask); 2249 2250 if(n & 1) { 2251 OUTREG(MGAREG_FXBNDRY, ((ppt->x + *pwidth) << 16) | (ppt->x & 0xffff)); 2252 OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (ppt->y << 16) | 1); 2253 ppt++; pwidth++; n--; 2254 } 2255 2256 if(n) { 2257 if(n > 838860) n = 838860; /* maximum number we have room for */ 2258 2259 OUTREG(MGAREG_OPMODE, MGAOPM_DMA_GENERAL); 2260 while(n) { 2261 base[0] = DMAINDICES(MGAREG_FXBNDRY, MGAREG_YDSTLEN + MGAREG_EXEC, 2262 MGAREG_FXBNDRY, MGAREG_YDSTLEN + MGAREG_EXEC); 2263 base[1] = ((ppt->x + *(pwidth++)) << 16) | (ppt->x & 0xffff); 2264 base[2] = (ppt->y << 16) | 1; 2265 ppt++; 2266 base[3] = ((ppt->x + *(pwidth++)) << 16) | (ppt->x & 0xffff); 2267 base[4] = (ppt->y << 16) | 1; 2268 ppt++; 2269 base += 5; n -= 2; 2270 } 2271 OUTREG(MGAREG_OPMODE, MGAOPM_DMA_BLIT); 2272 } 2273 2274 if(infoRec->ClipBox) { 2275 OUTREG(MGAREG_CXBNDRY, 0xFFFF0000); /* (maxX << 16) | minX */ 2276 OUTREG(MGAREG_YTOP, 0x00000000); /* minPixelPointer */ 2277 OUTREG(MGAREG_YBOT, 0x007FFFFF); /* maxPixelPointer */ 2278 } 2279} 2280 2281 2282static void 2283MGAFillMono8x8PatternRectsTwoPass( 2284 ScrnInfoPtr pScrn, 2285 int fg, int bg, int rop, 2286 unsigned int planemask, 2287 int nBoxInit, 2288 BoxPtr pBoxInit, 2289 int pattern0, int pattern1, 2290 int xorg, int yorg 2291){ 2292 MGAPtr pMga = MGAPTR(pScrn); 2293 XAAInfoRecPtr infoRec = pMga->AccelInfoRec; 2294 int nBox, SecondPassColor; 2295 BoxPtr pBox; 2296 2297 CHECK_DMA_QUIESCENT(pMga, pScrn); 2298 2299 if((rop == GXcopy) && (bg != -1)) { 2300 SecondPassColor = bg; 2301 bg = -1; 2302 } else SecondPassColor = -1; 2303 2304 WAITFIFO(1); 2305 OUTREG(MGAREG_SHIFT, (((-yorg) & 0x07) << 4) | ((-xorg) & 0x07)); 2306 2307SECOND_PASS: 2308 2309 nBox = nBoxInit; 2310 pBox = pBoxInit; 2311 2312 (*infoRec->SetupForMono8x8PatternFill)(pScrn, pattern0, pattern1, 2313 fg, bg, rop, planemask); 2314 2315 while(nBox--) { 2316 WAITFIFO(2); 2317 OUTREG(MGAREG_FXBNDRY, ((pBox->x2) << 16) | (pBox->x1 & 0xffff)); 2318 OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, 2319 (pBox->y1 << 16) | (pBox->y2 - pBox->y1)); 2320 pBox++; 2321 } 2322 2323 if(SecondPassColor != -1) { 2324 fg = SecondPassColor; 2325 SecondPassColor = -1; 2326 pattern0 = ~pattern0; 2327 pattern1 = ~pattern1; 2328 goto SECOND_PASS; 2329 } 2330 2331 SET_SYNC_FLAG(infoRec); 2332} 2333 2334 2335static void 2336MGAValidatePolyArc( 2337 GCPtr pGC, 2338 unsigned long changes, 2339 DrawablePtr pDraw 2340){ 2341 ScrnInfoPtr pScrn = xf86Screens[pGC->pScreen->myNum]; 2342 MGAPtr pMga = MGAPTR(pScrn); 2343 Bool fullPlanemask = TRUE; 2344 2345 if((pGC->planemask & pMga->AccelInfoRec->FullPlanemask) != 2346 pMga->AccelInfoRec->FullPlanemask) 2347 { 2348 if(pMga->AccelFlags & MGA_NO_PLANEMASK) return; 2349 fullPlanemask = FALSE; 2350 } 2351 2352 if(!pGC->lineWidth && 2353 (pGC->fillStyle == FillSolid) && 2354 (pGC->lineStyle == LineSolid) && 2355 ((pGC->alu != GXcopy) || !fullPlanemask)) 2356 { 2357 pGC->ops->PolyArc = MGAPolyArcThinSolid; 2358 } 2359} 2360 2361static void 2362MGAPolyPoint ( 2363 DrawablePtr pDraw, 2364 GCPtr pGC, 2365 int mode, 2366 int npt, 2367 xPoint *ppt 2368){ 2369 int numRects = REGION_NUM_RECTS(pGC->pCompositeClip); 2370 XAAInfoRecPtr infoRec; 2371 BoxPtr pbox; 2372 MGAPtr pMga; 2373 int xorg, yorg; 2374 ScrnInfoPtr pScrn; 2375 2376 if(!numRects) return; 2377 2378 if(numRects != 1) { 2379 XAAGetFallbackOps()->PolyPoint(pDraw, pGC, mode, npt, ppt); 2380 return; 2381 } 2382 2383 infoRec = GET_XAAINFORECPTR_FROM_GC(pGC); 2384 pScrn = infoRec->pScrn; 2385 pMga = MGAPTR(pScrn); 2386 xorg = pDraw->x; 2387 yorg = pDraw->y; 2388 2389 pbox = REGION_RECTS(pGC->pCompositeClip); 2390 2391 (*infoRec->SetClippingRectangle)(infoRec->pScrn, 2392 pbox->x1, pbox->y1, pbox->x2 - 1, pbox->y2 - 1); 2393 (*infoRec->SetupForSolidFill)(infoRec->pScrn, pGC->fgPixel, pGC->alu, 2394 pGC->planemask); 2395 2396 if(mode == CoordModePrevious) { 2397 while(npt--) { 2398 xorg += ppt->x; 2399 yorg += ppt->y; 2400 WAITFIFO(2); 2401 OUTREG(MGAREG_FXBNDRY, ((xorg + 1) << 16) | (xorg & 0xffff)); 2402 OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (yorg << 16) | 1); 2403 ppt++; 2404 } 2405 } else { 2406 int x; 2407 while(npt--) { 2408 x = ppt->x + xorg; 2409 WAITFIFO(2); 2410 OUTREG(MGAREG_FXBNDRY, ((x + 1) << 16) | (x & 0xffff)); 2411 OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, ((ppt->y + yorg) << 16) | 1); 2412 ppt++; 2413 } 2414 } 2415 2416 (*infoRec->DisableClipping)(infoRec->pScrn); 2417 2418 SET_SYNC_FLAG(infoRec); 2419} 2420 2421 2422static void 2423MGAValidatePolyPoint( 2424 GCPtr pGC, 2425 unsigned long changes, 2426 DrawablePtr pDraw 2427){ 2428 ScrnInfoPtr pScrn = xf86Screens[pGC->pScreen->myNum]; 2429 MGAPtr pMga = MGAPTR(pScrn); 2430 Bool fullPlanemask = TRUE; 2431 2432 pGC->ops->PolyPoint = XAAGetFallbackOps()->PolyPoint; 2433 2434 if((pGC->planemask & pMga->AccelInfoRec->FullPlanemask) != 2435 pMga->AccelInfoRec->FullPlanemask) 2436 { 2437 if(pMga->AccelFlags & MGA_NO_PLANEMASK) return; 2438 fullPlanemask = FALSE; 2439 } 2440 2441 if((pGC->alu != GXcopy) || !fullPlanemask) 2442 pGC->ops->PolyPoint = MGAPolyPoint; 2443} 2444 2445 2446static void 2447MGAFillCacheBltRects( 2448 ScrnInfoPtr pScrn, 2449 int rop, 2450 unsigned int planemask, 2451 int nBox, 2452 BoxPtr pBox, 2453 int xorg, int yorg, 2454 XAACacheInfoPtr pCache 2455){ 2456 XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn); 2457 int x, y, phaseY, phaseX, skipleft, height, width, w, blit_w, blit_h, start; 2458 2459 CHECK_DMA_QUIESCENT(MGAPTR(pScrn), pScrn); 2460 2461 (*infoRec->SetupForScreenToScreenCopy)(pScrn, 1, 1, rop, planemask, 2462 pCache->trans_color); 2463 2464 while(nBox--) { 2465 y = pBox->y1; 2466 phaseY = (y - yorg) % pCache->orig_h; 2467 if(phaseY < 0) phaseY += pCache->orig_h; 2468 phaseX = (pBox->x1 - xorg) % pCache->orig_w; 2469 if(phaseX < 0) phaseX += pCache->orig_w; 2470 height = pBox->y2 - y; 2471 width = pBox->x2 - pBox->x1; 2472 start = phaseY ? (pCache->orig_h - phaseY) : 0; 2473 2474 /* This is optimized for WRAM */ 2475 2476 if ((rop == GXcopy) && (height >= (pCache->orig_h + start))) { 2477 w = width; skipleft = phaseX; x = pBox->x1; 2478 blit_h = pCache->orig_h; 2479 2480 while(1) { 2481 blit_w = pCache->w - skipleft; 2482 if(blit_w > w) blit_w = w; 2483 (*infoRec->SubsequentScreenToScreenCopy)(pScrn, 2484 pCache->x + skipleft, pCache->y, 2485 x, y + start, blit_w, blit_h); 2486 w -= blit_w; 2487 if(!w) break; 2488 x += blit_w; 2489 skipleft = (skipleft + blit_w) % pCache->orig_w; 2490 } 2491 height -= blit_h; 2492 2493 if(start) { 2494 (*infoRec->SubsequentScreenToScreenCopy)(pScrn, 2495 pBox->x1, y + blit_h, pBox->x1, y, width, start); 2496 height -= start; 2497 y += start; 2498 } 2499 start = blit_h; 2500 2501 while(height) { 2502 if(blit_h > height) blit_h = height; 2503 (*infoRec->SubsequentScreenToScreenCopy)(pScrn, 2504 pBox->x1, y, 2505 pBox->x1, y + start, width, blit_h); 2506 height -= blit_h; 2507 start += blit_h; 2508 blit_h <<= 1; 2509 } 2510 } else { 2511 while(1) { 2512 w = width; skipleft = phaseX; x = pBox->x1; 2513 blit_h = pCache->h - phaseY; 2514 if(blit_h > height) blit_h = height; 2515 2516 while(1) { 2517 blit_w = pCache->w - skipleft; 2518 if(blit_w > w) blit_w = w; 2519 (*infoRec->SubsequentScreenToScreenCopy)(pScrn, 2520 pCache->x + skipleft, pCache->y + phaseY, 2521 x, y, blit_w, blit_h); 2522 w -= blit_w; 2523 if(!w) break; 2524 x += blit_w; 2525 skipleft = (skipleft + blit_w) % pCache->orig_w; 2526 } 2527 height -= blit_h; 2528 if(!height) break; 2529 y += blit_h; 2530 phaseY = (phaseY + blit_h) % pCache->orig_h; 2531 } 2532 } 2533 pBox++; 2534 } 2535 2536 SET_SYNC_FLAG(infoRec); 2537} 2538