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