102be438aSmrg
202be438aSmrg#ifdef HAVE_CONFIG_H
302be438aSmrg#include "config.h"
402be438aSmrg#endif
502be438aSmrg
602be438aSmrg/* All drivers should typically include these */
702be438aSmrg#include "xf86.h"
802be438aSmrg#include "xf86_OSproc.h"
902be438aSmrg#include "compiler.h"
1002be438aSmrg
1102be438aSmrg/* Drivers that need to access the PCI config space directly need this */
1202be438aSmrg#include "xf86Pci.h"
1302be438aSmrg
1402be438aSmrg/* Drivers that use XAA need this */
15909209eeSmrg#ifdef HAVE_XAA_H
1602be438aSmrg#include "xaalocal.h"
17909209eeSmrg#endif
1802be438aSmrg#include "xf86fbman.h"
1902be438aSmrg
2002be438aSmrg#include "miline.h"
2102be438aSmrg
2202be438aSmrg#include "tdfx.h"
2302be438aSmrg
24909209eeSmrg#ifdef HAVE_XAA_H
2502be438aSmrg#ifdef TDFX_DEBUG_CMDS
2602be438aSmrgstatic int cmdCnt=0;
2702be438aSmrgstatic int lastAddr=0;
2802be438aSmrg#endif
2902be438aSmrg
3002be438aSmrgstatic int TDFXROPCvt[] = {0x00, 0x88, 0x44, 0xCC, 0x22, 0xAA, 0x66, 0xEE,
3102be438aSmrg			   0x11, 0x99, 0x55, 0xDD, 0x33, 0xBB, 0x77, 0xFF,
3202be438aSmrg			   0x00, 0xA0, 0x50, 0xF0, 0x0A, 0xAA, 0x5A, 0xFA,
3302be438aSmrg			   0x05, 0xA5, 0x55, 0xF5, 0x0F, 0xAF, 0x5F, 0xFF};
3402be438aSmrg#define ROP_PATTERN_OFFSET 16
3502be438aSmrg
3602be438aSmrgstatic void TDFXSetClippingRectangle(ScrnInfoPtr pScrn, int left, int top,
3702be438aSmrg				     int right, int bottom);
3802be438aSmrgstatic void TDFXDisableClipping(ScrnInfoPtr pScrn);
3902be438aSmrgstatic void TDFXSetupForMono8x8PatternFill(ScrnInfoPtr pScrn, int patx,
4002be438aSmrg					   int paty, int fg, int bg, int rop,
4102be438aSmrg					   unsigned int planemask);
4202be438aSmrgstatic void TDFXSubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, int patx,
4302be438aSmrg						 int pay, int x, int y,
4402be438aSmrg						 int w, int h);
4502be438aSmrgstatic void TDFXSetupForSolidLine(ScrnInfoPtr pScrn, int color, int rop,
4602be438aSmrg				  unsigned int planemask);
4702be438aSmrgstatic void TDFXSubsequentSolidTwoPointLine(ScrnInfoPtr pScrn, int srcx,
4802be438aSmrg					    int srcy, int dstx, int dsty,
4902be438aSmrg					    int flags);
5002be438aSmrgstatic void TDFXSubsequentSolidHorVertLine(ScrnInfoPtr pScrn, int x, int y,
5102be438aSmrg					   int len, int dir);
5202be438aSmrgstatic void TDFXNonTEGlyphRenderer(ScrnInfoPtr pScrn, int x, int y, int n,
5302be438aSmrg				   NonTEGlyphPtr glyphs, BoxPtr pbox, int fg,
5402be438aSmrg				   int rop, unsigned int planemask);
5502be438aSmrgstatic void TDFXSetupForDashedLine(ScrnInfoPtr pScrn, int fg, int bg, int rop,
5602be438aSmrg                                   unsigned int planemask, int length,
5702be438aSmrg		                   unsigned char *pattern);
5802be438aSmrgstatic void TDFXSubsequentDashedTwoPointLine(ScrnInfoPtr pScrn, int x1, int y1,
5902be438aSmrg                                             int x2, int y2, int flags,
6002be438aSmrg                                             int phase);
6102be438aSmrg#ifdef ENABLE_SS_COLOR_EXPAND_FILL
6202be438aSmrgstatic void TDFXSetupForScreenToScreenColorExpandFill(ScrnInfoPtr pScrn,
6302be438aSmrg                                                      int fg, int bg, int rop,
6402be438aSmrg                                                      unsigned int planemask);
6502be438aSmrgstatic void TDFXSubsequentScreenToScreenColorExpandFill(ScrnInfoPtr pScrn,
6602be438aSmrg                                                        int x, int y, int w,
6702be438aSmrg                                                        int h, int srcx,
6802be438aSmrg                                                        int srcy, int offset);
6902be438aSmrg#endif
7002be438aSmrgstatic void TDFXSetupForCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
7102be438aSmrg                                                   int fg, int bg, int rop,
7202be438aSmrg                                                   unsigned int planemask);
7302be438aSmrgstatic void TDFXSubsequentCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
7402be438aSmrg                                                     int x, int y,
7502be438aSmrg                                                     int w, int h,
7602be438aSmrg                                                     int skipleft);
7702be438aSmrgstatic void TDFXSubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno);
7802be438aSmrg
79909209eeSmrg#endif
8002be438aSmrgvoid
8102be438aSmrgTDFXNeedSync(ScrnInfoPtr pScrn) {
8202be438aSmrg  TDFXPtr pTDFX = TDFXPTR(pScrn);
8302be438aSmrg  pTDFX->syncDone=FALSE;
84909209eeSmrg#ifdef HAVE_XAA_H
8502be438aSmrg  pTDFX->AccelInfoRec->NeedToSync = TRUE;
86909209eeSmrg#endif
8702be438aSmrg}
8802be438aSmrg
8902be438aSmrgvoid
9002be438aSmrgTDFXFirstSync(ScrnInfoPtr pScrn) {
9102be438aSmrg  TDFXPtr pTDFX = TDFXPTR(pScrn);
9202be438aSmrg
9302be438aSmrg  if (!pTDFX->syncDone) {
94909209eeSmrg#ifdef TDFXDRI
9502be438aSmrg    if (pTDFX->directRenderingEnabled) {
96909209eeSmrg      DRILock(xf86ScrnToScreen(pScrn), 0);
97909209eeSmrg      TDFXSwapContextFifo(xf86ScrnToScreen(pScrn));
9802be438aSmrg    }
9902be438aSmrg#endif
10002be438aSmrg    pTDFX->syncDone=TRUE;
10102be438aSmrg    pTDFX->sync(pScrn);
10202be438aSmrg  }
10302be438aSmrg}
10402be438aSmrg
10502be438aSmrgvoid
10602be438aSmrgTDFXCheckSync(ScrnInfoPtr pScrn) {
10702be438aSmrg  TDFXPtr pTDFX = TDFXPTR(pScrn);
10802be438aSmrg
10902be438aSmrg  if (pTDFX->syncDone) {
11002be438aSmrg    pTDFX->sync(pScrn);
11102be438aSmrg    pTDFX->syncDone=FALSE;
112909209eeSmrg#ifdef TDFXDRI
11302be438aSmrg    if (pTDFX->directRenderingEnabled) {
114909209eeSmrg      DRIUnlock(xf86ScrnToScreen(pScrn));
11502be438aSmrg    }
11602be438aSmrg#endif
11702be438aSmrg  }
11802be438aSmrg}
11902be438aSmrg
12002be438aSmrgvoid
12102be438aSmrgTDFXSelectBuffer(TDFXPtr pTDFX, int which) {
12202be438aSmrg  int fmt;
12302be438aSmrg
12402be438aSmrg  TDFXMakeRoom(pTDFX, 4);
12502be438aSmrg  DECLARE(SSTCP_SRCBASEADDR|SSTCP_DSTBASEADDR|SSTCP_SRCFORMAT|SSTCP_DSTFORMAT);
12602be438aSmrg  switch (which) {
12702be438aSmrg  case TDFX_FRONT:
12802be438aSmrg    if (pTDFX->cpp==1) fmt=pTDFX->stride|(1<<16);
12902be438aSmrg    else fmt=pTDFX->stride|((pTDFX->cpp+1)<<16);
13002be438aSmrg    TDFXWriteLong(pTDFX, SST_2D_DSTBASEADDR, pTDFX->fbOffset);
13102be438aSmrg    TDFXWriteLong(pTDFX, SST_2D_DSTFORMAT, fmt);
13202be438aSmrg    pTDFX->sst2DDstFmtShadow = fmt;
13302be438aSmrg    TDFXWriteLong(pTDFX, SST_2D_SRCBASEADDR, pTDFX->fbOffset);
13402be438aSmrg    TDFXWriteLong(pTDFX, SST_2D_SRCFORMAT, fmt);
13502be438aSmrg    pTDFX->sst2DSrcFmtShadow = fmt;
13602be438aSmrg    break;
13702be438aSmrg  case TDFX_BACK:
13802be438aSmrg    if (pTDFX->cpp==2)
13902be438aSmrg      fmt=((pTDFX->stride+127)/128)|(3<<16); /* Tiled 16bpp */
14002be438aSmrg    else
14102be438aSmrg      fmt=((pTDFX->stride+127)/128)|(5<<16); /* Tiled 32bpp */
14202be438aSmrg    TDFXWriteLong(pTDFX, SST_2D_DSTBASEADDR, pTDFX->backOffset|BIT(31));
14302be438aSmrg    TDFXWriteLong(pTDFX, SST_2D_DSTFORMAT, fmt);
14402be438aSmrg    pTDFX->sst2DDstFmtShadow = fmt;
14502be438aSmrg    TDFXWriteLong(pTDFX, SST_2D_SRCBASEADDR, pTDFX->backOffset|BIT(31));
14602be438aSmrg    TDFXWriteLong(pTDFX, SST_2D_SRCFORMAT, fmt);
14702be438aSmrg    pTDFX->sst2DSrcFmtShadow = fmt;
14802be438aSmrg    break;
14902be438aSmrg  case TDFX_DEPTH:
15002be438aSmrg    if (pTDFX->cpp==2)
15102be438aSmrg      fmt=((pTDFX->stride+127)/128)|(3<<16); /* Tiled 16bpp */
15202be438aSmrg    else
15302be438aSmrg      fmt=((pTDFX->stride+127)/128)|(5<<16); /* Tiled 32bpp */
15402be438aSmrg    TDFXWriteLong(pTDFX, SST_2D_DSTBASEADDR, pTDFX->depthOffset|BIT(31));
15502be438aSmrg    TDFXWriteLong(pTDFX, SST_2D_DSTFORMAT, fmt);
15602be438aSmrg    pTDFX->sst2DDstFmtShadow = fmt;
15702be438aSmrg    TDFXWriteLong(pTDFX, SST_2D_SRCBASEADDR, pTDFX->depthOffset|BIT(31));
15802be438aSmrg    TDFXWriteLong(pTDFX, SST_2D_SRCFORMAT, fmt);
15902be438aSmrg    pTDFX->sst2DSrcFmtShadow = fmt;
16002be438aSmrg    break;
16102be438aSmrg  default:
16202be438aSmrg    ;
16302be438aSmrg  }
16402be438aSmrg}
16502be438aSmrg
16602be438aSmrgvoid
16702be438aSmrgTDFXSetLFBConfig(TDFXPtr pTDFX) {
16802be438aSmrg  if (pTDFX->ChipType<=PCI_CHIP_VOODOO3) {
16902be438aSmrg#if X_BYTE_ORDER == X_BIG_ENDIAN
17002be438aSmrg    unsigned int lfbmode;
17102be438aSmrg    lfbmode=TDFXReadLongMMIO(pTDFX, SST_3D_LFBMODE);
17202be438aSmrg
17302be438aSmrg    lfbmode&=~BIT(12); /* 0 bit 12 is byte swizzle */
17402be438aSmrg    lfbmode|=BIT(11); /* 1 bit 11 is word swizzle */
17502be438aSmrg    lfbmode&=~BIT(10); /* 0 bit 10  ARGB or ABGR */
17602be438aSmrg    lfbmode&=~BIT(9); /* 0 bit 9 if bit10 = 0:  ARGB else ABGR */
17702be438aSmrg
17802be438aSmrg    TDFXWriteLongMMIO(pTDFX, SST_3D_LFBMODE, lfbmode);
17902be438aSmrg#endif
18002be438aSmrg    TDFXWriteLongMMIO(pTDFX, LFBMEMORYCONFIG, (pTDFX->backOffset>>12) |
18102be438aSmrg		      SST_RAW_LFB_ADDR_STRIDE_4K |
18202be438aSmrg		      ((pTDFX->stride+127)/128)<<SST_RAW_LFB_TILE_STRIDE_SHIFT);
18302be438aSmrg  } else {
18402be438aSmrg    int chip;
18502be438aSmrg    int stride, bits;
18602be438aSmrg    int TileAperturePitch, lg2TileAperturePitch;
18702be438aSmrg    if (pTDFX->cpp==2) stride=pTDFX->stride;
18802be438aSmrg    else stride=4*pTDFX->stride/pTDFX->cpp;
18902be438aSmrg    bits=pTDFX->backOffset>>12;
19002be438aSmrg    for (lg2TileAperturePitch = 0, TileAperturePitch = 1024;
19102be438aSmrg         (lg2TileAperturePitch < 5) &&
19202be438aSmrg             TileAperturePitch < stride;
19302be438aSmrg         lg2TileAperturePitch += 1, TileAperturePitch <<= 1);
19402be438aSmrg#if	0
19502be438aSmrg    fprintf(stderr, "Using %d (== lg2(%d)-10) for tile aperture pitch\n",
19602be438aSmrg            lg2TileAperturePitch, TileAperturePitch);
19702be438aSmrg    fprintf(stderr, "stride == %d\n", stride);
19802be438aSmrg#endif
19902be438aSmrg    for (chip=0; chip<pTDFX->numChips; chip++) {
20002be438aSmrg      TDFXWriteChipLongMMIO(pTDFX, chip, LFBMEMORYCONFIG, (bits&0x1FFF) |
20102be438aSmrg			    SST_RAW_LFB_ADDR_STRIDE(lg2TileAperturePitch) |
20202be438aSmrg			    ((bits&0x6000)<<10) |
20302be438aSmrg			    ((stride+127)/128)<<SST_RAW_LFB_TILE_STRIDE_SHIFT);
20402be438aSmrg    }
20502be438aSmrg  }
20602be438aSmrg}
20702be438aSmrg
208909209eeSmrg
20902be438aSmrgBool
21002be438aSmrgTDFXAccelInit(ScreenPtr pScreen)
21102be438aSmrg{
212909209eeSmrg#ifdef HAVE_XAA_H
21302be438aSmrg  XAAInfoRecPtr infoPtr;
214909209eeSmrg  ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
21502be438aSmrg  TDFXPtr pTDFX = TDFXPTR(pScrn);
21602be438aSmrg  CARD32 commonFlags;
21702be438aSmrg
21802be438aSmrg  pTDFX->AccelInfoRec = infoPtr = XAACreateInfoRec();
21902be438aSmrg  if (!infoPtr) return FALSE;
22002be438aSmrg
22102be438aSmrg  infoPtr->Flags = PIXMAP_CACHE | OFFSCREEN_PIXMAPS | LINEAR_FRAMEBUFFER;
22202be438aSmrg
22302be438aSmrg  infoPtr->Sync = pTDFX->sync;
22402be438aSmrg
22502be438aSmrg  infoPtr->SetClippingRectangle = TDFXSetClippingRectangle;
22602be438aSmrg  infoPtr->DisableClipping = TDFXDisableClipping;
22702be438aSmrg  infoPtr->ClippingFlags = HARDWARE_CLIP_SCREEN_TO_SCREEN_COLOR_EXPAND |
22802be438aSmrg    HARDWARE_CLIP_SCREEN_TO_SCREEN_COPY |
22902be438aSmrg    HARDWARE_CLIP_MONO_8x8_FILL |
23002be438aSmrg    HARDWARE_CLIP_COLOR_8x8_FILL |
23102be438aSmrg    HARDWARE_CLIP_SOLID_FILL |
23202be438aSmrg    HARDWARE_CLIP_DASHED_LINE |
23302be438aSmrg    HARDWARE_CLIP_SOLID_LINE;
23402be438aSmrg
23502be438aSmrg  miSetZeroLineBias(pScreen, OCTANT2 | OCTANT5 | OCTANT7 | OCTANT8);
23602be438aSmrg
23702be438aSmrg  commonFlags = BIT_ORDER_IN_BYTE_MSBFIRST | NO_PLANEMASK;
23802be438aSmrg
23902be438aSmrg  infoPtr->SetupForSolidFill = TDFXSetupForSolidFill;
24002be438aSmrg  infoPtr->SubsequentSolidFillRect = TDFXSubsequentSolidFillRect;
24102be438aSmrg  infoPtr->SolidFillFlags = commonFlags;
24202be438aSmrg
24302be438aSmrg  infoPtr->SetupForSolidLine = TDFXSetupForSolidLine;
24402be438aSmrg  infoPtr->SubsequentSolidTwoPointLine = TDFXSubsequentSolidTwoPointLine;
24502be438aSmrg  infoPtr->SubsequentSolidHorVertLine = TDFXSubsequentSolidHorVertLine;
24602be438aSmrg  infoPtr->SolidLineFlags = commonFlags;
24702be438aSmrg
24802be438aSmrg  infoPtr->SetupForDashedLine = TDFXSetupForDashedLine;
24902be438aSmrg  infoPtr->SubsequentDashedTwoPointLine = TDFXSubsequentDashedTwoPointLine;
25002be438aSmrg  infoPtr->DashedLineFlags = commonFlags | LINE_PATTERN_LSBFIRST_LSBJUSTIFIED;
25102be438aSmrg  infoPtr->DashPatternMaxLength = 32;
25202be438aSmrg
25302be438aSmrg  infoPtr->NonTEGlyphRenderer = TDFXNonTEGlyphRenderer;
25402be438aSmrg  infoPtr->NonTEGlyphRendererFlags = commonFlags;
25502be438aSmrg
25602be438aSmrg  infoPtr->SetupForScreenToScreenCopy = TDFXSetupForScreenToScreenCopy;
25702be438aSmrg  infoPtr->SubsequentScreenToScreenCopy = TDFXSubsequentScreenToScreenCopy;
25802be438aSmrg  infoPtr->ScreenToScreenCopyFlags = commonFlags;
25902be438aSmrg
26002be438aSmrg  /* When we're using the fifo we have to use indirect expansion */
261909209eeSmrg  pTDFX->scanlineColorExpandBuffers[0] = malloc((pScrn->virtualX+62)/32*4);
262909209eeSmrg  pTDFX->scanlineColorExpandBuffers[1] = malloc((pScrn->virtualX+62)/32*4);
26302be438aSmrg  infoPtr->NumScanlineColorExpandBuffers=2;
26402be438aSmrg  infoPtr->ScanlineColorExpandBuffers=pTDFX->scanlineColorExpandBuffers;
26502be438aSmrg  infoPtr->SetupForScanlineCPUToScreenColorExpandFill =
26602be438aSmrg    TDFXSetupForCPUToScreenColorExpandFill;
26702be438aSmrg  infoPtr->SubsequentScanlineCPUToScreenColorExpandFill =
26802be438aSmrg    TDFXSubsequentCPUToScreenColorExpandFill;
26902be438aSmrg  infoPtr->SubsequentColorExpandScanline =
27002be438aSmrg    TDFXSubsequentColorExpandScanline;
27102be438aSmrg  infoPtr->ScanlineCPUToScreenColorExpandFillFlags = NO_PLANEMASK |
27202be438aSmrg#if X_BYTE_ORDER == X_LITTLE_ENDIAN
27302be438aSmrg    BIT_ORDER_IN_BYTE_MSBFIRST |
27402be438aSmrg#endif
27502be438aSmrg    CPU_TRANSFER_PAD_DWORD | SCANLINE_PAD_DWORD |
27602be438aSmrg    LEFT_EDGE_CLIPPING; /* | LEFT_EDGE_CLIPPING_NEGATIVE_X; */
27702be438aSmrg
27802be438aSmrg  infoPtr->SetupForMono8x8PatternFill = TDFXSetupForMono8x8PatternFill;
27902be438aSmrg  infoPtr->SubsequentMono8x8PatternFillRect =
28002be438aSmrg    TDFXSubsequentMono8x8PatternFillRect;
28102be438aSmrg  infoPtr->Mono8x8PatternFillFlags = commonFlags |
28202be438aSmrg    HARDWARE_PATTERN_PROGRAMMED_BITS |
28302be438aSmrg    HARDWARE_PATTERN_PROGRAMMED_ORIGIN |
28402be438aSmrg    HARDWARE_PATTERN_SCREEN_ORIGIN;
28502be438aSmrg
28602be438aSmrg#ifdef ENABLE_SS_COLOR_EXPAND_FILL
28702be438aSmrg  /* This causes us to fail compliance */
28802be438aSmrg  /* I suspect 1bpp pixmaps are getting written to cache incorrectly */
28902be438aSmrg  infoPtr->SetupForScreenToScreenColorExpandFill =
29002be438aSmrg    TDFXSetupForScreenToScreenColorExpandFill;
29102be438aSmrg  infoPtr->SubsequentScreenToScreenColorExpandFill =
29202be438aSmrg    TDFXSubsequentScreenToScreenColorExpandFill;
29302be438aSmrg  infoPtr->ScreenToScreenColorExpandFillFlags = commonFlags;
29402be438aSmrg#endif
29502be438aSmrg
29602be438aSmrg  pTDFX->PciCnt=TDFXReadLongMMIO(pTDFX, 0)&0x1F;
29702be438aSmrg  pTDFX->PrevDrawState=pTDFX->DrawState=0;
29802be438aSmrg
29902be438aSmrg  pTDFX->ModeReg.srcbaseaddr=pTDFX->fbOffset;
30002be438aSmrg  TDFXWriteLongMMIO(pTDFX, SST_2D_SRCBASEADDR, pTDFX->ModeReg.srcbaseaddr);
30102be438aSmrg  pTDFX->ModeReg.dstbaseaddr=pTDFX->fbOffset;
30202be438aSmrg  TDFXWriteLongMMIO(pTDFX, SST_2D_DSTBASEADDR, pTDFX->ModeReg.dstbaseaddr);
30302be438aSmrg
30402be438aSmrg  pTDFX->sst2DSrcFmtShadow = TDFXReadLongMMIO(pTDFX, SST_2D_SRCFORMAT);
30502be438aSmrg  pTDFX->sst2DDstFmtShadow = TDFXReadLongMMIO(pTDFX, SST_2D_DSTFORMAT);
30602be438aSmrg
30702be438aSmrg  /* Fill in acceleration functions */
30802be438aSmrg  return XAAInit(pScreen, infoPtr);
309909209eeSmrg#else
310909209eeSmrg  return FALSE;
311909209eeSmrg#endif
31202be438aSmrg}
31302be438aSmrg
31402be438aSmrgstatic void TDFXMakeRoomNoProp(TDFXPtr pTDFX, int size) {
31502be438aSmrg  int stat;
31602be438aSmrg
31702be438aSmrg  pTDFX->PciCnt-=size;
31802be438aSmrg  if (pTDFX->PciCnt<1) {
31902be438aSmrg    do {
32002be438aSmrg      stat=TDFXReadLongMMIO(pTDFX, 0);
32102be438aSmrg      pTDFX->PciCnt=stat&0x1F;
32202be438aSmrg    } while (pTDFX->PciCnt<size);
32302be438aSmrg  }
32402be438aSmrg}
32502be438aSmrg
32602be438aSmrgstatic void TDFXSendNOPNoProp(ScrnInfoPtr pScrn)
32702be438aSmrg{
32802be438aSmrg  TDFXPtr pTDFX;
32902be438aSmrg
33002be438aSmrg  pTDFX=TDFXPTR(pScrn);
33102be438aSmrg  TDFXMakeRoomNoProp(pTDFX, 1);
33202be438aSmrg  TDFXWriteLongMMIO(pTDFX, SST_2D_COMMAND, SST_2D_NOP);
33302be438aSmrg}
33402be438aSmrg
33502be438aSmrgvoid TDFXSync(ScrnInfoPtr pScrn)
33602be438aSmrg{
33702be438aSmrg  TDFXPtr pTDFX;
33802be438aSmrg  int i;
33902be438aSmrg  int stat;
34002be438aSmrg
34102be438aSmrg  TDFXTRACEACCEL("TDFXSync\n");
34202be438aSmrg  pTDFX=TDFXPTR(pScrn);
34302be438aSmrg
34402be438aSmrg  TDFXSendNOPNoProp(pScrn);
34502be438aSmrg  i=0;
34602be438aSmrg  do {
34702be438aSmrg    stat=TDFXReadLongMMIO(pTDFX, 0);
34802be438aSmrg    if (stat&SST_BUSY) i=0; else i++;
34902be438aSmrg  } while (i<3);
35002be438aSmrg  pTDFX->PciCnt=stat&0x1F;
35102be438aSmrg}
35202be438aSmrg
353909209eeSmrg#ifdef HAVE_XAA_H
354909209eeSmrg
355909209eeSmrg
35602be438aSmrgstatic void
35702be438aSmrgTDFXMatchState(TDFXPtr pTDFX)
35802be438aSmrg{
35902be438aSmrg  if (pTDFX->PrevDrawState==pTDFX->DrawState) return;
36002be438aSmrg
36102be438aSmrg  /* Do we need to set a clipping rectangle? */
36202be438aSmrg  if (pTDFX->DrawState&DRAW_STATE_CLIPPING)
36302be438aSmrg    pTDFX->Cmd |= SST_2D_USECLIP1;
36402be438aSmrg  else
36502be438aSmrg    pTDFX->Cmd &= ~SST_2D_USECLIP1;
36602be438aSmrg
36702be438aSmrg  /* Do we need to set transparency? */
36802be438aSmrg  TDFXMakeRoom(pTDFX, 1);
36902be438aSmrg  DECLARE(SSTCP_COMMANDEXTRA);
37002be438aSmrg  if (pTDFX->DrawState&DRAW_STATE_TRANSPARENT) {
37102be438aSmrg    TDFXWriteLong(pTDFX, SST_2D_COMMANDEXTRA, SST_2D_SRC_COLORKEY_EX);
37202be438aSmrg  } else {
37302be438aSmrg    TDFXWriteLong(pTDFX, SST_2D_COMMANDEXTRA, 0);
37402be438aSmrg  }
37502be438aSmrg
37602be438aSmrg  /* Has the previous routine left clip1 changed? Reset it. */
37702be438aSmrg  if (pTDFX->DrawState&DRAW_STATE_CLIP1CHANGED) {
37802be438aSmrg    TDFXMakeRoom(pTDFX, 2);
37902be438aSmrg    DECLARE(SSTCP_CLIP1MIN|SSTCP_CLIP1MAX);
38002be438aSmrg    TDFXWriteLong(pTDFX, SST_2D_CLIP1MIN, pTDFX->ModeReg.clip1min);
38102be438aSmrg    TDFXWriteLong(pTDFX, SST_2D_CLIP1MAX, pTDFX->ModeReg.clip1max);
38202be438aSmrg    pTDFX->DrawState&=~DRAW_STATE_CLIP1CHANGED;
38302be438aSmrg  }
38402be438aSmrg
38502be438aSmrg  pTDFX->PrevDrawState=pTDFX->DrawState;
38602be438aSmrg}
38702be438aSmrg
38802be438aSmrgstatic void
38902be438aSmrgTDFXClearState(ScrnInfoPtr pScrn)
39002be438aSmrg{
39102be438aSmrg  TDFXPtr pTDFX;
39202be438aSmrg
39302be438aSmrg  pTDFX=TDFXPTR(pScrn);
39402be438aSmrg  pTDFX->Cmd=0;
39502be438aSmrg  pTDFX->DrawState&=~DRAW_STATE_TRANSPARENT;
39602be438aSmrg  /* Make sure we've done a sync */
39702be438aSmrg  TDFXFirstSync(pScrn);
39802be438aSmrg}
39902be438aSmrg
40002be438aSmrgstatic void
40102be438aSmrgTDFXSetClippingRectangle(ScrnInfoPtr pScrn, int left, int top, int right,
40202be438aSmrg			 int bottom)
40302be438aSmrg{
40402be438aSmrg  TDFXPtr pTDFX;
40502be438aSmrg
40602be438aSmrg  TDFXTRACEACCEL("TDFXSetClippingRectangle %d,%d to %d,%d\n", left, top,
40702be438aSmrg		 right, bottom);
40802be438aSmrg  pTDFX=TDFXPTR(pScrn);
40902be438aSmrg
41002be438aSmrg  pTDFX->ModeReg.clip1min=(top&0xFFF)<<16 | (left&0xFFF);
41102be438aSmrg  pTDFX->ModeReg.clip1max=((bottom+1)&0xFFF)<<16 | ((right+1)&0xFFF);
41202be438aSmrg
41302be438aSmrg  pTDFX->DrawState|=DRAW_STATE_CLIPPING|DRAW_STATE_CLIP1CHANGED;
41402be438aSmrg}
41502be438aSmrg
41602be438aSmrgstatic void
41702be438aSmrgTDFXDisableClipping(ScrnInfoPtr pScrn)
41802be438aSmrg{
41902be438aSmrg  TDFXPtr pTDFX;
42002be438aSmrg
42102be438aSmrg  TDFXTRACEACCEL("TDFXDisableClippingRectangle\n");
42202be438aSmrg  pTDFX=TDFXPTR(pScrn);
42302be438aSmrg
42402be438aSmrg  pTDFX->DrawState&=~DRAW_STATE_CLIPPING;
42502be438aSmrg}
42602be438aSmrg
42702be438aSmrgvoid
42802be438aSmrgTDFXSetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir, int rop,
42902be438aSmrg			       unsigned int planemask, int trans_color)
43002be438aSmrg{
43102be438aSmrg  TDFXPtr pTDFX;
43202be438aSmrg  int fmt;
43302be438aSmrg
43402be438aSmrg  TDFXTRACEACCEL("TDFXSetupForScreenToScreenCopy\n xdir=%d ydir=%d "
43502be438aSmrg		 "rop=%d planemask=%d trans_color=%d\n",
43602be438aSmrg		 xdir, ydir, rop, planemask, trans_color);
43702be438aSmrg  pTDFX=TDFXPTR(pScrn);
43802be438aSmrg  TDFXClearState(pScrn);
43902be438aSmrg
44002be438aSmrg  if (trans_color!=-1) {
44102be438aSmrg    TDFXMakeRoom(pTDFX, 3);
44202be438aSmrg    DECLARE(SSTCP_SRCCOLORKEYMIN|SSTCP_SRCCOLORKEYMAX|SSTCP_ROP);
44302be438aSmrg    TDFXWriteLong(pTDFX, SST_2D_SRCCOLORKEYMIN, trans_color);
44402be438aSmrg    TDFXWriteLong(pTDFX, SST_2D_SRCCOLORKEYMAX, trans_color);
44502be438aSmrg    TDFXWriteLong(pTDFX, SST_2D_ROP, TDFXROPCvt[GXnoop]<<8);
44602be438aSmrg    pTDFX->DrawState|=DRAW_STATE_TRANSPARENT;
44702be438aSmrg  }
44802be438aSmrg  pTDFX->Cmd = (TDFXROPCvt[rop]<<24) | SST_2D_SCRNTOSCRNBLIT;
44902be438aSmrg  if (xdir==-1) pTDFX->Cmd |= SST_2D_X_RIGHT_TO_LEFT;
45002be438aSmrg  if (ydir==-1) pTDFX->Cmd |= SST_2D_Y_BOTTOM_TO_TOP;
45102be438aSmrg  if (pTDFX->cpp==1) fmt=pTDFX->stride|(1<<16);
45202be438aSmrg  else fmt=pTDFX->stride|((pTDFX->cpp+1)<<16);
45302be438aSmrg
45402be438aSmrg  TDFXMakeRoom(pTDFX, 2);
45502be438aSmrg  DECLARE(SSTCP_SRCFORMAT|SSTCP_DSTFORMAT);
45602be438aSmrg  TDFXWriteLong(pTDFX, SST_2D_DSTFORMAT, fmt);
45702be438aSmrg  pTDFX->sst2DDstFmtShadow = fmt;
45802be438aSmrg  TDFXWriteLong(pTDFX, SST_2D_SRCFORMAT, fmt);
45902be438aSmrg  pTDFX->sst2DSrcFmtShadow = fmt;
46002be438aSmrg}
46102be438aSmrg
46202be438aSmrgvoid
46302be438aSmrgTDFXSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int srcX, int srcY,
46402be438aSmrg				 int dstX, int dstY, int w, int h)
46502be438aSmrg{
46602be438aSmrg  TDFXPtr pTDFX;
46702be438aSmrg
46802be438aSmrg  TDFXTRACEACCEL("TDFXSubsequentScreenToScreenCopy\n srcX=%d srcY=%d"
46902be438aSmrg                 " dstX=%d dstY=%d w=%d h=%d\n", srcX, srcY, dstX, dstY, w, h);
47002be438aSmrg  pTDFX=TDFXPTR(pScrn);
47102be438aSmrg  TDFXMatchState(pTDFX);
47202be438aSmrg
47302be438aSmrg  if (pTDFX->Cmd&SST_2D_Y_BOTTOM_TO_TOP) {
47402be438aSmrg    srcY += h-1;
47502be438aSmrg    dstY += h-1;
47602be438aSmrg  }
47702be438aSmrg  if (pTDFX->Cmd&SST_2D_X_RIGHT_TO_LEFT) {
47802be438aSmrg    srcX += w-1;
47902be438aSmrg    dstX += w-1;
48002be438aSmrg  }
48102be438aSmrg  if ((srcY>=dstY-32 && srcY<=dstY)||
48202be438aSmrg      (srcY>=pTDFX->prevBlitDest.y1-32 && srcY<=pTDFX->prevBlitDest.y1)) {
48302be438aSmrg    TDFXSendNOP(pScrn);
48402be438aSmrg  }
48502be438aSmrg  pTDFX->sync(pScrn);
48602be438aSmrg
48702be438aSmrg  TDFXMakeRoom(pTDFX, 4);
48802be438aSmrg  DECLARE(SSTCP_DSTSIZE|SSTCP_DSTXY|SSTCP_SRCXY|SSTCP_COMMAND);
48902be438aSmrg  TDFXWriteLong(pTDFX, SST_2D_SRCXY, (srcX&0x1FFF) | ((srcY&0x1FFF)<<16));
49002be438aSmrg  TDFXWriteLong(pTDFX, SST_2D_DSTSIZE, (w&0x1FFF) | ((h&0x1FFF)<<16));
49102be438aSmrg  TDFXWriteLong(pTDFX, SST_2D_DSTXY, (dstX&0x1FFF) | ((dstY&0x1FFF)<<16));
49202be438aSmrg  TDFXWriteLong(pTDFX, SST_2D_COMMAND, pTDFX->Cmd|SST_2D_GO);
49302be438aSmrg
49402be438aSmrg  pTDFX->prevBlitDest.y1=dstY;
49502be438aSmrg}
49602be438aSmrg
49702be438aSmrgvoid
49802be438aSmrgTDFXSetupForSolidFill(ScrnInfoPtr pScrn, int color, int rop,
49902be438aSmrg		      unsigned int planemask)
50002be438aSmrg{
50102be438aSmrg  TDFXPtr pTDFX;
50202be438aSmrg  int fmt;
50302be438aSmrg
50402be438aSmrg  TDFXTRACEACCEL("TDFXSetupForSolidFill color=%d rop=%d planemask=%d\n",
50502be438aSmrg                 color, rop, planemask);
50602be438aSmrg  pTDFX=TDFXPTR(pScrn);
50702be438aSmrg  TDFXClearState(pScrn);
50802be438aSmrg
50902be438aSmrg  pTDFX->Cmd=TDFXROPCvt[rop]<<24;
51002be438aSmrg  if (pTDFX->cpp==1) fmt=(1<<16)|pTDFX->stride;
51102be438aSmrg  else fmt=((pTDFX->cpp+1)<<16)|pTDFX->stride;
51202be438aSmrg
51302be438aSmrg  TDFXMakeRoom(pTDFX, 3);
51402be438aSmrg  DECLARE(SSTCP_DSTFORMAT|SSTCP_COLORFORE|
51502be438aSmrg		 SSTCP_COLORBACK);
51602be438aSmrg  TDFXWriteLong(pTDFX, SST_2D_DSTFORMAT, fmt);
51702be438aSmrg  pTDFX->sst2DDstFmtShadow = fmt;
51802be438aSmrg  TDFXWriteLong(pTDFX, SST_2D_COLORBACK, color);
51902be438aSmrg  TDFXWriteLong(pTDFX, SST_2D_COLORFORE, color);
52002be438aSmrg}
52102be438aSmrg
52202be438aSmrgvoid
52302be438aSmrgTDFXSubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h)
52402be438aSmrg{
52502be438aSmrg  /* Also called by TDFXSubsequentMono8x8PatternFillRect */
52602be438aSmrg  TDFXPtr pTDFX;
52702be438aSmrg
52802be438aSmrg  TDFXTRACEACCEL("TDFXSubsequentSolidFillRect x=%d y=%d w=%d h=%d\n",
52902be438aSmrg		 x, y, w, h);
53002be438aSmrg  pTDFX=TDFXPTR(pScrn);
53102be438aSmrg  TDFXMatchState(pTDFX);
53202be438aSmrg
53302be438aSmrg  TDFXMakeRoom(pTDFX, 3);
53402be438aSmrg  DECLARE(SSTCP_DSTSIZE|SSTCP_DSTXY|SSTCP_COMMAND);
53502be438aSmrg  TDFXWriteLong(pTDFX, SST_2D_DSTSIZE, ((h&0x1FFF)<<16) | (w&0x1FFF));
53602be438aSmrg  TDFXWriteLong(pTDFX, SST_2D_DSTXY, ((y&0x1FFF)<<16) | (x&0x1FFF));
53702be438aSmrg  TDFXWriteLong(pTDFX, SST_2D_COMMAND, pTDFX->Cmd | SST_2D_RECTANGLEFILL |
53802be438aSmrg		SST_2D_GO);
53902be438aSmrg}
54002be438aSmrg
54102be438aSmrgstatic void
54202be438aSmrgTDFXSetupForMono8x8PatternFill(ScrnInfoPtr pScrn, int patx, int paty,
54302be438aSmrg			       int fg, int bg, int rop, unsigned int planemask)
54402be438aSmrg{
54502be438aSmrg  TDFXPtr pTDFX;
54602be438aSmrg  int fmt;
54702be438aSmrg
54802be438aSmrg  TDFXTRACEACCEL("TDFXSetupForMono8x8PatternFill patx=%x paty=%x fg=%d"
54902be438aSmrg                 " bg=%d rop=%d planemask=%d\n", patx, paty, fg, bg, rop,
55002be438aSmrg		 planemask);
55102be438aSmrg  pTDFX=TDFXPTR(pScrn);
55202be438aSmrg  TDFXClearState(pScrn);
55302be438aSmrg
55402be438aSmrg  pTDFX->Cmd = (TDFXROPCvt[rop+ROP_PATTERN_OFFSET]<<24) |
55502be438aSmrg    SST_2D_MONOCHROME_PATTERN;
55602be438aSmrg  if (bg==-1) {
55702be438aSmrg    pTDFX->Cmd |= SST_2D_TRANSPARENT_MONOCHROME;
55802be438aSmrg  }
55902be438aSmrg  if (pTDFX->cpp==1) fmt=(1<<16)|pTDFX->stride;
56002be438aSmrg  else fmt=((pTDFX->cpp+1)<<16)|pTDFX->stride;
56102be438aSmrg
56202be438aSmrg  TDFXMakeRoom(pTDFX, 5);
56302be438aSmrg  DECLARE(SSTCP_DSTFORMAT|SSTCP_PATTERN0ALIAS
56402be438aSmrg		  |SSTCP_PATTERN1ALIAS|SSTCP_COLORFORE|
56502be438aSmrg		  SSTCP_COLORBACK);
56602be438aSmrg  TDFXWriteLong(pTDFX, SST_2D_DSTFORMAT, fmt);
56702be438aSmrg  pTDFX->sst2DDstFmtShadow = fmt;
56802be438aSmrg  TDFXWriteLong(pTDFX, SST_2D_PATTERN0, patx);
56902be438aSmrg  TDFXWriteLong(pTDFX, SST_2D_PATTERN1, paty);
57002be438aSmrg  TDFXWriteLong(pTDFX, SST_2D_COLORBACK, bg);
57102be438aSmrg  TDFXWriteLong(pTDFX, SST_2D_COLORFORE, fg);
57202be438aSmrg}
57302be438aSmrg
57402be438aSmrgstatic void
57502be438aSmrgTDFXSubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, int patx, int paty,
57602be438aSmrg				     int x, int y, int w, int h)
57702be438aSmrg{
57802be438aSmrg  TDFXPtr pTDFX;
57902be438aSmrg
58002be438aSmrg  TDFXTRACEACCEL("TDFXSubsequentMono8x8PatternFillRect patx=%x paty=%x"
58102be438aSmrg                 " x=%d y=%d w=%d h=%d\n", patx, paty, x, y, w, h);
58202be438aSmrg  pTDFX=TDFXPTR(pScrn);
58302be438aSmrg
58402be438aSmrg  pTDFX->Cmd |= ((patx&0x7)<<SST_2D_X_PATOFFSET_SHIFT) |
58502be438aSmrg    ((paty&0x7)<<SST_2D_Y_PATOFFSET_SHIFT);
58602be438aSmrg
58702be438aSmrg  TDFXSubsequentSolidFillRect(pScrn, x, y, w, h);
58802be438aSmrg}
58902be438aSmrg
59002be438aSmrgstatic void
59102be438aSmrgTDFXSetupForSolidLine(ScrnInfoPtr pScrn, int color, int rop,
59202be438aSmrg		      unsigned int planemask)
59302be438aSmrg{
59402be438aSmrg  TDFXPtr pTDFX;
59502be438aSmrg
59602be438aSmrg  TDFXTRACEACCEL("TDFXSetupForSolidLine\n");
59702be438aSmrg  pTDFX=TDFXPTR(pScrn);
59802be438aSmrg  TDFXClearState(pScrn);
59902be438aSmrg
60002be438aSmrg  pTDFX->Cmd = (TDFXROPCvt[rop]<<24);
60102be438aSmrg
60202be438aSmrg  TDFXMakeRoom(pTDFX, 2);
60302be438aSmrg  DECLARE(SSTCP_COLORFORE|SSTCP_COLORBACK);
60402be438aSmrg  TDFXWriteLong(pTDFX, SST_2D_COLORBACK, color);
60502be438aSmrg  TDFXWriteLong(pTDFX, SST_2D_COLORFORE, color);
60602be438aSmrg}
60702be438aSmrg
60802be438aSmrgstatic void
60902be438aSmrgTDFXSubsequentSolidTwoPointLine(ScrnInfoPtr pScrn, int srcx, int srcy,
61002be438aSmrg				int dstx, int dsty, int flags)
61102be438aSmrg{
61202be438aSmrg  /* Also used by TDFXSubsequentDashedTwoPointLine */
61302be438aSmrg  TDFXPtr pTDFX;
61402be438aSmrg
61502be438aSmrg  TDFXTRACEACCEL("TDFXSubsequentSolidTwoPointLine "
61602be438aSmrg		 "srcx=%d srcy=%d dstx=%d dsty=%d flags=%d\n",
61702be438aSmrg		 srcx, srcy, dstx, dsty, flags);
61802be438aSmrg  pTDFX=TDFXPTR(pScrn);
61902be438aSmrg  TDFXMatchState(pTDFX);
62002be438aSmrg
62102be438aSmrg  if (flags&OMIT_LAST) pTDFX->Cmd|=SST_2D_POLYLINE;
62202be438aSmrg  else pTDFX->Cmd|=SST_2D_LINE;
62302be438aSmrg
62402be438aSmrg  TDFXMakeRoom(pTDFX, 3);
62502be438aSmrg  DECLARE(SSTCP_SRCXY|SSTCP_DSTXY|SSTCP_COMMAND);
62602be438aSmrg  TDFXWriteLong(pTDFX, SST_2D_SRCXY, (srcy&0x1FFF)<<16 | (srcx&0x1FFF));
62702be438aSmrg  TDFXWriteLong(pTDFX, SST_2D_DSTXY, (dsty&0x1FFF)<<16 | (dstx&0x1FFF));
62802be438aSmrg  TDFXWriteLong(pTDFX, SST_2D_COMMAND, pTDFX->Cmd|SST_2D_GO);
62902be438aSmrg}
63002be438aSmrg
63102be438aSmrgstatic void
63202be438aSmrgTDFXSubsequentSolidHorVertLine(ScrnInfoPtr pScrn, int x, int y, int len,
63302be438aSmrg			       int dir)
63402be438aSmrg{
63502be438aSmrg  TDFXPtr pTDFX;
63602be438aSmrg
63702be438aSmrg  TDFXTRACEACCEL("TDFXSubsequentSolidHorVertLine\n");
63802be438aSmrg  pTDFX=TDFXPTR(pScrn);
63902be438aSmrg  TDFXMatchState(pTDFX);
64002be438aSmrg
64102be438aSmrg  TDFXMakeRoom(pTDFX, 3);
64202be438aSmrg  DECLARE(SSTCP_SRCXY|SSTCP_DSTXY|SSTCP_COMMAND);
64302be438aSmrg  TDFXWriteLong(pTDFX, SST_2D_SRCXY, (y&0x1FFF)<<16 | (x&0x1FFF));
64402be438aSmrg  if (dir == DEGREES_0)
64502be438aSmrg    TDFXWriteLong(pTDFX, SST_2D_DSTXY, (y&0x1FFF)<<16 | ((x+len)&0x1FFF));
64602be438aSmrg  else
64702be438aSmrg    TDFXWriteLong(pTDFX, SST_2D_DSTXY, ((y+len)&0x1FFF)<<16 | (x&0x1FFF));
64802be438aSmrg  TDFXWriteLong(pTDFX, SST_2D_COMMAND, pTDFX->Cmd|SST_2D_POLYLINE|SST_2D_GO);
64902be438aSmrg}
65002be438aSmrg
65102be438aSmrgstatic void
65202be438aSmrgTDFXNonTEGlyphRenderer(ScrnInfoPtr pScrn, int x, int y, int n,
65302be438aSmrg		       NonTEGlyphPtr glyphs, BoxPtr pbox, int fg, int rop,
65402be438aSmrg		       unsigned int planemask)
65502be438aSmrg{
65602be438aSmrg  TDFXPtr pTDFX;
65702be438aSmrg  int ndwords;
65802be438aSmrg  int g;
65902be438aSmrg  NonTEGlyphPtr glyph;
66002be438aSmrg
66102be438aSmrg  TDFXTRACEACCEL("TDFXNonTEGlyphRenderer\n");
66202be438aSmrg  pTDFX=TDFXPTR(pScrn);
66302be438aSmrg  TDFXClearState(pScrn);
66402be438aSmrg  /* Don't bother fixing clip1, we're going to change it anyway */
66502be438aSmrg  pTDFX->DrawState&=~DRAW_STATE_CLIP1CHANGED;
66602be438aSmrg  TDFXMatchState(pTDFX);
66702be438aSmrg  /* We're changing clip1 so make sure we use it and flag it */
66802be438aSmrg  pTDFX->Cmd|=SST_2D_USECLIP1;
66902be438aSmrg  pTDFX->DrawState|=DRAW_STATE_CLIP1CHANGED;
67002be438aSmrg
67102be438aSmrg  pTDFX->Cmd|=(TDFXROPCvt[rop]<<24)|SST_2D_TRANSPARENT_MONOCHROME;
67202be438aSmrg  pTDFX->Cmd|=SST_2D_HOSTTOSCRNBLIT;
67302be438aSmrg
67402be438aSmrg  TDFXMakeRoom(pTDFX, 6);
67502be438aSmrg  DECLARE(SSTCP_CLIP1MIN|SSTCP_CLIP1MAX|SSTCP_SRCFORMAT|
67602be438aSmrg	  SSTCP_SRCXY|SSTCP_COLORFORE|SSTCP_COMMAND);
67702be438aSmrg  TDFXWriteLong(pTDFX, SST_2D_CLIP1MIN, ((pbox->y1&0x1FFF)<<16) |
67802be438aSmrg		(pbox->x1&0x1FFF));
67902be438aSmrg  TDFXWriteLong(pTDFX, SST_2D_CLIP1MAX, ((pbox->y2&0x1FFF)<<16) |
68002be438aSmrg		(pbox->x2&0x1FFF));
68102be438aSmrg#if X_BYTE_ORDER == X_BIG_ENDIAN
68202be438aSmrg  TDFXWriteLong(pTDFX, SST_2D_SRCFORMAT, SST_2D_PIXFMT_1BPP |
68302be438aSmrg		SST_2D_SOURCE_PACKING_DWORD | BIT(20));
68402be438aSmrg#else
68502be438aSmrg  TDFXWriteLong(pTDFX, SST_2D_SRCFORMAT, SST_2D_PIXFMT_1BPP |
68602be438aSmrg		SST_2D_SOURCE_PACKING_DWORD);
68702be438aSmrg#endif
68802be438aSmrg  pTDFX->sst2DSrcFmtShadow = SST_2D_PIXFMT_1BPP | SST_2D_SOURCE_PACKING_DWORD;
68902be438aSmrg  TDFXWriteLong(pTDFX, SST_2D_SRCXY, 0);
69002be438aSmrg  TDFXWriteLong(pTDFX, SST_2D_COLORFORE, fg);
69102be438aSmrg  TDFXWriteLong(pTDFX, SST_2D_COMMAND, pTDFX->Cmd);
69202be438aSmrg
69302be438aSmrg  for (g=0, glyph=glyphs; g<n; g++, glyph++) {
69402be438aSmrg    int dx = x+glyph->start;
69502be438aSmrg    int dy = y-glyph->yoff;
69602be438aSmrg    int w = glyph->end - glyph->start;
69702be438aSmrg    int *glyph_data = (int*)glyph->bits;
69802be438aSmrg
69902be438aSmrg    if (!glyph->srcwidth) continue;
70002be438aSmrg    ndwords = (glyph->srcwidth+3)>>2;
70102be438aSmrg    ndwords *= glyph->height;
70202be438aSmrg
70302be438aSmrg    TDFXMakeRoom(pTDFX, 2);
70402be438aSmrg    DECLARE(SSTCP_DSTSIZE|SSTCP_DSTXY);
70502be438aSmrg    TDFXWriteLong(pTDFX, SST_2D_DSTSIZE, ((glyph->height&0x1FFF)<<16) |
70602be438aSmrg		  (w&0x1FFF));
70702be438aSmrg    TDFXWriteLong(pTDFX, SST_2D_DSTXY, ((dy&0x1FFF)<<16) | (dx&0x1FFF));
70802be438aSmrg
70902be438aSmrg    do {
71002be438aSmrg      int i = ndwords;
71102be438aSmrg      int j;
71202be438aSmrg
71302be438aSmrg      if (i>30) i=30;
71402be438aSmrg      TDFXMakeRoom(pTDFX, i);
71502be438aSmrg      DECLARE_LAUNCH(i, 0);
71602be438aSmrg      for (j=0; j<i; j++) {
71702be438aSmrg#if X_BYTE_ORDER == X_BIG_ENDIAN
71802be438aSmrg	TDFXWriteLong(pTDFX, SST_2D_LAUNCH, *glyph_data);
71902be438aSmrg#else
72002be438aSmrg	TDFXWriteLong(pTDFX, SST_2D_LAUNCH, XAAReverseBitOrder(*glyph_data));
72102be438aSmrg#endif
72202be438aSmrg	glyph_data++;
72302be438aSmrg      }
72402be438aSmrg      ndwords -= i;
72502be438aSmrg    } while (ndwords);
72602be438aSmrg  }
72702be438aSmrg}
72802be438aSmrg
72902be438aSmrgstatic void
73002be438aSmrgTDFXSetupForDashedLine(ScrnInfoPtr pScrn, int fg, int bg, int rop,
73102be438aSmrg                       unsigned int planemask, int length,
73202be438aSmrg		       unsigned char *pattern)
73302be438aSmrg{
73402be438aSmrg  TDFXPtr pTDFX;
73502be438aSmrg#if X_BYTE_ORDER == X_BIG_ENDIAN
73602be438aSmrg  unsigned int pat = *(unsigned int *)pattern;
73702be438aSmrg#endif
73802be438aSmrg
73902be438aSmrg  TDFXTRACEACCEL("TDFXSetupForDashedLine\n");
74002be438aSmrg  pTDFX=TDFXPTR(pScrn);
74102be438aSmrg
74202be438aSmrg#if X_BYTE_ORDER == X_BIG_ENDIAN
74302be438aSmrg  pat=((pat & 0xAAAAAAAA) >> 1) | ((pat & 0x55555555) << 1);
74402be438aSmrg  pat=((pat & 0xCCCCCCCC) >> 2) | ((pat & 0x33333333) << 2);
74502be438aSmrg  pat=((pat & 0xF0F0F0F0) >> 4) | ((pat & 0x0F0F0F0F) << 4);
74602be438aSmrg  pat=((pat & 0xFF00FF00) >> 8) | ((pat & 0x00FF00FF) << 8);
74702be438aSmrg  pat=((pat & 0xFFFF0000) >> 16) | ((pat & 0x0000FFFF) << 16);
74802be438aSmrg#endif
74902be438aSmrg
75002be438aSmrg  TDFXClearState(pScrn);
75102be438aSmrg
75202be438aSmrg  pTDFX->Cmd = (TDFXROPCvt[rop]<<24) | SST_2D_STIPPLE_LINE;
75302be438aSmrg  if(bg == -1) {
75402be438aSmrg    pTDFX->Cmd |= SST_2D_TRANSPARENT_MONOCHROME;
75502be438aSmrg  }
75602be438aSmrg  pTDFX->DashedLineSize = ((length-1)&0xFF)+1;
75702be438aSmrg
75802be438aSmrg  TDFXMakeRoom(pTDFX, 3);
75902be438aSmrg  DECLARE(SSTCP_COLORFORE|SSTCP_COLORBACK|SSTCP_LINESTIPPLE);
76002be438aSmrg#if X_BYTE_ORDER == X_BIG_ENDIAN
76102be438aSmrg  TDFXWriteLong(pTDFX, SST_2D_LINESTIPPLE, pat);
76202be438aSmrg#else
76302be438aSmrg  TDFXWriteLong(pTDFX, SST_2D_LINESTIPPLE, *(int *)pattern);
76402be438aSmrg#endif
76502be438aSmrg  TDFXWriteLong(pTDFX, SST_2D_COLORBACK, bg);
76602be438aSmrg  TDFXWriteLong(pTDFX, SST_2D_COLORFORE, fg);
76702be438aSmrg}
76802be438aSmrg
76902be438aSmrgstatic void
77002be438aSmrgTDFXSubsequentDashedTwoPointLine(ScrnInfoPtr pScrn, int x1, int y1,
77102be438aSmrg                                 int x2, int y2, int flags, int phase)
77202be438aSmrg{
77302be438aSmrg  TDFXPtr pTDFX;
77402be438aSmrg  int linestyle;
77502be438aSmrg
77602be438aSmrg  TDFXTRACEACCEL("TDFXSubsequentDashedTwoPointLine\n");
77702be438aSmrg  pTDFX=TDFXPTR(pScrn);
77802be438aSmrg
77902be438aSmrg  linestyle = ((pTDFX->DashedLineSize-1)<<8) |
78002be438aSmrg              (((phase%pTDFX->DashedLineSize)&0x1F)<<24);
78102be438aSmrg
78202be438aSmrg  TDFXMakeRoom(pTDFX, 1);
78302be438aSmrg  DECLARE(SSTCP_LINESTYLE);
78402be438aSmrg  TDFXWriteLong(pTDFX, SST_2D_LINESTYLE, linestyle);
78502be438aSmrg
78602be438aSmrg  TDFXSubsequentSolidTwoPointLine(pScrn, x1, y1, x2, y2, flags);
78702be438aSmrg}
78802be438aSmrg
78902be438aSmrg#ifdef ENABLE_SS_COLOR_EXPAND_FILL
79002be438aSmrgstatic void
79102be438aSmrgTDFXSetupForScreenToScreenColorExpandFill(ScrnInfoPtr pScrn, int fg, int bg,
79202be438aSmrg                                          int rop, unsigned int planemask)
79302be438aSmrg{
79402be438aSmrg  TDFXPtr pTDFX;
79502be438aSmrg
79602be438aSmrg  TDFXTRACEACCEL("TDFXSetupForScreenToScreenColorExpandFill\n");
79702be438aSmrg  pTDFX=TDFXPTR(pScrn);
79802be438aSmrg  TDFXClearState(pScrn);
79902be438aSmrg
80002be438aSmrg  TDFXMatchState(pTDFX);
80102be438aSmrg  pTDFX->Cmd|=SST_2D_SCRNTOSCRNBLIT|(TDFXROPCvt[rop]<<24);
80202be438aSmrg
80302be438aSmrg  if (bg==-1) {
80402be438aSmrg    pTDFX->Cmd |= SST_2D_TRANSPARENT_MONOCHROME;
80502be438aSmrg  }
80602be438aSmrg  TDFXMakeRoom(pTDFX, 2);
80702be438aSmrg  DECLARE(SSTCP_COLORFORE|SSTCP_COLORBACK);
80802be438aSmrg  TDFXWriteLong(pTDFX, SST_2D_COLORBACK, bg);
80902be438aSmrg  TDFXWriteLong(pTDFX, SST_2D_COLORFORE, fg);
81002be438aSmrg}
81102be438aSmrg
81202be438aSmrgstatic void
81302be438aSmrgTDFXSubsequentScreenToScreenColorExpandFill(ScrnInfoPtr pScrn, int x, int y,
81402be438aSmrg                                            int w, int h, int srcx, int srcy,
81502be438aSmrg                                            int offset)
81602be438aSmrg{
81702be438aSmrg  TDFXPtr pTDFX;
81802be438aSmrg  int fmt;
81902be438aSmrg
82002be438aSmrg  TDFXTRACEACCEL("TDFXSubsequentScreenToScreenColorExpandFill "
82102be438aSmrg		 "x=%d y=%d w=%d h=%d srcx=%d srcy=%d offset=%d\n",
82202be438aSmrg		 x, y, w, h, srcx, srcy, offset);
82302be438aSmrg  pTDFX=TDFXPTR(pScrn);
82402be438aSmrg  /* Don't bother resetting clip1 since we're changing it anyway */
82502be438aSmrg  pTDFX->DrawState&=~DRAW_STATE_CLIP1CHANGED;
82602be438aSmrg  TDFXMatchState(pTDFX);
82702be438aSmrg  /* We're changing clip1 so make sure we use it and flag it */
82802be438aSmrg  pTDFX->Cmd|=SST_2D_USECLIP1;
82902be438aSmrg  pTDFX->DrawState|=DRAW_STATE_CLIP1CHANGED;
83002be438aSmrg
83102be438aSmrg  if (srcy>=pTDFX->prevBlitDest.y1-8 && srcy<=pTDFX->prevBlitDest.y1) {
83202be438aSmrg    TDFXSendNOP(pScrn);
83302be438aSmrg  }
83402be438aSmrg
83502be438aSmrg  if (pTDFX->cpp==1) fmt=(1<<16)|pTDFX->stride;
83602be438aSmrg  else fmt=(pTDFX->cpp+1)<<16|pTDFX->stride;
83702be438aSmrg
83802be438aSmrg  TDFXMakeRoom(pTDFX, 8);
83902be438aSmrg  DECLARE(SSTCP_SRCFORMAT|SSTCP_SRCXY|SSTCP_DSTFORMAT |
84002be438aSmrg	  SSTCP_DSTSIZE|SSTCP_DSTXY|SSTCP_COMMAND |
84102be438aSmrg	  SSTCP_CLIP1MIN|SSTCP_CLIP1MAX);
84202be438aSmrg  TDFXWriteLong(pTDFX,SST_2D_DSTFORMAT, fmt);
84302be438aSmrg  pTDFX->sst2DDstFmtShadow = fmt;
84402be438aSmrg  TDFXWriteLong(pTDFX,SST_2D_CLIP1MIN, (x&0x1FFF) | ((y&0x1FFF)<<16));
84502be438aSmrg  TDFXWriteLong(pTDFX,SST_2D_CLIP1MAX, ((x+w)&0x1FFF) | (((y+h)&0x1FFF)<<16));
84602be438aSmrg  TDFXWriteLong(pTDFX,SST_2D_SRCFORMAT, pTDFX->stride);
84702be438aSmrg  pTDFX->sst2DSrcFmtShadow = pTDFX->stride;
84802be438aSmrg  TDFXWriteLong(pTDFX,SST_2D_SRCXY, (srcx&0x1FFF) | ((srcy&0x1FFF)<<16));
84902be438aSmrg  TDFXWriteLong(pTDFX,SST_2D_DSTSIZE, ((w+offset)&0x1FFF) | ((h&0x1FFF)<<16));
85002be438aSmrg  TDFXWriteLong(pTDFX,SST_2D_DSTXY, ((x-offset)&0x1FFF) | ((y&0x1FFF)<<16));
85102be438aSmrg  TDFXWriteLong(pTDFX,SST_2D_COMMAND, pTDFX->Cmd|SST_2D_GO);
85202be438aSmrg
85302be438aSmrg  pTDFX->prevBlitDest.y1=y;
85402be438aSmrg}
85502be438aSmrg#endif
85602be438aSmrg
85702be438aSmrgstatic void
85802be438aSmrgTDFXSetupForCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, int fg, int bg,
85902be438aSmrg                                       int rop, unsigned int planemask)
86002be438aSmrg{
86102be438aSmrg  TDFXPtr pTDFX;
86202be438aSmrg
86302be438aSmrg  TDFXTRACEACCEL("SetupForCPUToScreenColorExpandFill bg=%x fg=%x rop=%d\n",
86402be438aSmrg                 bg, fg, rop);
86502be438aSmrg  pTDFX=TDFXPTR(pScrn);
86602be438aSmrg  TDFXClearState(pScrn);
86702be438aSmrg
86802be438aSmrg  pTDFX->Cmd|=SST_2D_HOSTTOSCRNBLIT|(TDFXROPCvt[rop]<<24);
86902be438aSmrg
87002be438aSmrg  if (bg == -1) {
87102be438aSmrg    pTDFX->Cmd |= SST_2D_TRANSPARENT_MONOCHROME;
87202be438aSmrg  }
87302be438aSmrg
87402be438aSmrg  TDFXMakeRoom(pTDFX, 2);
87502be438aSmrg  DECLARE(SSTCP_COLORBACK|SSTCP_COLORFORE);
87602be438aSmrg  TDFXWriteLong(pTDFX, SST_2D_COLORBACK, bg);
87702be438aSmrg  TDFXWriteLong(pTDFX, SST_2D_COLORFORE, fg);
87802be438aSmrg}
87902be438aSmrg
88002be438aSmrgstatic void
88102be438aSmrgTDFXSubsequentCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, int x, int y,
88202be438aSmrg                                         int w, int h, int skipleft)
88302be438aSmrg{
88402be438aSmrg  TDFXPtr pTDFX;
88502be438aSmrg  int fmt;
88602be438aSmrg
88702be438aSmrg  TDFXTRACEACCEL("SubsequentCPUToScreenColorExpandFill x=%d y=%d w=%d h=%d"
88802be438aSmrg                 " skipleft=%d\n", x, y, w, h, skipleft);
88902be438aSmrg  pTDFX = TDFXPTR(pScrn);
89002be438aSmrg
89102be438aSmrg  /* We're changing clip1 anyway, so don't bother to reset it */
89202be438aSmrg  pTDFX->DrawState&=~DRAW_STATE_CLIP1CHANGED;
89302be438aSmrg  TDFXMatchState(pTDFX);
89402be438aSmrg  /* Make sure we use clip1 and flag it */
89502be438aSmrg  pTDFX->Cmd|=SST_2D_USECLIP1;
89602be438aSmrg  pTDFX->DrawState|=DRAW_STATE_CLIP1CHANGED;
89702be438aSmrg
89802be438aSmrg  if (pTDFX->cpp==1) fmt=(1<<16)|pTDFX->stride;
89902be438aSmrg  else fmt=((pTDFX->cpp+1)<<16)|pTDFX->stride;
90002be438aSmrg  pTDFX->scanlineWidth=w;
90102be438aSmrg
90202be438aSmrg  TDFXMakeRoom(pTDFX, 8);
90302be438aSmrg  DECLARE(SSTCP_CLIP1MIN|SSTCP_CLIP1MAX|SSTCP_SRCFORMAT|
90402be438aSmrg	  SSTCP_DSTFORMAT|SSTCP_DSTSIZE|SSTCP_SRCXY|
90502be438aSmrg	  SSTCP_DSTXY|SSTCP_COMMAND);
90602be438aSmrg  TDFXWriteLong(pTDFX, SST_2D_DSTFORMAT, fmt);
90702be438aSmrg  pTDFX->sst2DDstFmtShadow = fmt;
90802be438aSmrg  TDFXWriteLong(pTDFX, SST_2D_CLIP1MIN, ((y&0x1FFF)<<16)|(x&0x1FFF));
90902be438aSmrg  TDFXWriteLong(pTDFX, SST_2D_CLIP1MAX, (((y+h)&0x1FFF)<<16)|((x+w)&0x1FFF));
91002be438aSmrg#if X_BYTE_ORDER == X_BIG_ENDIAN
91102be438aSmrg  /* bit 20 byte swizzle */
91202be438aSmrg  TDFXWriteLong(pTDFX, SST_2D_SRCFORMAT, ((((w+31)/32)*4) & 0x3FFF) | BIT(20));
91302be438aSmrg#else
91402be438aSmrg  TDFXWriteLong(pTDFX, SST_2D_SRCFORMAT,  (((w+31)/32)*4) & 0x3FFF);
91502be438aSmrg#endif
91602be438aSmrg  pTDFX->sst2DSrcFmtShadow = (((w+31)/32)*4) & 0x3FFF;
91702be438aSmrg  TDFXWriteLong(pTDFX, SST_2D_SRCXY, skipleft&0x1F);
91802be438aSmrg  TDFXWriteLong(pTDFX, SST_2D_DSTSIZE, ((w-skipleft)&0x1FFF)|((h&0x1FFF)<<16));
91902be438aSmrg  TDFXWriteLong(pTDFX, SST_2D_DSTXY, ((x+skipleft)&0x1FFF) | ((y&0x1FFF)<<16));
92002be438aSmrg  TDFXWriteLong(pTDFX, SST_2D_COMMAND, pTDFX->Cmd|SST_2D_GO);
92102be438aSmrg}
92202be438aSmrg
92302be438aSmrgstatic void TDFXSubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno)
92402be438aSmrg{
92502be438aSmrg  TDFXPtr pTDFX;
92602be438aSmrg  int i, size, cnt;
92702be438aSmrg  CARD32 *pos;
92802be438aSmrg
92902be438aSmrg  TDFXTRACEACCEL("SubsequentColorExpandScanline bufno=%d\n", bufno);
93002be438aSmrg  pTDFX = TDFXPTR(pScrn);
93102be438aSmrg
93202be438aSmrg  cnt=(pTDFX->scanlineWidth+31)/32;
93302be438aSmrg  pos=(CARD32 *)pTDFX->scanlineColorExpandBuffers[bufno];
93402be438aSmrg  while (cnt>0) {
93502be438aSmrg    if (cnt>64) size=64;
93602be438aSmrg    else size=cnt;
93702be438aSmrg    TDFXMakeRoom(pTDFX, size);
93802be438aSmrg    DECLARE_LAUNCH(size, 0);
93902be438aSmrg    for (i=0; i<size; i++, pos++) {
94002be438aSmrg      TDFXWriteLong(pTDFX, SST_2D_LAUNCH, *pos);
94102be438aSmrg    }
94202be438aSmrg    cnt-=size;
94302be438aSmrg  }
94402be438aSmrg}
94502be438aSmrg
946909209eeSmrg#endif
947