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