summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEvgeny M. Zubok <evgeny.zubok@tochka.ru>2009-05-04 15:10:17 +0400
committerEvgeny M. Zubok <evgeny.zubok@tochka.ru>2009-05-04 15:10:17 +0400
commita1d6d9bec68c3bf47af69b73c875836bc46db3a1 (patch)
tree63e2cbcae18bfb88914a441763801f6632134a4d
parentdd2e8e7a5f0bbb0f6fc3cb32161a0024545179bc (diff)
shadowFB option. Interlace mode support. Close bug #14999.
-rw-r--r--ChangeLog17
-rw-r--r--src/Makefile.am3
-rw-r--r--src/s3.h16
-rw-r--r--src/s3_driver.c203
-rw-r--r--src/s3_shadow.c274
5 files changed, 421 insertions, 92 deletions
diff --git a/ChangeLog b/ChangeLog
index fab4ec7..39aada1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+2009-05-04 Evgeny M. Zubok <evgeny.zubok@tochka.ru>
+
+ * src/s3_driver.c:
+ * src/s3_shadow.c:
+
+ Add shadowFB option. It can be used to speedup drawing when
+ hardware acceleration is unwanted or unavailable (for colour depth
+ 24 with 24 bpp framebuffer, for example). shadowFB is disabled by
+ default. Enabling shadowFB option disables HW acceleration. Thanks
+ to Egor Ivanov for initial porting of shadowFB from s3virge.
+
+ Interlace mode support.
+
+ Close bug #14999.
+
2008-07-06 Evgeny M. Zubok <evgeny.zubok@tochka.ru>
* src/s3_video.c:
@@ -14,7 +29,7 @@
not implemented yet for all chipsets).
Close bug #5527: 24-bit colour depth support (24bpp and
- 32bpp framebuffer) for TRIO64V2. Acceleration doesn't work
+ 32bpp framebuffer) for TRIOs. Acceleration doesn't work
with packed colour mode (24 bpp FB) but works with 32bpp
framebuffer mode (hardware limitation? -- need data).
diff --git a/src/Makefile.am b/src/Makefile.am
index 743babd..84f926c 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -39,7 +39,8 @@ s3_drv_la_SOURCES = \
s3_pcirename.h \
s3_reg.h \
s3_Ti.c \
- s3_Trio64DAC.c
+ s3_Trio64DAC.c \
+ s3_shadow.c
noinst_LTLIBRARIES = libs3_accel_newmmio.la libs3_accel_pio.la
s3_drv_la_LIBADD = libs3_accel_newmmio.la libs3_accel_pio.la
diff --git a/src/s3.h b/src/s3.h
index a12ff6e..1857b0c 100644
--- a/src/s3.h
+++ b/src/s3.h
@@ -163,6 +163,13 @@ typedef struct _S3Rec {
int imageWidth;
int imageHeight;
Bool hwCursor;
+
+ Bool shadowFB;
+ int rotate;
+ unsigned char * ShadowPtr;
+ int ShadowPitch;
+ void (*PointerMoved)(int index, int x, int y);
+
} S3Rec, *S3Ptr;
#define S3PTR(p) ((S3Ptr)((p)->driverPrivate))
@@ -224,6 +231,15 @@ void S3OutTiIndReg(ScrnInfoPtr pScrn, CARD32 reg, unsigned char mask,
/* s3 gen cursor */
Bool S3_CursorInit(ScreenPtr pScreen);
+/* in s3_shadow.c */
+void S3PointerMoved(int index, int x, int y);
+void S3RefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox);
+void S3RefreshArea8(ScrnInfoPtr pScrn, int num, BoxPtr pbox);
+void S3RefreshArea16(ScrnInfoPtr pScrn, int num, BoxPtr pbox);
+void S3RefreshArea24(ScrnInfoPtr pScrn, int num, BoxPtr pbox);
+void S3RefreshArea32(ScrnInfoPtr pScrn, int num, BoxPtr pbox);
+
+
#define TRIO64_RAMDAC 0x8811
#define TI3025_RAMDAC 0x3025
#define TI3020_RAMDAC 0x3020
diff --git a/src/s3_driver.c b/src/s3_driver.c
index 29e7fb5..88dc25a 100644
--- a/src/s3_driver.c
+++ b/src/s3_driver.c
@@ -54,7 +54,7 @@
#include "mibstore.h"
#include "fb.h"
#include "inputstr.h"
-
+#include "shadowfb.h"
#include "IBM.h"
#include "TI.h"
@@ -157,7 +157,9 @@ typedef enum {
OPTION_SLOW_DRAM,
OPTION_SLOW_EDODRAM,
OPTION_SLOW_VRAM,
- OPTION_XVIDEO
+ OPTION_XVIDEO,
+ OPTION_SHADOW_FB,
+ OPTION_ROTATE
} S3Opts;
static OptionInfoRec S3Options[] = {
@@ -168,6 +170,8 @@ static OptionInfoRec S3Options[] = {
{ OPTION_SLOW_EDODRAM, "slow_edodram", OPTV_BOOLEAN, {0}, FALSE },
{ OPTION_SLOW_VRAM, "slow_vram", OPTV_BOOLEAN, {0}, FALSE },
{ OPTION_XVIDEO, "XVideo", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_SHADOW_FB, "ShadowFB", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_ROTATE, "Rotate", OPTV_ANYSTR, {0}, FALSE },
{ -1, NULL, OPTV_NONE, {0}, FALSE }
};
@@ -208,6 +212,12 @@ static const char *vbeSymbols[] = {
NULL
};
+static const char *shadowSymbols[] = {
+ "ShadowFBInit",
+ NULL
+};
+
+
static const char *int10Symbols[] = {
"xf86ExecX86int10",
"xf86FreeInt10",
@@ -269,6 +279,7 @@ pointer S3Setup (pointer module, pointer opts, int *errmaj, int *errmin)
xf86AddDriver(&S3, module, 0);
LoaderRefSymLists(vgaHWSymbols,
vbeSymbols, int10Symbols, ramdacSymbols,
+ shadowSymbols,
fbSymbols,
xaaSymbols,
NULL);
@@ -372,6 +383,7 @@ static Bool S3PreInit(ScrnInfoPtr pScrn, int flags)
Gamma gzeros = {0.0, 0.0, 0.0};
int i, vgaCRIndex, vgaCRReg;
unsigned char tmp;
+ char *s;
if (flags & PROBE_DETECT)
return FALSE;
@@ -435,6 +447,48 @@ static Bool S3PreInit(ScrnInfoPtr pScrn, int flags)
pS3->SlowDRAM = xf86ReturnOptValBool(S3Options, OPTION_SLOW_DRAM, FALSE);
pS3->SlowEDODRAM = xf86ReturnOptValBool(S3Options, OPTION_SLOW_EDODRAM, FALSE);
pS3->SlowVRAM = xf86ReturnOptValBool(S3Options, OPTION_SLOW_VRAM, FALSE);
+
+
+
+ if (xf86GetOptValBool(S3Options, OPTION_SHADOW_FB, &pS3->shadowFB))
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ShadowFB %s.\n",
+ pS3->shadowFB ? "enabled" : "disabled");
+
+ pS3->rotate = 0;
+ if ((s = xf86GetOptValString(S3Options, OPTION_ROTATE))) {
+ if(!xf86NameCmp(s, "CW")) {
+ /* accel is disabled below for shadowFB */
+ pS3->shadowFB = TRUE;
+ pS3->rotate = 1;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Rotating screen clockwise - acceleration disabled\n");
+ } else if(!xf86NameCmp(s, "CCW")) {
+ pS3->shadowFB = TRUE;
+ pS3->rotate = -1;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Rotating screen"
+ "counter clockwise - acceleration disabled\n");
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "\"%s\" is not a valid"
+ "value for Option \"Rotate\"\n", s);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Valid options are \"CW\" or \"CCW\"\n");
+ }
+ }
+
+ if(pS3->shadowFB && !pS3->NoAccel) {
+ pS3->NoAccel = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "HW acceleration not supported with \"shadowFB\".\n");
+ }
+
+
+ if (pS3->rotate && pS3->HWCursor) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "HW cursor not supported with \"rotate\".\n");
+ pS3->HWCursor = FALSE;
+ }
+
+
if (pScrn->numEntities > 1) {
S3FreeRec(pScrn);
return FALSE;
@@ -457,6 +511,14 @@ static Bool S3PreInit(ScrnInfoPtr pScrn, int flags)
pS3->pVBE = VBEInit(pS3->pInt10, pEnt->index);
}
+ if (pS3->shadowFB) {
+ if (!xf86LoadSubModule(pScrn, "shadowfb")) {
+ S3FreeRec(pScrn);
+ return FALSE;
+ }
+ xf86LoaderReqSymLists(shadowSymbols, NULL);
+ }
+
if (!xf86SetGamma(pScrn, gzeros))
return FALSE;
@@ -722,7 +784,7 @@ static Bool S3PreInit(ScrnInfoPtr pScrn, int flags)
return FALSE;
}
- xf86SetCrtcForModes(pScrn, 0);
+ xf86SetCrtcForModes(pScrn, INTERLACE_HALVE_V);
pScrn->currentMode = pScrn->modes;
xf86PrintModes(pScrn);
xf86SetDpi(pScrn, 0, 0);
@@ -744,6 +806,16 @@ static Bool S3ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc,
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
S3Ptr pS3 = S3PTR(pScrn);
BoxRec ScreenArea;
+ int width, height, displayWidth;
+
+ if (pS3->rotate) {
+ height = pScrn->virtualX;
+ width = pScrn->virtualY;
+ } else {
+ width = pScrn->virtualX;
+ height = pScrn->virtualY;
+ }
+
pScrn->fbOffset = 0;
@@ -778,7 +850,18 @@ static Bool S3ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc,
miSetPixmapDepths ();
- if (!fbScreenInit(pScreen, pS3->FBBase, pScrn->virtualX,
+ /* no screen rotation assumed */
+ if(pS3->shadowFB) {
+ pS3->ShadowPitch = BitmapBytePad(pScrn->bitsPerPixel * width);
+ pS3->ShadowPtr = xalloc(pS3->ShadowPitch * height);
+ displayWidth = pS3->ShadowPitch / (pScrn->bitsPerPixel >> 3);
+ } else {
+ pS3->ShadowPtr = NULL;
+ displayWidth = pScrn->displayWidth;
+ }
+
+ if (!fbScreenInit(pScreen, (pS3->shadowFB ? pS3->ShadowPtr : pS3->FBBase),
+ pScrn->virtualX,
pScrn->virtualY, pScrn->xDpi, pScrn->yDpi,
pScrn->displayWidth, pScrn->bitsPerPixel))
return FALSE;
@@ -824,7 +907,6 @@ static Bool S3ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc,
ScreenArea.x1, ScreenArea.y1,
ScreenArea.x2, ScreenArea.y2);
-
/* 2D acceleration setup */
if (pS3->NoAccel)
@@ -832,13 +914,13 @@ static Bool S3ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc,
"Acceleration disabled (by option)\n");
/* It seems that acceleration isn't supported for 24-bit packed
- colour. Disable it for S3 Trio64V2 */
- if (!pS3->NoAccel && (pScrn->bitsPerPixel == 24) &&
- (pS3->Chipset == PCI_CHIP_TRIO64V2_DXGX)) {
- xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Acceleration isn't supported for 24 bpp. Disabled.\n");
+ colour. So disable it. Using shadowFB is recommended in this mode. */
+ if (!pS3->NoAccel && (pScrn->bitsPerPixel == 24)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "HW acceleration isn't supported for 24 bpp. Disabled.\n");
pS3->NoAccel = TRUE;
}
+
if (!pS3->NoAccel) {
if (pS3->S3NewMMIO)
if (S3AccelInitNewMMIO(pScreen)) {
@@ -882,6 +964,28 @@ static Bool S3ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc,
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using SW cursor\n");
+ /* Shadow framebuffer setup */
+
+ if (pS3->shadowFB) {
+ RefreshAreaFuncPtr refreshArea = S3RefreshArea;
+
+ if (pS3->rotate) {
+ if (!pS3->PointerMoved) {
+ pS3->PointerMoved = pScrn->PointerMoved;
+ pScrn->PointerMoved = S3PointerMoved;
+ }
+
+ switch (pScrn->bitsPerPixel) {
+ case 8: refreshArea = S3RefreshArea8; break;
+ case 16: refreshArea = S3RefreshArea16; break;
+ case 24: refreshArea = S3RefreshArea24; break;
+ case 32: refreshArea = S3RefreshArea32; break;
+ }
+ }
+
+ ShadowFBInit(pScreen, refreshArea);
+ }
+
if (!miCreateDefColormap(pScreen))
@@ -1226,9 +1330,6 @@ static Bool S3ModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
if ((mode->HTotal == mode->CrtcHTotal) && (pS3->pixMuxShift != 0)) {
if (pS3->pixMuxShift > 0) {
- /* XXX hack */
-/* mode->Flags |= V_PIXMUX; */
-
mode->CrtcHTotal >>= pS3->pixMuxShift;
mode->CrtcHDisplay >>= pS3->pixMuxShift;
mode->CrtcHBlankStart >>= pS3->pixMuxShift;
@@ -1237,8 +1338,6 @@ static Bool S3ModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
mode->CrtcHSyncEnd >>= pS3->pixMuxShift;
mode->CrtcHSkew >>= pS3->pixMuxShift;
} else if (pS3->pixMuxShift < 0) {
-/* mode->Flags |= V_PIXMUX; */
-
mode->CrtcHTotal <<= -pS3->pixMuxShift;
mode->CrtcHDisplay <<= -pS3->pixMuxShift;
mode->CrtcHBlankStart <<= -pS3->pixMuxShift;
@@ -1249,15 +1348,6 @@ static Bool S3ModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
}
}
- /* This shouldn't be needed -- they should be set by vgaHWInit() */
- if (!mode->CrtcVAdjusted) {
- mode->CrtcVTotal >>= interlacedived;
- mode->CrtcVDisplay >>= interlacedived;
- mode->CrtcVSyncStart >>= interlacedived;
- mode->CrtcVSyncEnd >>= interlacedived;
- mode->CrtcVAdjusted = TRUE;
- }
-
if (!vgaHWInit(pScrn, mode))
return FALSE;
@@ -1932,71 +2022,6 @@ void S3Regdump(ScrnInfoPtr pScrn)
{
S3Ptr pS3 = S3PTR(pScrn);
int vgaCRIndex = pS3->vgaCRIndex, vgaCRReg = pS3->vgaCRReg;
-
-#if 0
- outb(vgaCRIndex, 0x31);
- ErrorF("cr31 = 0x%x\n", inb(vgaCRReg));
- outb(vgaCRIndex, 0x32);
- ErrorF("cr32 = 0x%x\n", inb(vgaCRReg));
- outb(vgaCRIndex, 0x33);
- ErrorF("cr33 = 0x%x\n", inb(vgaCRReg));
- outb(vgaCRIndex, 0x34);
- ErrorF("cr34 = 0x%x\n", inb(vgaCRReg));
- outb(vgaCRIndex, 0x3a);
- ErrorF("cr3a = 0x%x\n", inb(vgaCRReg));
- outb(vgaCRIndex, 0x3b);
- ErrorF("cr3b = 0x%x\n", inb(vgaCRReg));
- outb(vgaCRIndex, 0x3c);
- ErrorF("cr3c = 0x%x\n", inb(vgaCRReg));
-
- outb(vgaCRIndex, 0x40);
- ErrorF("cr40 = 0x%x\n", inb(vgaCRReg));
- outb(vgaCRIndex, 0x42);
- ErrorF("cr42 = 0x%x\n", inb(vgaCRReg));
- outb(vgaCRIndex, 0x43);
- ErrorF("cr43 = 0x%x\n", inb(vgaCRReg));
- outb(vgaCRIndex, 0x44);
- ErrorF("cr44 = 0x%x\n", inb(vgaCRReg));
- outb(vgaCRIndex, 0x45);
- ErrorF("cr45 = 0x%x\n", inb(vgaCRReg));
-
- outb(vgaCRIndex, 0x50);
- ErrorF("cr50 = 0x%x\n", inb(vgaCRReg));
- outb(vgaCRIndex, 0x51);
- ErrorF("cr51 = 0x%x\n", inb(vgaCRReg));
- outb(vgaCRIndex, 0x53);
- ErrorF("cr53 = 0x%x\n", inb(vgaCRReg));
- outb(vgaCRIndex, 0x54);
- ErrorF("cr54 = 0x%x\n", inb(vgaCRReg));
- outb(vgaCRIndex, 0x55);
- ErrorF("cr55 = 0x%x\n", inb(vgaCRReg));
- outb(vgaCRIndex, 0x58);
- ErrorF("cr58 = 0x%x\n", inb(vgaCRReg));
- outb(vgaCRIndex, 0x59);
- ErrorF("cr59 = 0x%x\n", inb(vgaCRReg));
- outb(vgaCRIndex, 0x5a);
- ErrorF("cr5a = 0x%x\n", inb(vgaCRReg));
- outb(vgaCRIndex, 0x5d);
- ErrorF("cr5d = 0x%x\n", inb(vgaCRReg));
- outb(vgaCRIndex, 0x5e);
- ErrorF("cr5e = 0x%x\n", inb(vgaCRReg));
-
- outb(vgaCRIndex, 0x60);
- ErrorF("cr60 = 0x%x\n", inb(vgaCRReg));
- outb(vgaCRIndex, 0x61);
- ErrorF("cr61 = 0x%x\n", inb(vgaCRReg));
- outb(vgaCRIndex, 0x62);
- ErrorF("cr62 = 0x%x\n", inb(vgaCRReg));
- outb(vgaCRIndex, 0x65);
- ErrorF("cr65 = 0x%x\n", inb(vgaCRReg));
- outb(vgaCRIndex, 0x66);
- ErrorF("cr66 = 0x%x\n", inb(vgaCRReg));
- outb(vgaCRIndex, 0x67);
- ErrorF("cr67 = 0x%x\n", inb(vgaCRReg));
- outb(vgaCRIndex, 0x6d);
- ErrorF("cr6d = 0x%x\n", inb(vgaCRReg));
-
-#else
{
int j;
@@ -2005,8 +2030,6 @@ void S3Regdump(ScrnInfoPtr pScrn)
ErrorF("CRTC 0x%x = 0x%x\n", j, inb(vgaCRReg));
}
}
-#endif
-
#if 0
ErrorF("DAC regs\n");
diff --git a/src/s3_shadow.c b/src/s3_shadow.c
new file mode 100644
index 0000000..1273765
--- /dev/null
+++ b/src/s3_shadow.c
@@ -0,0 +1,274 @@
+/*
+Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FIT-
+NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the XFree86 Project shall not
+be used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the XFree86 Project.
+*/
+
+/*
+ Copyright (c) 1999,2000 The XFree86 Project Inc.
+ based on code written by Mark Vojkovich <markv@valinux.com>
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86Resources.h"
+#include "xf86PciInfo.h"
+#include "xf86Pci.h"
+#include "shadowfb.h"
+#include "servermd.h"
+#include "s3.h"
+
+
+void
+S3RefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
+{
+ S3Ptr pS3 = S3PTR(pScrn);
+ int width, height, Bpp, FBPitch;
+ unsigned char *src, *dst;
+
+ Bpp = pScrn->bitsPerPixel >> 3;
+ FBPitch = BitmapBytePad(pScrn->displayWidth * pScrn->bitsPerPixel);
+
+ while(num--) {
+ width = (pbox->x2 - pbox->x1) * Bpp;
+ height = pbox->y2 - pbox->y1;
+ src = pS3->ShadowPtr + (pbox->y1 * pS3->ShadowPitch) +
+ (pbox->x1 * Bpp);
+ dst = pS3->FBBase + (pbox->y1 * FBPitch) + (pbox->x1 * Bpp);
+
+ while(height--) {
+ memcpy(dst, src, width);
+ dst += FBPitch;
+ src += pS3->ShadowPitch;
+ }
+
+ pbox++;
+ }
+}
+
+void
+S3PointerMoved(int index, int x, int y)
+{
+ ScrnInfoPtr pScrn = xf86Screens[index];
+ S3Ptr pS3 = S3PTR(pScrn);
+ int newX, newY;
+
+ if(pS3->rotate == 1) {
+ newX = pScrn->pScreen->height - y - 1;
+ newY = x;
+ } else {
+ newX = y;
+ newY = pScrn->pScreen->width - x - 1;
+ }
+
+ (*pS3->PointerMoved)(index, newX, newY);
+}
+
+void
+S3RefreshArea8(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
+{
+ S3Ptr pS3 = S3PTR(pScrn);
+ int count, width, height, y1, y2, dstPitch, srcPitch;
+ CARD8 *dstPtr, *srcPtr, *src;
+ CARD32 *dst;
+
+ dstPitch = pScrn->displayWidth;
+ srcPitch = -pS3->rotate * pS3->ShadowPitch;
+
+ while(num--) {
+ width = pbox->x2 - pbox->x1;
+ y1 = pbox->y1 & ~3;
+ y2 = (pbox->y2 + 3) & ~3;
+ height = (y2 - y1) >> 2; /* in dwords */
+
+ if(pS3->rotate == 1) {
+ dstPtr = pS3->FBBase +
+ (pbox->x1 * dstPitch) + pScrn->virtualX - y2;
+ srcPtr = pS3->ShadowPtr + ((1 - y2) * srcPitch) + pbox->x1;
+ } else {
+ dstPtr = pS3->FBBase +
+ ((pScrn->virtualY - pbox->x2) * dstPitch) + y1;
+ srcPtr = pS3->ShadowPtr + (y1 * srcPitch) + pbox->x2 - 1;
+ }
+
+ while(width--) {
+ src = srcPtr;
+ dst = (CARD32*)dstPtr;
+ count = height;
+ while(count--) {
+ *(dst++) = src[0] | (src[srcPitch] << 8) |
+ (src[srcPitch * 2] << 16) |
+ (src[srcPitch * 3] << 24);
+ src += srcPitch * 4;
+ }
+ srcPtr += pS3->rotate;
+ dstPtr += dstPitch;
+ }
+
+ pbox++;
+ }
+}
+
+
+void
+S3RefreshArea16(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
+{
+ S3Ptr pS3 = S3PTR(pScrn);
+ int count, width, height, y1, y2, dstPitch, srcPitch;
+ CARD16 *dstPtr, *srcPtr, *src;
+ CARD32 *dst;
+
+ dstPitch = pScrn->displayWidth;
+ srcPitch = -pS3->rotate * pS3->ShadowPitch >> 1;
+
+ while(num--) {
+ width = pbox->x2 - pbox->x1;
+ y1 = pbox->y1 & ~1;
+ y2 = (pbox->y2 + 1) & ~1;
+ height = (y2 - y1) >> 1; /* in dwords */
+
+ if(pS3->rotate == 1) {
+ dstPtr = (CARD16*)pS3->FBBase +
+ (pbox->x1 * dstPitch) + pScrn->virtualX - y2;
+ srcPtr = (CARD16*)pS3->ShadowPtr +
+ ((1 - y2) * srcPitch) + pbox->x1;
+ } else {
+ dstPtr = (CARD16*)pS3->FBBase +
+ ((pScrn->virtualY - pbox->x2) * dstPitch) + y1;
+ srcPtr = (CARD16*)pS3->ShadowPtr +
+ (y1 * srcPitch) + pbox->x2 - 1;
+ }
+
+ while(width--) {
+ src = srcPtr;
+ dst = (CARD32*)dstPtr;
+ count = height;
+ while(count--) {
+ *(dst++) = src[0] | (src[srcPitch] << 16);
+ src += srcPitch * 2;
+ }
+ srcPtr += pS3->rotate;
+ dstPtr += dstPitch;
+ }
+
+ pbox++;
+ }
+}
+
+
+/* this one could be faster */
+void
+S3RefreshArea24(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
+{
+ S3Ptr pS3 = S3PTR(pScrn);
+ int count, width, height, y1, y2, dstPitch, srcPitch;
+ CARD8 *dstPtr, *srcPtr, *src;
+ CARD32 *dst;
+
+ dstPitch = BitmapBytePad(pScrn->displayWidth * 24);
+ srcPitch = -pS3->rotate * pS3->ShadowPitch;
+
+ while(num--) {
+ width = pbox->x2 - pbox->x1;
+ y1 = pbox->y1 & ~3;
+ y2 = (pbox->y2 + 3) & ~3;
+ height = (y2 - y1) >> 2; /* blocks of 3 dwords */
+
+ if(pS3->rotate == 1) {
+ dstPtr = pS3->FBBase +
+ (pbox->x1 * dstPitch) + ((pScrn->virtualX - y2) * 3);
+ srcPtr = pS3->ShadowPtr + ((1 - y2) * srcPitch) + (pbox->x1 * 3);
+ } else {
+ dstPtr = pS3->FBBase +
+ ((pScrn->virtualY - pbox->x2) * dstPitch) + (y1 * 3);
+ srcPtr = pS3->ShadowPtr + (y1 * srcPitch) + (pbox->x2 * 3) - 3;
+ }
+
+ while(width--) {
+ src = srcPtr;
+ dst = (CARD32*)dstPtr;
+ count = height;
+ while(count--) {
+ dst[0] = src[0] | (src[1] << 8) | (src[2] << 16) |
+ (src[srcPitch] << 24);
+ dst[1] = src[srcPitch + 1] | (src[srcPitch + 2] << 8) |
+ (src[srcPitch * 2] << 16) |
+ (src[(srcPitch * 2) + 1] << 24);
+ dst[2] = src[(srcPitch * 2) + 2] | (src[srcPitch * 3] << 8) |
+ (src[(srcPitch * 3) + 1] << 16) |
+ (src[(srcPitch * 3) + 2] << 24);
+ dst += 3;
+ src += srcPitch * 4;
+ }
+ srcPtr += pS3->rotate * 3;
+ dstPtr += dstPitch;
+ }
+
+ pbox++;
+ }
+}
+
+void
+S3RefreshArea32(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
+{
+ S3Ptr pS3 = S3PTR(pScrn);
+ int count, width, height, dstPitch, srcPitch;
+ CARD32 *dstPtr, *srcPtr, *src, *dst;
+
+ dstPitch = pScrn->displayWidth;
+ srcPitch = -pS3->rotate * pS3->ShadowPitch >> 2;
+
+ while(num--) {
+ width = pbox->x2 - pbox->x1;
+ height = pbox->y2 - pbox->y1;
+
+ if(pS3->rotate == 1) {
+ dstPtr = (CARD32*)pS3->FBBase +
+ (pbox->x1 * dstPitch) + pScrn->virtualX - pbox->y2;
+ srcPtr = (CARD32*)pS3->ShadowPtr +
+ ((1 - pbox->y2) * srcPitch) + pbox->x1;
+ } else {
+ dstPtr = (CARD32*)pS3->FBBase +
+ ((pScrn->virtualY - pbox->x2) * dstPitch) + pbox->y1;
+ srcPtr = (CARD32*)pS3->ShadowPtr +
+ (pbox->y1 * srcPitch) + pbox->x2 - 1;
+ }
+
+ while(width--) {
+ src = srcPtr;
+ dst = dstPtr;
+ count = height;
+ while(count--) {
+ *(dst++) = *src;
+ src += srcPitch;
+ }
+ srcPtr += pS3->rotate;
+ dstPtr += dstPitch;
+ }
+
+ pbox++;
+ }
+}