trident_dga.c revision 95b296d0
1/*
2 * Copyright 1997-2003 by Alan Hourihane, North Wales, UK.
3 *
4 * Permission to use, copy, modify, distribute, and sell this software and its
5 * documentation for any purpose is hereby granted without fee, provided that
6 * the above copyright notice appear in all copies and that both that
7 * copyright notice and this permission notice appear in supporting
8 * documentation, and that the name of Alan Hourihane not be used in
9 * advertising or publicity pertaining to distribution of the software without
10 * specific, written prior permission.  Alan Hourihane makes no representations
11 * about the suitability of this software for any purpose.  It is provided
12 * "as is" without express or implied warranty.
13 *
14 * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16 * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
20 * PERFORMANCE OF THIS SOFTWARE.
21 *
22 * Authors:  Alan Hourihane, <alanh@fairlite.demon.co.uk>
23 */
24/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/trident/trident_dga.c,v 1.4 2002/10/08 22:14:11 tsi Exp $ */
25
26#ifdef HAVE_CONFIG_H
27#include "config.h"
28#endif
29
30#include "xf86.h"
31#include "xf86_OSproc.h"
32#include "xf86Pci.h"
33#include "xf86PciInfo.h"
34#include "xaa.h"
35#include "xaalocal.h"
36#include "trident.h"
37#include "trident_regs.h"
38#include "dgaproc.h"
39
40
41static Bool TRIDENT_OpenFramebuffer(ScrnInfoPtr, char **, unsigned char **,
42					int *, int *, int *);
43static Bool TRIDENT_SetMode(ScrnInfoPtr, DGAModePtr);
44static void TRIDENT_Sync(ScrnInfoPtr);
45static int  TRIDENT_GetViewport(ScrnInfoPtr);
46static void TRIDENT_SetViewport(ScrnInfoPtr, int, int, int);
47static void TRIDENT_FillRect(ScrnInfoPtr, int, int, int, int, unsigned long);
48static void TRIDENT_BlitRect(ScrnInfoPtr, int, int, int, int, int, int);
49#if 0
50static void TRIDENT_BlitTransRect(ScrnInfoPtr, int, int, int, int, int, int,
51					unsigned long);
52#endif
53
54static
55DGAFunctionRec TRIDENTDGAFuncs = {
56   TRIDENT_OpenFramebuffer,
57   NULL,
58   TRIDENT_SetMode,
59   TRIDENT_SetViewport,
60   TRIDENT_GetViewport,
61   TRIDENT_Sync,
62   TRIDENT_FillRect,
63   TRIDENT_BlitRect,
64#if 0
65   TRIDENT_BlitTransRect
66#else
67   NULL
68#endif
69};
70
71Bool
72TRIDENTDGAInit(ScreenPtr pScreen)
73{
74   ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
75   TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
76   DGAModePtr modes = NULL, newmodes = NULL, currentMode;
77   DisplayModePtr pMode, firstMode;
78   int Bpp = pScrn->bitsPerPixel >> 3;
79   int num = 0;
80   Bool oneMore;
81
82   pMode = firstMode = pScrn->modes;
83
84   while(pMode) {
85
86	if(0 /*pScrn->displayWidth != pMode->HDisplay*/) {
87	    newmodes = xrealloc(modes, (num + 2) * sizeof(DGAModeRec));
88	    oneMore = TRUE;
89	} else {
90	    newmodes = xrealloc(modes, (num + 1) * sizeof(DGAModeRec));
91	    oneMore = FALSE;
92	}
93
94	if(!newmodes) {
95	   xfree(modes);
96	   return FALSE;
97	}
98	modes = newmodes;
99
100SECOND_PASS:
101
102	currentMode = modes + num;
103	num++;
104
105	currentMode->mode = pMode;
106	currentMode->flags = DGA_CONCURRENT_ACCESS | DGA_PIXMAP_AVAILABLE;
107	if(!pTrident->NoAccel)
108	   currentMode->flags |= DGA_FILL_RECT | DGA_BLIT_RECT;
109	if(pMode->Flags & V_DBLSCAN)
110	   currentMode->flags |= DGA_DOUBLESCAN;
111	if(pMode->Flags & V_INTERLACE)
112	   currentMode->flags |= DGA_INTERLACED;
113	currentMode->byteOrder = pScrn->imageByteOrder;
114	currentMode->depth = pScrn->depth;
115	currentMode->bitsPerPixel = pScrn->bitsPerPixel;
116	currentMode->red_mask = pScrn->mask.red;
117	currentMode->green_mask = pScrn->mask.green;
118	currentMode->blue_mask = pScrn->mask.blue;
119	currentMode->visualClass = (Bpp == 1) ? PseudoColor : TrueColor;
120	currentMode->viewportWidth = pMode->HDisplay;
121	currentMode->viewportHeight = pMode->VDisplay;
122	currentMode->xViewportStep = 1;
123	currentMode->yViewportStep = 1;
124	currentMode->viewportFlags = DGA_FLIP_RETRACE;
125	currentMode->offset = 0;
126	currentMode->address = pTrident->FbBase;
127
128	if(oneMore) { /* first one is narrow width */
129	    currentMode->bytesPerScanline = ((pMode->HDisplay * Bpp) + 3) & ~3L;
130	    currentMode->imageWidth = pMode->HDisplay;
131	    currentMode->imageHeight =  pMode->VDisplay;
132	    currentMode->pixmapWidth = currentMode->imageWidth;
133	    currentMode->pixmapHeight = currentMode->imageHeight;
134	    currentMode->maxViewportX = currentMode->imageWidth -
135					currentMode->viewportWidth;
136	    /* this might need to get clamped to some maximum */
137	    currentMode->maxViewportY = currentMode->imageHeight -
138					currentMode->viewportHeight;
139	    oneMore = FALSE;
140	    goto SECOND_PASS;
141	} else {
142	    currentMode->bytesPerScanline =
143			((pScrn->displayWidth * Bpp) + 3) & ~3L;
144	    currentMode->imageWidth = pScrn->displayWidth;
145	    currentMode->imageHeight =  pMode->VDisplay;
146	    currentMode->pixmapWidth = currentMode->imageWidth;
147	    currentMode->pixmapHeight = currentMode->imageHeight;
148	    currentMode->maxViewportX = currentMode->imageWidth -
149					currentMode->viewportWidth;
150	    /* this might need to get clamped to some maximum */
151	    currentMode->maxViewportY = currentMode->imageHeight -
152					currentMode->viewportHeight;
153	}
154
155	pMode = pMode->next;
156	if(pMode == firstMode)
157	   break;
158   }
159
160   pTrident->numDGAModes = num;
161   pTrident->DGAModes = modes;
162
163   return DGAInit(pScreen, &TRIDENTDGAFuncs, modes, num);
164}
165
166
167static Bool
168TRIDENT_SetMode(
169   ScrnInfoPtr pScrn,
170   DGAModePtr pMode
171){
172   static int OldDisplayWidth[MAXSCREENS];
173   int index = pScrn->pScreen->myNum;
174   TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
175
176   if(!pMode) { /* restore the original mode */
177	/* put the ScreenParameters back */
178
179	pScrn->displayWidth = OldDisplayWidth[index];
180
181        TRIDENTSwitchMode(index, pScrn->currentMode, 0);
182	pTrident->DGAactive = FALSE;
183   } else {
184	if(!pTrident->DGAactive) {  /* save the old parameters */
185	    OldDisplayWidth[index] = pScrn->displayWidth;
186
187	    pTrident->DGAactive = TRUE;
188	}
189
190	pScrn->displayWidth = pMode->bytesPerScanline /
191			      (pMode->bitsPerPixel >> 3);
192
193        TRIDENTSwitchMode(index, pMode->mode, 0);
194   }
195
196   return TRUE;
197}
198
199
200
201static int
202TRIDENT_GetViewport(
203  ScrnInfoPtr pScrn
204){
205    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
206
207    return pTrident->DGAViewportStatus;
208}
209
210static void
211TRIDENT_SetViewport(
212   ScrnInfoPtr pScrn,
213   int x, int y,
214   int flags
215){
216   TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
217
218   TRIDENTAdjustFrame(pScrn->pScreen->myNum, x, y, flags);
219   pTrident->DGAViewportStatus = 0;  /* TRIDENTAdjustFrame loops until finished */
220}
221
222static void
223TRIDENT_FillRect (
224   ScrnInfoPtr pScrn,
225   int x, int y, int w, int h,
226   unsigned long color
227){
228    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
229
230    if(pTrident->AccelInfoRec) {
231	(*pTrident->AccelInfoRec->SetupForSolidFill)(pScrn, color, GXcopy, ~0);
232	(*pTrident->AccelInfoRec->SubsequentSolidFillRect)(pScrn, x, y, w, h);
233	SET_SYNC_FLAG(pTrident->AccelInfoRec);
234    }
235}
236
237static void
238TRIDENT_Sync(
239   ScrnInfoPtr pScrn
240){
241    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
242
243    if(pTrident->AccelInfoRec) {
244	(*pTrident->AccelInfoRec->Sync)(pScrn);
245    }
246}
247
248static void
249TRIDENT_BlitRect(
250   ScrnInfoPtr pScrn,
251   int srcx, int srcy,
252   int w, int h,
253   int dstx, int dsty
254){
255    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
256
257    if(pTrident->AccelInfoRec) {
258	int xdir = ((srcx < dstx) && (srcy == dsty)) ? -1 : 1;
259	int ydir = (srcy < dsty) ? -1 : 1;
260
261	(*pTrident->AccelInfoRec->SetupForScreenToScreenCopy)(
262		pScrn, xdir, ydir, GXcopy, ~0, -1);
263	(*pTrident->AccelInfoRec->SubsequentScreenToScreenCopy)(
264		pScrn, srcx, srcy, dstx, dsty, w, h);
265	SET_SYNC_FLAG(pTrident->AccelInfoRec);
266    }
267}
268
269#if 0
270static void
271TRIDENT_BlitTransRect(
272   ScrnInfoPtr pScrn,
273   int srcx, int srcy,
274   int w, int h,
275   int dstx, int dsty,
276   unsigned long color
277){
278  /* this one should be separate since the XAA function would
279     prohibit usage of ~0 as the key */
280}
281#endif
282
283static Bool
284TRIDENT_OpenFramebuffer(
285   ScrnInfoPtr pScrn,
286   char **name,
287   unsigned char **mem,
288   int *size,
289   int *offset,
290   int *flags
291){
292    TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
293
294    *name = NULL; 		/* no special device */
295    *mem = (unsigned char*)pTrident->FbAddress;
296    *size = pTrident->FbMapSize;
297    *offset = 0;
298    *flags = DGA_NEED_ROOT;
299
300    return TRUE;
301}
302