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