1 /* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/riva/riva_dga.c $ */
3 #include "riva_local.h"
4 #include "riva_include.h"
6 #include "riva_proto.h"
11 static Bool Riva_OpenFramebuffer(ScrnInfoPtr, char **, unsigned char **,
13 static Bool Riva_SetMode(ScrnInfoPtr, DGAModePtr);
14 static int Riva_GetViewport(ScrnInfoPtr);
15 static void Riva_SetViewport(ScrnInfoPtr, int, int, int);
16 static void Riva_FillRect(ScrnInfoPtr, int, int, int, int, unsigned long);
17 static void Riva_BlitRect(ScrnInfoPtr, int, int, int, int, int, int);
18 static void Riva_BlitTransRect(ScrnInfoPtr, int, int, int, int, int, int,
22 DGAFunctionRec Riva_DGAFuncs = {
50 DisplayModePtr firstMode, pMode;
51 RivaPtr pRiva = RivaPTR(pScrn);
52 DGAModePtr mode, newmodes;
53 int size, pitch, Bpp = bitsPerPixel >> 3;
57 pMode = firstMode = pScrn->modes;
61 pitch = (pMode->HDisplay + 31) & ~31;
62 size = pitch * Bpp * pMode->VDisplay;
64 if((!secondPitch || (pitch != secondPitch)) &&
65 (size <= pRiva->FbUsableSize)) {
70 if(!(newmodes = xrealloc(modes, (*num + 1) * sizeof(DGAModeRec))))
77 mode->flags = DGA_CONCURRENT_ACCESS;
80 mode->flags |= DGA_PIXMAP_AVAILABLE;
82 mode->flags |= DGA_FILL_RECT | DGA_BLIT_RECT;
83 if(pMode->Flags & V_DBLSCAN)
84 mode->flags |= DGA_DOUBLESCAN;
85 if(pMode->Flags & V_INTERLACE)
86 mode->flags |= DGA_INTERLACED;
87 mode->byteOrder = pScrn->imageByteOrder;
89 mode->bitsPerPixel = bitsPerPixel;
91 mode->green_mask = green;
92 mode->blue_mask = blue;
93 mode->visualClass = visualClass;
94 mode->viewportWidth = pMode->HDisplay;
95 mode->viewportHeight = pMode->VDisplay;
96 mode->xViewportStep = 4 / Bpp;
97 mode->yViewportStep = 1;
98 mode->viewportFlags = DGA_FLIP_RETRACE;
100 mode->address = pRiva->FbStart;
101 mode->bytesPerScanline = pitch * Bpp;
102 mode->imageWidth = pitch;
103 mode->imageHeight = pRiva->FbUsableSize / mode->bytesPerScanline;
104 mode->pixmapWidth = mode->imageWidth;
105 mode->pixmapHeight = mode->imageHeight;
106 mode->maxViewportX = mode->imageWidth - mode->viewportWidth;
107 mode->maxViewportY = mode->imageHeight - mode->viewportHeight;
112 if(pMode == firstMode)
126 RivaDGAInit(ScreenPtr pScreen)
128 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
129 RivaPtr pRiva = RivaPTR(pScrn);
130 DGAModePtr modes = NULL;
134 modes = RivaSetupDGAMode (pScrn, modes, &num, 8, 8,
135 (pScrn->bitsPerPixel == 8),
136 (pScrn->bitsPerPixel != 8) ? 0 : pScrn->displayWidth,
137 0, 0, 0, PseudoColor);
140 modes = RivaSetupDGAMode (pScrn, modes, &num, 16, 15,
141 (pScrn->bitsPerPixel == 16),
142 (pScrn->depth != 15) ? 0 : pScrn->displayWidth,
143 0x7c00, 0x03e0, 0x001f, TrueColor);
146 modes = RivaSetupDGAMode (pScrn, modes, &num, 32, 24,
147 (pScrn->bitsPerPixel == 32),
148 (pScrn->bitsPerPixel != 32) ? 0 : pScrn->displayWidth,
149 0xff0000, 0x00ff00, 0x0000ff, TrueColor);
151 pRiva->numDGAModes = num;
152 pRiva->DGAModes = modes;
154 return DGAInit(pScreen, &Riva_DGAFuncs, modes, num);
159 BitsSet(unsigned long data)
164 for(mask = 1; mask; mask <<= 1)
165 if(mask & data) set++;
175 static RivaFBLayout SavedLayouts[MAXSCREENS];
176 int index = pScrn->pScreen->myNum;
178 RivaPtr pRiva = RivaPTR(pScrn);
180 if(!pMode) { /* restore the original mode */
182 memcpy(&pRiva->CurrentLayout, &SavedLayouts[index], sizeof(RivaFBLayout));
184 pScrn->currentMode = pRiva->CurrentLayout.mode;
185 RivaSwitchMode(index, pScrn->currentMode, 0);
186 RivaAdjustFrame(index, pScrn->frameX0, pScrn->frameY0, 0);
187 pRiva->DGAactive = FALSE;
189 if(!pRiva->DGAactive) { /* save the old parameters */
190 memcpy(&SavedLayouts[index], &pRiva->CurrentLayout, sizeof(RivaFBLayout));
191 pRiva->DGAactive = TRUE;
194 /* update CurrentLayout */
195 pRiva->CurrentLayout.bitsPerPixel = pMode->bitsPerPixel;
196 pRiva->CurrentLayout.depth = pMode->depth;
197 pRiva->CurrentLayout.displayWidth = pMode->bytesPerScanline /
198 (pMode->bitsPerPixel >> 3);
199 pRiva->CurrentLayout.weight.red = BitsSet(pMode->red_mask);
200 pRiva->CurrentLayout.weight.green = BitsSet(pMode->green_mask);
201 pRiva->CurrentLayout.weight.blue = BitsSet(pMode->blue_mask);
202 /* RivaModeInit() will set the mode field */
203 RivaSwitchMode(index, pMode->mode, 0);
215 RivaPtr pRiva = RivaPTR(pScrn);
217 return pRiva->DGAViewportStatus;
226 RivaPtr pRiva = RivaPTR(pScrn);
228 RivaAdjustFrame(pScrn->pScreen->myNum, x, y, flags);
230 while(VGA_RD08(pRiva->riva.PCIO, 0x3da) & 0x08);
231 while(!(VGA_RD08(pRiva->riva.PCIO, 0x3da) & 0x08));
233 pRiva->DGAViewportStatus = 0;
239 int x, int y, int w, int h,
242 RivaPtr pRiva = RivaPTR(pScrn);
244 if(!pRiva->AccelInfoRec) return;
246 (*pRiva->AccelInfoRec->SetupForSolidFill)(pScrn, color, GXcopy, ~0);
247 (*pRiva->AccelInfoRec->SubsequentSolidFillRect)(pScrn, x, y, w, h);
249 SET_SYNC_FLAG(pRiva->AccelInfoRec);
259 RivaPtr pRiva = RivaPTR(pScrn);
260 int xdir = ((srcx < dstx) && (srcy == dsty)) ? -1 : 1;
261 int ydir = (srcy < dsty) ? -1 : 1;
263 if(!pRiva->AccelInfoRec) return;
265 (*pRiva->AccelInfoRec->SetupForScreenToScreenCopy)(
266 pScrn, xdir, ydir, GXcopy, ~0, -1);
268 (*pRiva->AccelInfoRec->SubsequentScreenToScreenCopy)(
269 pScrn, srcx, srcy, dstx, dsty, w, h);
271 SET_SYNC_FLAG(pRiva->AccelInfoRec);
283 /* not implemented... yet */
288 Riva_OpenFramebuffer(
296 RivaPtr pRiva = RivaPTR(pScrn);
298 *name = NULL; /* no special device */
299 *mem = (unsigned char*)pRiva->FbAddress;
300 *size = pRiva->FbMapSize;
302 *flags = DGA_NEED_ROOT;