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