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