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