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