1
2#ifdef HAVE_CONFIG_H
3#include "config.h"
4#endif
5
6#include "xf86.h"
7#include "xf86_OSproc.h"
8#include "dgaproc.h"
9
10#include "tdfx.h"
11#include "vgaHW.h"
12
13static Bool TDFX_OpenFramebuffer(ScrnInfoPtr, char **, unsigned char **,
14				 int *, int *, int *);
15static Bool TDFX_SetMode(ScrnInfoPtr, DGAModePtr);
16static int  TDFX_GetViewport(ScrnInfoPtr);
17static void TDFX_SetViewport(ScrnInfoPtr, int, int, int);
18#ifdef HAVE_XAA_H
19static void TDFX_FillRect(ScrnInfoPtr, int, int, int, int, unsigned long);
20static void TDFX_BlitRect(ScrnInfoPtr, int, int, int, int, int, int);
21static void TDFX_BlitTransRect(ScrnInfoPtr, int, int, int, int, int, int,
22			       unsigned long);
23#endif
24
25
26static
27DGAFunctionRec TDFX_DGAFuncs = {
28  TDFX_OpenFramebuffer,
29  0,
30  TDFX_SetMode,
31  TDFX_SetViewport,
32  TDFX_GetViewport,
33  TDFXSync,
34#ifdef HAVE_XAA_H
35  TDFX_FillRect,
36  TDFX_BlitRect,
37  TDFX_BlitTransRect
38#else
39  NULL, NULL, NULL
40#endif
41};
42
43
44Bool
45TDFXDGAInit(ScreenPtr pScreen)
46{
47  ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
48  TDFXPtr pTDFX;
49  DisplayModePtr pMode, firstMode;
50  DGAModePtr modes=0, newmodes=0, currentMode;
51  int num=0;
52
53  pTDFX = TDFXPTR(pScrn);
54  pMode = firstMode = pScrn->modes;
55
56  while (pMode) {
57    newmodes = realloc(modes, (num+1)*sizeof(DGAModeRec));
58
59    if (!newmodes) {
60      free(modes);
61      return FALSE;
62    }
63    modes = newmodes;
64
65    currentMode = modes+num;
66    num++;
67    currentMode->mode = pMode;
68    currentMode->flags = DGA_CONCURRENT_ACCESS | DGA_PIXMAP_AVAILABLE;
69#ifdef HAVE_XAA_H
70    if (!pTDFX->NoAccel)
71      currentMode->flags |= DGA_FILL_RECT | DGA_BLIT_RECT;
72#endif
73    if (pMode->Flags & V_DBLSCAN)
74      currentMode->flags |= DGA_DOUBLESCAN;
75    if (pMode->Flags & V_INTERLACE)
76      currentMode->flags |= DGA_INTERLACED;
77    currentMode->byteOrder = pScrn->imageByteOrder;
78    currentMode->depth = pScrn->depth;
79    currentMode->bitsPerPixel = pScrn->bitsPerPixel;
80    currentMode->red_mask = pScrn->mask.red;
81    currentMode->green_mask = pScrn->mask.green;
82    currentMode->blue_mask = pScrn->mask.blue;
83    currentMode->visualClass = pScrn->defaultVisual;
84    currentMode->viewportWidth = pMode->HDisplay;
85    currentMode->viewportHeight = pMode->VDisplay;
86    currentMode->xViewportStep = 1;
87    currentMode->yViewportStep = 1;
88    currentMode->viewportFlags = DGA_FLIP_RETRACE;
89    currentMode->offset = 0;
90    currentMode->address = pTDFX->FbBase;
91    currentMode->bytesPerScanline = ((pScrn->displayWidth*pTDFX->cpp)+3) & ~3L;
92    currentMode->imageWidth = pScrn->displayWidth;
93    currentMode->imageHeight =  pTDFX->pixmapCacheLinesMax;
94    currentMode->pixmapWidth = currentMode->imageWidth;
95    currentMode->pixmapHeight = currentMode->imageHeight;
96    currentMode->maxViewportX = currentMode->imageWidth -
97                                currentMode->viewportWidth;
98    /* this might need to get clamped to some maximum */
99    currentMode->maxViewportY = currentMode->imageHeight -
100                                currentMode->viewportHeight;
101
102    pMode = pMode->next;
103    if (pMode == firstMode) break;
104  }
105
106  pTDFX->DGAModes = modes;
107
108  return DGAInit(pScreen, &TDFX_DGAFuncs, modes, num);
109}
110
111static Bool
112TDFX_SetMode(ScrnInfoPtr pScrn, DGAModePtr pMode)
113{
114   static DisplayModePtr OldModes[MAXSCREENS];
115   int index = pScrn->pScreen->myNum;
116
117   TDFXPtr pTDFX = TDFXPTR(pScrn);
118
119   if (!pMode) { /* restore the original mode */
120     /* put the ScreenParameters back */
121     if(pTDFX->DGAactive) {
122	TDFXSwitchMode(SWITCH_MODE_ARGS(pScrn, OldModes[index]));
123	TDFXAdjustFrame(ADJUST_FRAME_ARGS(pScrn, 0, 0));
124	pTDFX->DGAactive = FALSE;
125     }
126   } else {
127     if (!pTDFX->DGAactive) {  /* save the old parameters */
128        OldModes[index] = pScrn->currentMode;
129        pTDFX->DGAactive = TRUE;
130     }
131
132     TDFXSwitchMode(SWITCH_MODE_ARGS(pScrn, pMode->mode));
133   }
134
135   return TRUE;
136}
137
138static int
139TDFX_GetViewport(ScrnInfoPtr pScrn)
140{
141    TDFXPtr pTDFX = TDFXPTR(pScrn);
142
143    return pTDFX->DGAViewportStatus;
144}
145
146static void
147TDFX_SetViewport(ScrnInfoPtr pScrn, int x, int y, int flags)
148{
149   TDFXPtr pTDFX = TDFXPTR(pScrn);
150   vgaHWPtr hwp = VGAHWPTR(pScrn);
151
152   TDFXAdjustFrame(ADJUST_FRAME_ARGS(pScrn, x, y));
153
154   /* fixme */
155   while(hwp->readST01(hwp) & 0x08);
156   while(!(hwp->readST01(hwp) & 0x08));
157
158   pTDFX->DGAViewportStatus = 0;
159}
160
161#ifdef HAVE_XAA_H
162static void
163TDFX_FillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h,
164	      unsigned long color)
165{
166  TDFXPtr pTDFX = TDFXPTR(pScrn);
167
168  if (pTDFX->AccelInfoRec) {
169    (*pTDFX->AccelInfoRec->SetupForSolidFill)(pScrn, color, GXcopy, ~0);
170    (*pTDFX->AccelInfoRec->SubsequentSolidFillRect)(pScrn, x, y, w, h);
171  }
172}
173
174static void
175TDFX_BlitRect(ScrnInfoPtr pScrn, int srcx, int srcy, int w, int h,
176	      int dstx, int dsty)
177{
178  TDFXPtr pTDFX = TDFXPTR(pScrn);
179
180  if (pTDFX->AccelInfoRec) {
181    int xdir = ((srcx < dstx) && (srcy == dsty)) ? -1 : 1;
182    int ydir = (srcy < dsty) ? -1 : 1;
183
184    (*pTDFX->AccelInfoRec->SetupForScreenToScreenCopy)(pScrn, xdir, ydir, GXcopy, ~0, -1);
185    (*pTDFX->AccelInfoRec->SubsequentScreenToScreenCopy)(pScrn, srcx, srcy, dstx, dsty, w, h);
186  }
187}
188
189
190static void
191TDFX_BlitTransRect(
192   ScrnInfoPtr pScrn,
193   int srcx, int srcy,
194   int w, int h,
195   int dstx, int dsty,
196   unsigned long color
197){
198  /* this one should be separate since the XAA function would
199     prohibit usage of ~0 as the key */
200}
201#endif
202
203
204static Bool
205TDFX_OpenFramebuffer(
206   ScrnInfoPtr pScrn,
207   char **name,
208   unsigned char **mem,
209   int *size,
210   int *offset,
211   int *flags
212){
213    TDFXPtr pTDFX = TDFXPTR(pScrn);
214
215    *name = NULL; 		/* no special device */
216    *mem = (unsigned char*)pTDFX->LinearAddr[0] + pTDFX->fbOffset;
217    *size = pTDFX->FbMapSize;
218    *offset = /* pTDFX->fbOffset */ 0 ;  /* DGA is broken */
219    *flags = DGA_NEED_ROOT;
220
221    return TRUE;
222}
223