nv_dga.c revision fc5a983d
1#ifdef HAVE_CONFIG_H
2#include "config.h"
3#endif
4
5#include "nv_local.h"
6#include "nv_include.h"
7#include "nv_type.h"
8#include "nv_proto.h"
9#include "xaalocal.h"
10#include "dgaproc.h"
11
12
13static Bool NV_OpenFramebuffer(ScrnInfoPtr, char **, unsigned char **,
14					int *, int *, int *);
15static Bool NV_SetMode(ScrnInfoPtr, DGAModePtr);
16static int  NV_GetViewport(ScrnInfoPtr);
17static void NV_SetViewport(ScrnInfoPtr, int, int, int);
18static void NV_FillRect(ScrnInfoPtr, int, int, int, int, unsigned long);
19static void NV_BlitRect(ScrnInfoPtr, int, int, int, int, int, int);
20static void NV_BlitTransRect(ScrnInfoPtr, int, int, int, int, int, int,
21					unsigned long);
22
23static
24DGAFunctionRec NV_DGAFuncs = {
25   NV_OpenFramebuffer,
26   NULL,
27   NV_SetMode,
28   NV_SetViewport,
29   NV_GetViewport,
30   NVSync,
31   NV_FillRect,
32   NV_BlitRect,
33   NV_BlitTransRect
34};
35
36
37
38static DGAModePtr
39NVSetupDGAMode(
40   ScrnInfoPtr pScrn,
41   DGAModePtr modes,
42   int *num,
43   int bitsPerPixel,
44   int depth,
45   Bool pixmap,
46   int secondPitch,
47   unsigned long red,
48   unsigned long green,
49   unsigned long blue,
50   short visualClass
51){
52   DisplayModePtr firstMode, pMode;
53   NVPtr pNv = NVPTR(pScrn);
54   DGAModePtr mode, newmodes;
55   int size, pitch, Bpp = bitsPerPixel >> 3;
56
57SECOND_PASS:
58
59   pMode = firstMode = pScrn->modes;
60
61   while(1) {
62
63	pitch = (pMode->HDisplay + 31) & ~31;
64	size = pitch * Bpp * pMode->VDisplay;
65
66	if((!secondPitch || (pitch != secondPitch)) &&
67		(size <= pNv->ScratchBufferStart)) {
68
69	    if(secondPitch)
70		pitch = secondPitch;
71
72	    if(!(newmodes = xrealloc(modes, (*num + 1) * sizeof(DGAModeRec))))
73		break;
74
75	    modes = newmodes;
76	    mode = modes + *num;
77
78	    mode->mode = pMode;
79	    mode->flags = DGA_CONCURRENT_ACCESS;
80
81	    if(pixmap)
82		mode->flags |= DGA_PIXMAP_AVAILABLE;
83	    if(!pNv->NoAccel)
84		mode->flags |= DGA_FILL_RECT | DGA_BLIT_RECT;
85	    if(pMode->Flags & V_DBLSCAN)
86		mode->flags |= DGA_DOUBLESCAN;
87	    if(pMode->Flags & V_INTERLACE)
88		mode->flags |= DGA_INTERLACED;
89	    mode->byteOrder = pScrn->imageByteOrder;
90	    mode->depth = depth;
91	    mode->bitsPerPixel = bitsPerPixel;
92	    mode->red_mask = red;
93	    mode->green_mask = green;
94	    mode->blue_mask = blue;
95	    mode->visualClass = visualClass;
96	    mode->viewportWidth = pMode->HDisplay;
97	    mode->viewportHeight = pMode->VDisplay;
98	    mode->xViewportStep = 4 / Bpp;
99	    mode->yViewportStep = 1;
100	    mode->viewportFlags = DGA_FLIP_RETRACE;
101	    mode->offset = 0;
102	    mode->address = pNv->FbStart;
103	    mode->bytesPerScanline = pitch * Bpp;
104	    mode->imageWidth = pitch;
105	    mode->imageHeight =  pNv->ScratchBufferStart /
106                                 mode->bytesPerScanline;
107	    mode->pixmapWidth = mode->imageWidth;
108	    mode->pixmapHeight = mode->imageHeight;
109	    mode->maxViewportX = mode->imageWidth - mode->viewportWidth;
110	    mode->maxViewportY = mode->imageHeight - mode->viewportHeight;
111	    (*num)++;
112	}
113
114	pMode = pMode->next;
115	if(pMode == firstMode)
116	   break;
117    }
118
119    if(secondPitch) {
120	secondPitch = 0;
121	goto SECOND_PASS;
122    }
123
124    return modes;
125}
126
127
128Bool
129NVDGAInit(ScreenPtr pScreen)
130{
131   ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
132   NVPtr pNv = NVPTR(pScrn);
133   DGAModePtr modes = NULL;
134   int num = 0;
135
136   /* 8 */
137   modes = NVSetupDGAMode (pScrn, modes, &num, 8, 8,
138		(pScrn->bitsPerPixel == 8),
139		(pScrn->bitsPerPixel != 8) ? 0 : pScrn->displayWidth,
140		0, 0, 0, PseudoColor);
141
142   /* 15 */
143   modes = NVSetupDGAMode (pScrn, modes, &num, 16, 15,
144		(pScrn->bitsPerPixel == 16),
145		(pScrn->depth != 15) ? 0 : pScrn->displayWidth,
146		0x7c00, 0x03e0, 0x001f, TrueColor);
147
148   /* 16 */
149   modes = NVSetupDGAMode (pScrn, modes, &num, 16, 16,
150		(pScrn->bitsPerPixel == 16),
151		(pScrn->depth != 16) ? 0 : pScrn->displayWidth,
152		0xf800, 0x07e0, 0x001f, TrueColor);
153
154   /* 32 */
155   modes = NVSetupDGAMode (pScrn, modes, &num, 32, 24,
156		(pScrn->bitsPerPixel == 32),
157		(pScrn->bitsPerPixel != 32) ? 0 : pScrn->displayWidth,
158		0xff0000, 0x00ff00, 0x0000ff, TrueColor);
159
160   pNv->numDGAModes = num;
161   pNv->DGAModes = modes;
162
163   return DGAInit(pScreen, &NV_DGAFuncs, modes, num);
164}
165
166
167static int
168BitsSet(unsigned long data)
169{
170   unsigned long mask;
171   int set = 0;
172
173   for(mask = 1; mask; mask <<= 1)
174        if(mask & data) set++;
175
176   return set;
177}
178
179static Bool
180NV_SetMode(
181   ScrnInfoPtr pScrn,
182   DGAModePtr pMode
183){
184   static NVFBLayout SavedLayouts[MAXSCREENS];
185   int index = pScrn->pScreen->myNum;
186
187   NVPtr pNv = NVPTR(pScrn);
188
189   if(!pMode) { /* restore the original mode */
190      if(pNv->DGAactive)
191        memcpy(&pNv->CurrentLayout, &SavedLayouts[index], sizeof(NVFBLayout));
192
193      pScrn->currentMode = pNv->CurrentLayout.mode;
194      NVSwitchMode(index, pScrn->currentMode, 0);
195      NVAdjustFrame(index, pScrn->frameX0, pScrn->frameY0, 0);
196      pNv->DGAactive = FALSE;
197   } else {
198      if(!pNv->DGAactive) {  /* save the old parameters */
199	memcpy(&SavedLayouts[index], &pNv->CurrentLayout, sizeof(NVFBLayout));
200	pNv->DGAactive = TRUE;
201      }
202
203      /* update CurrentLayout */
204      pNv->CurrentLayout.bitsPerPixel = pMode->bitsPerPixel;
205      pNv->CurrentLayout.depth = pMode->depth;
206      pNv->CurrentLayout.displayWidth = pMode->bytesPerScanline /
207                              (pMode->bitsPerPixel >> 3);
208      pNv->CurrentLayout.weight.red = BitsSet(pMode->red_mask);
209      pNv->CurrentLayout.weight.green = BitsSet(pMode->green_mask);
210      pNv->CurrentLayout.weight.blue = BitsSet(pMode->blue_mask);
211      /* NVModeInit() will set the mode field */
212      NVSwitchMode(index, pMode->mode, 0);
213   }
214
215   return TRUE;
216}
217
218
219
220static int
221NV_GetViewport(
222  ScrnInfoPtr pScrn
223){
224    NVPtr pNv = NVPTR(pScrn);
225
226    return pNv->DGAViewportStatus;
227}
228
229static void
230NV_SetViewport(
231   ScrnInfoPtr pScrn,
232   int x, int y,
233   int flags
234){
235   NVPtr pNv = NVPTR(pScrn);
236
237   NVAdjustFrame(pScrn->pScreen->myNum, x, y, flags);
238
239   while(VGA_RD08(pNv->PCIO, 0x3da) & 0x08);
240   while(!(VGA_RD08(pNv->PCIO, 0x3da) & 0x08));
241
242   pNv->DGAViewportStatus = 0;
243}
244
245static void
246NV_FillRect (
247   ScrnInfoPtr pScrn,
248   int x, int y, int w, int h,
249   unsigned long color
250){
251    NVPtr pNv = NVPTR(pScrn);
252
253    if(!pNv->AccelInfoRec) return;
254
255    (*pNv->AccelInfoRec->SetupForSolidFill)(pScrn, color, GXcopy, ~0);
256    (*pNv->AccelInfoRec->SubsequentSolidFillRect)(pScrn, x, y, w, h);
257
258    SET_SYNC_FLAG(pNv->AccelInfoRec);
259}
260
261static void
262NV_BlitRect(
263   ScrnInfoPtr pScrn,
264   int srcx, int srcy,
265   int w, int h,
266   int dstx, int dsty
267){
268    NVPtr pNv = NVPTR(pScrn);
269    int xdir = ((srcx < dstx) && (srcy == dsty)) ? -1 : 1;
270    int ydir = (srcy < dsty) ? -1 : 1;
271
272    if(!pNv->AccelInfoRec) return;
273
274    (*pNv->AccelInfoRec->SetupForScreenToScreenCopy)(
275		pScrn, xdir, ydir, GXcopy, ~0, -1);
276
277    (*pNv->AccelInfoRec->SubsequentScreenToScreenCopy)(
278		pScrn, srcx, srcy, dstx, dsty, w, h);
279
280    SET_SYNC_FLAG(pNv->AccelInfoRec);
281}
282
283
284static void
285NV_BlitTransRect(
286   ScrnInfoPtr pScrn,
287   int srcx, int srcy,
288   int w, int h,
289   int dstx, int dsty,
290   unsigned long color
291){
292   /* not implemented */
293}
294
295
296static Bool
297NV_OpenFramebuffer(
298   ScrnInfoPtr pScrn,
299   char **name,
300   unsigned char **mem,
301   int *size,
302   int *offset,
303   int *flags
304){
305    NVPtr pNv = NVPTR(pScrn);
306
307    *name = NULL; 		/* no special device */
308    *mem = (unsigned char*)pNv->FbAddress;
309    *size = pNv->FbMapSize;
310    *offset = 0;
311    *flags = DGA_NEED_ROOT;
312
313    return TRUE;
314}
315