4 * Copyright (C) 2000 by Alan Hourihane, Sychdyn, North Wales, UK.
5 * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria
7 * Portions from radeon_dga.c which is
8 * Copyright 2000 ATI Technologies Inc., Markham, Ontario, and
9 * VA Linux Systems Inc., Fremont, California.
11 * Licensed under the following terms:
13 * Permission to use, copy, modify, distribute, and sell this software and its
14 * documentation for any purpose is hereby granted without fee, provided that
15 * the above copyright notice appear in all copies and that both that
16 * copyright notice and this permission notice appear in supporting
17 * documentation, and that the name of the providers not be used in
18 * advertising or publicity pertaining to distribution of the software without
19 * specific, written prior permission. The providers make no representations
20 * about the suitability of this software for any purpose. It is provided
21 * "as is" without express or implied warranty.
23 * THE PROVIDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
24 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
25 * EVENT SHALL THE PROVIDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
26 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
27 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
28 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
29 * PERFORMANCE OF THIS SOFTWARE.
31 * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk>
32 * Thomas Winischhofer <thomas@winischhofer.net>
44 #ifndef NEW_DGAOPENFRAMEBUFFER
45 static Bool
SIS_OpenFramebuffer(ScrnInfoPtr
, char **, UChar
**,
48 static Bool
SIS_OpenFramebuffer(ScrnInfoPtr
, char **, unsigned int *,
49 unsigned int *, unsigned int *, unsigned int *);
51 static Bool
SIS_SetMode(ScrnInfoPtr
, DGAModePtr
);
52 static void SIS_Sync(ScrnInfoPtr
);
53 static int SIS_GetViewport(ScrnInfoPtr
);
54 static void SIS_SetViewport(ScrnInfoPtr
, int, int, int);
55 static void SIS_FillRect(ScrnInfoPtr
, int, int, int, int, unsigned long);
56 static void SIS_BlitRect(ScrnInfoPtr
, int, int, int, int, int, int);
57 static void SIS_BlitTransRect(ScrnInfoPtr
, int, int, int, int, int, int, unsigned long);
60 DGAFunctionRec SISDGAFuncs
= {
73 DGAFunctionRec SISDGAFuncs3xx
= {
99 SISPtr pSiS
= SISPTR(pScrn
);
100 DGAModePtr newmodes
= NULL
, currentMode
;
101 DisplayModePtr pMode
, firstMode
;
102 int otherPitch
, Bpp
= bitsPerPixel
>> 3;
105 pMode
= firstMode
= pScrn
->modes
;
112 /* Filter out all meta modes that would require driver-side panning */
113 switch(((SiSMergedDisplayModePtr
)pMode
->Private
)->CRT2Position
) {
115 if( (((SiSMergedDisplayModePtr
)pMode
->Private
)->CRT1
->HDisplay
!=
116 ((SiSMergedDisplayModePtr
)pMode
->Private
)->CRT2
->HDisplay
) ||
117 (((SiSMergedDisplayModePtr
)pMode
->Private
)->CRT1
->VDisplay
!=
118 ((SiSMergedDisplayModePtr
)pMode
->Private
)->CRT2
->VDisplay
) ||
119 (((SiSMergedDisplayModePtr
)pMode
->Private
)->CRT1
->HDisplay
!=
121 (((SiSMergedDisplayModePtr
)pMode
->Private
)->CRT1
->VDisplay
!=
127 if( (((SiSMergedDisplayModePtr
)pMode
->Private
)->CRT1
->VDisplay
!=
128 ((SiSMergedDisplayModePtr
)pMode
->Private
)->CRT2
->VDisplay
) ||
129 (((SiSMergedDisplayModePtr
)pMode
->Private
)->CRT1
->VDisplay
!= pMode
->VDisplay
) )
133 if( (((SiSMergedDisplayModePtr
)pMode
->Private
)->CRT1
->HDisplay
!=
134 ((SiSMergedDisplayModePtr
)pMode
->Private
)->CRT2
->HDisplay
) ||
135 (((SiSMergedDisplayModePtr
)pMode
->Private
)->CRT1
->HDisplay
!= pMode
->HDisplay
) )
139 if(depth
== 16) { /* Print this only the first time */
140 xf86DrvMsg(pScrn
->scrnIndex
, X_INFO
,
141 "DGA: MetaMode %dx%d not suitable for DGA, skipping\n",
142 pMode
->HDisplay
, pMode
->VDisplay
);
149 otherPitch
= secondPitch
? secondPitch
: pMode
->HDisplay
;
151 if(pMode
->HDisplay
!= otherPitch
) {
153 newmodes
= realloc(modes
, (*num
+ 2) * sizeof(DGAModeRec
));
158 newmodes
= realloc(modes
, (*num
+ 1) * sizeof(DGAModeRec
));
171 currentMode
= modes
+ *num
;
174 currentMode
->mode
= pMode
;
175 currentMode
->flags
= DGA_CONCURRENT_ACCESS
;
177 currentMode
->flags
|= DGA_PIXMAP_AVAILABLE
;
179 currentMode
->flags
|= DGA_FILL_RECT
| DGA_BLIT_RECT
;
180 if((pSiS
->VGAEngine
== SIS_300_VGA
) ||
181 (pSiS
->VGAEngine
== SIS_315_VGA
) ||
182 (pSiS
->VGAEngine
== SIS_530_VGA
)) {
183 currentMode
->flags
|= DGA_BLIT_RECT_TRANS
;
186 if(pMode
->Flags
& V_DBLSCAN
)
187 currentMode
->flags
|= DGA_DOUBLESCAN
;
188 if(pMode
->Flags
& V_INTERLACE
)
189 currentMode
->flags
|= DGA_INTERLACED
;
190 currentMode
->byteOrder
= pScrn
->imageByteOrder
;
191 currentMode
->depth
= depth
;
192 currentMode
->bitsPerPixel
= bitsPerPixel
;
193 currentMode
->red_mask
= red
;
194 currentMode
->green_mask
= green
;
195 currentMode
->blue_mask
= blue
;
196 currentMode
->visualClass
= visualClass
;
197 currentMode
->viewportWidth
= pMode
->HDisplay
;
198 currentMode
->viewportHeight
= pMode
->VDisplay
;
199 currentMode
->xViewportStep
= 1;
200 currentMode
->yViewportStep
= 1;
201 currentMode
->viewportFlags
= DGA_FLIP_RETRACE
;
202 currentMode
->offset
= 0;
203 currentMode
->address
= pSiS
->FbBase
;
207 /* first one is narrow width */
208 currentMode
->bytesPerScanline
= (((pMode
->HDisplay
* Bpp
) + 3) & ~3L);
209 currentMode
->imageWidth
= pMode
->HDisplay
;
210 currentMode
->imageHeight
= pMode
->VDisplay
;
211 currentMode
->pixmapWidth
= currentMode
->imageWidth
;
212 currentMode
->pixmapHeight
= currentMode
->imageHeight
;
213 currentMode
->maxViewportX
= currentMode
->imageWidth
-
214 currentMode
->viewportWidth
;
215 /* this might need to get clamped to some maximum */
216 currentMode
->maxViewportY
= (currentMode
->imageHeight
-
217 currentMode
->viewportHeight
);
223 currentMode
->bytesPerScanline
= ((otherPitch
* Bpp
) + 3) & ~3L;
224 currentMode
->imageWidth
= otherPitch
;
225 currentMode
->imageHeight
= pMode
->VDisplay
;
226 currentMode
->pixmapWidth
= currentMode
->imageWidth
;
227 currentMode
->pixmapHeight
= currentMode
->imageHeight
;
228 currentMode
->maxViewportX
= (currentMode
->imageWidth
-
229 currentMode
->viewportWidth
);
230 /* this might need to get clamped to some maximum */
231 currentMode
->maxViewportY
= (currentMode
->imageHeight
-
232 currentMode
->viewportHeight
);
240 if(pMode
== firstMode
)
248 SISDGAInit(ScreenPtr pScreen
)
250 ScrnInfoPtr pScrn
= xf86ScreenToScrn(pScreen
);
251 SISPtr pSiS
= SISPTR(pScrn
);
252 DGAModePtr modes
= NULL
;
256 /* We don't support 8bpp modes in dual head or MergedFB mode,
257 * so don't offer them to DGA either.
260 if(!pSiS
->DualHeadMode
) {
263 if(!(pSiS
->MergedFB
)) {
265 modes
= SISSetupDGAMode(pScrn
, modes
, &num
, 8, 8,
266 (pScrn
->bitsPerPixel
== 8),
267 ((pScrn
->bitsPerPixel
!= 8)
268 ? 0 : pScrn
->displayWidth
),
269 0, 0, 0, PseudoColor
);
278 modes
= SISSetupDGAMode(pScrn
, modes
, &num
, 16, 16,
279 (pScrn
->bitsPerPixel
== 16),
280 ((pScrn
->depth
!= 16)
281 ? 0 : pScrn
->displayWidth
),
282 0xf800, 0x07e0, 0x001f, TrueColor
);
284 if((pSiS
->VGAEngine
== SIS_530_VGA
) || (pSiS
->VGAEngine
== SIS_OLD_VGA
)) {
286 modes
= SISSetupDGAMode(pScrn
, modes
, &num
, 24, 24,
287 (pScrn
->bitsPerPixel
== 24),
288 ((pScrn
->bitsPerPixel
!= 24)
289 ? 0 : pScrn
->displayWidth
),
290 0xff0000, 0x00ff00, 0x0000ff, TrueColor
);
293 if(pSiS
->VGAEngine
!= SIS_OLD_VGA
) {
295 modes
= SISSetupDGAMode(pScrn
, modes
, &num
, 32, 24,
296 (pScrn
->bitsPerPixel
== 32),
297 ((pScrn
->bitsPerPixel
!= 32)
298 ? 0 : pScrn
->displayWidth
),
299 0xff0000, 0x00ff00, 0x0000ff, TrueColor
);
302 pSiS
->numDGAModes
= num
;
303 pSiS
->DGAModes
= modes
;
306 if((pSiS
->VGAEngine
== SIS_300_VGA
) ||
307 (pSiS
->VGAEngine
== SIS_315_VGA
) ||
308 (pSiS
->VGAEngine
== SIS_530_VGA
)) {
309 return DGAInit(pScreen
, &SISDGAFuncs3xx
, modes
, num
);
311 return DGAInit(pScreen
, &SISDGAFuncs
, modes
, num
);
314 xf86DrvMsg(pScrn
->scrnIndex
, X_WARNING
,
315 "No DGA-suitable modes found, disabling DGA\n");
324 #ifndef NEW_DGAOPENFRAMEBUFFER
332 unsigned int *offset
,
336 SISPtr pSiS
= SISPTR(pScrn
);
338 *name
= NULL
; /* no special device */
339 #ifndef NEW_DGAOPENFRAMEBUFFER
340 *mem
= (UChar
*)pSiS
->FbAddress
;
342 *mem
= pSiS
->FbAddress
;
344 *size
= pSiS
->maxxfbmem
;
346 #ifndef NEW_DGAOPENFRAMEBUFFER
347 *flags
= DGA_NEED_ROOT
;
360 static SISFBLayout BackupLayouts
[MAXSCREENS
];
361 int index
= pScrn
->pScreen
->myNum
;
362 SISPtr pSiS
= SISPTR(pScrn
);
364 if(!pMode
) { /* restore the original mode */
366 if(pSiS
->DGAactive
) {
367 /* put the ScreenParameters back */
368 memcpy(&pSiS
->CurrentLayout
, &BackupLayouts
[index
], sizeof(SISFBLayout
));
371 pScrn
->currentMode
= pSiS
->CurrentLayout
.mode
;
372 pSiS
->DGAactive
= FALSE
;
374 (*pScrn
->SwitchMode
)(SWITCH_MODE_ARGS(pScrn
, pScrn
->currentMode
));
375 (*pScrn
->AdjustFrame
)(ADJUST_FRAME_ARGS(pScrn
, pScrn
->frameX0
, pScrn
->frameY0
));
377 } else { /* set new mode */
379 if(!pSiS
->DGAactive
) {
380 /* save the old parameters */
381 memcpy(&BackupLayouts
[index
], &pSiS
->CurrentLayout
, sizeof(SISFBLayout
));
382 pSiS
->DGAactive
= TRUE
;
385 pSiS
->CurrentLayout
.bitsPerPixel
= pMode
->bitsPerPixel
;
386 pSiS
->CurrentLayout
.depth
= pMode
->depth
;
387 pSiS
->CurrentLayout
.displayWidth
= pMode
->bytesPerScanline
/ (pMode
->bitsPerPixel
>> 3);
388 pSiS
->CurrentLayout
.displayHeight
= pMode
->imageHeight
;
390 (*pScrn
->SwitchMode
)(SWITCH_MODE_ARGS(pScrn
, pMode
->mode
));
391 /* Adjust viewport to 0/0 after mode switch */
392 /* This fixes the vmware-in-dualhead problems */
393 (*pScrn
->AdjustFrame
)(ADJUST_FRAME_ARGS(pScrn
, 0, 0));
394 pSiS
->CurrentLayout
.DGAViewportX
= pSiS
->CurrentLayout
.DGAViewportY
= 0;
404 SISPtr pSiS
= SISPTR(pScrn
);
406 return pSiS
->DGAViewportStatus
;
415 SISPtr pSiS
= SISPTR(pScrn
);
417 (*pScrn
->AdjustFrame
)(ADJUST_FRAME_ARGS(pScrn
, x
, y
));
418 pSiS
->DGAViewportStatus
= 0; /* There are never pending Adjusts */
419 pSiS
->CurrentLayout
.DGAViewportX
= x
;
420 pSiS
->CurrentLayout
.DGAViewportY
= y
;
427 SISPtr pSiS
= SISPTR(pScrn
);
429 (*pSiS
->SyncAccel
)(pScrn
);
435 int x
, int y
, int w
, int h
,
438 SISPtr pSiS
= SISPTR(pScrn
);
441 (*pSiS
->FillRect
)(pScrn
, x
, y
, w
, h
, (int)color
);
443 if(!pSiS
->useEXA
&& pSiS
->AccelInfoPtr
) {
444 SET_SYNC_FLAG(pSiS
->AccelInfoPtr
);
457 SISPtr pSiS
= SISPTR(pScrn
);
460 (*pSiS
->BlitRect
)(pScrn
, srcx
, srcy
, dstx
, dsty
, w
, h
, -1);
462 if(!pSiS
->useEXA
&& pSiS
->AccelInfoPtr
) {
463 SET_SYNC_FLAG(pSiS
->AccelInfoPtr
);
477 SISPtr pSiS
= SISPTR(pScrn
);
480 (*pSiS
->BlitRect
)(pScrn
, srcx
, srcy
, dstx
, dsty
, w
, h
, (int)color
);
482 if(!pSiS
->useEXA
&& pSiS
->AccelInfoPtr
) {
483 SET_SYNC_FLAG(pSiS
->AccelInfoPtr
);