tdfx_accel.c revision 02be438a
1/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_accel.c,v 1.19 2001/04/05 21:29:17 dawes Exp $ */ 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#include "compiler.h" 11 12/* Drivers that need to access the PCI config space directly need this */ 13#include "xf86Pci.h" 14 15/* Drivers for PCI hardware need this */ 16#include "xf86PciInfo.h" 17 18/* Drivers that use XAA need this */ 19#include "xaa.h" 20#include "xaalocal.h" 21#include "xf86fbman.h" 22 23#include "miline.h" 24 25#include "tdfx.h" 26 27#ifdef TDFX_DEBUG_CMDS 28static int cmdCnt=0; 29static int lastAddr=0; 30#endif 31 32static int TDFXROPCvt[] = {0x00, 0x88, 0x44, 0xCC, 0x22, 0xAA, 0x66, 0xEE, 33 0x11, 0x99, 0x55, 0xDD, 0x33, 0xBB, 0x77, 0xFF, 34 0x00, 0xA0, 0x50, 0xF0, 0x0A, 0xAA, 0x5A, 0xFA, 35 0x05, 0xA5, 0x55, 0xF5, 0x0F, 0xAF, 0x5F, 0xFF}; 36#define ROP_PATTERN_OFFSET 16 37 38static void TDFXSetClippingRectangle(ScrnInfoPtr pScrn, int left, int top, 39 int right, int bottom); 40static void TDFXDisableClipping(ScrnInfoPtr pScrn); 41static void TDFXSetupForMono8x8PatternFill(ScrnInfoPtr pScrn, int patx, 42 int paty, int fg, int bg, int rop, 43 unsigned int planemask); 44static void TDFXSubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, int patx, 45 int pay, int x, int y, 46 int w, int h); 47static void TDFXSetupForSolidLine(ScrnInfoPtr pScrn, int color, int rop, 48 unsigned int planemask); 49static void TDFXSubsequentSolidTwoPointLine(ScrnInfoPtr pScrn, int srcx, 50 int srcy, int dstx, int dsty, 51 int flags); 52static void TDFXSubsequentSolidHorVertLine(ScrnInfoPtr pScrn, int x, int y, 53 int len, int dir); 54static void TDFXNonTEGlyphRenderer(ScrnInfoPtr pScrn, int x, int y, int n, 55 NonTEGlyphPtr glyphs, BoxPtr pbox, int fg, 56 int rop, unsigned int planemask); 57static void TDFXSetupForDashedLine(ScrnInfoPtr pScrn, int fg, int bg, int rop, 58 unsigned int planemask, int length, 59 unsigned char *pattern); 60static void TDFXSubsequentDashedTwoPointLine(ScrnInfoPtr pScrn, int x1, int y1, 61 int x2, int y2, int flags, 62 int phase); 63#ifdef ENABLE_SS_COLOR_EXPAND_FILL 64static void TDFXSetupForScreenToScreenColorExpandFill(ScrnInfoPtr pScrn, 65 int fg, int bg, int rop, 66 unsigned int planemask); 67static void TDFXSubsequentScreenToScreenColorExpandFill(ScrnInfoPtr pScrn, 68 int x, int y, int w, 69 int h, int srcx, 70 int srcy, int offset); 71#endif 72static void TDFXSetupForCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, 73 int fg, int bg, int rop, 74 unsigned int planemask); 75static void TDFXSubsequentCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, 76 int x, int y, 77 int w, int h, 78 int skipleft); 79static void TDFXSubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno); 80 81void 82TDFXNeedSync(ScrnInfoPtr pScrn) { 83 TDFXPtr pTDFX = TDFXPTR(pScrn); 84 pTDFX->syncDone=FALSE; 85 pTDFX->AccelInfoRec->NeedToSync = TRUE; 86} 87 88void 89TDFXFirstSync(ScrnInfoPtr pScrn) { 90 TDFXPtr pTDFX = TDFXPTR(pScrn); 91 92 if (!pTDFX->syncDone) { 93#ifdef XF86DRI 94 if (pTDFX->directRenderingEnabled) { 95 DRILock(screenInfo.screens[pScrn->scrnIndex], 0); 96 TDFXSwapContextFifo(screenInfo.screens[pScrn->scrnIndex]); 97 } 98#endif 99 pTDFX->syncDone=TRUE; 100 pTDFX->sync(pScrn); 101 } 102} 103 104void 105TDFXCheckSync(ScrnInfoPtr pScrn) { 106 TDFXPtr pTDFX = TDFXPTR(pScrn); 107 108 if (pTDFX->syncDone) { 109 pTDFX->sync(pScrn); 110 pTDFX->syncDone=FALSE; 111#ifdef XF86DRI 112 if (pTDFX->directRenderingEnabled) { 113 DRIUnlock(screenInfo.screens[pScrn->scrnIndex]); 114 } 115#endif 116 } 117} 118 119void 120TDFXSelectBuffer(TDFXPtr pTDFX, int which) { 121 int fmt; 122 123 TDFXMakeRoom(pTDFX, 4); 124 DECLARE(SSTCP_SRCBASEADDR|SSTCP_DSTBASEADDR|SSTCP_SRCFORMAT|SSTCP_DSTFORMAT); 125 switch (which) { 126 case TDFX_FRONT: 127 if (pTDFX->cpp==1) fmt=pTDFX->stride|(1<<16); 128 else fmt=pTDFX->stride|((pTDFX->cpp+1)<<16); 129 TDFXWriteLong(pTDFX, SST_2D_DSTBASEADDR, pTDFX->fbOffset); 130 TDFXWriteLong(pTDFX, SST_2D_DSTFORMAT, fmt); 131 pTDFX->sst2DDstFmtShadow = fmt; 132 TDFXWriteLong(pTDFX, SST_2D_SRCBASEADDR, pTDFX->fbOffset); 133 TDFXWriteLong(pTDFX, SST_2D_SRCFORMAT, fmt); 134 pTDFX->sst2DSrcFmtShadow = fmt; 135 break; 136 case TDFX_BACK: 137 if (pTDFX->cpp==2) 138 fmt=((pTDFX->stride+127)/128)|(3<<16); /* Tiled 16bpp */ 139 else 140 fmt=((pTDFX->stride+127)/128)|(5<<16); /* Tiled 32bpp */ 141 TDFXWriteLong(pTDFX, SST_2D_DSTBASEADDR, pTDFX->backOffset|BIT(31)); 142 TDFXWriteLong(pTDFX, SST_2D_DSTFORMAT, fmt); 143 pTDFX->sst2DDstFmtShadow = fmt; 144 TDFXWriteLong(pTDFX, SST_2D_SRCBASEADDR, pTDFX->backOffset|BIT(31)); 145 TDFXWriteLong(pTDFX, SST_2D_SRCFORMAT, fmt); 146 pTDFX->sst2DSrcFmtShadow = fmt; 147 break; 148 case TDFX_DEPTH: 149 if (pTDFX->cpp==2) 150 fmt=((pTDFX->stride+127)/128)|(3<<16); /* Tiled 16bpp */ 151 else 152 fmt=((pTDFX->stride+127)/128)|(5<<16); /* Tiled 32bpp */ 153 TDFXWriteLong(pTDFX, SST_2D_DSTBASEADDR, pTDFX->depthOffset|BIT(31)); 154 TDFXWriteLong(pTDFX, SST_2D_DSTFORMAT, fmt); 155 pTDFX->sst2DDstFmtShadow = fmt; 156 TDFXWriteLong(pTDFX, SST_2D_SRCBASEADDR, pTDFX->depthOffset|BIT(31)); 157 TDFXWriteLong(pTDFX, SST_2D_SRCFORMAT, fmt); 158 pTDFX->sst2DSrcFmtShadow = fmt; 159 break; 160 default: 161 ; 162 } 163} 164 165void 166TDFXSetLFBConfig(TDFXPtr pTDFX) { 167 if (pTDFX->ChipType<=PCI_CHIP_VOODOO3) { 168#if X_BYTE_ORDER == X_BIG_ENDIAN 169 unsigned int lfbmode; 170 lfbmode=TDFXReadLongMMIO(pTDFX, SST_3D_LFBMODE); 171 172 lfbmode&=~BIT(12); /* 0 bit 12 is byte swizzle */ 173 lfbmode|=BIT(11); /* 1 bit 11 is word swizzle */ 174 lfbmode&=~BIT(10); /* 0 bit 10 ARGB or ABGR */ 175 lfbmode&=~BIT(9); /* 0 bit 9 if bit10 = 0: ARGB else ABGR */ 176 177 TDFXWriteLongMMIO(pTDFX, SST_3D_LFBMODE, lfbmode); 178#endif 179 TDFXWriteLongMMIO(pTDFX, LFBMEMORYCONFIG, (pTDFX->backOffset>>12) | 180 SST_RAW_LFB_ADDR_STRIDE_4K | 181 ((pTDFX->stride+127)/128)<<SST_RAW_LFB_TILE_STRIDE_SHIFT); 182 } else { 183 int chip; 184 int stride, bits; 185 int TileAperturePitch, lg2TileAperturePitch; 186 if (pTDFX->cpp==2) stride=pTDFX->stride; 187 else stride=4*pTDFX->stride/pTDFX->cpp; 188 bits=pTDFX->backOffset>>12; 189 for (lg2TileAperturePitch = 0, TileAperturePitch = 1024; 190 (lg2TileAperturePitch < 5) && 191 TileAperturePitch < stride; 192 lg2TileAperturePitch += 1, TileAperturePitch <<= 1); 193#if 0 194 fprintf(stderr, "Using %d (== lg2(%d)-10) for tile aperture pitch\n", 195 lg2TileAperturePitch, TileAperturePitch); 196 fprintf(stderr, "stride == %d\n", stride); 197#endif 198 for (chip=0; chip<pTDFX->numChips; chip++) { 199 TDFXWriteChipLongMMIO(pTDFX, chip, LFBMEMORYCONFIG, (bits&0x1FFF) | 200 SST_RAW_LFB_ADDR_STRIDE(lg2TileAperturePitch) | 201 ((bits&0x6000)<<10) | 202 ((stride+127)/128)<<SST_RAW_LFB_TILE_STRIDE_SHIFT); 203 } 204 } 205} 206 207Bool 208TDFXAccelInit(ScreenPtr pScreen) 209{ 210 XAAInfoRecPtr infoPtr; 211 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 212 TDFXPtr pTDFX = TDFXPTR(pScrn); 213 CARD32 commonFlags; 214 215 pTDFX->AccelInfoRec = infoPtr = XAACreateInfoRec(); 216 if (!infoPtr) return FALSE; 217 218 infoPtr->Flags = PIXMAP_CACHE | OFFSCREEN_PIXMAPS | LINEAR_FRAMEBUFFER; 219 220 infoPtr->Sync = pTDFX->sync; 221 222 infoPtr->SetClippingRectangle = TDFXSetClippingRectangle; 223 infoPtr->DisableClipping = TDFXDisableClipping; 224 infoPtr->ClippingFlags = HARDWARE_CLIP_SCREEN_TO_SCREEN_COLOR_EXPAND | 225 HARDWARE_CLIP_SCREEN_TO_SCREEN_COPY | 226 HARDWARE_CLIP_MONO_8x8_FILL | 227 HARDWARE_CLIP_COLOR_8x8_FILL | 228 HARDWARE_CLIP_SOLID_FILL | 229 HARDWARE_CLIP_DASHED_LINE | 230 HARDWARE_CLIP_SOLID_LINE; 231 232 miSetZeroLineBias(pScreen, OCTANT2 | OCTANT5 | OCTANT7 | OCTANT8); 233 234 commonFlags = BIT_ORDER_IN_BYTE_MSBFIRST | NO_PLANEMASK; 235 236 infoPtr->SetupForSolidFill = TDFXSetupForSolidFill; 237 infoPtr->SubsequentSolidFillRect = TDFXSubsequentSolidFillRect; 238 infoPtr->SolidFillFlags = commonFlags; 239 240 infoPtr->SetupForSolidLine = TDFXSetupForSolidLine; 241 infoPtr->SubsequentSolidTwoPointLine = TDFXSubsequentSolidTwoPointLine; 242 infoPtr->SubsequentSolidHorVertLine = TDFXSubsequentSolidHorVertLine; 243 infoPtr->SolidLineFlags = commonFlags; 244 245 infoPtr->SetupForDashedLine = TDFXSetupForDashedLine; 246 infoPtr->SubsequentDashedTwoPointLine = TDFXSubsequentDashedTwoPointLine; 247 infoPtr->DashedLineFlags = commonFlags | LINE_PATTERN_LSBFIRST_LSBJUSTIFIED; 248 infoPtr->DashPatternMaxLength = 32; 249 250 infoPtr->NonTEGlyphRenderer = TDFXNonTEGlyphRenderer; 251 infoPtr->NonTEGlyphRendererFlags = commonFlags; 252 253 infoPtr->SetupForScreenToScreenCopy = TDFXSetupForScreenToScreenCopy; 254 infoPtr->SubsequentScreenToScreenCopy = TDFXSubsequentScreenToScreenCopy; 255 infoPtr->ScreenToScreenCopyFlags = commonFlags; 256 257 /* When we're using the fifo we have to use indirect expansion */ 258 pTDFX->scanlineColorExpandBuffers[0] = xalloc((pScrn->virtualX+62)/32*4); 259 pTDFX->scanlineColorExpandBuffers[1] = xalloc((pScrn->virtualX+62)/32*4); 260 infoPtr->NumScanlineColorExpandBuffers=2; 261 infoPtr->ScanlineColorExpandBuffers=pTDFX->scanlineColorExpandBuffers; 262 infoPtr->SetupForScanlineCPUToScreenColorExpandFill = 263 TDFXSetupForCPUToScreenColorExpandFill; 264 infoPtr->SubsequentScanlineCPUToScreenColorExpandFill = 265 TDFXSubsequentCPUToScreenColorExpandFill; 266 infoPtr->SubsequentColorExpandScanline = 267 TDFXSubsequentColorExpandScanline; 268 infoPtr->ScanlineCPUToScreenColorExpandFillFlags = NO_PLANEMASK | 269#if X_BYTE_ORDER == X_LITTLE_ENDIAN 270 BIT_ORDER_IN_BYTE_MSBFIRST | 271#endif 272 CPU_TRANSFER_PAD_DWORD | SCANLINE_PAD_DWORD | 273 LEFT_EDGE_CLIPPING; /* | LEFT_EDGE_CLIPPING_NEGATIVE_X; */ 274 275 infoPtr->SetupForMono8x8PatternFill = TDFXSetupForMono8x8PatternFill; 276 infoPtr->SubsequentMono8x8PatternFillRect = 277 TDFXSubsequentMono8x8PatternFillRect; 278 infoPtr->Mono8x8PatternFillFlags = commonFlags | 279 HARDWARE_PATTERN_PROGRAMMED_BITS | 280 HARDWARE_PATTERN_PROGRAMMED_ORIGIN | 281 HARDWARE_PATTERN_SCREEN_ORIGIN; 282 283#ifdef ENABLE_SS_COLOR_EXPAND_FILL 284 /* This causes us to fail compliance */ 285 /* I suspect 1bpp pixmaps are getting written to cache incorrectly */ 286 infoPtr->SetupForScreenToScreenColorExpandFill = 287 TDFXSetupForScreenToScreenColorExpandFill; 288 infoPtr->SubsequentScreenToScreenColorExpandFill = 289 TDFXSubsequentScreenToScreenColorExpandFill; 290 infoPtr->ScreenToScreenColorExpandFillFlags = commonFlags; 291#endif 292 293 pTDFX->PciCnt=TDFXReadLongMMIO(pTDFX, 0)&0x1F; 294 pTDFX->PrevDrawState=pTDFX->DrawState=0; 295 296 pTDFX->ModeReg.srcbaseaddr=pTDFX->fbOffset; 297 TDFXWriteLongMMIO(pTDFX, SST_2D_SRCBASEADDR, pTDFX->ModeReg.srcbaseaddr); 298 pTDFX->ModeReg.dstbaseaddr=pTDFX->fbOffset; 299 TDFXWriteLongMMIO(pTDFX, SST_2D_DSTBASEADDR, pTDFX->ModeReg.dstbaseaddr); 300 301 pTDFX->sst2DSrcFmtShadow = TDFXReadLongMMIO(pTDFX, SST_2D_SRCFORMAT); 302 pTDFX->sst2DDstFmtShadow = TDFXReadLongMMIO(pTDFX, SST_2D_DSTFORMAT); 303 304 /* Fill in acceleration functions */ 305 return XAAInit(pScreen, infoPtr); 306} 307 308static void TDFXMakeRoomNoProp(TDFXPtr pTDFX, int size) { 309 int stat; 310 311 pTDFX->PciCnt-=size; 312 if (pTDFX->PciCnt<1) { 313 do { 314 stat=TDFXReadLongMMIO(pTDFX, 0); 315 pTDFX->PciCnt=stat&0x1F; 316 } while (pTDFX->PciCnt<size); 317 } 318} 319 320static void TDFXSendNOPNoProp(ScrnInfoPtr pScrn) 321{ 322 TDFXPtr pTDFX; 323 324 pTDFX=TDFXPTR(pScrn); 325 TDFXMakeRoomNoProp(pTDFX, 1); 326 TDFXWriteLongMMIO(pTDFX, SST_2D_COMMAND, SST_2D_NOP); 327} 328 329void TDFXSync(ScrnInfoPtr pScrn) 330{ 331 TDFXPtr pTDFX; 332 int i; 333 int stat; 334 335 TDFXTRACEACCEL("TDFXSync\n"); 336 pTDFX=TDFXPTR(pScrn); 337 338 TDFXSendNOPNoProp(pScrn); 339 i=0; 340 do { 341 stat=TDFXReadLongMMIO(pTDFX, 0); 342 if (stat&SST_BUSY) i=0; else i++; 343 } while (i<3); 344 pTDFX->PciCnt=stat&0x1F; 345} 346 347static void 348TDFXMatchState(TDFXPtr pTDFX) 349{ 350 if (pTDFX->PrevDrawState==pTDFX->DrawState) return; 351 352 /* Do we need to set a clipping rectangle? */ 353 if (pTDFX->DrawState&DRAW_STATE_CLIPPING) 354 pTDFX->Cmd |= SST_2D_USECLIP1; 355 else 356 pTDFX->Cmd &= ~SST_2D_USECLIP1; 357 358 /* Do we need to set transparency? */ 359 TDFXMakeRoom(pTDFX, 1); 360 DECLARE(SSTCP_COMMANDEXTRA); 361 if (pTDFX->DrawState&DRAW_STATE_TRANSPARENT) { 362 TDFXWriteLong(pTDFX, SST_2D_COMMANDEXTRA, SST_2D_SRC_COLORKEY_EX); 363 } else { 364 TDFXWriteLong(pTDFX, SST_2D_COMMANDEXTRA, 0); 365 } 366 367 /* Has the previous routine left clip1 changed? Reset it. */ 368 if (pTDFX->DrawState&DRAW_STATE_CLIP1CHANGED) { 369 TDFXMakeRoom(pTDFX, 2); 370 DECLARE(SSTCP_CLIP1MIN|SSTCP_CLIP1MAX); 371 TDFXWriteLong(pTDFX, SST_2D_CLIP1MIN, pTDFX->ModeReg.clip1min); 372 TDFXWriteLong(pTDFX, SST_2D_CLIP1MAX, pTDFX->ModeReg.clip1max); 373 pTDFX->DrawState&=~DRAW_STATE_CLIP1CHANGED; 374 } 375 376 pTDFX->PrevDrawState=pTDFX->DrawState; 377} 378 379static void 380TDFXClearState(ScrnInfoPtr pScrn) 381{ 382 TDFXPtr pTDFX; 383 384 pTDFX=TDFXPTR(pScrn); 385 pTDFX->Cmd=0; 386 pTDFX->DrawState&=~DRAW_STATE_TRANSPARENT; 387 /* Make sure we've done a sync */ 388 TDFXFirstSync(pScrn); 389} 390 391static void 392TDFXSetClippingRectangle(ScrnInfoPtr pScrn, int left, int top, int right, 393 int bottom) 394{ 395 TDFXPtr pTDFX; 396 397 TDFXTRACEACCEL("TDFXSetClippingRectangle %d,%d to %d,%d\n", left, top, 398 right, bottom); 399 pTDFX=TDFXPTR(pScrn); 400 401 pTDFX->ModeReg.clip1min=(top&0xFFF)<<16 | (left&0xFFF); 402 pTDFX->ModeReg.clip1max=((bottom+1)&0xFFF)<<16 | ((right+1)&0xFFF); 403 404 pTDFX->DrawState|=DRAW_STATE_CLIPPING|DRAW_STATE_CLIP1CHANGED; 405} 406 407static void 408TDFXDisableClipping(ScrnInfoPtr pScrn) 409{ 410 TDFXPtr pTDFX; 411 412 TDFXTRACEACCEL("TDFXDisableClippingRectangle\n"); 413 pTDFX=TDFXPTR(pScrn); 414 415 pTDFX->DrawState&=~DRAW_STATE_CLIPPING; 416} 417 418void 419TDFXSetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir, int rop, 420 unsigned int planemask, int trans_color) 421{ 422 TDFXPtr pTDFX; 423 int fmt; 424 425 TDFXTRACEACCEL("TDFXSetupForScreenToScreenCopy\n xdir=%d ydir=%d " 426 "rop=%d planemask=%d trans_color=%d\n", 427 xdir, ydir, rop, planemask, trans_color); 428 pTDFX=TDFXPTR(pScrn); 429 TDFXClearState(pScrn); 430 431 if (trans_color!=-1) { 432 TDFXMakeRoom(pTDFX, 3); 433 DECLARE(SSTCP_SRCCOLORKEYMIN|SSTCP_SRCCOLORKEYMAX|SSTCP_ROP); 434 TDFXWriteLong(pTDFX, SST_2D_SRCCOLORKEYMIN, trans_color); 435 TDFXWriteLong(pTDFX, SST_2D_SRCCOLORKEYMAX, trans_color); 436 TDFXWriteLong(pTDFX, SST_2D_ROP, TDFXROPCvt[GXnoop]<<8); 437 pTDFX->DrawState|=DRAW_STATE_TRANSPARENT; 438 } 439 pTDFX->Cmd = (TDFXROPCvt[rop]<<24) | SST_2D_SCRNTOSCRNBLIT; 440 if (xdir==-1) pTDFX->Cmd |= SST_2D_X_RIGHT_TO_LEFT; 441 if (ydir==-1) pTDFX->Cmd |= SST_2D_Y_BOTTOM_TO_TOP; 442 if (pTDFX->cpp==1) fmt=pTDFX->stride|(1<<16); 443 else fmt=pTDFX->stride|((pTDFX->cpp+1)<<16); 444 445 TDFXMakeRoom(pTDFX, 2); 446 DECLARE(SSTCP_SRCFORMAT|SSTCP_DSTFORMAT); 447 TDFXWriteLong(pTDFX, SST_2D_DSTFORMAT, fmt); 448 pTDFX->sst2DDstFmtShadow = fmt; 449 TDFXWriteLong(pTDFX, SST_2D_SRCFORMAT, fmt); 450 pTDFX->sst2DSrcFmtShadow = fmt; 451} 452 453void 454TDFXSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int srcX, int srcY, 455 int dstX, int dstY, int w, int h) 456{ 457 TDFXPtr pTDFX; 458 459 TDFXTRACEACCEL("TDFXSubsequentScreenToScreenCopy\n srcX=%d srcY=%d" 460 " dstX=%d dstY=%d w=%d h=%d\n", srcX, srcY, dstX, dstY, w, h); 461 pTDFX=TDFXPTR(pScrn); 462 TDFXMatchState(pTDFX); 463 464 if (pTDFX->Cmd&SST_2D_Y_BOTTOM_TO_TOP) { 465 srcY += h-1; 466 dstY += h-1; 467 } 468 if (pTDFX->Cmd&SST_2D_X_RIGHT_TO_LEFT) { 469 srcX += w-1; 470 dstX += w-1; 471 } 472 if ((srcY>=dstY-32 && srcY<=dstY)|| 473 (srcY>=pTDFX->prevBlitDest.y1-32 && srcY<=pTDFX->prevBlitDest.y1)) { 474 TDFXSendNOP(pScrn); 475 } 476 pTDFX->sync(pScrn); 477 478 TDFXMakeRoom(pTDFX, 4); 479 DECLARE(SSTCP_DSTSIZE|SSTCP_DSTXY|SSTCP_SRCXY|SSTCP_COMMAND); 480 TDFXWriteLong(pTDFX, SST_2D_SRCXY, (srcX&0x1FFF) | ((srcY&0x1FFF)<<16)); 481 TDFXWriteLong(pTDFX, SST_2D_DSTSIZE, (w&0x1FFF) | ((h&0x1FFF)<<16)); 482 TDFXWriteLong(pTDFX, SST_2D_DSTXY, (dstX&0x1FFF) | ((dstY&0x1FFF)<<16)); 483 TDFXWriteLong(pTDFX, SST_2D_COMMAND, pTDFX->Cmd|SST_2D_GO); 484 485 pTDFX->prevBlitDest.y1=dstY; 486} 487 488void 489TDFXSetupForSolidFill(ScrnInfoPtr pScrn, int color, int rop, 490 unsigned int planemask) 491{ 492 TDFXPtr pTDFX; 493 int fmt; 494 495 TDFXTRACEACCEL("TDFXSetupForSolidFill color=%d rop=%d planemask=%d\n", 496 color, rop, planemask); 497 pTDFX=TDFXPTR(pScrn); 498 TDFXClearState(pScrn); 499 500 pTDFX->Cmd=TDFXROPCvt[rop]<<24; 501 if (pTDFX->cpp==1) fmt=(1<<16)|pTDFX->stride; 502 else fmt=((pTDFX->cpp+1)<<16)|pTDFX->stride; 503 504 TDFXMakeRoom(pTDFX, 3); 505 DECLARE(SSTCP_DSTFORMAT|SSTCP_COLORFORE| 506 SSTCP_COLORBACK); 507 TDFXWriteLong(pTDFX, SST_2D_DSTFORMAT, fmt); 508 pTDFX->sst2DDstFmtShadow = fmt; 509 TDFXWriteLong(pTDFX, SST_2D_COLORBACK, color); 510 TDFXWriteLong(pTDFX, SST_2D_COLORFORE, color); 511} 512 513void 514TDFXSubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h) 515{ 516 /* Also called by TDFXSubsequentMono8x8PatternFillRect */ 517 TDFXPtr pTDFX; 518 519 TDFXTRACEACCEL("TDFXSubsequentSolidFillRect x=%d y=%d w=%d h=%d\n", 520 x, y, w, h); 521 pTDFX=TDFXPTR(pScrn); 522 TDFXMatchState(pTDFX); 523 524 TDFXMakeRoom(pTDFX, 3); 525 DECLARE(SSTCP_DSTSIZE|SSTCP_DSTXY|SSTCP_COMMAND); 526 TDFXWriteLong(pTDFX, SST_2D_DSTSIZE, ((h&0x1FFF)<<16) | (w&0x1FFF)); 527 TDFXWriteLong(pTDFX, SST_2D_DSTXY, ((y&0x1FFF)<<16) | (x&0x1FFF)); 528 TDFXWriteLong(pTDFX, SST_2D_COMMAND, pTDFX->Cmd | SST_2D_RECTANGLEFILL | 529 SST_2D_GO); 530} 531 532static void 533TDFXSetupForMono8x8PatternFill(ScrnInfoPtr pScrn, int patx, int paty, 534 int fg, int bg, int rop, unsigned int planemask) 535{ 536 TDFXPtr pTDFX; 537 int fmt; 538 539 TDFXTRACEACCEL("TDFXSetupForMono8x8PatternFill patx=%x paty=%x fg=%d" 540 " bg=%d rop=%d planemask=%d\n", patx, paty, fg, bg, rop, 541 planemask); 542 pTDFX=TDFXPTR(pScrn); 543 TDFXClearState(pScrn); 544 545 pTDFX->Cmd = (TDFXROPCvt[rop+ROP_PATTERN_OFFSET]<<24) | 546 SST_2D_MONOCHROME_PATTERN; 547 if (bg==-1) { 548 pTDFX->Cmd |= SST_2D_TRANSPARENT_MONOCHROME; 549 } 550 if (pTDFX->cpp==1) fmt=(1<<16)|pTDFX->stride; 551 else fmt=((pTDFX->cpp+1)<<16)|pTDFX->stride; 552 553 TDFXMakeRoom(pTDFX, 5); 554 DECLARE(SSTCP_DSTFORMAT|SSTCP_PATTERN0ALIAS 555 |SSTCP_PATTERN1ALIAS|SSTCP_COLORFORE| 556 SSTCP_COLORBACK); 557 TDFXWriteLong(pTDFX, SST_2D_DSTFORMAT, fmt); 558 pTDFX->sst2DDstFmtShadow = fmt; 559 TDFXWriteLong(pTDFX, SST_2D_PATTERN0, patx); 560 TDFXWriteLong(pTDFX, SST_2D_PATTERN1, paty); 561 TDFXWriteLong(pTDFX, SST_2D_COLORBACK, bg); 562 TDFXWriteLong(pTDFX, SST_2D_COLORFORE, fg); 563} 564 565static void 566TDFXSubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, int patx, int paty, 567 int x, int y, int w, int h) 568{ 569 TDFXPtr pTDFX; 570 571 TDFXTRACEACCEL("TDFXSubsequentMono8x8PatternFillRect patx=%x paty=%x" 572 " x=%d y=%d w=%d h=%d\n", patx, paty, x, y, w, h); 573 pTDFX=TDFXPTR(pScrn); 574 575 pTDFX->Cmd |= ((patx&0x7)<<SST_2D_X_PATOFFSET_SHIFT) | 576 ((paty&0x7)<<SST_2D_Y_PATOFFSET_SHIFT); 577 578 TDFXSubsequentSolidFillRect(pScrn, x, y, w, h); 579} 580 581static void 582TDFXSetupForSolidLine(ScrnInfoPtr pScrn, int color, int rop, 583 unsigned int planemask) 584{ 585 TDFXPtr pTDFX; 586 587 TDFXTRACEACCEL("TDFXSetupForSolidLine\n"); 588 pTDFX=TDFXPTR(pScrn); 589 TDFXClearState(pScrn); 590 591 pTDFX->Cmd = (TDFXROPCvt[rop]<<24); 592 593 TDFXMakeRoom(pTDFX, 2); 594 DECLARE(SSTCP_COLORFORE|SSTCP_COLORBACK); 595 TDFXWriteLong(pTDFX, SST_2D_COLORBACK, color); 596 TDFXWriteLong(pTDFX, SST_2D_COLORFORE, color); 597} 598 599static void 600TDFXSubsequentSolidTwoPointLine(ScrnInfoPtr pScrn, int srcx, int srcy, 601 int dstx, int dsty, int flags) 602{ 603 /* Also used by TDFXSubsequentDashedTwoPointLine */ 604 TDFXPtr pTDFX; 605 606 TDFXTRACEACCEL("TDFXSubsequentSolidTwoPointLine " 607 "srcx=%d srcy=%d dstx=%d dsty=%d flags=%d\n", 608 srcx, srcy, dstx, dsty, flags); 609 pTDFX=TDFXPTR(pScrn); 610 TDFXMatchState(pTDFX); 611 612 if (flags&OMIT_LAST) pTDFX->Cmd|=SST_2D_POLYLINE; 613 else pTDFX->Cmd|=SST_2D_LINE; 614 615 TDFXMakeRoom(pTDFX, 3); 616 DECLARE(SSTCP_SRCXY|SSTCP_DSTXY|SSTCP_COMMAND); 617 TDFXWriteLong(pTDFX, SST_2D_SRCXY, (srcy&0x1FFF)<<16 | (srcx&0x1FFF)); 618 TDFXWriteLong(pTDFX, SST_2D_DSTXY, (dsty&0x1FFF)<<16 | (dstx&0x1FFF)); 619 TDFXWriteLong(pTDFX, SST_2D_COMMAND, pTDFX->Cmd|SST_2D_GO); 620} 621 622static void 623TDFXSubsequentSolidHorVertLine(ScrnInfoPtr pScrn, int x, int y, int len, 624 int dir) 625{ 626 TDFXPtr pTDFX; 627 628 TDFXTRACEACCEL("TDFXSubsequentSolidHorVertLine\n"); 629 pTDFX=TDFXPTR(pScrn); 630 TDFXMatchState(pTDFX); 631 632 TDFXMakeRoom(pTDFX, 3); 633 DECLARE(SSTCP_SRCXY|SSTCP_DSTXY|SSTCP_COMMAND); 634 TDFXWriteLong(pTDFX, SST_2D_SRCXY, (y&0x1FFF)<<16 | (x&0x1FFF)); 635 if (dir == DEGREES_0) 636 TDFXWriteLong(pTDFX, SST_2D_DSTXY, (y&0x1FFF)<<16 | ((x+len)&0x1FFF)); 637 else 638 TDFXWriteLong(pTDFX, SST_2D_DSTXY, ((y+len)&0x1FFF)<<16 | (x&0x1FFF)); 639 TDFXWriteLong(pTDFX, SST_2D_COMMAND, pTDFX->Cmd|SST_2D_POLYLINE|SST_2D_GO); 640} 641 642static void 643TDFXNonTEGlyphRenderer(ScrnInfoPtr pScrn, int x, int y, int n, 644 NonTEGlyphPtr glyphs, BoxPtr pbox, int fg, int rop, 645 unsigned int planemask) 646{ 647 TDFXPtr pTDFX; 648 int ndwords; 649 int g; 650 NonTEGlyphPtr glyph; 651 652 TDFXTRACEACCEL("TDFXNonTEGlyphRenderer\n"); 653 pTDFX=TDFXPTR(pScrn); 654 TDFXClearState(pScrn); 655 /* Don't bother fixing clip1, we're going to change it anyway */ 656 pTDFX->DrawState&=~DRAW_STATE_CLIP1CHANGED; 657 TDFXMatchState(pTDFX); 658 /* We're changing clip1 so make sure we use it and flag it */ 659 pTDFX->Cmd|=SST_2D_USECLIP1; 660 pTDFX->DrawState|=DRAW_STATE_CLIP1CHANGED; 661 662 pTDFX->Cmd|=(TDFXROPCvt[rop]<<24)|SST_2D_TRANSPARENT_MONOCHROME; 663 pTDFX->Cmd|=SST_2D_HOSTTOSCRNBLIT; 664 665 TDFXMakeRoom(pTDFX, 6); 666 DECLARE(SSTCP_CLIP1MIN|SSTCP_CLIP1MAX|SSTCP_SRCFORMAT| 667 SSTCP_SRCXY|SSTCP_COLORFORE|SSTCP_COMMAND); 668 TDFXWriteLong(pTDFX, SST_2D_CLIP1MIN, ((pbox->y1&0x1FFF)<<16) | 669 (pbox->x1&0x1FFF)); 670 TDFXWriteLong(pTDFX, SST_2D_CLIP1MAX, ((pbox->y2&0x1FFF)<<16) | 671 (pbox->x2&0x1FFF)); 672#if X_BYTE_ORDER == X_BIG_ENDIAN 673 TDFXWriteLong(pTDFX, SST_2D_SRCFORMAT, SST_2D_PIXFMT_1BPP | 674 SST_2D_SOURCE_PACKING_DWORD | BIT(20)); 675#else 676 TDFXWriteLong(pTDFX, SST_2D_SRCFORMAT, SST_2D_PIXFMT_1BPP | 677 SST_2D_SOURCE_PACKING_DWORD); 678#endif 679 pTDFX->sst2DSrcFmtShadow = SST_2D_PIXFMT_1BPP | SST_2D_SOURCE_PACKING_DWORD; 680 TDFXWriteLong(pTDFX, SST_2D_SRCXY, 0); 681 TDFXWriteLong(pTDFX, SST_2D_COLORFORE, fg); 682 TDFXWriteLong(pTDFX, SST_2D_COMMAND, pTDFX->Cmd); 683 684 for (g=0, glyph=glyphs; g<n; g++, glyph++) { 685 int dx = x+glyph->start; 686 int dy = y-glyph->yoff; 687 int w = glyph->end - glyph->start; 688 int *glyph_data = (int*)glyph->bits; 689 690 if (!glyph->srcwidth) continue; 691 ndwords = (glyph->srcwidth+3)>>2; 692 ndwords *= glyph->height; 693 694 TDFXMakeRoom(pTDFX, 2); 695 DECLARE(SSTCP_DSTSIZE|SSTCP_DSTXY); 696 TDFXWriteLong(pTDFX, SST_2D_DSTSIZE, ((glyph->height&0x1FFF)<<16) | 697 (w&0x1FFF)); 698 TDFXWriteLong(pTDFX, SST_2D_DSTXY, ((dy&0x1FFF)<<16) | (dx&0x1FFF)); 699 700 do { 701 int i = ndwords; 702 int j; 703 704 if (i>30) i=30; 705 TDFXMakeRoom(pTDFX, i); 706 DECLARE_LAUNCH(i, 0); 707 for (j=0; j<i; j++) { 708#if X_BYTE_ORDER == X_BIG_ENDIAN 709 TDFXWriteLong(pTDFX, SST_2D_LAUNCH, *glyph_data); 710#else 711 TDFXWriteLong(pTDFX, SST_2D_LAUNCH, XAAReverseBitOrder(*glyph_data)); 712#endif 713 glyph_data++; 714 } 715 ndwords -= i; 716 } while (ndwords); 717 } 718} 719 720static void 721TDFXSetupForDashedLine(ScrnInfoPtr pScrn, int fg, int bg, int rop, 722 unsigned int planemask, int length, 723 unsigned char *pattern) 724{ 725 TDFXPtr pTDFX; 726#if X_BYTE_ORDER == X_BIG_ENDIAN 727 unsigned int pat = *(unsigned int *)pattern; 728#endif 729 730 TDFXTRACEACCEL("TDFXSetupForDashedLine\n"); 731 pTDFX=TDFXPTR(pScrn); 732 733#if X_BYTE_ORDER == X_BIG_ENDIAN 734 pat=((pat & 0xAAAAAAAA) >> 1) | ((pat & 0x55555555) << 1); 735 pat=((pat & 0xCCCCCCCC) >> 2) | ((pat & 0x33333333) << 2); 736 pat=((pat & 0xF0F0F0F0) >> 4) | ((pat & 0x0F0F0F0F) << 4); 737 pat=((pat & 0xFF00FF00) >> 8) | ((pat & 0x00FF00FF) << 8); 738 pat=((pat & 0xFFFF0000) >> 16) | ((pat & 0x0000FFFF) << 16); 739#endif 740 741 TDFXClearState(pScrn); 742 743 pTDFX->Cmd = (TDFXROPCvt[rop]<<24) | SST_2D_STIPPLE_LINE; 744 if(bg == -1) { 745 pTDFX->Cmd |= SST_2D_TRANSPARENT_MONOCHROME; 746 } 747 pTDFX->DashedLineSize = ((length-1)&0xFF)+1; 748 749 TDFXMakeRoom(pTDFX, 3); 750 DECLARE(SSTCP_COLORFORE|SSTCP_COLORBACK|SSTCP_LINESTIPPLE); 751#if X_BYTE_ORDER == X_BIG_ENDIAN 752 TDFXWriteLong(pTDFX, SST_2D_LINESTIPPLE, pat); 753#else 754 TDFXWriteLong(pTDFX, SST_2D_LINESTIPPLE, *(int *)pattern); 755#endif 756 TDFXWriteLong(pTDFX, SST_2D_COLORBACK, bg); 757 TDFXWriteLong(pTDFX, SST_2D_COLORFORE, fg); 758} 759 760static void 761TDFXSubsequentDashedTwoPointLine(ScrnInfoPtr pScrn, int x1, int y1, 762 int x2, int y2, int flags, int phase) 763{ 764 TDFXPtr pTDFX; 765 int linestyle; 766 767 TDFXTRACEACCEL("TDFXSubsequentDashedTwoPointLine\n"); 768 pTDFX=TDFXPTR(pScrn); 769 770 linestyle = ((pTDFX->DashedLineSize-1)<<8) | 771 (((phase%pTDFX->DashedLineSize)&0x1F)<<24); 772 773 TDFXMakeRoom(pTDFX, 1); 774 DECLARE(SSTCP_LINESTYLE); 775 TDFXWriteLong(pTDFX, SST_2D_LINESTYLE, linestyle); 776 777 TDFXSubsequentSolidTwoPointLine(pScrn, x1, y1, x2, y2, flags); 778} 779 780#ifdef ENABLE_SS_COLOR_EXPAND_FILL 781static void 782TDFXSetupForScreenToScreenColorExpandFill(ScrnInfoPtr pScrn, int fg, int bg, 783 int rop, unsigned int planemask) 784{ 785 TDFXPtr pTDFX; 786 787 TDFXTRACEACCEL("TDFXSetupForScreenToScreenColorExpandFill\n"); 788 pTDFX=TDFXPTR(pScrn); 789 TDFXClearState(pScrn); 790 791 TDFXMatchState(pTDFX); 792 pTDFX->Cmd|=SST_2D_SCRNTOSCRNBLIT|(TDFXROPCvt[rop]<<24); 793 794 if (bg==-1) { 795 pTDFX->Cmd |= SST_2D_TRANSPARENT_MONOCHROME; 796 } 797 TDFXMakeRoom(pTDFX, 2); 798 DECLARE(SSTCP_COLORFORE|SSTCP_COLORBACK); 799 TDFXWriteLong(pTDFX, SST_2D_COLORBACK, bg); 800 TDFXWriteLong(pTDFX, SST_2D_COLORFORE, fg); 801} 802 803static void 804TDFXSubsequentScreenToScreenColorExpandFill(ScrnInfoPtr pScrn, int x, int y, 805 int w, int h, int srcx, int srcy, 806 int offset) 807{ 808 TDFXPtr pTDFX; 809 int fmt; 810 811 TDFXTRACEACCEL("TDFXSubsequentScreenToScreenColorExpandFill " 812 "x=%d y=%d w=%d h=%d srcx=%d srcy=%d offset=%d\n", 813 x, y, w, h, srcx, srcy, offset); 814 pTDFX=TDFXPTR(pScrn); 815 /* Don't bother resetting clip1 since we're changing it anyway */ 816 pTDFX->DrawState&=~DRAW_STATE_CLIP1CHANGED; 817 TDFXMatchState(pTDFX); 818 /* We're changing clip1 so make sure we use it and flag it */ 819 pTDFX->Cmd|=SST_2D_USECLIP1; 820 pTDFX->DrawState|=DRAW_STATE_CLIP1CHANGED; 821 822 if (srcy>=pTDFX->prevBlitDest.y1-8 && srcy<=pTDFX->prevBlitDest.y1) { 823 TDFXSendNOP(pScrn); 824 } 825 826 if (pTDFX->cpp==1) fmt=(1<<16)|pTDFX->stride; 827 else fmt=(pTDFX->cpp+1)<<16|pTDFX->stride; 828 829 TDFXMakeRoom(pTDFX, 8); 830 DECLARE(SSTCP_SRCFORMAT|SSTCP_SRCXY|SSTCP_DSTFORMAT | 831 SSTCP_DSTSIZE|SSTCP_DSTXY|SSTCP_COMMAND | 832 SSTCP_CLIP1MIN|SSTCP_CLIP1MAX); 833 TDFXWriteLong(pTDFX,SST_2D_DSTFORMAT, fmt); 834 pTDFX->sst2DDstFmtShadow = fmt; 835 TDFXWriteLong(pTDFX,SST_2D_CLIP1MIN, (x&0x1FFF) | ((y&0x1FFF)<<16)); 836 TDFXWriteLong(pTDFX,SST_2D_CLIP1MAX, ((x+w)&0x1FFF) | (((y+h)&0x1FFF)<<16)); 837 TDFXWriteLong(pTDFX,SST_2D_SRCFORMAT, pTDFX->stride); 838 pTDFX->sst2DSrcFmtShadow = pTDFX->stride; 839 TDFXWriteLong(pTDFX,SST_2D_SRCXY, (srcx&0x1FFF) | ((srcy&0x1FFF)<<16)); 840 TDFXWriteLong(pTDFX,SST_2D_DSTSIZE, ((w+offset)&0x1FFF) | ((h&0x1FFF)<<16)); 841 TDFXWriteLong(pTDFX,SST_2D_DSTXY, ((x-offset)&0x1FFF) | ((y&0x1FFF)<<16)); 842 TDFXWriteLong(pTDFX,SST_2D_COMMAND, pTDFX->Cmd|SST_2D_GO); 843 844 pTDFX->prevBlitDest.y1=y; 845} 846#endif 847 848static void 849TDFXSetupForCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, int fg, int bg, 850 int rop, unsigned int planemask) 851{ 852 TDFXPtr pTDFX; 853 854 TDFXTRACEACCEL("SetupForCPUToScreenColorExpandFill bg=%x fg=%x rop=%d\n", 855 bg, fg, rop); 856 pTDFX=TDFXPTR(pScrn); 857 TDFXClearState(pScrn); 858 859 pTDFX->Cmd|=SST_2D_HOSTTOSCRNBLIT|(TDFXROPCvt[rop]<<24); 860 861 if (bg == -1) { 862 pTDFX->Cmd |= SST_2D_TRANSPARENT_MONOCHROME; 863 } 864 865 TDFXMakeRoom(pTDFX, 2); 866 DECLARE(SSTCP_COLORBACK|SSTCP_COLORFORE); 867 TDFXWriteLong(pTDFX, SST_2D_COLORBACK, bg); 868 TDFXWriteLong(pTDFX, SST_2D_COLORFORE, fg); 869} 870 871static void 872TDFXSubsequentCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, int x, int y, 873 int w, int h, int skipleft) 874{ 875 TDFXPtr pTDFX; 876 int fmt; 877 878 TDFXTRACEACCEL("SubsequentCPUToScreenColorExpandFill x=%d y=%d w=%d h=%d" 879 " skipleft=%d\n", x, y, w, h, skipleft); 880 pTDFX = TDFXPTR(pScrn); 881 882 /* We're changing clip1 anyway, so don't bother to reset it */ 883 pTDFX->DrawState&=~DRAW_STATE_CLIP1CHANGED; 884 TDFXMatchState(pTDFX); 885 /* Make sure we use clip1 and flag it */ 886 pTDFX->Cmd|=SST_2D_USECLIP1; 887 pTDFX->DrawState|=DRAW_STATE_CLIP1CHANGED; 888 889 if (pTDFX->cpp==1) fmt=(1<<16)|pTDFX->stride; 890 else fmt=((pTDFX->cpp+1)<<16)|pTDFX->stride; 891 pTDFX->scanlineWidth=w; 892 893 TDFXMakeRoom(pTDFX, 8); 894 DECLARE(SSTCP_CLIP1MIN|SSTCP_CLIP1MAX|SSTCP_SRCFORMAT| 895 SSTCP_DSTFORMAT|SSTCP_DSTSIZE|SSTCP_SRCXY| 896 SSTCP_DSTXY|SSTCP_COMMAND); 897 TDFXWriteLong(pTDFX, SST_2D_DSTFORMAT, fmt); 898 pTDFX->sst2DDstFmtShadow = fmt; 899 TDFXWriteLong(pTDFX, SST_2D_CLIP1MIN, ((y&0x1FFF)<<16)|(x&0x1FFF)); 900 TDFXWriteLong(pTDFX, SST_2D_CLIP1MAX, (((y+h)&0x1FFF)<<16)|((x+w)&0x1FFF)); 901#if X_BYTE_ORDER == X_BIG_ENDIAN 902 /* bit 20 byte swizzle */ 903 TDFXWriteLong(pTDFX, SST_2D_SRCFORMAT, ((((w+31)/32)*4) & 0x3FFF) | BIT(20)); 904#else 905 TDFXWriteLong(pTDFX, SST_2D_SRCFORMAT, (((w+31)/32)*4) & 0x3FFF); 906#endif 907 pTDFX->sst2DSrcFmtShadow = (((w+31)/32)*4) & 0x3FFF; 908 TDFXWriteLong(pTDFX, SST_2D_SRCXY, skipleft&0x1F); 909 TDFXWriteLong(pTDFX, SST_2D_DSTSIZE, ((w-skipleft)&0x1FFF)|((h&0x1FFF)<<16)); 910 TDFXWriteLong(pTDFX, SST_2D_DSTXY, ((x+skipleft)&0x1FFF) | ((y&0x1FFF)<<16)); 911 TDFXWriteLong(pTDFX, SST_2D_COMMAND, pTDFX->Cmd|SST_2D_GO); 912} 913 914static void TDFXSubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno) 915{ 916 TDFXPtr pTDFX; 917 int i, size, cnt; 918 CARD32 *pos; 919 920 TDFXTRACEACCEL("SubsequentColorExpandScanline bufno=%d\n", bufno); 921 pTDFX = TDFXPTR(pScrn); 922 923 cnt=(pTDFX->scanlineWidth+31)/32; 924 pos=(CARD32 *)pTDFX->scanlineColorExpandBuffers[bufno]; 925 while (cnt>0) { 926 if (cnt>64) size=64; 927 else size=cnt; 928 TDFXMakeRoom(pTDFX, size); 929 DECLARE_LAUNCH(size, 0); 930 for (i=0; i<size; i++, pos++) { 931 TDFXWriteLong(pTDFX, SST_2D_LAUNCH, *pos); 932 } 933 cnt-=size; 934 } 935} 936 937