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