summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hw/kdrive/fbdev/fbdev.c34
-rw-r--r--hw/kdrive/fbdev/fbdev.h4
-rw-r--r--hw/kdrive/igs/Imakefile14
-rw-r--r--hw/kdrive/igs/igs.c201
-rw-r--r--hw/kdrive/igs/igs.h244
-rw-r--r--hw/kdrive/igs/igsdraw.c1114
-rw-r--r--hw/kdrive/igs/igsdraw.h188
-rw-r--r--hw/kdrive/igs/igsstub.c57
-rw-r--r--hw/kdrive/savage/s3.c834
-rw-r--r--hw/kdrive/savage/s3.h199
-rw-r--r--hw/kdrive/savage/s3clock.c12
-rw-r--r--hw/kdrive/savage/s3cmap.c15
-rw-r--r--hw/kdrive/savage/s3curs.c51
-rw-r--r--hw/kdrive/savage/s3draw.c991
-rw-r--r--hw/kdrive/savage/s3draw.h18
-rw-r--r--hw/kdrive/savage/s3reg.c62
-rw-r--r--hw/kdrive/savage/s3reg.h14
-rw-r--r--hw/kdrive/sis530/sis.c98
-rw-r--r--hw/kdrive/sis530/sis.h4
-rw-r--r--hw/kdrive/sis530/siscmap.c4
-rw-r--r--hw/kdrive/sis530/sisdraw.c4
-rw-r--r--hw/kdrive/src/kcmap.c127
-rw-r--r--hw/kdrive/src/kcurscol.c29
-rw-r--r--hw/kdrive/src/kdrive.c125
-rw-r--r--hw/kdrive/src/kdrive.h43
-rw-r--r--hw/kdrive/src/kinput.c5
-rw-r--r--hw/kdrive/src/kmode.c10
-rw-r--r--hw/kdrive/trident/trident.c2
-rw-r--r--hw/kdrive/trident/tridentcurs.c4
-rw-r--r--hw/kdrive/trident/tridentdraw.c4
-rw-r--r--hw/kdrive/trio/s3.c106
-rw-r--r--hw/kdrive/trio/s3.h17
-rw-r--r--hw/kdrive/trio/s3cmap.c4
-rw-r--r--hw/kdrive/trio/s3curs.c4
34 files changed, 3961 insertions, 681 deletions
diff --git a/hw/kdrive/fbdev/fbdev.c b/hw/kdrive/fbdev/fbdev.c
index ccd5505ff..c4026f629 100644
--- a/hw/kdrive/fbdev/fbdev.c
+++ b/hw/kdrive/fbdev/fbdev.c
@@ -88,40 +88,40 @@ fbdevScreenInit (KdScreenInfo *screen)
screen->width = priv->var.xres;
screen->height = priv->var.yres;
- screen->depth = priv->var.bits_per_pixel;
- screen->bitsPerPixel = priv->var.bits_per_pixel;
- screen->byteStride = priv->fix.line_length;
- screen->pixelStride = (priv->fix.line_length * 8 /
+ screen->fb[0].depth = priv->var.bits_per_pixel;
+ screen->fb[0].bitsPerPixel = priv->var.bits_per_pixel;
+ screen->fb[0].byteStride = priv->fix.line_length;
+ screen->fb[0].pixelStride = (priv->fix.line_length * 8 /
priv->var.bits_per_pixel);
switch (priv->fix.visual) {
case FB_VISUAL_PSEUDOCOLOR:
- screen->visuals = ((1 << StaticGray) |
+ screen->fb[0].visuals = ((1 << StaticGray) |
(1 << GrayScale) |
(1 << StaticColor) |
(1 << PseudoColor) |
(1 << TrueColor) |
(1 << DirectColor));
- screen->blueMask = 0x00;
- screen->greenMask = 0x00;
- screen->redMask = 0x00;
+ screen->fb[0].blueMask = 0x00;
+ screen->fb[0].greenMask = 0x00;
+ screen->fb[0].redMask = 0x00;
break;
case FB_VISUAL_TRUECOLOR:
- screen->visuals = (1 << TrueColor);
- screen->redMask = FbStipMask (priv->var.red.offset, priv->var.red.length);
- screen->greenMask = FbStipMask (priv->var.green.offset, priv->var.green.length);
- screen->blueMask = FbStipMask (priv->var.blue.offset, priv->var.blue.length);
- allbits = screen->redMask | screen->greenMask | screen->blueMask;
+ screen->fb[0].visuals = (1 << TrueColor);
+ screen->fb[0].redMask = FbStipMask (priv->var.red.offset, priv->var.red.length);
+ screen->fb[0].greenMask = FbStipMask (priv->var.green.offset, priv->var.green.length);
+ screen->fb[0].blueMask = FbStipMask (priv->var.blue.offset, priv->var.blue.length);
+ allbits = screen->fb[0].redMask | screen->fb[0].greenMask | screen->fb[0].blueMask;
depth = 32;
while (depth && !(allbits & (1 << (depth - 1))))
depth--;
- screen->depth = depth;
+ screen->fb[0].depth = depth;
break;
default:
return FALSE;
break;
}
screen->rate = 72;
- screen->frameBuffer = (CARD8 *) (priv->fb);
+ screen->fb[0].frameBuffer = (CARD8 *) (priv->fb);
return TRUE;
}
@@ -191,7 +191,7 @@ fbdevCardFini (KdCardInfo *card)
}
void
-fbdevGetColors (ScreenPtr pScreen, int n, xColorItem *pdefs)
+fbdevGetColors (ScreenPtr pScreen, int fb, int n, xColorItem *pdefs)
{
KdScreenPriv(pScreen);
FbdevPriv *priv = pScreenPriv->card->driver;
@@ -232,7 +232,7 @@ fbdevGetColors (ScreenPtr pScreen, int n, xColorItem *pdefs)
}
void
-fbdevPutColors (ScreenPtr pScreen, int n, xColorItem *pdefs)
+fbdevPutColors (ScreenPtr pScreen, int fb, int n, xColorItem *pdefs)
{
KdScreenPriv(pScreen);
FbdevPriv *priv = pScreenPriv->card->driver;
diff --git a/hw/kdrive/fbdev/fbdev.h b/hw/kdrive/fbdev/fbdev.h
index 5504a9804..a5a9e44e9 100644
--- a/hw/kdrive/fbdev/fbdev.h
+++ b/hw/kdrive/fbdev/fbdev.h
@@ -75,10 +75,10 @@ void
fbdevCardFini (KdCardInfo *card);
void
-fbdevGetColors (ScreenPtr pScreen, int n, xColorItem *pdefs);
+fbdevGetColors (ScreenPtr pScreen, int fb, int n, xColorItem *pdefs);
void
-fbdevPutColors (ScreenPtr pScreen, int n, xColorItem *pdefs);
+fbdevPutColors (ScreenPtr pScreen, int fb, int n, xColorItem *pdefs);
#endif /* _FBDEV_H_ */
diff --git a/hw/kdrive/igs/Imakefile b/hw/kdrive/igs/Imakefile
new file mode 100644
index 000000000..05d1e1c76
--- /dev/null
+++ b/hw/kdrive/igs/Imakefile
@@ -0,0 +1,14 @@
+XCOMM $XFree86$
+#include <Server.tmpl>
+
+SRCS = igs.c igsdraw.c igsstub.c
+
+OBJS = igs.o igsdraw.o igsstub.o
+
+INCLUDES = -I.. -I. -I$(XBUILDINCDIR) -I$(FONTINCSRC) \
+ -I../../../fb -I../../../mi -I../../../include -I../../../os \
+ -I$(EXTINCSRC) -I$(XINCLUDESRC)
+
+NormalLibraryObjectRule()
+NormalLibraryTarget(igs,$(OBJS))
+DependTarget()
diff --git a/hw/kdrive/igs/igs.c b/hw/kdrive/igs/igs.c
new file mode 100644
index 000000000..62b31af48
--- /dev/null
+++ b/hw/kdrive/igs/igs.c
@@ -0,0 +1,201 @@
+/*
+ * $XFree86$
+ *
+ * Copyright © 1999 SuSE, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. SuSE makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Keith Packard, SuSE, Inc.
+ */
+
+#include "igs.h"
+
+Bool
+igsCardInit (KdCardInfo *card)
+{
+ int k;
+ char *pixels;
+ IgsCardInfo *igsc;
+
+ igsc = (IgsCardInfo *) xalloc (sizeof (IgsCardInfo));
+ if (!igsc)
+ return FALSE;
+
+ memset (igsc, '\0', sizeof (IgsCardInfo));
+
+ igsc->frameBuffer = (CARD8 *) KdMapDevice (card->attr.address[0],
+ 4096 * 1024);
+
+ igsc->cop = (Cop5xxx *) KdMapDevice (card->attr.address[0] +
+ IGS_COP_OFFSET,
+ sizeof (Cop5xxx));
+
+ igsc->copData = (VOL32 *) KdMapDevice (card->attr.address[0] +
+ IGS_COP_DATA,
+ IGS_COP_DATA_LEN);
+
+ card->driver = igsc;
+
+ return TRUE;
+}
+
+Bool
+igsScreenInit (KdScreenInfo *screen)
+{
+ IgsCardInfo *igsc = screen->card->driver;
+ int fb = 0;
+
+ if (screen->fb[fb].depth >= 24)
+ {
+ screen->fb[fb].depth = 24;
+ if (screen->fb[fb].bitsPerPixel != 24)
+ screen->fb[fb].bitsPerPixel = 32;
+ }
+ else if (screen->fb[fb].depth >= 16)
+ {
+ screen->fb[fb].depth = 16;
+ screen->fb[fb].bitsPerPixel = 16;
+ }
+ else if (screen->fb[fb].depth >= 15)
+ {
+ screen->fb[fb].depth = 15;
+ screen->fb[fb].bitsPerPixel = 16;
+ }
+ else
+ {
+ screen->fb[fb].depth = 8;
+ screen->fb[fb].bitsPerPixel = 8;
+ }
+ switch (screen->fb[fb].depth) {
+ case 8:
+ screen->fb[fb].visuals = ((1 << StaticGray) |
+ (1 << GrayScale) |
+ (1 << StaticColor) |
+ (1 << PseudoColor) |
+ (1 << TrueColor) |
+ (1 << DirectColor));
+ screen->fb[fb].blueMask = 0x00;
+ screen->fb[fb].greenMask = 0x00;
+ screen->fb[fb].redMask = 0x00;
+ break;
+ case 15:
+ screen->fb[fb].visuals = (1 << TrueColor);
+ screen->fb[fb].blueMask = 0x001f;
+ screen->fb[fb].greenMask = 0x03e0;
+ screen->fb[fb].redMask = 0x7c00;
+ break;
+ case 16:
+ screen->fb[fb].visuals = (1 << TrueColor);
+ screen->fb[fb].blueMask = 0x001f;
+ screen->fb[fb].greenMask = 0x07e0;
+ screen->fb[fb].redMask = 0xf800;
+ break;
+ case 24:
+ screen->fb[fb].visuals = (1 << TrueColor);
+ screen->fb[fb].blueMask = 0x0000ff;
+ screen->fb[fb].greenMask = 0x00ff00;
+ screen->fb[fb].redMask = 0xff0000;
+ break;
+ }
+ screen->fb[fb].pixelStride = screen->width;
+ screen->fb[fb].byteStride = screen->width * (screen->fb[fb].bitsPerPixel >> 3);
+ screen->fb[fb].frameBuffer = igsc->frameBuffer;
+ if (!igsc->cop)
+ screen->dumb = TRUE;
+ return TRUE;
+}
+
+Bool
+igsInitScreen(ScreenPtr pScreen)
+{
+ return TRUE;
+}
+
+void
+igsPreserve (KdCardInfo *card)
+{
+}
+
+void
+igsEnable (ScreenPtr pScreen)
+{
+}
+
+Bool
+igsDPMS (ScreenPtr pScreen, int mode)
+{
+ return TRUE;
+}
+
+void
+igsDisable (ScreenPtr pScreen)
+{
+}
+
+void
+igsRestore (KdCardInfo *card)
+{
+}
+
+void
+igsScreenFini (KdScreenInfo *screen)
+{
+}
+
+void
+igsCardFini (KdCardInfo *card)
+{
+ IgsCardInfo *igsc = card->driver;
+
+ if (igsc->copData)
+ KdUnmapDevice ((void *) igsc->copData, IGS_COP_DATA_LEN);
+ if (igsc->cop)
+ KdUnmapDevice (igsc->cop, sizeof (Cop5xxx));
+ if (igsc->frameBuffer)
+ KdUnmapDevice (igsc->frameBuffer, 4096 * 1024);
+ xfree (igsc);
+ card->driver = 0;
+}
+
+KdCardFuncs igsFuncs = {
+ igsCardInit, /* cardinit */
+ igsScreenInit, /* scrinit */
+ igsInitScreen,
+ igsPreserve, /* preserve */
+ igsEnable, /* enable */
+ igsDPMS, /* dpms */
+ igsDisable, /* disable */
+ igsRestore, /* restore */
+ igsScreenFini, /* scrfini */
+ igsCardFini, /* cardfini */
+
+ 0, /* initCursor */
+ 0, /* enableCursor */
+ 0, /* disableCursor */
+ 0, /* finiCursor */
+ 0, /* recolorCursor */
+
+ igsDrawInit, /* initAccel */
+ igsDrawEnable, /* enableAccel */
+ igsDrawSync, /* drawSync */
+ igsDrawDisable, /* disableAccel */
+ igsDrawFini, /* finiAccel */
+
+ 0, /* getColors */
+ 0, /* putColors */
+};
diff --git a/hw/kdrive/igs/igs.h b/hw/kdrive/igs/igs.h
new file mode 100644
index 000000000..9316ef249
--- /dev/null
+++ b/hw/kdrive/igs/igs.h
@@ -0,0 +1,244 @@
+/*
+ * $XFree86$
+ *
+ * Copyright © 1999 SuSE, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. SuSE makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Keith Packard, SuSE, Inc.
+ */
+
+#ifndef _IGS_H_
+#define _IGS_H_
+
+#include "kdrive.h"
+
+extern KdCardFuncs igsFuncs;
+
+/*
+ * FB 0x00000000
+ * VGA 0x00800000
+ * Blt window 0x008a0000
+ * Coprocessor 0x008bf000
+ */
+
+#define IGS_COP_DATA 0x008a0000
+#define IGS_COP_DATA_LEN 0x00010000
+#define IGS_COP_OFFSET 0x008bf000
+
+typedef volatile CARD8 VOL8;
+typedef volatile CARD16 VOL16;
+typedef volatile CARD32 VOL32;
+
+typedef struct _Cop5xxx {
+ VOL8 pad000[0x11]; /* 0x000 */
+
+ VOL8 control; /* 0x011 */
+#define IGS_CONTROL_HBLTW_RDYZ 0x01
+#define IGS_CONTROL_MALLWBEPTZ 0x02
+#define IGS_CONTROL_CMDFF 0x04
+#define IGS_CONTROL_SOP 0x08
+#define IGS_CONTROL_OPS 0x10
+#define IGS_CONTROL_TER 0x20
+#define IGS_CONTROL_HBACKZ 0x40
+#define IGS_CONTROL_BUSY 0x80
+
+ VOL8 pad012[0x06]; /* 0x012 */
+
+ VOL32 src1_stride; /* 0x018 */
+
+ VOL32 format; /* 0x01c */
+
+#define IGS_FORMAT_8BPP 0
+#define IGS_FORMAT_16BPP 1
+#define IGS_FORMAT_24BPP 2
+#define IGS_FORMAT_32BPP 3
+
+ VOL32 bres_error; /* 0x020 */
+ VOL32 bres_k1; /* 0x024 */
+ VOL32 bres_k2; /* 0x028 */
+ VOL8 pad02c[0x1c]; /* 0x02c */
+
+ VOL32 mix; /* 0x048 */
+#define IGS_MIX_FG 0x00ff
+#define IGS_MIX_BG 0xff00
+#define IGS_MAKE_MIX(fg,bg) ((fg) | ((bg) << 8))
+
+#define IGS_MIX_ZERO 0x0
+#define IGS_MIX_SRC_AND_DST 0x1
+#define IGS_MIX_SRC_AND_NOT_DST 0x2
+#define IGS_MIX_SRC 0x3
+#define IGS_MIX_NOT_SRC_AND_DST 0x4
+#define IGS_MIX_DST 0x5
+#define IGS_MIX_SRC_XOR_DST 0x6
+#define IGS_MIX_SRC_OR_DST 0x7
+#define IGS_MIX_NOT_SRC_AND_NOT_DST 0x8
+#define IGS_MIX_SRC_XOR_NOT_DST 0x9
+#define IGS_MIX_NOT_DST 0xa
+#define IGS_MIX_SRC_OR_NOT_DST 0xb
+#define IGS_MIX_NOT_SRC 0xc
+#define IGS_MIX_NOT_SRC_OR_DST 0xd
+#define IGS_MIX_NOT_SRC_OR_NOT_DST 0xe
+#define IGS_MIX_ONE 0xf
+
+ VOL32 colorComp; /* 0x04c */
+ VOL32 planemask; /* 0x050 */
+
+ VOL8 pad054[0x4]; /* 0x054 */
+
+ VOL32 fg; /* 0x058 */
+ VOL32 bg; /* 0x05c */
+ VOL32 dim; /* 0x060 */
+#define IGS_MAKE_DIM(w,h) ((w) | ((h) << 16))
+ VOL8 pad5[0x0c]; /* 0x064 */
+
+ VOL32 src1_base_address; /* 0x070 */
+ VOL8 pad074[0x04]; /* 0x074 */
+
+ VOL16 dst_x_rotate; /* 0x078 */
+ VOL16 pat_y_rotate; /* 0x07a */
+ VOL32 operation; /* 0x07c */
+
+/* OCT[2:0] */
+#define IGS_DRAW_X_MAJOR 0x00000000
+#define IGS_DRAW_Y_MAJOR 0x00000001
+#define IGS_DRAW_T_B 0x00000000
+#define IGS_DRAW_B_T 0x00000002
+#define IGS_DRAW_L_R 0x00000000
+#define IGS_DRAW_R_L 0x00000004
+
+/* Draw_Mode[1:0] */
+#define IGS_DRAW_ALL 0x00000000
+#define IGS_DRAW_NOT_FIRST 0x00000010
+#define IGS_DRAW_NOT_LAST 0x00000020
+#define IGS_DRAW_NOT_FIRST_LAST 0x00000030
+
+/* TRPS[1:0] */
+#define IGS_TRANS_SRC1 0x00000000
+#define IGS_TRANS_SRC2 0x00000100
+#define IGS_TRANS_DST 0x00000200
+/* TRPS2 Transparent Invert */
+#define IGS_TRANS_INVERT 0x00000400
+/* TRPS3, Transparent Enable */
+#define IGS_TRANS_ENABLE 0x00000800
+
+/* PPS[3:0], Pattern Pixel Select */
+#define IGS_PIXEL_TEXT_OPAQUE 0x00001000
+#define IGS_PIXEL_STIP_OPAQUE 0x00002000
+#define IGS_PIXEL_LINE_OPAQUE 0x00003000
+#define IGS_PIXEL_TEXT_TRANS 0x00005000
+#define IGS_PIXEL_STIP_TRANS 0x00006000
+#define IGS_PIXEL_LINE_TRANS 0x00007000
+#define IGS_PIXEL_FG 0x00008000
+#define IGS_PIXEL_TILE 0x00009000
+
+/* HostBltEnable[1:0] */
+#define IGS_HBLT_DISABLE 0x00000000
+#define IGS_HBLT_READ 0x00010000
+#define IGS_HBLT_WRITE_1 0x00020000
+#define IGS_HBLT_WRITE_2 0x00030000
+
+/* Src2MapSelect[2:0], Src2 map select mode */
+#define IGS_SRC2_NORMAL 0x00000000
+#define IGS_SRC2_MONO_OPAQUE 0x00100000
+#define IGS_SRC2_FG 0x00200000
+#define IGS_SRC2_MONO_TRANS 0x00500000
+
+/* StepFunction[3:0], Step function select */
+#define IGS_STEP_DRAW_AND_STEP 0x04000000
+#define IGS_STEP_LINE_DRAW 0x05000000
+#define IGS_STEP_PXBLT 0x08000000
+#define IGS_STEP_INVERT_PXBLT 0x09000000
+#define IGS_STEP_TERNARY_PXBLT 0x0b000000
+
+/* FGS */
+#define IGS_FGS_FG 0x00000000
+#define IGS_FGS_SRC 0x20000000
+
+/* BGS */
+#define IGS_BGS_BG 0x00000000
+#define IGS_BGS_SRC 0x80000000
+ VOL8 pad080[0x91]; /* 0x080 */
+
+ VOL8 debug_control_1; /* 0x111 */
+ VOL8 debug_control_2; /* 0x112 */
+ VOL8 pad113[0x05]; /* 0x113 */
+
+ VOL32 src2_stride; /* 0x118 */
+ VOL8 pad11c[0x14]; /* 0x11c */
+
+ VOL32 extension; /* 0x130 */
+
+#define IGS_BURST_ENABLE 0x01
+#define IGS_STYLE_LINE 0x02
+#define IGS_ADDITIONAL_WAIT 0x04
+#define IGS_BLOCK_COP_REG 0x08
+#define IGS_TURBO_MONO 0x10
+#define IGS_SELECT_SAMPLE 0x40
+#define IGS_MDSBL_RD_B_WR 0x80
+#define IGS_WRMRSTZ 0x100
+#define IGS_TEST_MTST 0x200
+
+ VOL8 style_line_roll_over; /* 0x134 */
+ VOL8 style_line_inc; /* 0x135 */
+ VOL8 style_line_pattern; /* 0x136 */
+ VOL8 style_line_accumulator; /* 0x137 */
+ VOL8 style_line_pattern_index; /* 0x138 */
+ VOL8 pad139[0x3]; /* 0x139 */
+
+ VOL16 mono_burst_total; /* 0x13c */
+ VOL8 pad13e[0x12]; /* 0x13e */
+
+ VOL8 pat_x_rotate; /* 0x150 */
+ VOL8 pad151[0x1f]; /* 0x151 */
+
+ VOL32 src1_start; /* 0x170 */
+ VOL32 src2_start; /* 0x174 */
+ VOL32 dst_start; /* 0x178 */
+ VOL8 pad17c[0x9c]; /* 0x17c */
+
+ VOL16 dst_stride; /* 0x218 */
+} Cop5xxx;
+
+typedef struct _igsCardInfo {
+ Cop5xxx *cop;
+ VOL32 *copData;
+ Bool need_sync;
+ CARD8 *frameBuffer;
+} IgsCardInfo;
+
+#define getIgsCardInfo(kd) ((IgsCardInfo *) ((kd)->card->driver))
+#define igsCardInfo(kd) IgsCardInfo *igsc = getIgsCardInfo(kd)
+
+Bool
+igsDrawInit (ScreenPtr pScreen);
+
+void
+igsDrawEnable (ScreenPtr pScreen);
+
+void
+igsDrawDisable (ScreenPtr pScreen);
+
+void
+igsDrawSync (ScreenPtr pScreen);
+
+void
+igsDrawFini (ScreenPtr pScreen);
+
+
+#endif /* _IGS_H_ */
diff --git a/hw/kdrive/igs/igsdraw.c b/hw/kdrive/igs/igsdraw.c
new file mode 100644
index 000000000..43ca7cf6e
--- /dev/null
+++ b/hw/kdrive/igs/igsdraw.c
@@ -0,0 +1,1114 @@
+/*
+ * $XFree86$
+ *
+ * Copyright © 2000 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "igs.h"
+#include "igsdraw.h"
+
+#include "Xmd.h"
+#include "gcstruct.h"
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+#include "regionstr.h"
+#include "mistruct.h"
+#include "fontstruct.h"
+#include "dixfontstr.h"
+#include "fb.h"
+#include "migc.h"
+#include "miline.h"
+
+CARD8 igsPatRop[16] = {
+ /* GXclear */ 0x00, /* 0 */
+ /* GXand */ 0xa0, /* src AND dst */
+ /* GXandReverse */ 0x50, /* src AND NOT dst */
+ /* GXcopy */ 0xf0, /* src */
+ /* GXandInverted*/ 0x0a, /* NOT src AND dst */
+ /* GXnoop */ 0xaa, /* dst */
+ /* GXxor */ 0x5a, /* src XOR dst */
+ /* GXor */ 0xfa, /* src OR dst */
+ /* GXnor */ 0x05, /* NOT src AND NOT dst */
+ /* GXequiv */ 0xa5, /* NOT src XOR dst */
+ /* GXinvert */ 0x55, /* NOT dst */
+ /* GXorReverse */ 0xf5, /* src OR NOT dst */
+ /* GXcopyInverted*/ 0x0f, /* NOT src */
+ /* GXorInverted */ 0xaf, /* NOT src OR dst */
+ /* GXnand */ 0x5f, /* NOT src OR NOT dst */
+ /* GXset */ 0xff, /* 1 */
+};
+
+/*
+ * Handle pixel transfers
+ */
+
+#define BURST
+#ifdef BURST
+#define PixTransDeclare VOL32 *pix_trans_base = igsc->copData,\
+ *pix_trans = pix_trans_base
+#define PixTransStart(n) if (pix_trans + (n) > pix_trans_base + 16384) pix_trans = pix_trans_base
+#define PixTransStore(t) *pix_trans++ = (t)
+#else
+#define PixTransDeclare VOL32 *pix_trans = igsc->copData
+#define PixTransStart(n)
+#define PixTransStore(t) *pix_trans = (t)
+#endif
+
+void
+igsFillBoxSolid (DrawablePtr pDrawable, int nBox, BoxPtr pBox,
+ unsigned long pixel, int alu, unsigned long planemask)
+{
+ SetupIgs(pDrawable->pScreen);
+ CARD32 cmd;
+
+ _igsSetSolidRect(cop,alu,planemask,pixel,cmd);
+ while (nBox--)
+ {
+ _igsRect(cop,pBox->x1,pBox->y1,pBox->x2-pBox->x1,pBox->y2-pBox->y1,cmd);
+ pBox++;
+ }
+ KdMarkSync (pDrawable->pScreen);
+}
+
+void
+igsCopyNtoN (DrawablePtr pSrcDrawable,
+ DrawablePtr pDstDrawable,
+ GCPtr pGC,
+ BoxPtr pbox,
+ int nbox,
+ int dx,
+ int dy,
+ Bool reverse,
+ Bool upsidedown,
+ Pixel bitplane,
+ void *closure)
+{
+ SetupIgs(pDstDrawable->pScreen);
+ int srcX, srcY, dstX, dstY;
+ int w, h;
+ CARD32 flags;
+ CARD32 cmd;
+ CARD8 alu;
+
+ if (pGC)
+ {
+ alu = pGC->alu;
+ if (sourceInvarient (pGC->alu))
+ {
+ igsFillBoxSolid (pDstDrawable, nbox, pbox, 0, pGC->alu, pGC->planemask);
+ return;
+ }
+ }
+ else
+ alu = GXcopy;
+
+ _igsSetBlt(cop,alu,pGC->planemask,reverse,upsidedown,cmd);
+ while (nbox--)
+ {
+ w = pbox->x2 - pbox->x1;
+ h = pbox->y2 - pbox->y1;
+ if (reverse)
+ dstX = pbox->x2 - 1;
+ else
+ dstX = pbox->x1;
+ srcX = dstX + dx;
+
+ if (upsidedown)
+ dstY = pbox->y2 - 1;
+ else
+ dstY = pbox->y1;
+
+ srcY = dstY + dy;
+
+ _igsBlt (cop, srcX, srcY, dstX, dstY, w, h, cmd);
+ pbox++;
+ }
+ KdMarkSync (pDstDrawable->pScreen);
+}
+
+RegionPtr
+igsCopyArea(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC,
+ int srcx, int srcy, int width, int height, int dstx, int dsty)
+{
+ KdScreenPriv(pDstDrawable->pScreen);
+ FbBits depthMask;
+
+ depthMask = FbFullMask (pDstDrawable->depth);
+ if ((pGC->planemask & depthMask) == depthMask &&
+ pSrcDrawable->type == DRAWABLE_WINDOW &&
+ pDstDrawable->type == DRAWABLE_WINDOW)
+ {
+ return fbDoCopy (pSrcDrawable, pDstDrawable, pGC,
+ srcx, srcy, width, height,
+ dstx, dsty, igsCopyNtoN, 0, 0);
+ }
+ return KdCheckCopyArea (pSrcDrawable, pDstDrawable, pGC,
+ srcx, srcy, width, height, dstx, dsty);
+}
+
+BOOL
+igsFillOk (GCPtr pGC)
+{
+ FbBits depthMask;
+
+ depthMask = FbFullMask(pGC->depth);
+ if ((pGC->planemask & depthMask) != depthMask)
+ return FALSE;
+ switch (pGC->fillStyle) {
+ case FillSolid:
+ return TRUE;
+#if 0
+ case FillTiled:
+ return (igsPatternDimOk (pGC->tile.pixmap->drawable.width) &&
+ igsPatternDimOk (pGC->tile.pixmap->drawable.height));
+ case FillStippled:
+ case FillOpaqueStippled:
+ return (igsPatternDimOk (pGC->stipple->drawable.width) &&
+ igsPatternDimOk (pGC->stipple->drawable.height));
+#endif
+ }
+ return FALSE;
+}
+
+void
+igsFillSpans (DrawablePtr pDrawable, GCPtr pGC, int n,
+ DDXPointPtr ppt, int *pwidth, int fSorted)
+{
+ SetupIgs(pDrawable->pScreen);
+ DDXPointPtr pptFree;
+ FbGCPrivPtr fbPriv = fbGetGCPrivate(pGC);
+ int *pwidthFree;/* copies of the pointers to free */
+ CARD32 cmd;
+ int nTmp;
+ INT16 x, y;
+ int width;
+
+ if (!igsFillOk (pGC))
+ {
+ KdCheckFillSpans (pDrawable, pGC, n, ppt, pwidth, fSorted);
+ return;
+ }
+ nTmp = n * miFindMaxBand(fbGetCompositeClip(pGC));
+ pwidthFree = (int *)ALLOCATE_LOCAL(nTmp * sizeof(int));
+ pptFree = (DDXPointRec *)ALLOCATE_LOCAL(nTmp * sizeof(DDXPointRec));
+ if(!pptFree || !pwidthFree)
+ {
+ if (pptFree) DEALLOCATE_LOCAL(pptFree);
+ if (pwidthFree) DEALLOCATE_LOCAL(pwidthFree);
+ return;
+ }
+ n = miClipSpans(fbGetCompositeClip(pGC),
+ ppt, pwidth, n,
+ pptFree, pwidthFree, fSorted);
+ pwidth = pwidthFree;
+ ppt = pptFree;
+ switch (pGC->fillStyle) {
+ case FillSolid:
+ _igsSetSolidRect(cop,pGC->alu,pGC->planemask,pGC->fgPixel,cmd);
+ break;
+#if 0
+ case FillTiled:
+ cmd = igsTilePrepare (pGC->tile.pixmap,
+ pGC->patOrg.x + pDrawable->x,
+ pGC->patOrg.y + pDrawable->y,
+ pGC->alu);
+ break;
+ default:
+ cmd = igsStipplePrepare (pDrawable, pGC);
+ break;
+#endif
+ }
+ while (n--)
+ {
+ x = ppt->x;
+ y = ppt->y;
+ ppt++;
+ width = *pwidth++;
+ if (width)
+ {
+ _igsRect(cop,x,y,width,1,cmd);
+ }
+ }
+ DEALLOCATE_LOCAL(pptFree);
+ DEALLOCATE_LOCAL(pwidthFree);
+ KdMarkSync (pDrawable->pScreen);
+}
+
+#define NUM_STACK_RECTS 1024
+
+void
+igsPolyFillRect (DrawablePtr pDrawable, GCPtr pGC,
+ int nrectFill, xRectangle *prectInit)
+{
+ SetupIgs(pDrawable->pScreen);
+ xRectangle *prect;
+ RegionPtr prgnClip;
+ register BoxPtr pbox;
+ register BoxPtr pboxClipped;
+ BoxPtr pboxClippedBase;
+ BoxPtr pextent;
+ BoxRec stackRects[NUM_STACK_RECTS];
+ FbGCPrivPtr fbPriv = fbGetGCPrivate (pGC);
+ int numRects;
+ int n;
+ int xorg, yorg;
+ int x, y;
+
+ if (!igsFillOk (pGC))
+ {
+ KdCheckPolyFillRect (pDrawable, pGC, nrectFill, prectInit);
+ return;
+ }
+ prgnClip = fbGetCompositeClip (pGC);
+ xorg = pDrawable->x;
+ yorg = pDrawable->y;
+
+ if (xorg || yorg)
+ {
+ prect = prectInit;
+ n = nrectFill;
+ while(n--)
+ {
+ prect->x += xorg;
+ prect->y += yorg;
+ prect++;
+ }
+ }
+
+ prect = prectInit;
+
+ numRects = REGION_NUM_RECTS(prgnClip) * nrectFill;
+ if (numRects > NUM_STACK_RECTS)
+ {
+ pboxClippedBase = (BoxPtr)xalloc(numRects * sizeof(BoxRec));
+ if (!pboxClippedBase)
+ return;
+ }
+ else
+ pboxClippedBase = stackRects;
+
+ pboxClipped = pboxClippedBase;
+
+ if (REGION_NUM_RECTS(prgnClip) == 1)
+ {
+ int x1, y1, x2, y2, bx2, by2;
+
+ pextent = REGION_RECTS(prgnClip);
+ x1 = pextent->x1;
+ y1 = pextent->y1;
+ x2 = pextent->x2;
+ y2 = pextent->y2;
+ while (nrectFill--)
+ {
+ if ((pboxClipped->x1 = prect->x) < x1)
+ pboxClipped->x1 = x1;
+
+ if ((pboxClipped->y1 = prect->y) < y1)
+ pboxClipped->y1 = y1;
+
+ bx2 = (int) prect->x + (int) prect->width;
+ if (bx2 > x2)
+ bx2 = x2;
+ pboxClipped->x2 = bx2;
+
+ by2 = (int) prect->y + (int) prect->height;
+ if (by2 > y2)
+ by2 = y2;
+ pboxClipped->y2 = by2;
+
+ prect++;
+ if ((pboxClipped->x1 < pboxClipped->x2) &&
+ (pboxClipped->y1 < pboxClipped->y2))
+ {
+ pboxClipped++;
+ }
+ }
+ }
+ else
+ {
+ int x1, y1, x2, y2, bx2, by2;
+
+ pextent = REGION_EXTENTS(pGC->pScreen, prgnClip);
+ x1 = pextent->x1;
+ y1 = pextent->y1;
+ x2 = pextent->x2;
+ y2 = pextent->y2;
+ while (nrectFill--)
+ {
+ BoxRec box;
+
+ if ((box.x1 = prect->x) < x1)
+ box.x1 = x1;
+
+ if ((box.y1 = prect->y) < y1)
+ box.y1 = y1;
+
+ bx2 = (int) prect->x + (int) prect->width;
+ if (bx2 > x2)
+ bx2 = x2;
+ box.x2 = bx2;
+
+ by2 = (int) prect->y + (int) prect->height;
+ if (by2 > y2)
+ by2 = y2;
+ box.y2 = by2;
+
+ prect++;
+
+ if ((box.x1 >= box.x2) || (box.y1 >= box.y2))
+ continue;
+
+ n = REGION_NUM_RECTS (prgnClip);
+ pbox = REGION_RECTS(prgnClip);
+
+ /* clip the rectangle to each box in the clip region
+ this is logically equivalent to calling Intersect()
+ */
+ while(n--)
+ {
+ pboxClipped->x1 = max(box.x1, pbox->x1);
+ pboxClipped->y1 = max(box.y1, pbox->y1);
+ pboxClipped->x2 = min(box.x2, pbox->x2);
+ pboxClipped->y2 = min(box.y2, pbox->y2);
+ pbox++;
+
+ /* see if clipping left anything */
+ if(pboxClipped->x1 < pboxClipped->x2 &&
+ pboxClipped->y1 < pboxClipped->y2)
+ {
+ pboxClipped++;
+ }
+ }
+ }
+ }
+ if (pboxClipped != pboxClippedBase)
+ {
+ switch (pGC->fillStyle) {
+ case FillSolid:
+ igsFillBoxSolid(pDrawable,
+ pboxClipped-pboxClippedBase, pboxClippedBase,
+ pGC->fgPixel, pGC->alu, pGC->planemask);
+ break;
+#if 0
+ case FillTiled:
+ igsFillBoxTiled(pDrawable,
+ pboxClipped-pboxClippedBase, pboxClippedBase,
+ pGC->tile.pixmap,
+ pGC->patOrg.x + pDrawable->x,
+ pGC->patOrg.y + pDrawable->y,
+ pGC->alu);
+ break;
+ case FillStippled:
+ case FillOpaqueStippled:
+ igsFillBoxStipple (pDrawable, pGC,
+ pboxClipped-pboxClippedBase, pboxClippedBase);
+ break;
+#endif
+ }
+ }
+ if (pboxClippedBase != stackRects)
+ xfree(pboxClippedBase);
+}
+
+int
+igsTextInRegion (GCPtr pGC,
+ int x,
+ int y,
+ unsigned int nglyph,
+ CharInfoPtr *ppci)
+{
+ int w;
+ FontPtr pfont = pGC->font;
+ BoxRec bbox;
+
+ if (FONTCONSTMETRICS(pfont))
+ w = FONTMAXBOUNDS(pfont,characterWidth) * nglyph;
+ else
+ {
+ w = 0;
+ while (nglyph--)
+ w += (*ppci++)->metrics.characterWidth;
+ }
+ if (w < 0)
+ {
+ bbox.x1 = x + w;
+ bbox.x2 = x;
+ }
+ else
+ {
+ bbox.x1 = x;
+ bbox.x2 = x + w;
+ }
+ w = FONTMINBOUNDS(pfont,leftSideBearing);
+ if (w < 0)
+ bbox.x1 += w;
+ w = FONTMAXBOUNDS(pfont, rightSideBearing) - FONTMINBOUNDS(pfont, characterWidth);
+ if (w > 0)
+ bbox.x2 += w;
+ bbox.y1 = y - FONTMAXBOUNDS(pfont,ascent);
+ bbox.y2 = y + FONTMAXBOUNDS(pfont,descent);
+
+ return RECT_IN_REGION(pGC->pScreen, fbGetCompositeClip(pGC), &bbox);
+}
+
+void
+igsGlyphBltClipped (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x,
+ int y,
+ unsigned int nglyph,
+ CharInfoPtr *ppciInit,
+ Bool image)
+{
+ SetupIgs(pDrawable->pScreen);
+ CARD32 cmd;
+ int h;
+ int w;
+ int xBack, yBack;
+ int hBack, wBack;
+ int lw;
+ FontPtr pfont = pGC->font;
+ CharInfoPtr pci;
+ unsigned long *bits;
+ BoxPtr extents;
+ BoxRec bbox;
+ CARD32 b;
+ CharInfoPtr *ppci;
+ FbGCPrivPtr fbPriv = fbGetGCPrivate(pGC);
+ RegionPtr pClip = fbGetCompositeClip(pGC);
+ BoxPtr pBox;
+ int nbox;
+ int x1, y1, x2, y2;
+ unsigned char alu;
+ Bool set;
+ PixTransDeclare;
+
+ if (image)
+ {
+ xBack = x;
+ yBack = y - FONTASCENT(pGC->font);
+ wBack = 0;
+ hBack = FONTASCENT(pGC->font) + FONTDESCENT(pGC->font);
+ if (hBack)
+ {
+ h = nglyph;
+ ppci = ppciInit;
+ while (h--)
+ wBack += (*ppci++)->metrics.characterWidth;
+ }
+ if (wBack < 0)
+ {
+ xBack = xBack + wBack;
+ wBack = -wBack;
+ }
+ if (hBack < 0)
+ {
+ yBack = yBack + hBack;
+ hBack = -hBack;
+ }
+ alu = GXcopy;
+ if (wBack)
+ {
+ _igsSetSolidRect (cop, GXcopy, pGC->planemask, pGC->bgPixel, cmd);
+ for (nbox = REGION_NUM_RECTS (pClip),
+ pBox = REGION_RECTS (pClip);
+ nbox--;
+ pBox++)
+ {
+ x1 = xBack;
+ x2 = xBack + wBack;
+ y1 = yBack;
+ y2 = yBack + hBack;
+ if (x1 < pBox->x1) x1 = pBox->x1;
+ if (x2 > pBox->x2) x2 = pBox->x2;
+ if (y1 < pBox->y1) y1 = pBox->y1;
+ if (y2 > pBox->y2) y2 = pBox->y2;
+ if (x1 < x2 && y1 < y2)
+ {
+ _igsRect (cop, x1, y1, x2 - x1, y2 - y1, cmd);
+ }
+ }
+ KdMarkSync (pDrawable->pScreen);
+ }
+ }
+ else
+ {
+ wBack = 0;
+ alu = pGC->alu;
+ }
+
+ ppci = ppciInit;
+ set = FALSE;
+ while (nglyph--)
+ {
+ pci = *ppci++;
+ h = pci->metrics.ascent + pci->metrics.descent;
+ w = pci->metrics.rightSideBearing - pci->metrics.leftSideBearing;
+ x1 = x + pci->metrics.leftSideBearing;
+ y1 = y - pci->metrics.ascent;
+ bbox.x1 = x1;
+ bbox.y1 = y1;
+ bbox.x2 = x1 + w;
+ bbox.y2 = y1 + h;
+ switch (RECT_IN_REGION(pGC->pScreen, pClip, &bbox))
+ {
+ case rgnIN:
+ lw = h * ((w + 31) >> 5);
+ if (lw)
+ {
+ if (!set)
+ {
+ _igsSetTransparentPlaneBlt (cop, alu, pGC->planemask, pGC->fgPixel, cmd);
+ set = TRUE;
+ }
+ _igsPlaneBlt(cop,
+ x + pci->metrics.leftSideBearing,
+ y - pci->metrics.ascent,
+ w, h, cmd);
+ bits = (unsigned long *) pci->bits;
+ PixTransStart (lw);
+ while (lw--)
+ {
+ b = *bits++;
+ IgsAdjustBits32 (b);
+ PixTransStore(b);
+ }
+ KdMarkSync (pDrawable->pScreen);
+ }
+ break;
+ case rgnPART:
+ set = FALSE;
+ KdCheckSync (pDrawable->pScreen);
+ fbPutXYImage (pDrawable,
+ pClip,
+ fbPriv->fg,
+ fbPriv->bg,
+ fbPriv->pm,
+ alu,
+ FALSE,
+ x1, y1,
+ w, h,
+ (FbStip *) pci->bits,
+ (w + 31) >> 5,
+ 0);
+ break;
+ case rgnOUT:
+ break;
+ }
+ x += pci->metrics.characterWidth;
+ }
+}
+
+void
+igsGlyphBlt (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x,
+ int y,
+ unsigned int nglyph,
+ CharInfoPtr *ppciInit,
+ Bool image)
+{
+ SetupIgs(pDrawable->pScreen);
+ CARD32 cmd;
+ int h;
+ int w;
+ int xBack, yBack;
+ int hBack, wBack;
+ int lw;
+ FontPtr pfont = pGC->font;
+ CharInfoPtr pci;
+ unsigned long *bits;
+ BoxPtr extents;
+ BoxRec bbox;
+ CARD32 b;
+ CharInfoPtr *ppci;
+ unsigned char alu;
+ PixTransDeclare;
+
+ /*
+ * Paint background for image text
+ */
+ if (image)
+ {
+ xBack = x;
+ yBack = y - FONTASCENT(pGC->font);
+ wBack = 0;
+ hBack = FONTASCENT(pGC->font) + FONTDESCENT(pGC->font);
+ if (hBack)
+ {
+ h = nglyph;
+ ppci = ppciInit;
+ while (h--)
+ wBack += (*ppci++)->metrics.characterWidth;
+ }
+ if (wBack < 0)
+ {
+ xBack = xBack + wBack;
+ wBack = -wBack;
+ }
+ if (hBack < 0)
+ {
+ yBack = yBack + hBack;
+ hBack = -hBack;
+ }
+ alu = GXcopy;
+ if (wBack)
+ {
+ _igsSetSolidRect (cop, GXcopy, pGC->planemask, pGC->bgPixel, cmd);
+ _igsRect (cop, xBack, yBack, wBack, hBack, cmd);
+ }
+ }
+ else
+ {
+ wBack = 0;
+ alu = pGC->alu;
+ }
+
+ _igsSetTransparentPlaneBlt (cop, alu, pGC->planemask, pGC->fgPixel, cmd);
+ ppci = ppciInit;
+ while (nglyph--)
+ {
+ pci = *ppci++;
+ h = pci->metrics.ascent + pci->metrics.descent;
+ w = pci->metrics.rightSideBearing - pci->metrics.leftSideBearing;
+ lw = h * ((w + 31) >> 5);
+ if (lw)
+ {
+ _igsPlaneBlt(cop,
+ x + pci->metrics.leftSideBearing,
+ y - pci->metrics.ascent,
+ w, h, cmd);
+ bits = (unsigned long *) pci->bits;
+ PixTransStart(lw);
+ while (lw--)
+ {
+ b = *bits++;
+ IgsAdjustBits32 (b);
+ PixTransStore(b);
+ }
+ }
+ x += pci->metrics.characterWidth;
+ }
+ KdMarkSync (pDrawable->pScreen);
+}
+
+void
+igsTEGlyphBlt (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int xInit,
+ int yInit,
+ unsigned int nglyph,
+ CharInfoPtr *ppci,
+ Bool image)
+{
+ SetupIgs(pDrawable->pScreen);
+ CARD32 cmd;
+ int x, y;
+ int h, lw, lwTmp;
+ int w;
+ FontPtr pfont = pGC->font;
+ unsigned long *char1, *char2, *char3, *char4;
+ int widthGlyphs, widthGlyph;
+ BoxRec bbox;
+ CARD32 tmp;
+ PixTransDeclare;
+
+ widthGlyph = FONTMAXBOUNDS(pfont,characterWidth);
+ if (!widthGlyph)
+ return;
+
+ h = FONTASCENT(pfont) + FONTDESCENT(pfont);
+ if (!h)
+ return;
+
+ x = xInit + FONTMAXBOUNDS(pfont,leftSideBearing);
+ y = yInit - FONTASCENT(pfont);
+
+ if (image)
+ {
+ _igsSetOpaquePlaneBlt (cop, GXcopy, pGC->planemask, pGC->fgPixel, pGC->bgPixel, cmd);
+ }
+ else
+ {
+ _igsSetTransparentPlaneBlt (cop, pGC->alu, pGC->planemask, pGC->fgPixel, cmd);
+ }
+
+#if BITMAP_BIT_ORDER == LSBFirst
+#define SHIFT <<
+#else
+#define SHIFT >>
+#endif
+
+#define LoopIt(count, w, loadup, fetch) \
+ while (nglyph >= count) \
+ { \
+ nglyph -= count; \
+ _igsPlaneBlt (cop, x, y, w, h, cmd); \
+ x += w; \
+ loadup \
+ lwTmp = h; \
+ PixTransStart(h); \
+ while (lwTmp--) { \
+ tmp = fetch; \
+ IgsAdjustBits32(tmp); \
+ PixTransStore(tmp); \
+ } \
+ }
+
+ if (widthGlyph <= 8)
+ {
+ widthGlyphs = widthGlyph << 2;
+ LoopIt(4, widthGlyphs,
+ char1 = (unsigned long *) (*ppci++)->bits;
+ char2 = (unsigned long *) (*ppci++)->bits;
+ char3 = (unsigned long *) (*ppci++)->bits;
+ char4 = (unsigned long *) (*ppci++)->bits;,
+ (*char1++ | ((*char2++ | ((*char3++ | (*char4++
+ SHIFT widthGlyph))
+ SHIFT widthGlyph))
+ SHIFT widthGlyph)))
+ }
+ else if (widthGlyph <= 10)
+ {
+ widthGlyphs = (widthGlyph << 1) + widthGlyph;
+ LoopIt(3, widthGlyphs,
+ char1 = (unsigned long *) (*ppci++)->bits;
+ char2 = (unsigned long *) (*ppci++)->bits;
+ char3 = (unsigned long *) (*ppci++)->bits;,
+ (*char1++ | ((*char2++ | (*char3++ SHIFT widthGlyph)) SHIFT widthGlyph)))
+ }
+ else if (widthGlyph <= 16)
+ {
+ widthGlyphs = widthGlyph << 1;
+ LoopIt(2, widthGlyphs,
+ char1 = (unsigned long *) (*ppci++)->bits;
+ char2 = (unsigned long *) (*ppci++)->bits;,
+ (*char1++ | (*char2++ SHIFT widthGlyph)))
+ }
+ lw = h * ((widthGlyph + 31) >> 5);
+ while (nglyph--)
+ {
+ _igsPlaneBlt (cop, x, y, widthGlyph, h, cmd);
+ x += widthGlyph;
+ char1 = (unsigned long *) (*ppci++)->bits;
+ lwTmp = lw;
+ PixTransStart(lw);
+ while (lwTmp--)
+ {
+ tmp = *char1++;
+ IgsAdjustBits32(tmp);
+ PixTransStore(tmp);
+ }
+ }
+ KdMarkSync (pDrawable->pScreen);
+}
+
+/*
+ * Blt glyphs using image transfer window
+ */
+
+void
+igsPolyGlyphBlt (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x,
+ int y,
+ unsigned int nglyph,
+ CharInfoPtr *ppci,
+ pointer pglyphBase)
+{
+ x += pDrawable->x;
+ y += pDrawable->y;
+
+ switch (igsTextInRegion (pGC, x, y, nglyph, ppci)) {
+ case rgnIN:
+ if (TERMINALFONT(pGC->font))
+ igsTEGlyphBlt (pDrawable, pGC, x, y, nglyph, ppci, FALSE);
+ else
+ igsGlyphBlt (pDrawable, pGC, x, y, nglyph, ppci, FALSE);
+ break;
+ case rgnPART:
+ igsGlyphBltClipped (pDrawable, pGC, x, y, nglyph, ppci, FALSE);
+ break;
+ case rgnOUT:
+ break;
+ }
+}
+
+void
+igsImageGlyphBlt (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x, int y,
+ unsigned int nglyph,
+ CharInfoPtr *ppci,
+ pointer pglyphBase)
+{
+ x += pDrawable->x;
+ y += pDrawable->y;
+
+ switch (igsTextInRegion (pGC, x, y, nglyph, ppci)) {
+ case rgnIN:
+ if (TERMINALFONT(pGC->font))
+ igsTEGlyphBlt (pDrawable, pGC, x, y, nglyph, ppci, TRUE);
+ else
+ igsGlyphBlt (pDrawable, pGC, x, y, nglyph, ppci, TRUE);
+ break;
+ case rgnPART:
+ igsGlyphBltClipped (pDrawable, pGC, x, y, nglyph, ppci, TRUE);
+ break;
+ case rgnOUT:
+ break;
+ }
+}
+
+static const GCOps igsOps = {
+ igsFillSpans,
+ KdCheckSetSpans,
+ KdCheckPutImage,
+ igsCopyArea,
+ KdCheckCopyPlane,
+ KdCheckPolyPoint,
+ KdCheckPolylines,
+ KdCheckPolySegment,
+ miPolyRectangle,
+ KdCheckPolyArc,
+ miFillPolygon,
+ igsPolyFillRect,
+ KdCheckPolyFillArc,
+ miPolyText8,
+ miPolyText16,
+ miImageText8,
+ miImageText16,
+ igsImageGlyphBlt,
+ igsPolyGlyphBlt,
+ KdCheckPushPixels,
+#ifdef NEED_LINEHELPER
+ ,NULL
+#endif
+};
+
+void
+igsValidateGC (GCPtr pGC, Mask changes, DrawablePtr pDrawable)
+{
+ FbGCPrivPtr fbPriv = fbGetGCPrivate(pGC);
+
+ fbValidateGC (pGC, changes, pDrawable);
+
+ if (pDrawable->type == DRAWABLE_WINDOW)
+ pGC->ops = (GCOps *) &igsOps;
+ else
+ pGC->ops = (GCOps *) &fbGCOps;
+}
+
+GCFuncs igsGCFuncs = {
+ igsValidateGC,
+ miChangeGC,
+ miCopyGC,
+ miDestroyGC,
+ miChangeClip,
+ miDestroyClip,
+ miCopyClip
+};
+
+int
+igsCreateGC (GCPtr pGC)
+{
+ if (!fbCreateGC (pGC))
+ return FALSE;
+
+ if (pGC->depth != 1)
+ pGC->funcs = &igsGCFuncs;
+
+ return TRUE;
+}
+
+void
+igsCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ KdScreenPriv(pScreen);
+ RegionRec rgnDst;
+ int dx, dy;
+ WindowPtr pwinRoot;
+
+ pwinRoot = WindowTable[pWin->drawable.pScreen->myNum];
+
+ dx = ptOldOrg.x - pWin->drawable.x;
+ dy = ptOldOrg.y - pWin->drawable.y;
+ REGION_TRANSLATE(pWin->drawable.pScreen, prgnSrc, -dx, -dy);
+
+ REGION_INIT (pWin->drawable.pScreen, &rgnDst, NullBox, 0);
+
+ REGION_INTERSECT(pWin->drawable.pScreen, &rgnDst, &pWin->borderClip, prgnSrc);
+
+ fbCopyRegion ((DrawablePtr)pwinRoot, (DrawablePtr)pwinRoot,
+ 0,
+ &rgnDst, dx, dy, igsCopyNtoN, 0, 0);
+
+ REGION_UNINIT(pWin->drawable.pScreen, &rgnDst);
+}
+
+void
+igsPaintWindow(WindowPtr pWin, RegionPtr pRegion, int what)
+{
+ KdScreenPriv(pWin->drawable.pScreen);
+ PixmapPtr pTile;
+
+ if (!REGION_NUM_RECTS(pRegion))
+ return;
+ switch (what) {
+ case PW_BACKGROUND:
+ switch (pWin->backgroundState) {
+ case None:
+ return;
+ case ParentRelative:
+ do {
+ pWin = pWin->parent;
+ } while (pWin->backgroundState == ParentRelative);
+ (*pWin->drawable.pScreen->PaintWindowBackground)(pWin, pRegion,
+ what);
+ return;
+#if 0
+ case BackgroundPixmap:
+ pTile = pWin->background.pixmap;
+ if (igsPatternDimOk (pTile->drawable.width) &&
+ igsPatternDimOk (pTile->drawable.height))
+ {
+ igsFillBoxTiled ((DrawablePtr)pWin,
+ (int)REGION_NUM_RECTS(pRegion),
+ REGION_RECTS(pRegion),
+ pTile,
+ pWin->drawable.x, pWin->drawable.y, GXcopy);
+ return;
+ }
+ break;
+#endif
+ case BackgroundPixel:
+ igsFillBoxSolid((DrawablePtr)pWin,
+ (int)REGION_NUM_RECTS(pRegion),
+ REGION_RECTS(pRegion),
+ pWin->background.pixel, GXcopy, ~0);
+ return;
+ }
+ break;
+ case PW_BORDER:
+ if (pWin->borderIsPixel)
+ {
+ igsFillBoxSolid((DrawablePtr)pWin,
+ (int)REGION_NUM_RECTS(pRegion),
+ REGION_RECTS(pRegion),
+ pWin->border.pixel, GXcopy, ~0);
+ return;
+ }
+#if 0
+ else
+ {
+ pTile = pWin->border.pixmap;
+ if (igsPatternDimOk (pTile->drawable.width) &&
+ igsPatternDimOk (pTile->drawable.height))
+ {
+ igsFillBoxTiled ((DrawablePtr)pWin,
+ (int)REGION_NUM_RECTS(pRegion),
+ REGION_RECTS(pRegion),
+ pTile,
+ pWin->drawable.x, pWin->drawable.y, GXcopy);
+ return;
+ }
+ }
+#endif
+ break;
+ }
+ KdCheckPaintWindow (pWin, pRegion, what);
+}
+
+Bool
+igsDrawInit (ScreenPtr pScreen)
+{
+ /*
+ * Replace various fb screen functions
+ */
+ pScreen->CreateGC = igsCreateGC;
+ pScreen->CopyWindow = igsCopyWindow;
+ pScreen->PaintWindowBackground = igsPaintWindow;
+ pScreen->PaintWindowBorder = igsPaintWindow;
+
+ KdScreenInitAsync (pScreen);
+
+ return TRUE;
+}
+
+void
+igsDrawEnable (ScreenPtr pScreen)
+{
+ SetupIgs(pScreen);
+ CARD32 cmd;
+ CARD32 base;
+ CARD16 stride;
+ CARD32 format;
+
+ stride = pScreenPriv->screen->fb[0].pixelStride;
+ _igsWaitIdleEmpty(cop);
+ _igsReset(cop);
+ switch (pScreenPriv->screen->fb[0].bitsPerPixel) {
+ case 8:
+ format = IGS_FORMAT_8BPP;
+ break;
+ case 16:
+ format = IGS_FORMAT_16BPP;
+ break;
+ case 24:
+ format = IGS_FORMAT_24BPP;
+ break;
+ case 32:
+ format = IGS_FORMAT_32BPP;
+ break;
+ }
+ cop->format = format;
+ cop->dst_stride = stride - 1;
+ cop->src1_stride = stride - 1;
+ cop->src2_stride = stride - 1;
+ cop->src1_start = 0;
+ cop->src2_start = 0;
+ cop->extension |= IGS_BLOCK_COP_REG | IGS_BURST_ENABLE;
+
+ _igsSetSolidRect(cop, GXcopy, ~0, pScreen->blackPixel, cmd);
+ _igsRect (cop, 0, 0,
+ pScreenPriv->screen->width, pScreenPriv->screen->height,
+ cmd);
+ _igsWaitIdleEmpty (cop);
+}
+
+void
+igsDrawDisable (ScreenPtr pScreen)
+{
+}
+
+void
+igsDrawFini (ScreenPtr pScreen)
+{
+}
+
+void
+igsDrawSync (ScreenPtr pScreen)
+{
+ SetupIgs(pScreen);
+
+ _igsWaitIdleEmpty(cop);
+}
diff --git a/hw/kdrive/igs/igsdraw.h b/hw/kdrive/igs/igsdraw.h
new file mode 100644
index 000000000..5388d8e34
--- /dev/null
+++ b/hw/kdrive/igs/igsdraw.h
@@ -0,0 +1,188 @@
+/*
+ * $XFree86$
+ *
+ * Copyright © 2000 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _IGSDRAW_H_
+#define _IGSDRAW_H_
+
+extern CARD8 igsPatRop[];
+
+#define SetupIgs(s) KdScreenPriv(s); \
+ igsCardInfo(pScreenPriv); \
+ Cop5xxx *cop = igsc->cop; \
+ int cop_stride = pScreenPriv->screen->fb[0].pixelStride
+
+#define _igsWaitLoop(cop,mask,value) { \
+ int __loop = 1000000; \
+ while (((cop)->control & (mask)) != (value)) { \
+ if (--__loop <= 0) { \
+ FatalError("Warning: igsWaitLoop 0x%x 0x%x failed\n", mask, value); \
+ } \
+ } \
+}
+
+#define _igsWaitDone(cop) _igsWaitLoop(cop, \
+ (IGS_CONTROL_BUSY| \
+ IGS_CONTROL_MALLWBEPTZ), \
+ 0)
+
+#define _igsWaitFull(cop) _igsWaitLoop(cop, \
+ IGS_CONTROL_CMDFF, \
+ 0)
+
+#define _igsWaitIdleEmpty(cop) _igsWaitDone(cop)
+#define _igsWaitHostBltAck(cop) _igsWaitLoop(cop, \
+ (IGS_CONTROL_HBACKZ| \
+ IGS_CONTROL_CMDFF), \
+ 0)
+
+#define _igsReset(cop) ((cop)->control = 0)
+
+#define IgsInvertBits32(v) { \
+ v = ((v & 0x55555555) << 1) | ((v >> 1) & 0x55555555); \
+ v = ((v & 0x33333333) << 2) | ((v >> 2) & 0x33333333); \
+ v = ((v & 0x0f0f0f0f) << 4) | ((v >> 4) & 0x0f0f0f0f); \
+}
+
+#define IgsInvertBits16(v) { \
+ v = ((v & 0x5555) << 1) | ((v >> 1) & 0x5555); \
+ v = ((v & 0x3333) << 2) | ((v >> 2) & 0x3333); \
+ v = ((v & 0x0f0f) << 4) | ((v >> 4) & 0x0f0f); \
+}
+
+#define IgsInvertBits8(v) { \
+ v = ((v & 0x55) << 1) | ((v >> 1) & 0x55); \
+ v = ((v & 0x33) << 2) | ((v >> 2) & 0x33); \
+ v = ((v & 0x0f) << 4) | ((v >> 4) & 0x0f); \
+}
+
+#define IgsAdjustBits32(b) IgsInvertBits32(b)
+
+#define _igsSetSolidRect(cop,alu,pm,pix,cmd) {\
+ _igsWaitFull(cop); \
+ (cop)->mix = IGS_MAKE_MIX(alu,alu); \
+ (cop)->fg = (pix); \
+ (cop)->planemask = (pm); \
+ (cmd) = (IGS_DRAW_T_B | \
+ IGS_DRAW_L_R | \
+ IGS_DRAW_ALL | \
+ IGS_PIXEL_FG | \
+ IGS_HBLT_DISABLE | \
+ IGS_SRC2_NORMAL | \
+ IGS_STEP_PXBLT | \
+ IGS_FGS_FG | \
+ IGS_BGS_BG); \
+}
+
+#define _igsRect(cop,x,y,w,h,cmd) { \
+ _igsWaitFull(cop); \
+ (cop)->dst_start = (x) + (y) * (cop_stride); \
+ (cop)->dim = IGS_MAKE_DIM(w-1,h-1); \
+ (cop)->operation = (cmd); \
+}
+
+#define _igsSetBlt(cop,alu,pm,backwards,upsidedown,cmd) { \
+ _igsWaitFull(cop); \
+ (cop)->mix = IGS_MAKE_MIX(alu,GXnoop); \
+ (cop)->planemask = (pm); \
+ (cop)->src1_stride = cop_stride - 1; \
+ (cmd) = (IGS_DRAW_ALL | \
+ IGS_PIXEL_FG | \
+ IGS_HBLT_DISABLE | \
+ IGS_SRC2_NORMAL | \
+ IGS_STEP_PXBLT | \
+ IGS_FGS_SRC | \
+ IGS_BGS_BG); \
+ if (backwards) (cmd) |= IGS_DRAW_R_L; \
+ if (upsidedown) (cmd) |= IGS_DRAW_B_T; \
+}
+
+#if 0
+#define _igsPreparePlaneBlt(cop) { \
+ _igsReset(cop); \
+ (cop)->dst_stride = cop_stride - 1; \
+ (cop)->src1_stride = cop_stride - 1; \
+ (cop)->src2_stride = cop_stride - 1; \
+ (cop)->format = IGS_FORMAT_16BPP; \
+ (cop)->src1_start = 0; \
+ (cop)->src2_start = 0; \
+}
+#else
+#define _igsPreparePlaneBlt(cop)
+#endif
+
+#define _igsSetTransparentPlaneBlt(cop,alu,pm,fg_pix,cmd) { \
+ _igsWaitIdleEmpty(cop); \
+ _igsPreparePlaneBlt(cop); \
+ (cop)->mix = IGS_MAKE_MIX(igsPatRop[alu],igsPatRop[GXnoop]); \
+ (cop)->fg = (fg_pix); \
+ (cop)->planemask = (pm); \
+ (cmd) = (IGS_DRAW_T_B | \
+ IGS_DRAW_L_R | \
+ IGS_DRAW_ALL | \
+ IGS_PIXEL_FG | \
+ IGS_HBLT_WRITE_2 | \
+ IGS_SRC2_MONO_TRANS | \
+ IGS_STEP_TERNARY_PXBLT | \
+ IGS_FGS_FG | \
+ IGS_BGS_BG); \
+}
+
+#define _igsSetOpaquePlaneBlt(cop,alu,pm,fg_pix,bg_pix,cmd) { \
+ _igsWaitIdleEmpty(cop); \
+ _igsPreparePlaneBlt(cop); \
+ (cop)->mix = IGS_MAKE_MIX(igsPatRop[alu],igsPatRop[alu]); \
+ (cop)->planemask = (pm); \
+ (cop)->fg = (fg_pix); \
+ (cop)->bg = (bg_pix); \
+ (cmd) = (IGS_DRAW_T_B | \
+ IGS_DRAW_L_R | \
+ IGS_DRAW_ALL | \
+ IGS_PIXEL_FG | \
+ IGS_HBLT_WRITE_2 | \
+ IGS_SRC2_MONO_OPAQUE | \
+ IGS_STEP_TERNARY_PXBLT | \
+ IGS_FGS_FG | \
+ IGS_BGS_BG); \
+}
+
+#define _igsPlaneBlt(cop,x,y,w,h,cmd) { \
+/* _igsWaitFull(cop); */ \
+ (cop)->dst_start = (x) + (y) * (cop_stride); \
+ (cop)->dim = IGS_MAKE_DIM((w)-1,(h)-1); \
+ (cop)->operation = (cmd); \
+/* _igsWaitHostBltAck(cop); */ \
+}
+
+#define _igsBlt(cop,sx,sy,dx,dy,w,h,cmd) { \
+ _igsWaitFull(cop); \
+ (cop)->dst_start = (dx) + (dy) * cop_stride; \
+ (cop)->src1_start = (sx) + (sy) * cop_stride; \
+ (cop)->src1_stride = cop_stride - 1; \
+ (cop)->dim = IGS_MAKE_DIM(w-1,h-1); \
+ (cop)->operation = (cmd); \
+}
+
+#define sourceInvarient(alu) (((alu) & 3) == (((alu) >> 2) & 3))
+
+#endif
diff --git a/hw/kdrive/igs/igsstub.c b/hw/kdrive/igs/igsstub.c
new file mode 100644
index 000000000..9d4c3d854
--- /dev/null
+++ b/hw/kdrive/igs/igsstub.c
@@ -0,0 +1,57 @@
+/*
+ * $XFree86$
+ *
+ * Copyright © 2000 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "igs.h"
+
+void
+InitCard (char *name)
+{
+ KdCardAttr attr;
+ CARD32 count;
+
+ count = 0;
+ while (LinuxFindPci (0x10ea, 0x5000, count, &attr))
+ {
+ KdCardInfoAdd (&igsFuncs, &attr, 0);
+ count++;
+ }
+}
+
+void
+InitOutput (ScreenInfo *pScreenInfo, int argc, char **argv)
+{
+ KdInitOutput (pScreenInfo, argc, argv);
+}
+
+void
+InitInput (int argc, char **argv)
+{
+ KdInitInput (&Ps2MouseFuncs, &LinuxKeyboardFuncs);
+}
+
+int
+ddxProcessArgument (int argc, char **argv, int i)
+{
+ return KdProcessArgument (argc, argv, i);
+}
diff --git a/hw/kdrive/savage/s3.c b/hw/kdrive/savage/s3.c
index 044ce0e7e..df62a27ce 100644
--- a/hw/kdrive/savage/s3.c
+++ b/hw/kdrive/savage/s3.c
@@ -22,7 +22,7 @@
*
* Author: Keith Packard, SuSE, Inc.
*/
-/* $XFree86: xc/programs/Xserver/hw/kdrive/savage/s3.c,v 1.2 1999/12/30 03:03:10 robin Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/kdrive/savage/s3.c,v 1.3 2000/02/23 20:30:01 dawes Exp $ */
#include "s3.h"
@@ -30,6 +30,8 @@
#define PACKED_OFFSET (0x8100)
#define IOMAP_OFFSET (0x8000)
+#define S3_MIN_CLOCK 250000
+
static void
_s3SetBlank (S3Ptr s3, S3Vga *s3vga, Bool blank)
{
@@ -171,6 +173,15 @@ Bool
s3ModeSupported (KdScreenInfo *screen,
const KdMonitorTiming *t)
{
+ if (screen->fb[1].depth)
+ {
+ /*
+ * Must have at least one true color stream
+ */
+ if (screen->fb[0].depth <= 8 &&
+ screen->fb[1].depth <= 8)
+ return FALSE;
+ }
/* make sure the clock isn't too fast */
if (t->clock > S3_MAX_CLOCK * 2)
return FALSE;
@@ -188,35 +199,40 @@ s3ModeUsable (KdScreenInfo *screen)
int screen_size;
int pixel_width;
int byte_width;
+ int fb;
- if (screen->depth >= 24)
- {
- screen->depth = 24;
- screen->bitsPerPixel = 32;
- }
- else if (screen->depth >= 16)
- {
- screen->depth = 16;
- screen->bitsPerPixel = 16;
- }
- else if (screen->depth >= 15)
- {
- screen->depth = 15;
- screen->bitsPerPixel = 16;
- }
- else
+ screen_size = 0;
+ for (fb = 0; fb < KD_MAX_FB && screen->fb[fb].depth; fb++)
{
- screen->depth = 8;
- screen->bitsPerPixel = 8;
+ if (screen->fb[fb].depth >= 24)
+ {
+ screen->fb[fb].depth = 24;
+ if (screen->fb[fb].bitsPerPixel != 24)
+ screen->fb[fb].bitsPerPixel = 32;
+ }
+ else if (screen->fb[fb].depth >= 16)
+ {
+ screen->fb[fb].depth = 16;
+ screen->fb[fb].bitsPerPixel = 16;
+ }
+ else if (screen->fb[fb].depth >= 15)
+ {
+ screen->fb[fb].depth = 15;
+ screen->fb[fb].bitsPerPixel = 16;
+ }
+ else
+ {
+ screen->fb[fb].depth = 8;
+ screen->fb[fb].bitsPerPixel = 8;
+ }
+
+ byte_width = screen->width * (screen->fb[fb].bitsPerPixel >> 3);
+ pixel_width = screen->width;
+ screen->fb[fb].pixelStride = pixel_width;
+ screen->fb[fb].byteStride = byte_width;
+ screen_size += byte_width * screen->height;
}
- byte_width = screen->width * (screen->bitsPerPixel >> 3);
- pixel_width = screen->width;
- screen->pixelStride = pixel_width;
- screen->byteStride = byte_width;
-
- screen_size = byte_width * screen->height;
-
return screen_size <= s3c->memory;
}
@@ -233,6 +249,8 @@ s3ScreenInit (KdScreenInfo *screen)
int i;
const KdMonitorTiming *t;
int screen_size;
+ int fb;
+ int ma;
s3s = (S3ScreenInfo *) xalloc (sizeof (S3ScreenInfo));
if (!s3s)
@@ -252,23 +270,25 @@ s3ScreenInit (KdScreenInfo *screen)
screen->height = 600;
screen->rate = 72;
}
- if (!screen->depth)
- screen->depth = 8;
+ if (!screen->fb[0].depth)
+ screen->fb[0].depth = 8;
t = KdFindMode (screen, s3ModeSupported);
screen->rate = t->rate;
screen->width = t->horizontal;
screen->height = t->vertical;
- s3GetClock (t->clock, &m, &n, &r, 511, 127, 4);
+ s3GetClock (t->clock, &m, &n, &r, 511, 127, 4, 250000);
#ifdef DEBUG
fprintf (stderr, "computed %d,%d,%d (%d)\n",
m, n, r, S3_CLOCK(m,n,r));
#endif
+#if 0
/*
* Can only operate in pixel-doubled mode at 8 or 16 bits per pixel
*/
if (screen->depth > 16 && S3_CLOCK(m,n,r) > S3_MAX_CLOCK)
screen->depth = 16;
+#endif
if (!KdTuneMode (screen, s3ModeUsable, s3ModeSupported))
{
@@ -276,14 +296,31 @@ s3ScreenInit (KdScreenInfo *screen)
return FALSE;
}
- screen_size = screen->byteStride * screen->height;
+ s3s->fbmap[2] = -1;
+ if (screen->fb[1].depth)
+ {
+ if (screen->fb[0].bitsPerPixel >= 16)
+ {
+ s3s->fbmap[0] = 1;
+ s3s->fbmap[1] = 0;
+ }
+ else
+ {
+ s3s->fbmap[0] = 0;
+ s3s->fbmap[1] = 1;
+ }
+ }
+ else
+ {
+ s3s->fbmap[0] = 0;
+ s3s->fbmap[1] = -1;
+ }
- memory = s3c->memory - screen_size;
+ screen_size = 0;
+ for (fb = 0; fb < KD_MAX_FB && screen->fb[fb].depth; fb++)
+ screen_size += screen->fb[fb].byteStride * screen->height;
- /*
- * Stick frame buffer at start of memory
- */
- screen->frameBuffer = s3c->frameBuffer;
+ memory = s3c->memory - screen_size;
/*
* Stick cursor at end of memory
@@ -296,60 +333,61 @@ s3ScreenInit (KdScreenInfo *screen)
else
s3s->cursor_base = 0;
- /*
- * Use remaining memory for off-screen storage, but only use
- * one piece (either right or bottom).
- */
- if (memory >= screen->byteStride * S3_TILE_SIZE)
- {
- s3s->offscreen = s3c->frameBuffer + screen_size;
- s3s->offscreen_x = 0;
- s3s->offscreen_y = screen_size / screen->byteStride;
- s3s->offscreen_width = screen->pixelStride;
- s3s->offscreen_height = memory / screen->byteStride;
- memory -= s3s->offscreen_height * screen->byteStride;
- }
- else if (screen->pixelStride - screen->width >= S3_TILE_SIZE)
+ screen_size = 0;
+ for (ma = 0; s3s->fbmap[ma] >= 0; ma++)
{
- s3s->offscreen = s3c->frameBuffer + screen->width;
- s3s->offscreen_x = screen->width;
- s3s->offscreen_y = 0;
- s3s->offscreen_width = screen->pixelStride - screen->width;
- s3s->offscreen_height = screen->height;
- }
- else
- s3s->offscreen = 0;
-
- switch (screen->depth) {
- case 8:
- screen->visuals = ((1 << StaticGray) |
- (1 << GrayScale) |
- (1 << StaticColor) |
- (1 << PseudoColor) |
- (1 << TrueColor) |
- (1 << DirectColor));
- screen->blueMask = 0x00;
- screen->greenMask = 0x00;
- screen->redMask = 0x00;
- break;
- case 15:
- screen->visuals = (1 << TrueColor);
- screen->blueMask = 0x001f;
- screen->greenMask = 0x03e0;
- screen->redMask = 0x7c00;
- break;
- case 16:
- screen->visuals = (1 << TrueColor);
- screen->blueMask = 0x001f;
- screen->greenMask = 0x07e0;
- screen->redMask = 0xf800;
- break;
- case 24:
- screen->visuals = (1 << TrueColor);
- screen->blueMask = 0x0000ff;
- screen->greenMask = 0x00ff00;
- screen->redMask = 0xff0000;
- break;
+ fb = s3s->fbmap[ma];
+ screen->fb[fb].frameBuffer = s3c->frameBuffer + screen_size;
+ screen_size += screen->fb[fb].byteStride * screen->height;
+
+ /*
+ * Use remaining memory for off-screen storage, but only use
+ * one piece (either right or bottom).
+ */
+ if (memory >= screen->fb[fb].byteStride * S3_TILE_SIZE)
+ {
+ s3s->fb[ma].offscreen = screen->fb[fb].frameBuffer;
+ s3s->fb[ma].offscreen_x = 0;
+ s3s->fb[ma].offscreen_y = screen->height;
+ s3s->fb[ma].offscreen_width = screen->fb[fb].pixelStride;
+ s3s->fb[ma].offscreen_height = S3_TILE_SIZE;
+ memory -= s3s->fb[ma].offscreen_height * screen->fb[fb].byteStride;
+ screen_size += s3s->fb[ma].offscreen_height * screen->fb[fb].byteStride;
+ }
+ else
+ s3s->fb[ma].offscreen = 0;
+
+ switch (screen->fb[fb].depth) {
+ case 8:
+ screen->fb[fb].visuals = ((1 << StaticGray) |
+ (1 << GrayScale) |
+ (1 << StaticColor) |
+ (1 << PseudoColor) |
+ (1 << TrueColor) |
+ (1 << DirectColor));
+ screen->fb[fb].blueMask = 0x00;
+ screen->fb[fb].greenMask = 0x00;
+ screen->fb[fb].redMask = 0x00;
+ break;
+ case 15:
+ screen->fb[fb].visuals = (1 << TrueColor);
+ screen->fb[fb].blueMask = 0x001f;
+ screen->fb[fb].greenMask = 0x03e0;
+ screen->fb[fb].redMask = 0x7c00;
+ break;
+ case 16:
+ screen->fb[fb].visuals = (1 << TrueColor);
+ screen->fb[fb].blueMask = 0x001f;
+ screen->fb[fb].greenMask = 0x07e0;
+ screen->fb[fb].redMask = 0xf800;
+ break;
+ case 24:
+ screen->fb[fb].visuals = (1 << TrueColor);
+ screen->fb[fb].blueMask = 0x0000ff;
+ screen->fb[fb].greenMask = 0x00ff00;
+ screen->fb[fb].redMask = 0xff0000;
+ break;
+ }
}
screen->driver = s3s;
@@ -821,6 +859,7 @@ s3Preserve (KdCardInfo *card)
S3Save *save = &s3c->save;
CARD8 t1, t2;
CARD8 *cursor_base;
+ CARD8 streams_mode;
s3Save (s3vga);
if (!s3c->bios_initialized)
@@ -842,9 +881,30 @@ s3Preserve (KdCardInfo *card)
save->write_mask = s3->write_mask;
save->fg = s3->fg;
save->bg = s3->bg;
+ /*
+ * Preserve streams processor state
+ */
+ streams_mode = s3Get (s3vga, s3_streams_mode);
+ s3SetImm (s3vga, s3_streams_mode, 3);
save->global_bitmap_1 = s3->global_bitmap_1;
save->global_bitmap_2 = s3->global_bitmap_2;
+ save->adv_func_cntl = s3->adv_func_cntl;
save->primary_bitmap_1 = s3->primary_bitmap_1;
+ save->primary_bitmap_2 = s3->primary_bitmap_2;
+ save->secondary_bitmap_1 = s3->secondary_bitmap_1;
+ save->secondary_bitmap_2 = s3->secondary_bitmap_2;
+ save->primary_stream_control = s3->primary_stream_control;
+ save->blend_control = s3->blend_control;
+ save->primary_stream_addr_0 = s3->primary_stream_addr_0;
+ save->primary_stream_addr_1 = s3->primary_stream_addr_1;
+ save->primary_stream_stride = s3->primary_stream_stride;
+ save->primary_stream_xy = s3->primary_stream_xy;
+ save->primary_stream_size = s3->primary_stream_size;
+ save->primary_stream_mem = s3->primary_stream_mem;
+ save->secondary_stream_xy = s3->secondary_stream_xy;
+ save->secondary_stream_size = s3->secondary_stream_size;
+ save->streams_fifo = s3->streams_fifo;
+ s3SetImm (s3vga, s3_streams_mode, streams_mode);
_s3SetBlank (s3, s3vga, FALSE);
}
@@ -855,6 +915,49 @@ s3Preserve (KdCardInfo *card)
int s3CpuTimeout, s3AccelTimeout;
void
+s3SetGlobalBitmap (ScreenPtr pScreen, int ma)
+{
+ KdScreenPriv(pScreen);
+ s3ScreenInfo (pScreenPriv);
+
+ if (s3s->current_ma != ma)
+ {
+ s3CardInfo (pScreenPriv);
+ S3Vga *s3vga = &s3c->s3vga;
+ S3Ptr s3 = s3c->s3;
+ CARD32 gb1, gb2;
+ int depth;
+ int length;
+ KdCheckSync (pScreen);
+ switch (s3s->fb[ma].accel_bpp) {
+ case 8:
+ case 24:
+ length = 0;
+ break;
+ case 16:
+ length = 1;
+ break;
+ case 32:
+ length = 3;
+ break;
+ }
+ s3SetImm (s3vga, s3_pixel_length, length);
+ gb1 = s3s->fb[ma].bitmap_offset;
+ gb2 = ((1 << 0) |
+ (0 << 2) |
+ (1 << 3) |
+ ((s3s->fb[ma].accel_stride >> 4) << 4) |
+ (s3s->fb[ma].accel_bpp << 16) |
+ (0 << 24) |
+ (1 << 28));
+ s3->global_bitmap_1 = gb1;
+ s3->global_bitmap_2 = gb2;
+ s3->global_bitmap_2 = gb2;
+ s3s->current_ma = ma;
+ }
+}
+
+void
s3Enable (ScreenPtr pScreen)
{
KdScreenPriv(pScreen);
@@ -878,7 +981,7 @@ s3Enable (ScreenPtr pScreen)
int h_screen_off;
int h_start_fifo_fetch;
- int primary_stream_l1;
+ int primary_stream_l1[KD_MAX_FB];
int v_total;
int v_retrace_start;
@@ -886,9 +989,14 @@ s3Enable (ScreenPtr pScreen)
int v_display_end;
int v_blank_start;
int v_blank_end;
-
- int h_blank_start_adjust;
- int h_blank_end_adjust;
+ int v_blank_start_adjust = 0;
+ int v_blank_end_adjust = 0;
+
+ int h_blank_start_adjust = 0;
+ int h_blank_end_adjust = 0;
+ int h_sync_start_adjust = 0;
+ int h_sync_end_adjust = 0;
+ int h_start_fifo_fetch_adjust = 0;
int h_sync_extend;
int h_blank_extend;
int i;
@@ -899,6 +1007,13 @@ s3Enable (ScreenPtr pScreen)
int cpu_timeout;
int accel_timeout;
int bytes_per_ms;
+ CARD32 control[2];
+ int fb;
+ int ma;
+
+ s3s->primary_depth = screen->fb[s3s->fbmap[0]].depth;
+
+ s3s->use_streams = TRUE;
t = KdFindMode (screen, s3ModeSupported);
@@ -912,24 +1027,38 @@ s3Enable (ScreenPtr pScreen)
vblank = t->vblank;
vactive = t->vertical;
+
m = s3Get (s3vga, s3_dclk_m);
n = s3Get (s3vga, s3_dclk_n);
r = s3Get (s3vga, s3_dclk_r);
-#ifdef DEBUG
- fprintf (stderr, "old clock %d, %d, %d\n", m, n, r);
+#define DEBUG_CLOCK
+#ifdef DEBUG_CLOCK
+ fprintf (stderr, "old clock %d, %d, %d (%d)\n", m, n, r, S3_CLOCK(m,n,r));
#endif
clock_double = FALSE;
- s3GetClock (t->clock, &m, &n, &r, 511, 127, 4);
- if (S3_CLOCK(m,n,r) > S3_MAX_CLOCK)
+ s3GetClock (t->clock, &m, &n, &r, 511, 127, 4, 250000);
+ if (S3_CLOCK(m,n,r) > S3_MAX_CLOCK && !s3s->use_streams)
clock_double = TRUE;
s3Set (s3vga, s3_clock_select, 3);
s3Set (s3vga, s3_dclk_m, m);
s3Set (s3vga, s3_dclk_n, n);
s3Set (s3vga, s3_dclk_r, r);
-#ifdef DEBUG
+#ifdef DEBUG_CLOCK
fprintf (stderr, "new clock %d, %d, %d (%d)\n", m, n, r, S3_CLOCK(m,n,r));
#endif
+ if (s3s->use_streams)
+ {
+ s3Set (s3vga, s3_streams_mode, 3);
+ s3Set (s3vga, s3_enable_l1_parameter, 1);
+ }
+ else
+ {
+ s3Set (s3vga, s3_streams_mode, 0);
+ s3Set (s3vga, s3_enable_l1_parameter, 0);
+ }
+ s3Set (s3vga, s3_flat_panel_output_control_1, 0);
+ s3Set (s3vga, s3_flat_panel_output_control_2, 0);
s3Set (s3vga, s3_select_graphics_mode, 1);
s3Set (s3vga, s3_enable_blinking, 0);
s3Set (s3vga, s3_enable_vga_16bit, 0);
@@ -949,10 +1078,12 @@ s3Enable (ScreenPtr pScreen)
s3Set (s3vga, s3_enable_2d_3d, 1);
s3Set (s3vga, s3_refresh_control, 1);
s3Set (s3vga, s3_disable_pci_read_bursts, 0);
+ s3Set (s3vga, s3_pci_disconnect_enable, 1);
+ s3Set (s3vga, s3_primary_load_control, 0);
+ s3Set (s3vga, s3_secondary_load_control, 0);
s3Set (s3vga, s3_pci_retry_enable, 1);
s3Set (s3vga, s3_enable_256, 1);
-/* s3Set (s3vga, s3_border_select, 1); /* eliminate white border */
- s3Set (s3vga, s3_border_select, 0); /* eliminate white border */
+ s3Set (s3vga, s3_border_select, 1); /* eliminate white border */
s3SetImm (s3vga, s3_lock_palette, 0); /* unlock palette/border regs */
s3Set (s3vga, s3_disable_v_retrace_int, 1);
if (t->hpol == KdSyncPositive)
@@ -976,16 +1107,48 @@ s3Enable (ScreenPtr pScreen)
s3Set (s3vga, s3_enable_clock_double, 0);
s3Set (s3vga, s3_dclk_over_2, 0);
- s3Set (s3vga, s3_fifo_fetch_timing, 1);
- s3Set (s3vga, s3_fifo_drain_delay, 7);
-
-
s3Set (s3vga, s3_delay_h_enable, 0);
s3Set (s3vga, s3_sdclk_skew, 0);
s3Set (s3vga, s3_dac_mask, 0xff);
- s3Set (s3vga, s3_dac_power_saving_disable, 1);
+#if 0
+#ifdef DEBUG_CLOCK
+ m = s3Get (s3vga, s3_mclk_m);
+ n = s3Get (s3vga, s3_mclk_n);
+ r = s3Get (s3vga, s3_mclk_r);
+ fprintf (stderr, "old mclk %d, %d, %d (%d)\n", m, n, r, S3_CLOCK(m,n,r));
+#endif
+
+ s3GetClock (125282, &m, &n, &r, 127, 31, 3, 250000);
+
+#ifdef DEBUG_CLOCK
+ fprintf (stderr, "new mclk %d, %d, %d (%d)\n", m, n, r,S3_CLOCK(m,n,r));
+#endif
+
+ s3Set (s3vga, s3_mclk_m, m);
+ s3Set (s3vga, s3_mclk_n, n);
+ s3Set (s3vga, s3_mclk_r, r);
+
+#ifdef DEBUG_CLOCK
+ m = s3Get (s3vga, s3_eclk_m);
+ n = s3Get (s3vga, s3_eclk_n);
+ r = s3Get (s3vga, s3_eclk_r);
+ fprintf (stderr, "old eclk %d, %d, %d (%d)\n", m, n, r, S3_CLOCK(m,n,r));
+#endif
+
+#define S3_ECLK 125282
+
+ s3GetClock (S3_ECLK, &m, &n, &r, 127, 31, 3, 250000);
+
+#ifdef DEBUG_CLOCK
+ fprintf (stderr, "new eclk %d, %d, %d (%d)\n", m, n, r,S3_CLOCK(m,n,r));
+#endif
+
+ s3Set (s3vga, s3_eclk_m, m);
+ s3Set (s3vga, s3_eclk_n, n);
+ s3Set (s3vga, s3_eclk_r, r);
+#endif
s3s->manage_border = FALSE;
/*
@@ -998,61 +1161,85 @@ s3Enable (ScreenPtr pScreen)
/*
* Set pixel size, choose clock doubling mode
*/
- h_blank_start_adjust = 0;
- h_blank_end_adjust = 0;
-
- switch (screen->bitsPerPixel) {
- case 8:
- h_screen_off = hactive;
- s3Set (s3vga, s3_pixel_length, 0);
- s3Set (s3vga, s3_color_mode, 0);
- /*
- * Set up for double-pixel mode, switch color modes,
- * divide the dclk and delay h blank by 2 dclks
- */
- if (clock_double)
- {
- s3Set (s3vga, s3_color_mode, 1);
- s3Set (s3vga, s3_dclk_over_2, 1);
- s3Set (s3vga, s3_enable_clock_double, 1);
- s3Set (s3vga, s3_border_select, 0);
-/* s3Set (s3vga, s3_border_color, pScreen->blackPixel); */
- h_blank_start_adjust = 4;
- h_blank_end_adjust = -4;
- s3s->manage_border = TRUE;
- }
- break;
- case 16:
- h_screen_off = hactive * 2;
- s3Set (s3vga, s3_pixel_length, 1);
- if (clock_double)
- {
- if (screen->depth == 15)
- s3Set (s3vga, s3_color_mode, 3);
+
+ bytes_per_ms = 0;
+
+ for (ma = 0; s3s->fbmap[ma] >= 0; ma++)
+ {
+ fb = s3s->fbmap[ma];
+ s3s->fb[ma].accel_bpp = screen->fb[fb].bitsPerPixel;
+ s3s->fb[ma].accel_stride = screen->fb[fb].pixelStride;
+ s3s->fb[ma].bitmap_offset = screen->fb[fb].frameBuffer - s3c->frameBuffer;
+ switch (s3s->fb[ma].accel_bpp) {
+ case 8:
+ h_screen_off = hactive;
+ s3Set (s3vga, s3_pixel_length, 0);
+ s3Set (s3vga, s3_color_mode, 0);
+ control[ma] = 0;
+ /*
+ * Set up for double-pixel mode, switch color modes,
+ * divide the dclk and delay h blank by 2 dclks
+ */
+ if (clock_double)
+ {
+ s3Set (s3vga, s3_color_mode, 1);
+ s3Set (s3vga, s3_dclk_over_2, 1);
+ s3Set (s3vga, s3_enable_clock_double, 1);
+ s3Set (s3vga, s3_h_skew, 1);
+ h_blank_start_adjust = -3;
+ h_blank_end_adjust = -4;
+ s3Set (s3vga, s3_border_select, 0);
+#if 0
+ s3s->manage_border = TRUE;
+ /* s3Set (s3vga, s3_border_color, pScreen->blackPixel); */
+#endif
+ }
+ break;
+ case 16:
+ h_screen_off = hactive * 2;
+ s3Set (s3vga, s3_pixel_length, 1);
+ if (screen->fb[fb].depth == 15)
+ control[ma] = 3 << 24;
else
- s3Set (s3vga, s3_color_mode, 5);
- s3Set (s3vga, s3_dclk_over_2, 1);
- s3Set (s3vga, s3_enable_clock_double, 1);
- s3Set (s3vga, s3_border_select, 0);
- h_blank_start_adjust = 4;
- h_blank_end_adjust = -4;
- }
- else
- {
- if (screen->depth == 15)
- s3Set (s3vga, s3_color_mode, 2);
+ control[ma] = 5 << 24;
+ if (clock_double)
+ {
+ if (screen->fb[fb].depth == 15)
+ s3Set (s3vga, s3_color_mode, 3);
+ else
+ s3Set (s3vga, s3_color_mode, 5);
+ s3Set (s3vga, s3_dclk_over_2, 1);
+ s3Set (s3vga, s3_enable_clock_double, 1);
+ s3Set (s3vga, s3_border_select, 0);
+ h_blank_start_adjust = 4;
+ h_blank_end_adjust = -4;
+ }
else
- s3Set (s3vga, s3_color_mode, 4);
- s3Set (s3vga, s3_dclk_over_2, 0);
- s3Set (s3vga, s3_enable_clock_double, 0);
- s3Set (s3vga, s3_delay_blank, 0);
+ {
+ if (screen->fb[fb].depth == 15)
+ s3Set (s3vga, s3_color_mode, 2);
+ else
+ s3Set (s3vga, s3_color_mode, 4);
+ s3Set (s3vga, s3_dclk_over_2, 0);
+ s3Set (s3vga, s3_enable_clock_double, 0);
+ s3Set (s3vga, s3_delay_blank, 0);
+ }
+ break;
+ case 24:
+ control[ma] = 6 << 24;
+ h_screen_off = hactive * 3;
+ s3s->fb[ma].accel_bpp = 8;
+ s3s->fb[ma].accel_stride = screen->fb[fb].pixelStride * 3;
+ break;
+ case 32:
+ control[ma] = 7 << 24;
+ h_screen_off = hactive * 4;
+ s3Set (s3vga, s3_pixel_length, 3);
+ s3Set (s3vga, s3_color_mode, 0xd);
+ break;
}
- break;
- case 32:
- h_screen_off = hactive * 4;
- s3Set (s3vga, s3_pixel_length, 3);
- s3Set (s3vga, s3_color_mode, 0xd);
- break;
+ bytes_per_ms += t->clock * (screen->fb[fb].bitsPerPixel / 8);
+ primary_stream_l1[ma] = (screen->width * screen->fb[fb].bitsPerPixel / (8 * 8)) - 1;
}
/*
@@ -1060,11 +1247,9 @@ s3Enable (ScreenPtr pScreen)
*/
s3Set (s3vga, s3_start_address, 0);
-
/*
* Set various registers to avoid snow on the screen
*/
- bytes_per_ms = t->clock * (screen->bitsPerPixel / 8);
fprintf (stderr, "bytes_per_ms %d\n", bytes_per_ms);
fprintf (stderr, "primary 0x%x master 0x%x command 0x%x lpb 0x%x cpu 0x%x 2d 0x%x\n",
@@ -1075,28 +1260,105 @@ s3Enable (ScreenPtr pScreen)
s3Get (s3vga, s3_cpu_timeout),
s3Get (s3vga, s3_2d_graphics_engine_timeout));
- /* cpu 2d
- * 576000
- * 288000 0x1f 0x19
-
+ /*
+ * Test:
+ * accel x11perf -line500
+ * cpu x11perf -circle500
+ *
+ * cpu accel
+ * 1600x1200x32x85 (918000) 1 1 not enough
+ * 1600x1200x32x75 (810000) 3 2
+ * 1600x1200x32x70 (756000) 4 3
+ * 1600x1200x32x60 (648000) 6 5
+ *
+ * 1280x1024x32x85 (630000) 6 4
+ * 1280x1024x32x75 (540000) a 6
+ * 1280x1024x32x60 (432000) 1f a
+ *
+ * 1152x900x32x85 (490000) a 6
+ * 1152x900x32x75 (433000) 1f 8
+ * 1152x900x32x70 (401000) 1f a
+ * 1152x900x32x66 (380000) 1f a
+ *
+ * 1024x768x32x85 (378000) 1f a
+ * 1024x768x32x75 (315000) 1f b
+ * 1024x768x32x70 (300000) 1f b
+ * 1024x768x32x60 (260000) 1f 12
+ *
+ * 800x600x32x85 (225000) 1f 1a
+ * 800x600x32x72 (200000) 1f 1d
+ * 800x600x32x75 (198000) 1f 1d
+ *
+ * 1600x1200x16x85 (459000) 1f 8
+ * 1600x1200x16x75 (405000) 1f a
+ * 1600x1200x16x70 (378000) 1f b
+ * 1600x1200x16x60 (324000) 1f f
+ *
+ * 1280x1024x16x85 (315000) 1f 12
+ * 1280x1024x16x75 (270000) 1f 16
+ * 1280x1024x16x60 (216000) 1f 1d
+ *
+ * 1600x1200x8x85 (229000) 1f 1f
+ *
*/
+
if (s3CpuTimeout)
{
- cpu_timeout = s3CpuTimeout;
- if (s3AccelTimeout)
+ if (s3CpuTimeout < 0)
+ cpu_timeout = 0;
+ else
+ cpu_timeout = s3CpuTimeout;
+ if (s3AccelTimeout < 0)
+ accel_timeout = 0;
+ else if (s3AccelTimeout)
accel_timeout = s3AccelTimeout;
else
accel_timeout = s3CpuTimeout;
}
- else if (bytes_per_ms > 400000)
+ else if (bytes_per_ms >= 900000)
{
- cpu_timeout = 0x10;
- accel_timeout = 0x7;
+ cpu_timeout = 0x01;
+ accel_timeout = 0x01;
}
- else if (bytes_per_ms > 250000)
+ else if (bytes_per_ms >= 800000)
{
- cpu_timeout = 0x10;
- accel_timeout = 0x18;
+ cpu_timeout = 0x03;
+ accel_timeout = 0x02;
+ }
+ else if (bytes_per_ms >= 700000)
+ {
+ cpu_timeout = 0x04;
+ accel_timeout = 0x03;
+ }
+ else if (bytes_per_ms >= 600000)
+ {
+ cpu_timeout = 0x06;
+ accel_timeout = 0x04;
+ }
+ else if (bytes_per_ms >= 475000)
+ {
+ cpu_timeout = 0x0a;
+ accel_timeout = 0x06;
+ }
+ else if (bytes_per_ms >= 425000)
+ {
+ cpu_timeout = 0x1f;
+ accel_timeout = 0x8;
+ }
+ else if (bytes_per_ms >= 300000)
+ {
+ cpu_timeout = 0x1f;
+ accel_timeout = 0x0a;
+ }
+ else if (bytes_per_ms >= 250000)
+ {
+ cpu_timeout = 0x1f;
+ accel_timeout = 0x12;
+ }
+ else if (bytes_per_ms >= 200000)
+ {
+ cpu_timeout = 0x1f;
+ accel_timeout = 0x1a;
}
else
{
@@ -1104,6 +1366,8 @@ s3Enable (ScreenPtr pScreen)
accel_timeout = 0x1f;
}
+ fprintf (stderr, "cpu 0x%x accel 0x%x\n", cpu_timeout, accel_timeout);
+
s3Set (s3vga, s3_primary_stream_timeout, 0xc0);
s3Set (s3vga, s3_master_control_unit_timeout, 0xf);
s3Set (s3vga, s3_command_buffer_timeout, 0x1f);
@@ -1111,14 +1375,17 @@ s3Enable (ScreenPtr pScreen)
s3Set (s3vga, s3_2d_graphics_engine_timeout, accel_timeout);
s3Set (s3vga, s3_cpu_timeout, cpu_timeout);
+ s3Set (s3vga, s3_fifo_fetch_timing, 1);
+ s3Set (s3vga, s3_fifo_drain_delay, 2);
+
/*
* Compute horizontal register values from timings
*/
h_total = hactive + hblank - 5;
h_display_end = hactive - 1;
- h_sync_start = hactive + hfp;
- h_sync_end = hactive + hblank - hbp;
+ h_sync_start = hactive + hfp + h_sync_start_adjust;
+ h_sync_end = hactive + hblank - hbp + h_sync_end_adjust;
/*
* pad the blank values narrow a bit and use the border_select to
* eliminate the remaining border; don't know why, but it doesn't
@@ -1141,6 +1408,7 @@ s3Enable (ScreenPtr pScreen)
else
h_start_fifo_fetch = h_total - 5;
+ h_start_fifo_fetch += h_start_fifo_fetch_adjust;
if (h_blank_end - h_blank_start >= 0x40)
h_blank_extend = 1;
else
@@ -1151,8 +1419,6 @@ s3Enable (ScreenPtr pScreen)
else
h_sync_extend = 0;
- primary_stream_l1 = (screen->width * screen->bitsPerPixel / (8 * 8)) - 1;
-
#ifdef DEBUG
fprintf (stderr, "h_total %d h_display_end %d\n",
h_total, h_display_end);
@@ -1173,18 +1439,18 @@ s3Enable (ScreenPtr pScreen)
s3Set (s3vga, s3_h_sync_extend, h_sync_extend);
s3Set (s3vga, s3_h_blank_extend, h_blank_extend);
- s3Set (s3vga, s3_primary_stream_l1, primary_stream_l1);
+ s3Set (s3vga, s3_dac_power_saving_disable, 0);
+ s3Set (s3vga, s3_dac_power_up_time, hactive + hblank);
+
+ s3Set (s3vga, s3_primary_stream_l1, primary_stream_l1[0]);
+ s3Set (s3vga, s3_streams_fifo_delay, 0);
+
v_total = vactive + vblank - 2;
v_display_end = vactive - 1;
-#if 0
- v_blank_start = vactive - 1;
- v_blank_end = v_blank_start + vblank - 1;
-#else
- v_blank_start = vactive - 1;
- v_blank_end = v_blank_start + vblank - 1;
-#endif
+ v_blank_start = vactive - 1 + v_blank_start_adjust;
+ v_blank_end = v_blank_start + vblank - 1 + v_blank_end_adjust;
v_retrace_start = vactive + vfp;
v_retrace_end = vactive + vblank - vbp;
@@ -1206,7 +1472,7 @@ s3Enable (ScreenPtr pScreen)
*/
if (!screen->softCursor)
{
- cursor_address = (s3s->cursor_base - screen->frameBuffer) / 1024;
+ cursor_address = (s3s->cursor_base - s3c->frameBuffer) / 1024;
s3Set (s3vga, s3_cursor_address, cursor_address);
s3Set (s3vga, s3_cursor_ms_x11, 0);
@@ -1225,12 +1491,14 @@ s3Enable (ScreenPtr pScreen)
* Set accelerator
*/
switch (screen->width) {
- case 640: s3Set (s3vga, s3_ge_screen_width, 1); break;
- case 800: s3Set (s3vga, s3_ge_screen_width, 2); break;
- case 1024: s3Set (s3vga, s3_ge_screen_width, 0); break;
- case 1152: s3Set (s3vga, s3_ge_screen_width, 4); break;
- case 1280: s3Set (s3vga, s3_ge_screen_width, 3); break;
- case 1600: s3Set (s3vga, s3_ge_screen_width, 6); break;
+#if 0
+ case 640: s3Set (s3vga, s3_ge_screen_width, 1); break;
+ case 800: s3Set (s3vga, s3_ge_screen_width, 2); break;
+ case 1024: s3Set (s3vga, s3_ge_screen_width, 0); break;
+ case 1152: s3Set (s3vga, s3_ge_screen_width, 4); break;
+ case 1280: s3Set (s3vga, s3_ge_screen_width, 3); break;
+ case 1600: s3Set (s3vga, s3_ge_screen_width, 6); break;
+#endif
default:
s3Set (s3vga, s3_ge_screen_width, 7); /* use global bitmap descriptor */
}
@@ -1246,17 +1514,70 @@ s3Enable (ScreenPtr pScreen)
s3Set (s3vga, s3_vsync_control, 0);
_s3SetBlank (s3, s3vga, TRUE);
+ if (s3s->use_streams)
+ s3Set (s3vga, s3_primary_stream_definition, 1);
+ else
+ s3Set (s3vga, s3_primary_stream_definition, 0);
+
VgaFlush(&s3vga->card);
VgaSetImm (&s3vga->card, s3_clock_load_imm, 1);
VgaSetImm(&s3vga->card, s3_clock_load_imm, 0);
- s3->global_bitmap_1 = 0;
- s3->global_bitmap_2 = MAKE_GBF (1, /* 64 bit bitmap descriptor size */
- 0, /* disable BCI */
- pScreenPriv->screen->pixelStride >> 4,
- pScreenPriv->screen->bitsPerPixel,
- 0); /* tile format */
+ if (s3s->use_streams)
+ {
+ fb = s3s->fbmap[0];
+ s3->primary_stream_control = control[0];
+ s3->primary_stream_addr_0 =
+ s3->primary_stream_addr_1 = s3s->fb[0].bitmap_offset;
+ s3->primary_stream_stride = screen->fb[fb].byteStride;
+ s3->primary_stream_xy = (1 << 16) | 1;
+ s3->primary_stream_size = ((screen->fb[fb].pixelStride - 1) << 16) | screen->height;
+ s3->primary_stream_mem = (screen->fb[fb].byteStride * screen->height) / 8 - 1;
+ if (s3s->fbmap[1] >= 0)
+ {
+ fb = s3s->fbmap[1];
+ s3->blend_control = 5 << 24;
+ if (s3s->fb[0].accel_bpp == 8)
+ s3->chroma_key_control = 0x330000ff;
+ else
+ s3->chroma_key_control = 0x13010101;
+ s3->secondary_stream_control = control[1] | screen->width;
+ s3->secondary_stream_h_scale = (1 << 15);
+ s3->color_adjustment = 0;
+ s3->secondary_stream_vscale = (1 << 15);
+ s3->secondary_stream_vinit = 0;
+ s3->secondary_stream_mbuf = 0;
+ s3->secondary_stream_addr_0 =
+ s3->secondary_stream_addr_1 = s3s->fb[1].bitmap_offset;
+ s3->secondary_stream_stride = screen->fb[fb].byteStride;
+ s3->secondary_stream_scount = screen->height;
+ s3->secondary_stream_xy = (1 << 16) | 1;
+ s3->secondary_stream_size = ((screen->fb[fb].pixelStride - 1) << 16) | screen->height;
+ s3->secondary_stream_mem = (1 << 22) | ((screen->fb[fb].byteStride * screen->height) / 8 - 1);
+ }
+ else
+ {
+ s3->blend_control = 1 << 24;
+ s3->secondary_stream_xy = 0x07ff07ff;
+ s3->secondary_stream_size = 0x00010001;
+ }
+ s3->streams_fifo = (0x20 << 11) | (0x20 << 5) | 0x2;
+ }
+ s3->mult_misc_read_sel = (((1 << 9) |
+ (1 << 11) |
+ (0xe << 12)) |
+ (((0xe << 0) |
+ (0xf << 12)) << 16));
+
+ s3->cmd_overflow_buf_ptr = (1 << 3);
+ s3->bci_power_management = (1 << 9);
+ s3->adv_func_cntl = (3 << 8) | (1 << 4) | (1 << 2) | 1;
+ s3->primary_bitmap_1 = 0;
+ s3->primary_bitmap_2 = 0;
+ s3->secondary_bitmap_1 = 0;
+ s3->secondary_bitmap_2 = 0;
+ s3s->current_ma = -1;
_s3SetBlank (s3, s3vga, FALSE);
-#if 1
+#if 0
{
VGA16 r;
static CARD32 streams[][2] = {
@@ -1354,10 +1675,32 @@ s3Restore (KdCardInfo *card)
S3Vga *s3vga = &s3c->s3vga;
S3Save *save = &s3c->save;
CARD8 *cursor_base;
+ CARD8 streams_mode;
- /* graphics engine state */
+ _s3SetBlank (s3, s3vga, TRUE);
+ /* streams processor state */
+ streams_mode = s3Get (s3vga, s3_streams_mode);
+ s3SetImm (s3vga, s3_streams_mode, 3);
s3->global_bitmap_1 = save->global_bitmap_1;
s3->global_bitmap_2 = save->global_bitmap_2;
+ s3->adv_func_cntl = save->adv_func_cntl;
+ s3->primary_bitmap_1 = save->primary_bitmap_1;
+ s3->primary_bitmap_2 = save->primary_bitmap_2;
+ s3->secondary_bitmap_1 = save->secondary_bitmap_1;
+ s3->secondary_bitmap_2 = save->secondary_bitmap_2;
+ s3->primary_stream_control = save->primary_stream_control;
+ s3->blend_control = save->blend_control;
+ s3->primary_stream_addr_0 = save->primary_stream_addr_0;
+ s3->primary_stream_addr_0 = save->primary_stream_addr_0;
+ s3->primary_stream_stride = save->primary_stream_stride;
+ s3->primary_stream_xy = save->primary_stream_xy;
+ s3->primary_stream_size = save->primary_stream_size;
+ s3->primary_stream_mem = save->primary_stream_mem;
+ s3->secondary_stream_xy = save->secondary_stream_xy;
+ s3->secondary_stream_size = save->secondary_stream_size;
+ s3->streams_fifo = save->streams_fifo;
+ s3SetImm (s3vga, s3_streams_mode, streams_mode);
+ /* graphics engine state */
s3->alt_mix = save->alt_mix;
s3->write_mask = save->write_mask;
s3->fg = save->fg;
@@ -1366,7 +1709,6 @@ s3Restore (KdCardInfo *card)
s3->scissors_tl = 0x00000000;
s3->scissors_br = 0x0fff0fff;
- _s3SetBlank (s3, s3vga, TRUE);
VgaRestore (&s3vga->card);
s3Set (s3vga, s3_linear_window_size, 3);
s3Set (s3vga, s3_enable_linear, 1);
@@ -1417,6 +1759,100 @@ s3DPMS (ScreenPtr pScreen, int mode)
}
void
+s3DumbPaintChromaKey (WindowPtr pWin, RegionPtr pRegion)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ KdScreenPriv(pScreen);
+ KdCardInfo *card = pScreenPriv->card;
+ KdScreenInfo *screen = pScreenPriv->screen;
+ s3CardInfo (pScreenPriv);
+ s3ScreenInfo (pScreenPriv);
+
+ if (pWin->drawable.depth != s3s->primary_depth)
+ {
+ int nBox = REGION_NUM_RECTS(pRegion);
+ BoxPtr pBox = REGION_RECTS(pRegion);
+ PixmapPtr pPixmap;
+ FbOverlayScrPrivPtr pScrPriv = fbOverlayGetScrPriv(pScreen);
+ FbBits *dst;
+ FbStride dstStride;
+ int dstBpp;
+
+ if (pScrPriv->pLayer[0]->drawable.depth == pWin->drawable.depth)
+ pPixmap = pScrPriv->pLayer[1];
+ else
+ pPixmap = pScrPriv->pLayer[0];
+ fbGetDrawable (&pPixmap->drawable, dst, dstStride, dstBpp);
+ while (nBox--)
+ {
+ fbSolid (dst + pBox->y1 * dstStride,
+ dstStride,
+ pBox->x1 * dstBpp,
+ dstBpp,
+ (pBox->x2 - pBox->x1) * dstBpp,
+ (pBox->y2 - pBox->y1),
+ 0x0, FB_ALLONES);
+ pBox++;
+ }
+ }
+}
+
+void
+s3DumbPaintWindow (WindowPtr pWin, RegionPtr pRegion, int what)
+{
+ s3DumbPaintChromaKey (pWin, pRegion);
+ fbPaintWindow (pWin, pRegion, what);
+}
+
+void
+s3DumbCopyWindow (WindowPtr pWin,
+ DDXPointRec ptOldOrg,
+ RegionPtr prgnSrc)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ RegionRec rgnDst;
+ int dx, dy;
+ PixmapPtr pPixmap;
+ FbOverlayScrPrivPtr pScrPriv = fbOverlayGetScrPriv(pScreen);
+ int fb;
+
+ KdCheckSync (pScreen);
+ dx = ptOldOrg.x - pWin->drawable.x;
+ dy = ptOldOrg.y - pWin->drawable.y;
+ REGION_TRANSLATE(pWin->drawable.pScreen, prgnSrc, -dx, -dy);
+
+ REGION_INIT (pWin->drawable.pScreen, &rgnDst, NullBox, 0);
+
+ REGION_INTERSECT(pWin->drawable.pScreen, &rgnDst, &pWin->borderClip, prgnSrc);
+
+ for (fb = 0; fb < pScrPriv->nlayers; fb++)
+ {
+ pPixmap = pScrPriv->pLayer[fb];
+ fbCopyRegion (&pPixmap->drawable, &pPixmap->drawable,
+ 0,
+ &rgnDst, dx, dy, fbCopyWindowProc, 0, 0);
+ }
+
+ REGION_UNINIT(pWin->drawable.pScreen, &rgnDst);
+ fbValidateDrawable (&pWin->drawable);
+}
+
+Bool
+s3InitScreen(ScreenPtr pScreen)
+{
+ KdScreenPriv(pScreen);
+ KdCardInfo *card = pScreenPriv->card;
+ KdScreenInfo *screen = pScreenPriv->screen;
+ s3CardInfo (pScreenPriv);
+ s3ScreenInfo (pScreenPriv);
+
+ pScreen->PaintWindowBackground = s3DumbPaintWindow;
+ pScreen->PaintWindowBorder = s3DumbPaintWindow;
+ pScreen->CopyWindow = s3DumbCopyWindow;
+ return TRUE;
+}
+
+void
s3ScreenFini (KdScreenInfo *screen)
{
S3ScreenInfo *s3s = (S3ScreenInfo *) screen->driver;
@@ -1439,7 +1875,7 @@ s3CardFini (KdCardInfo *card)
KdCardFuncs s3Funcs = {
s3CardInit,
s3ScreenInit,
- 0,
+ s3InitScreen,
s3Preserve,
s3Enable,
s3DPMS,
diff --git a/hw/kdrive/savage/s3.h b/hw/kdrive/savage/s3.h
index 86cd1b0e9..a19b9c3d3 100644
--- a/hw/kdrive/savage/s3.h
+++ b/hw/kdrive/savage/s3.h
@@ -22,7 +22,7 @@
*
* Author: Keith Packard, SuSE, Inc.
*/
-/* $XFree86: xc/programs/Xserver/hw/kdrive/savage/s3.h,v 1.2 1999/12/30 03:03:10 robin Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/kdrive/savage/s3.h,v 1.3 2000/02/23 20:30:02 dawes Exp $ */
#ifndef _S3_H_
#define _S3_H_
@@ -98,110 +98,37 @@ typedef volatile struct _s3 {
VOL32 blend_control; /* 81a0 */
VOL8 _pad3c[0x1c]; /* 81a4 */
VOL32 primary_stream_addr_0; /* 81c0 */
- VOL8 _pad3d[0x124]; /* 81c4 */
-#if 0
- VOL16 cur_y; /* 82e8 */
- VOL8 _pad4[0xc6]; /* 82ea */
-#else
+ VOL32 primary_stream_addr_1; /* 81c4 */
+ VOL32 primary_stream_stride; /* 81c8 */
+ VOL32 secondary_stream_mbuf; /* 81cc */
+ VOL32 secondary_stream_addr_0;/* 81d0 */
+ VOL32 secondary_stream_addr_1;/* 81d4 */
+ VOL32 secondary_stream_stride;/* 81d8 */
+ VOL8 _pad81dc[4]; /* 81dc */
+ VOL32 secondary_stream_vscale;/* 81e0 */
+ VOL32 secondary_stream_vinit; /* 81e4 */
+ VOL32 secondary_stream_scount;/* 81e8 */
+ VOL32 streams_fifo; /* 81ec */
+ VOL32 primary_stream_xy; /* 81f0 */
+ VOL32 primary_stream_size; /* 81f4 */
+ VOL32 secondary_stream_xy; /* 81f8 */
+ VOL32 secondary_stream_size; /* 81fc */
+ VOL8 _pad8200[0xe8]; /* 8200 */
VOL32 cur_y; /* 82e8 */
- VOL8 _pad4[0xc4]; /* 82ec */
-#endif
-
-#if 0
- VOL8 crt_vga_3b0; /* 83b0 */
- VOL8 crt_vga_3b1; /* 83b1 */
- VOL8 crt_vga_3b2; /* 83b2 */
- VOL8 crt_vga_3b3; /* 83b3 */
- VOL8 crt_vga_3b4; /* 83b4 */
- VOL8 crt_vga_3b5; /* 83b5 */
- VOL8 crt_vga_3b6; /* 83b6 */
- VOL8 crt_vga_3b7; /* 83b7 */
- VOL8 crt_vga_3b8; /* 83b8 */
- VOL8 crt_vga_3b9; /* 83b9 */
- VOL8 crt_vga_3ba; /* 83ba */
- VOL8 crt_vga_3bb; /* 83bb */
- VOL8 crt_vga_3bc; /* 83bc */
- VOL8 crt_vga_3bd; /* 83bd */
- VOL8 crt_vga_3be; /* 83be */
- VOL8 crt_vga_3bf; /* 83bf */
-
- VOL8 crt_vga_3c0; /* 83c0 */
- VOL8 crt_vga_3c1; /* 83c1 */
- VOL8 crt_vga_3c2; /* 83c2 */
- VOL8 crt_vga_3c3; /* 83c3 */
- VOL8 crt_vga_3c4; /* 83c4 */
- VOL8 crt_vga_3c5; /* 83c5 */
- VOL8 crt_vga_dac_ad_mk; /* 83c6 */
- VOL8 crt_vga_dac_rd_ad; /* 83c7 */
- VOL8 crt_vga_dac_wt_ad; /* 83c8 */
- VOL8 crt_vga_dac_data; /* 83c9 */
- VOL8 crt_vga_3ca; /* 83ca */
- VOL8 crt_vga_3cb; /* 83cb */
- VOL8 crt_vga_3cc; /* 83cc */
- VOL8 crt_vga_3cd; /* 83cd */
- VOL8 crt_vga_3ce; /* 83ce */
- VOL8 crt_vga_3cf; /* 83cf */
-
- VOL8 crt_vga_3d0; /* 83d0 */
- VOL8 crt_vga_3d1; /* 83d1 */
- VOL8 crt_vga_3d2; /* 83d2 */
- VOL8 crt_vga_3d3; /* 83d3 */
- VOL8 crt_vga_3d4; /* 83d4 */
- VOL8 crt_vga_3d5; /* 83d5 */
- VOL8 crt_vga_3d6; /* 83d6 */
- VOL8 crt_vga_3d7; /* 83d7 */
- VOL8 crt_vga_3d8; /* 83d8 */
- VOL8 crt_vga_3d9; /* 83d9 */
- VOL8 crt_vga_status_1; /* 83da */
- VOL8 crt_vga_3db; /* 83db */
- VOL8 crt_vga_3dc; /* 83dc */
- VOL8 crt_vga_3dd; /* 83dd */
- VOL8 crt_vga_3de; /* 83de */
- VOL8 crt_vga_3df; /* 83df */
-
- VOL8 _pad5[0x124]; /* 83e0 */
- VOL16 subsys_status; /* 8504 */
- VOL8 _pad6[0x6]; /* 8506 */
- VOL32 subsys_status; /* 8504 */
- VOL8 _pad6[0x4]; /* 8508 */
- VOL16 adv_control; /* 850c */
- VOL8 _pad7[0x1da]; /* 850e */
- VOL16 cur_x; /* 86e8 */
- VOL8 _pad8[0x3fe]; /* 86ea */
- VOL16 desty_axstp; /* 8ae8 */
- VOL8 _pad9[0x3fe]; /* 8aea */
- VOL16 destx_diastp; /* 8ee8 */
- VOL8 _pad10[0x3fe]; /* 8eea */
- VOL16 enh_err_term; /* 92e8 */
- VOL8 _pad11[0x3fe]; /* 92ea */
- VOL16 maj_axis_pcnt; /* 96e8 */
- VOL8 _pad12[0x3fe]; /* 96ea */
- VOL16 enh_cmd_gp_stat; /* 9ae8 */
- VOL8 _pad13[0x3fe]; /* 9aea */
- VOL16 enh_short_stroke; /* 9ee8 */
- VOL8 _pad14[0x3fe]; /* 9eea */
- VOL16 enh_bg; /* a2e8 */
- VOL8 _pad15[0x3fe]; /* a2ea */
- VOL16 enh_fg; /* a6e8 */
- VOL8 _pad16[0x3fe]; /* a6ea */
- VOL16 enh_wrt_mask; /* aae8 */
- VOL8 _pad17[0x3fe]; /* aaea */
- VOL16 enh_rd_mask; /* aee8 */
- VOL8 _pad18[0x3fe]; /* aeea */
- VOL16 enh_color_cmp; /* b2e8 */
- VOL8 _pad19[0x3fe]; /* b2ea */
- VOL16 enh_bg_mix; /* b6e8 */
- VOL8 _pad20[0x3fe]; /* b6ea */
- VOL16 enh_fg_mix; /* bae8 */
- VOL8 _pad21[0x3fe]; /* baea */
- VOL16 enh_rd_reg_dt; /* bee8 */
- VOL8 _pad22[0x23fe]; /* beea */
-#else
- VOL8 _pad_reg[0x5f38]; /* 83b0 */
-#endif
+ VOL8 _pad4[0x14]; /* 82ec */
+ VOL32 primary_stream_mem; /* 8300 */
+ VOL32 secondary_stream_mem; /* 8304 */
+ VOL8 _pad8308[0xD2]; /* 8308 */
+ VOL8 input_status_1; /* 83da */
+ VOL8 _pad83db[0x131]; /* 83db */
+ VOL32 adv_func_cntl; /* 850c */
+ VOL8 _pad8510[0x5dd8]; /* 8510 */
VOL32 pix_trans; /* e2e8 */
-
- VOL8 _pad23[0x3a974]; /* e2ec */
+ VOL8 _pade2ec[0x3a92c]; /* e2ec */
+ VOL32 cmd_overflow_buf_ptr; /* 48c18 */
+ VOL8 _pad48c1c[0x8]; /* 48c1c */
+ VOL32 bci_power_management; /* 48c24 */
+ VOL8 _pad48c28[0x38]; /* 48c28 */
VOL32 alt_status_0; /* 48c60 */
VOL32 alt_status_1; /* 48c64 */
} S3, *S3Ptr;
@@ -368,6 +295,22 @@ typedef volatile struct _s3 {
#define COLCMPOP_GT 0x0038
#define PLANEMODE 0x0004
+/* Multifunction Control Misc 8144 */
+#define MISC_DST_BA_0 (0x0 << 0)
+#define MISC_DST_BA_1 (0x1 << 0)
+#define MISC_DST_BA_2 (0x2 << 0)
+#define MISC_DST_BA_3 (0x3 << 0)
+#define MISC_SRC_BA_0 (0x0 << 2)
+#define MISC_SRC_BA_1 (0x1 << 2)
+#define MISC_SRC_BA_2 (0x2 << 2)
+#define MISC_SRC_BA_3 (0x3 << 2)
+#define MISC_RSF (1 << 4)
+#define MISC_EXT_CLIP (1 << 5)
+#define MISC_SRC_NE (1 << 7)
+#define MISC_ENB_CMP (1 << 8)
+#define MISC_32B (1 << 9)
+#define MISC_DC (1 << 11)
+#define MISC_INDEX_E (0xe << 12)
#define S3_SAVAGE4_SLOTS 0x0001ffff
#define S3_SAVAGE4_2DI 0x00800000
@@ -393,8 +336,7 @@ typedef volatile struct _s3 {
}
#define _s3WaitEmpty(s3) _s3WaitLoop(s3,S3_SAVAGE4_SLOTS, 0)
-#define _s3WaitIdleEmpty(s3) _s3WaitLoop(s3,S3_SAVAGE4_SLOTS|S3_SAVAGE4_2DI, \
- S3_SAVAGE4_2DI)
+#define _s3WaitIdleEmpty(s3) _s3WaitLoop(s3,S3_SAVAGE4_SLOTS|S3_SAVAGE4_2DI, S3_SAVAGE4_2DI)
#define _s3WaitIdle(s3) _s3WaitLoop(s3,S3_SAVAGE4_2DI, S3_SAVAGE4_2DI)
typedef struct _s3Cursor {
@@ -457,8 +399,22 @@ typedef struct _s3Save {
CARD32 bg;
CARD32 global_bitmap_1;
CARD32 global_bitmap_2;
+ CARD32 adv_func_cntl;
CARD32 primary_bitmap_1;
CARD32 primary_bitmap_2;
+ CARD32 secondary_bitmap_1;
+ CARD32 secondary_bitmap_2;
+ CARD32 primary_stream_control;
+ CARD32 blend_control;
+ CARD32 primary_stream_addr_0;
+ CARD32 primary_stream_addr_1;
+ CARD32 primary_stream_stride;
+ CARD32 primary_stream_xy;
+ CARD32 primary_stream_size;
+ CARD32 primary_stream_mem;
+ CARD32 secondary_stream_xy;
+ CARD32 secondary_stream_size;
+ CARD32 streams_fifo;
CARD8 text_save[S3_TEXT_SAVE];
} S3Save;
@@ -473,18 +429,29 @@ typedef struct _s3CardInfo {
Bool bios_initialized; /* whether the bios has been run */
} S3CardInfo;
-typedef struct _s3ScreenInfo {
- CARD8 *cursor_base; /* pointer to cursor area */
+typedef struct _s3FbInfo {
CARD8 *offscreen; /* pointer to offscreen area */
int offscreen_y; /* top y coordinate of offscreen area */
int offscreen_x; /* top x coordinate of offscreen area */
int offscreen_width; /* width of offscreen area */
int offscreen_height; /* height of offscreen area */
- S3Cursor cursor;
S3Patterns patterns;
+ CARD32 bitmap_offset;
+ int accel_stride;
+ int accel_bpp;
+} S3FBInfo;
+
+typedef struct _s3ScreenInfo {
+ CARD8 *cursor_base; /* pointer to cursor area */
+ S3Cursor cursor;
Bool manage_border;
Bool managing_border;
+ Bool use_streams;
+ int primary_depth;
+ int current_ma;
CARD32 border_pixel;
+ S3FBInfo fb[KD_MAX_FB];
+ int fbmap[KD_MAX_FB+1]; /* map from fb to stream */
} S3ScreenInfo;
#define getS3CardInfo(kd) ((S3CardInfo *) ((kd)->card->driver))
@@ -505,18 +472,21 @@ void s3CursorDisable (ScreenPtr pScreen);
void s3CursorFini (ScreenPtr pScreen);
void s3RecolorCursor (ScreenPtr pScreen, int ndef, xColorItem *pdefs);
+void s3DumbPaintWindow (WindowPtr pWin, RegionPtr pRegion, int what);
+void s3DumbCopyWindow (WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc);
+
Bool s3DrawInit (ScreenPtr pScreen);
void s3DrawEnable (ScreenPtr pScreen);
void s3DrawSync (ScreenPtr pScreen);
void s3DrawDisable (ScreenPtr pScreen);
void s3DrawFini (ScreenPtr pScreen);
-void s3GetColors (ScreenPtr pScreen, int ndef, xColorItem *pdefs);
-void s3PutColors (ScreenPtr pScreen, int ndef, xColorItem *pdefs);
+void s3GetColors (ScreenPtr pScreen, int fb, int ndef, xColorItem *pdefs);
+void s3PutColors (ScreenPtr pScreen, int fb, int ndef, xColorItem *pdefs);
void S3InitCard (KdCardAttr *attr);
-void s3GetClock (int target, int *Mp, int *Np, int *Rp, int maxM, int maxN, int maxR);
+void s3GetClock (int target, int *Mp, int *Np, int *Rp, int maxM, int maxN, int maxR, int minVco);
extern KdCardFuncs s3Funcs;
@@ -539,6 +509,13 @@ extern KdCardFuncs s3Funcs;
_loop_count = 0; \
while (s3GetImm(s3vga, s3_vertical_sync_active) == 0) S3_RETRACE_LOOP_CHECK; \
}
+#define _s3WaitVRetraceFast(s3) { \
+ int _loop_count; \
+ _loop_count = 0; \
+ while (s3->input_status_1 & 8) S3_RETRACE_LOOP_CHECK; \
+ _loop_count = 0; \
+ while ((s3->input_status_1 & 8) == 0) S3_RETRACE_LOOP_CHECK; \
+}
/*
* Wait for the begining of the retrace interval
*/
diff --git a/hw/kdrive/savage/s3clock.c b/hw/kdrive/savage/s3clock.c
index 49b843624..d62762bee 100644
--- a/hw/kdrive/savage/s3clock.c
+++ b/hw/kdrive/savage/s3clock.c
@@ -22,7 +22,7 @@
*
* Author: Keith Packard, SuSE, Inc.
*/
-/* $XFree86: xc/programs/Xserver/hw/kdrive/savage/s3clock.c,v 1.2 1999/12/30 03:03:11 robin Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/kdrive/savage/s3clock.c,v 1.3 2000/02/23 20:30:02 dawes Exp $ */
#include "s3.h"
@@ -41,11 +41,9 @@
*/
/* all in kHz */
-#define MIN_VCO 135000.0
-#define MAX_VCO 270000.0
void
-s3GetClock (int target, int *Mp, int *Np, int *Rp, int maxM, int maxN, int maxR)
+s3GetClock (int target, int *Mp, int *Np, int *Rp, int maxM, int maxN, int maxR, int minVco)
{
int M, N, R, bestM, bestN;
int f_vco, f_out;
@@ -57,15 +55,15 @@ s3GetClock (int target, int *Mp, int *Np, int *Rp, int maxM, int maxN, int maxR)
for (R = 0; R <= maxR; R++)
{
f_vco = target * (1 << R);
- if (f_vco >= MIN_VCO)
+ if (f_vco >= minVco)
break;
}
/* M = f_out / f_ref * ((N + 2) * (1 << R)); */
besterr = target;
- for (N = 0; N <= maxN; N++)
+ for (N = 1; N <= maxN; N++)
{
- M = (target * (N + 2) * (1 << R) + (S3_CLOCK_REF/2)) / S3_CLOCK_REF - 2;
+ M = ((target * (N + 2) * (1 << R) + (S3_CLOCK_REF/2)) + S3_CLOCK_REF/2) / S3_CLOCK_REF - 2;
if (0 <= M && M <= maxM)
{
f_out = S3_CLOCK(M,N,R);
diff --git a/hw/kdrive/savage/s3cmap.c b/hw/kdrive/savage/s3cmap.c
index b6540cbd1..a3ede490f 100644
--- a/hw/kdrive/savage/s3cmap.c
+++ b/hw/kdrive/savage/s3cmap.c
@@ -22,12 +22,12 @@
*
* Author: Keith Packard, SuSE, Inc.
*/
-/* $XFree86: xc/programs/Xserver/hw/kdrive/savage/s3cmap.c,v 1.2 1999/12/30 03:03:11 robin Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/kdrive/savage/s3cmap.c,v 1.3 2000/02/23 20:30:02 dawes Exp $ */
#include "s3.h"
void
-s3GetColors (ScreenPtr pScreen, int ndef, xColorItem *pdefs)
+s3GetColors (ScreenPtr pScreen, int fb, int ndef, xColorItem *pdefs)
{
KdScreenPriv(pScreen);
s3CardInfo(pScreenPriv);
@@ -44,7 +44,7 @@ s3GetColors (ScreenPtr pScreen, int ndef, xColorItem *pdefs)
}
void
-s3PutColors (ScreenPtr pScreen, int ndef, xColorItem *pdefs)
+s3PutColors (ScreenPtr pScreen, int fb, int ndef, xColorItem *pdefs)
{
KdScreenPriv(pScreen);
s3CardInfo(pScreenPriv);
@@ -53,7 +53,12 @@ s3PutColors (ScreenPtr pScreen, int ndef, xColorItem *pdefs)
Bool hit_border = FALSE;
Bool check_border = FALSE;
+#if 0
_s3WaitVRetrace (s3vga);
+#else
+ S3Ptr s3 = s3c->s3;
+ _s3WaitVRetraceFast(s3);
+#endif
if (pScreenPriv->enabled && s3s->manage_border && !s3s->managing_border)
check_border = TRUE;
while (ndef--)
@@ -77,10 +82,10 @@ s3PutColors (ScreenPtr pScreen, int ndef, xColorItem *pdefs)
black.green = 0;
black.blue = 0;
s3s->managing_border = TRUE;
- FakeAllocColor (pScreenPriv->pInstalledmap,
+ FakeAllocColor (pScreenPriv->pInstalledmap[fb],
&black);
s3s->border_pixel = black.pixel;
- FakeFreeColor (pScreenPriv->pInstalledmap, s3s->border_pixel);
+ FakeFreeColor (pScreenPriv->pInstalledmap[fb], s3s->border_pixel);
/* s3SetImm (&s3c->s3vga, s3_border_color, (VGA8) s3s->border_pixel); */
}
}
diff --git a/hw/kdrive/savage/s3curs.c b/hw/kdrive/savage/s3curs.c
index fd61d5e32..1faa6d8c0 100644
--- a/hw/kdrive/savage/s3curs.c
+++ b/hw/kdrive/savage/s3curs.c
@@ -22,7 +22,7 @@
*
* Author: Keith Packard, SuSE, Inc.
*/
-/* $XFree86: xc/programs/Xserver/hw/kdrive/savage/s3curs.c,v 1.2 1999/12/30 03:03:11 robin Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/kdrive/savage/s3curs.c,v 1.3 2000/02/23 20:30:03 dawes Exp $ */
#include "s3.h"
#include "s3draw.h"
@@ -90,24 +90,42 @@ s3MoveCursor (ScreenPtr pScreen, int x, int y)
_s3MoveCursor (pScreen, x, y);
}
+#define S3Trunc(c) (((c) >> 8) & 0xff)
+
+#define S3CursColor(r,g,b) ((S3Trunc(r) << 16) | \
+ (S3Trunc(g) << 8) | \
+ (S3Trunc(b)))
+
static void
s3AllocCursorColors (ScreenPtr pScreen)
{
SetupCursor (pScreen);
CursorPtr pCursor = pCurPriv->pCursor;
- KdAllocateCursorPixels (pScreen, pCursor,
- &pCurPriv->source, &pCurPriv->mask);
- switch (pScreenPriv->screen->bitsPerPixel) {
- case 4:
- pCurPriv->source |= pCurPriv->source << 4;
- pCurPriv->mask |= pCurPriv->mask << 4;
- case 8:
- pCurPriv->source |= pCurPriv->source << 8;
- pCurPriv->mask |= pCurPriv->mask << 8;
- case 16:
- pCurPriv->source |= pCurPriv->source << 16;
- pCurPriv->mask |= pCurPriv->mask << 16;
+ if (s3s->use_streams)
+ {
+ pCurPriv->source = S3CursColor(pCursor->foreRed,
+ pCursor->foreGreen,
+ pCursor->foreBlue);
+ pCurPriv->mask = S3CursColor(pCursor->backRed,
+ pCursor->backGreen,
+ pCursor->backBlue);
+ }
+ else
+ {
+ KdAllocateCursorPixels (pScreen, 0, pCursor,
+ &pCurPriv->source, &pCurPriv->mask);
+ switch (pScreenPriv->screen->fb[0].bitsPerPixel) {
+ case 4:
+ pCurPriv->source |= pCurPriv->source << 4;
+ pCurPriv->mask |= pCurPriv->mask << 4;
+ case 8:
+ pCurPriv->source |= pCurPriv->source << 8;
+ pCurPriv->mask |= pCurPriv->mask << 8;
+ case 16:
+ pCurPriv->source |= pCurPriv->source << 16;
+ pCurPriv->mask |= pCurPriv->mask << 16;
+ }
}
}
@@ -221,6 +239,13 @@ s3LoadCursor (ScreenPtr pScreen, int x, int y)
S3AdjustBits32(and);
S3AdjustBits32(xor);
+#define S3SwapNibbles(x) ((x) = (((x) & 0x0f0f0f0f) << 4 | \
+ ((x) >> 4) & 0x0f0f0f0f))
+ if (s3s->use_streams)
+ {
+ S3SwapNibbles(and);
+ S3SwapNibbles(xor);
+ }
*ram++ = (and & 0xffff) | (xor << 16);
*ram++ = (and >> 16) | (xor & 0xffff0000);
}
diff --git a/hw/kdrive/savage/s3draw.c b/hw/kdrive/savage/s3draw.c
index d4d645184..c4c369c43 100644
--- a/hw/kdrive/savage/s3draw.c
+++ b/hw/kdrive/savage/s3draw.c
@@ -22,7 +22,7 @@
*
* Author: Keith Packard, SuSE, Inc.
*/
-/* $XFree86: xc/programs/Xserver/hw/kdrive/savage/s3draw.c,v 1.2 1999/12/30 03:03:11 robin Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/kdrive/savage/s3draw.c,v 1.3 2000/02/23 20:30:03 dawes Exp $ */
#include "s3.h"
#include "s3draw.h"
@@ -114,6 +114,7 @@ s3CopyNtoN (DrawablePtr pSrcDrawable,
return;
}
+ s3SetGlobalBitmap (pDstDrawable->pScreen, s3GCMap (pGC));
_s3SetBlt(s3,pGC->alu,pGC->planemask);
DRAW_DEBUG ((DEBUG_RENDER, "s3CopyNtoN alu %d planemask 0x%x",
pGC->alu, pGC->planemask));
@@ -265,6 +266,7 @@ s3Copy1toN (DrawablePtr pSrcDrawable,
return;
}
+ s3SetGlobalBitmap (pDstDrawable->pScreen, s3GCMap (pGC));
fbGetStipDrawable (pSrcDrawable, psrcBase, widthSrc, srcBpp);
if (args->opaque)
@@ -345,6 +347,7 @@ s3FillBoxSolid (DrawablePtr pDrawable, int nBox, BoxPtr pBox,
SetupS3(pDrawable->pScreen);
register int r;
+ s3SetGlobalBitmap (pDrawable->pScreen, s3DrawMap (pDrawable));
_s3SetSolidFill(s3,pixel,alu,planemask);
while (nBox--) {
@@ -355,13 +358,13 @@ s3FillBoxSolid (DrawablePtr pDrawable, int nBox, BoxPtr pBox,
}
void
-_s3SetPattern (ScreenPtr pScreen,
+_s3SetPattern (ScreenPtr pScreen, int ma,
int alu, unsigned long planemask, s3PatternPtr pPattern)
{
SetupS3(pScreen);
S3PatternCache *cache;
- _s3LoadPattern (pScreen, pPattern);
+ _s3LoadPattern (pScreen, ma, pPattern);
cache = pPattern->cache;
switch (pPattern->fillStyle) {
@@ -385,7 +388,8 @@ s3FillBoxPattern (DrawablePtr pDrawable, int nBox, BoxPtr pBox,
S3PatternCache *cache;
int patx, paty;
- _s3SetPattern (pDrawable->pScreen, alu, planemask, pPattern);
+ s3SetGlobalBitmap (pDrawable->pScreen, s3DrawMap (pDrawable));
+ _s3SetPattern (pDrawable->pScreen, s3DrawMap(pDrawable), alu, planemask, pPattern);
cache = pPattern->cache;
while (nBox--)
{
@@ -415,6 +419,7 @@ s3FillBoxLargeStipple (DrawablePtr pDrawable, GCPtr pGC,
stipHeight = pStipple->height;
fbGetStipDrawable (pStipple, stip, stipStride, stipBpp);
+ s3SetGlobalBitmap (pDrawable->pScreen, s3DrawMap (pDrawable));
if (pGC->fillStyle == FillOpaqueStippled)
{
_s3SetOpaquePlaneBlt(s3,pGC->alu,pGC->planemask,
@@ -648,6 +653,7 @@ _s3FillSpanLargeStipple (DrawablePtr pDrawable, GCPtr pGC,
int stipWidth, stipHeight;
int dstX, dstY, width, height;
+ s3SetGlobalBitmap (pDrawable->pScreen, s3GCMap (pGC));
stipWidth = pStipple->width;
stipHeight = pStipple->height;
fbGetStipDrawable (pStipple, stip, stipStride, stipBpp);
@@ -711,6 +717,7 @@ s3FillSpans (DrawablePtr pDrawable, GCPtr pGC, int n,
S3PatternCache *cache;
RegionPtr pClip = fbGetCompositeClip (pGC);
+ s3SetGlobalBitmap (pDrawable->pScreen, s3GCMap (pGC));
if (REGION_NUM_RECTS(pClip) == 1 &&
(pGC->fillStyle == FillSolid || s3Priv->pPattern))
{
@@ -726,7 +733,7 @@ s3FillSpans (DrawablePtr pDrawable, GCPtr pGC, int n,
}
else
{
- _s3SetPattern (pDrawable->pScreen, pGC->alu, pGC->planemask,
+ _s3SetPattern (pDrawable->pScreen, s3GCMap(pGC), pGC->alu, pGC->planemask,
s3Priv->pPattern);
cache = s3Priv->pPattern->cache;
}
@@ -793,7 +800,7 @@ s3FillSpans (DrawablePtr pDrawable, GCPtr pGC, int n,
}
else if (s3Priv->pPattern)
{
- _s3SetPattern (pDrawable->pScreen, pGC->alu, pGC->planemask,
+ _s3SetPattern (pDrawable->pScreen, s3GCMap(pGC), pGC->alu, pGC->planemask,
s3Priv->pPattern);
cache = s3Priv->pPattern->cache;
while (n--)
@@ -843,6 +850,7 @@ s3FillSpans (DrawablePtr pDrawable, GCPtr pGC, int n,
static void
_s3FillEllipse (DrawablePtr pDraw, S3Ptr s3, xArc *arc)
{
+ KdScreenPriv(pDraw->pScreen);
int x, y, e;
int yk, xk, ym, xm, dx, dy, xorg, yorg;
int y_top, y_bot;
@@ -850,6 +858,7 @@ _s3FillEllipse (DrawablePtr pDraw, S3Ptr s3, xArc *arc)
register int xpos;
int slw;
+ s3SetGlobalBitmap (pDraw->pScreen, s3DrawMap (pDraw));
miFillArcSetup(arc, &info);
MIFILLARCSETUP();
y_top = pDraw->y + yorg - y;
@@ -873,6 +882,7 @@ _s3FillEllipse (DrawablePtr pDraw, S3Ptr s3, xArc *arc)
static void
_s3FillArcSlice (DrawablePtr pDraw, GCPtr pGC, S3Ptr s3, xArc *arc)
{
+ KdScreenPriv(pDraw->pScreen);
int yk, xk, ym, xm, dx, dy, xorg, yorg, slw;
register int x, y, e;
miFillArcRec info;
@@ -880,6 +890,7 @@ _s3FillArcSlice (DrawablePtr pDraw, GCPtr pGC, S3Ptr s3, xArc *arc)
int xl, xr, xc;
int y_top, y_bot;
+ s3SetGlobalBitmap (pDraw->pScreen, s3DrawMap (pDraw));
DRAW_DEBUG ((DEBUG_ARCS, "slice %dx%d+%d+%d %d->%d",
arc->width, arc->height, arc->x, arc->y,
arc->angle1, arc->angle2));
@@ -1013,6 +1024,7 @@ s3FillPoly1Rect (DrawablePtr pDrawable, GCPtr pGC, int shape,
return;
}
+ s3SetGlobalBitmap (pDrawable->pScreen, s3GCMap (pGC));
fbPriv = fbGetGCPrivate(pGC);
sy = pDrawable->y;
sx = pDrawable->x;
@@ -1258,6 +1270,7 @@ s3PolyGlyphBltClipped (DrawablePtr pDrawable,
Bool set;
PixTransDeclare;
+ s3SetGlobalBitmap (pDrawable->pScreen, s3GCMap (pGC));
x += pDrawable->x;
y += pDrawable->y;
@@ -1408,6 +1421,7 @@ s3PolyGlyphBlt (DrawablePtr pDrawable,
unsigned char alu;
PixTransDeclare;
+ s3SetGlobalBitmap (pDrawable->pScreen, s3GCMap (pGC));
x += pDrawable->x;
y += pDrawable->y;
@@ -1549,6 +1563,7 @@ s3ImageTEGlyphBlt (DrawablePtr pDrawable, GCPtr pGC,
CARD32 tmp;
PixTransDeclare;
+ s3SetGlobalBitmap (pDrawable->pScreen, s3GCMap (pGC));
widthGlyph = FONTMAXBOUNDS(pfont,characterWidth);
if (!widthGlyph)
return;
@@ -1701,6 +1716,7 @@ _s3Segment (DrawablePtr pDrawable,
unsigned int oc1; /* outcode of point 1 */
unsigned int oc2; /* outcode of point 2 */
+ s3SetGlobalBitmap (pDrawable->pScreen, s3GCMap (pGC));
nBox = REGION_NUM_RECTS (pClip);
pBox = REGION_RECTS (pClip);
CalcLineDeltas(x1, y1, x2, y2, adx, ady, signdx, signdy,
@@ -1875,6 +1891,7 @@ s3PolySegment (DrawablePtr pDrawable, GCPtr pGC,
Bool
s3AllocPattern (ScreenPtr pScreen,
+ int ma,
PixmapPtr pPixmap,
int xorg, int yorg,
int fillStyle, Pixel fg, Pixel bg,
@@ -1884,7 +1901,7 @@ s3AllocPattern (ScreenPtr pScreen,
s3ScreenInfo(pScreenPriv);
s3PatternPtr pPattern;
- if (s3s->patterns.cache && fillStyle != FillSolid &&
+ if (s3s->fb[ma].patterns.cache && fillStyle != FillSolid &&
s3CheckPattern (pPixmap->drawable.width, pPixmap->drawable.height))
{
if (!(pPattern = *ppPattern))
@@ -1935,6 +1952,7 @@ s3CheckGCFill (GCPtr pGC)
break;
}
s3AllocPattern (pGC->pScreen,
+ s3GCMap(pGC),
pPixmap,
pGC->patOrg.x + pGC->lastWinOrg.x,
pGC->patOrg.y + pGC->lastWinOrg.y,
@@ -2005,27 +2023,33 @@ s3FetchPatternPixel (s3PatternPtr pPattern, int x, int y)
* Place pattern image on screen; done with S3 locked
*/
void
-_s3PutPattern (ScreenPtr pScreen, s3PatternPtr pPattern)
+_s3PutPattern (ScreenPtr pScreen, int ma, s3PatternPtr pPattern)
{
SetupS3(pScreen);
+ s3ScreenInfo(pScreenPriv);
int x, y;
CARD8 *dstLine, *dst8;
CARD16 *dst16;
CARD32 *dst32;
S3PatternCache *cache = pPattern->cache;
+#ifdef S3_TRIO
+ int fb = 0;
+#else
+ int fb = s3s->fbmap[ma];
+#endif
DRAW_DEBUG ((DEBUG_PATTERN, "_s3PutPattern 0x%x id %d to %d %d",
pPattern, pPattern->id, cache->x, cache->y));
- dstLine = (pScreenPriv->screen->frameBuffer +
- cache->y * pScreenPriv->screen->byteStride +
- cache->x * pScreenPriv->bytesPerPixel);
+ dstLine = (pScreenPriv->screen->fb[fb].frameBuffer +
+ cache->y * pScreenPriv->screen->fb[fb].byteStride +
+ cache->x * pScreenPriv->bytesPerPixel[fb]);
CheckSyncS3 (pScreen);
for (y = 0; y < S3_TILE_SIZE; y++)
{
- switch (pScreenPriv->screen->bitsPerPixel) {
+ switch (pScreenPriv->screen->fb[fb].bitsPerPixel) {
case 8:
dst8 = dstLine;
for (x = 0; x < S3_TILE_SIZE; x++)
@@ -2051,7 +2075,7 @@ _s3PutPattern (ScreenPtr pScreen, s3PatternPtr pPattern)
*dst32++ = s3FetchPatternPixel (pPattern, x, y);
break;
}
- dstLine += pScreenPriv->screen->byteStride;
+ dstLine += pScreenPriv->screen->fb[fb].byteStride;
}
}
@@ -2059,7 +2083,7 @@ _s3PutPattern (ScreenPtr pScreen, s3PatternPtr pPattern)
* Load a stipple to off-screen memory; done with S3 locked
*/
void
-_s3LoadPattern (ScreenPtr pScreen, s3PatternPtr pPattern)
+_s3LoadPattern (ScreenPtr pScreen, int ma, s3PatternPtr pPattern)
{
SetupS3(pScreen);
s3ScreenInfo(pScreenPriv);
@@ -2078,13 +2102,13 @@ _s3LoadPattern (ScreenPtr pScreen, s3PatternPtr pPattern)
/*
* Lame replacement strategy; assume we'll have plenty of room.
*/
- cache = &s3s->patterns.cache[s3s->patterns.last_used];
- if (++s3s->patterns.last_used == s3s->patterns.ncache)
- s3s->patterns.last_used = 0;
- cache->id = ++s3s->patterns.last_id;
+ cache = &s3s->fb[ma].patterns.cache[s3s->fb[ma].patterns.last_used];
+ if (++s3s->fb[ma].patterns.last_used == s3s->fb[ma].patterns.ncache)
+ s3s->fb[ma].patterns.last_used = 0;
+ cache->id = ++s3s->fb[ma].patterns.last_id;
pPattern->id = cache->id;
pPattern->cache = cache;
- _s3PutPattern (pScreen, pPattern);
+ _s3PutPattern (pScreen, ma, pPattern);
}
void
@@ -2110,6 +2134,8 @@ GCFuncs s3GCFuncs = {
int
s3CreateGC (GCPtr pGC)
{
+ KdScreenPriv(pGC->pScreen);
+ s3ScreenInfo(pScreenPriv);
s3PrivGCPtr s3Priv;
if (!fbCreateGC (pGC))
@@ -2121,17 +2147,30 @@ s3CreateGC (GCPtr pGC)
s3Priv = s3GetGCPrivate(pGC);
s3Priv->type = DRAWABLE_PIXMAP;
s3Priv->pPattern = 0;
-
+#ifndef S3_TRIO
+ if (pGC->depth == s3s->primary_depth)
+ s3Priv->ma = 0;
+ else
+ s3Priv->ma = 1;
+#endif
return TRUE;
}
Bool
s3CreateWindow (WindowPtr pWin)
{
+ KdScreenPriv(pWin->drawable.pScreen);
+ s3ScreenInfo(pScreenPriv);
+
if (!KdCreateWindow (pWin))
return FALSE;
pWin->devPrivates[s3WindowPrivateIndex].ptr = 0;
- return TRUE;
+#ifndef S3_TRIO
+ if (pWin->drawable.depth != s3s->primary_depth)
+ return fbOverlayCreateWindow (pWin);
+ else
+#endif
+ return fbCreateWindow (pWin);
}
Bool
@@ -2146,6 +2185,7 @@ s3DestroyWindow (WindowPtr pWin)
Bool
s3ChangeWindowAttributes (WindowPtr pWin, Mask mask)
{
+ KdScreenPriv(pWin->drawable.pScreen);
Bool ret;
s3PatternPtr pPattern;
PixmapPtr pPixmap;
@@ -2165,7 +2205,9 @@ s3ChangeWindowAttributes (WindowPtr pWin, Mask mask)
fillStyle = FillSolid;
}
pPattern = s3GetWindowPrivate(pWin);
- s3AllocPattern (pWin->drawable.pScreen, pPixmap,
+ s3AllocPattern (pWin->drawable.pScreen,
+ s3DrawMap (&pWin->drawable),
+ pPixmap,
pWin->drawable.x, pWin->drawable.y,
fillStyle, 0, 0, &pPattern);
DRAW_DEBUG ((DEBUG_PAINT_WINDOW, "Background pattern 0x%x pixmap 0x%x style %d",
@@ -2175,6 +2217,30 @@ s3ChangeWindowAttributes (WindowPtr pWin, Mask mask)
return ret;
}
+#ifndef S3_TRIO
+void
+s3PaintChromaKey (WindowPtr pWin, RegionPtr pRegion)
+{
+ SetupS3 (pWin->drawable.pScreen);
+ s3ScreenInfo (pScreenPriv);
+
+ if (pWin->drawable.depth != s3s->primary_depth)
+ {
+ int nBox = REGION_NUM_RECTS(pRegion);
+ BoxPtr pBox = REGION_RECTS(pRegion);
+
+ s3SetGlobalBitmap (pWin->drawable.pScreen, 0);
+ _s3SetSolidFill(s3,0xffffffff,GXcopy,0xffffffff);
+ while (nBox--)
+ {
+ _s3SolidRect(s3,pBox->x1,pBox->y1,pBox->x2-pBox->x1,pBox->y2-pBox->y1);
+ pBox++;
+ }
+ MarkSyncS3 (pWin->drawable.pScreen);
+ }
+}
+#endif
+
void
s3PaintWindow(WindowPtr pWin, RegionPtr pRegion, int what)
{
@@ -2188,6 +2254,9 @@ s3PaintWindow(WindowPtr pWin, RegionPtr pRegion, int what)
REGION_NUM_RECTS(pRegion)));
if (!REGION_NUM_RECTS(pRegion))
return;
+#ifndef S3_TRIO
+ s3PaintChromaKey (pWin, pRegion);
+#endif
switch (what) {
case PW_BACKGROUND:
switch (pWin->backgroundState) {
@@ -2234,11 +2303,24 @@ s3PaintWindow(WindowPtr pWin, RegionPtr pRegion, int what)
}
void
+s3RestoreAreas(PixmapPtr pPixmap,
+ RegionPtr prgnRestore,
+ int xorg,
+ int yorg,
+ WindowPtr pWin)
+{
+#ifndef S3_TRIO
+ s3PaintChromaKey (pWin, prgnRestore);
+#endif
+ KdCheckRestoreAreas (pPixmap, prgnRestore, xorg, yorg, pWin);
+}
+
+void
s3CopyWindowProc (DrawablePtr pSrcDrawable,
DrawablePtr pDstDrawable,
GCPtr pGC,
- BoxPtr pbox,
- int nbox,
+ BoxPtr pboxOrig,
+ int nboxOrig,
int dx,
int dy,
Bool reverse,
@@ -2247,23 +2329,248 @@ s3CopyWindowProc (DrawablePtr pSrcDrawable,
void *closure)
{
SetupS3(pDstDrawable->pScreen);
+ s3ScreenInfo(pScreenPriv);
+ int srcX, srcY, dstX, dstY;
+ int x1, x2;
+ int w, h;
+ int flags;
+ int ma;
+ BoxPtr pbox;
+ int nbox;
+
+ if (pSrcDrawable->bitsPerPixel == 24)
+ dx *= 3;
+#ifdef S3_TRIO
+ ma = 0;
+#else
+ for (ma = 0; s3s->fbmap[ma] >= 0; ma++)
+#endif
+ {
+ nbox = nboxOrig;
+ pbox = pboxOrig;
+ s3SetGlobalBitmap (pDstDrawable->pScreen, ma);
+ _s3SetBlt(s3,GXcopy,~0);
+ while (nbox--)
+ {
+ x1 = pbox->x1;
+ x2 = pbox->x2;
+ if (pSrcDrawable->bitsPerPixel == 24)
+ {
+ x1 *= 3;
+ x2 *= 3;
+ }
+
+ w = x2 - x1;
+ h = pbox->y2 - pbox->y1;
+ flags = 0;
+ if (reverse)
+ {
+ dstX = x2 - 1;
+ }
+ else
+ {
+ dstX = x1;
+ flags |= INC_X;
+ }
+ srcX = dstX + dx;
+
+ if (upsidedown)
+ {
+ dstY = pbox->y2 - 1;
+ }
+ else
+ {
+ dstY = pbox->y1;
+ flags |= INC_Y;
+ }
+ srcY = dstY + dy;
+
+ _s3Blt (s3, srcX, srcY, dstX, dstY, w, h, flags);
+ pbox++;
+ }
+ MarkSyncS3 (pDstDrawable->pScreen);
+ }
+}
+
+void
+s3CopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ KdScreenPriv(pScreen);
+ RegionRec rgnDst;
+ int dx, dy;
+ WindowPtr pwinRoot;
+
+ pwinRoot = WindowTable[pWin->drawable.pScreen->myNum];
+
+ dx = ptOldOrg.x - pWin->drawable.x;
+ dy = ptOldOrg.y - pWin->drawable.y;
+ REGION_TRANSLATE(pWin->drawable.pScreen, prgnSrc, -dx, -dy);
+
+ REGION_INIT (pWin->drawable.pScreen, &rgnDst, NullBox, 0);
+
+ REGION_INTERSECT(pWin->drawable.pScreen, &rgnDst, &pWin->borderClip, prgnSrc);
+
+ fbCopyRegion ((DrawablePtr)pwinRoot, (DrawablePtr)pwinRoot,
+ 0,
+ &rgnDst, dx, dy, s3CopyWindowProc, 0, 0);
+
+ REGION_UNINIT(pWin->drawable.pScreen, &rgnDst);
+}
+
+void
+s3_24FillBoxSolid (DrawablePtr pDrawable, int nBox, BoxPtr pBox,
+ unsigned long pixel, int alu, unsigned long planemask)
+{
+ SetupS3(pDrawable->pScreen);
+ register int r;
+ int x1, x2;
+
+ s3SetGlobalBitmap (pDrawable->pScreen, s3DrawMap (pDrawable));
+ _s3SetSolidFill(s3,pixel,alu,planemask);
+
+ while (nBox--) {
+ x1 = pBox->x1 * 3;
+ x2 = pBox->x2 * 3;
+ _s3SolidRect(s3,x1,pBox->y1,x2-x1,pBox->y2-pBox->y1);
+ pBox++;
+ }
+ MarkSyncS3 (pDrawable->pScreen);
+}
+
+#define ok24(p) (((p) & 0xffffff) == ((((p) & 0xff) << 16) | (((p) >> 8) & 0xffff)))
+
+void
+s3_24FillSpans (DrawablePtr pDrawable, GCPtr pGC, int n,
+ DDXPointPtr ppt, int *pwidth, int fSorted)
+{
+ SetupS3(pDrawable->pScreen);
+ int x, y, x1, y1, x2, y2;
+ int width;
+ /* next three parameters are post-clip */
+ int nTmp;
+ int *pwidthFree;/* copies of the pointers to free */
+ DDXPointPtr pptFree;
+ FbGCPrivPtr fbPriv = fbGetGCPrivate(pGC);
+ BoxPtr extents;
+ RegionPtr pClip = fbGetCompositeClip (pGC);
+
+ if (pGC->fillStyle != FillSolid || !ok24 (pGC->fgPixel) || !ok24(pGC->planemask))
+ {
+ KdCheckFillSpans (pDrawable, pGC, n, ppt, pwidth, fSorted);
+ return;
+ }
+
+ s3SetGlobalBitmap (pDrawable->pScreen, s3GCMap (pGC));
+ if (REGION_NUM_RECTS(pClip) == 1)
+ {
+ extents = REGION_RECTS(pClip);
+ x1 = extents->x1;
+ x2 = extents->x2;
+ y1 = extents->y1;
+ y2 = extents->y2;
+ _s3SetSolidFill(s3,pGC->fgPixel,pGC->alu,pGC->planemask);
+ while (n--)
+ {
+ y = ppt->y;
+ if (y1 <= y && y < y2)
+ {
+ x = ppt->x;
+ width = *pwidth;
+ if (x < x1)
+ {
+ width -= (x1 - x);
+ x = x1;
+ }
+ if (x2 < x + width)
+ width = x2 - x;
+ if (width > 0)
+ {
+ _s3SolidRect(s3,x*3,y,width*3,1);
+ }
+ }
+ ppt++;
+ pwidth++;
+ }
+ }
+ else
+ {
+ nTmp = n * miFindMaxBand(pClip);
+ pwidthFree = (int *)ALLOCATE_LOCAL(nTmp * sizeof(int));
+ pptFree = (DDXPointRec *)ALLOCATE_LOCAL(nTmp * sizeof(DDXPointRec));
+ if(!pptFree || !pwidthFree)
+ {
+ if (pptFree) DEALLOCATE_LOCAL(pptFree);
+ if (pwidthFree) DEALLOCATE_LOCAL(pwidthFree);
+ return;
+ }
+ n = miClipSpans(fbGetCompositeClip(pGC),
+ ppt, pwidth, n,
+ pptFree, pwidthFree, fSorted);
+ pwidth = pwidthFree;
+ ppt = pptFree;
+ _s3SetSolidFill(s3,pGC->fgPixel,pGC->alu,pGC->planemask);
+ while (n--)
+ {
+ x = ppt->x;
+ y = ppt->y;
+ ppt++;
+ width = *pwidth++;
+ if (width)
+ {
+ _s3SolidRect(s3,x*3,y,width*3,1);
+ }
+ }
+ DEALLOCATE_LOCAL(pptFree);
+ DEALLOCATE_LOCAL(pwidthFree);
+ }
+ MarkSyncS3 (pDrawable->pScreen);
+}
+
+void
+s3_24CopyNtoN (DrawablePtr pSrcDrawable,
+ DrawablePtr pDstDrawable,
+ GCPtr pGC,
+ BoxPtr pbox,
+ int nbox,
+ int dx,
+ int dy,
+ Bool reverse,
+ Bool upsidedown,
+ Pixel bitplane,
+ void *closure)
+{
+ SetupS3(pDstDrawable->pScreen);
int srcX, srcY, dstX, dstY;
int w, h;
int flags;
+ int x1, x2;
+
+ if (sourceInvarient (pGC->alu))
+ {
+ s3_24FillBoxSolid (pDstDrawable, nbox, pbox, 0, pGC->alu, pGC->planemask);
+ return;
+ }
- _s3SetBlt(s3,GXcopy,~0);
+ s3SetGlobalBitmap (pDstDrawable->pScreen, s3GCMap (pGC));
+ _s3SetBlt(s3,pGC->alu,pGC->planemask);
+ DRAW_DEBUG ((DEBUG_RENDER, "s3CopyNtoN alu %d planemask 0x%x",
+ pGC->alu, pGC->planemask));
+ dx *= 3;
while (nbox--)
{
- w = pbox->x2 - pbox->x1;
+ x1 = pbox->x1 * 3;
+ x2 = pbox->x2 * 3;
+ w = x2 - x1;
h = pbox->y2 - pbox->y1;
flags = 0;
if (reverse)
{
- dstX = pbox->x2 - 1;
+ dstX = x2 - 1;
}
else
{
- dstX = pbox->x1;
+ dstX = x1;
flags |= INC_X;
}
srcX = dstX + dx;
@@ -2282,33 +2589,456 @@ s3CopyWindowProc (DrawablePtr pSrcDrawable,
_s3Blt (s3, srcX, srcY, dstX, dstY, w, h, flags);
pbox++;
}
- MarkSyncS3 (pDstDrawable->pScreen);
+ MarkSyncS3 (pSrcDrawable->pScreen);
}
-void
-s3CopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
+RegionPtr
+s3_24CopyArea(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC,
+ int srcx, int srcy, int width, int height, int dstx, int dsty)
{
- ScreenPtr pScreen = pWin->drawable.pScreen;
- KdScreenPriv(pScreen);
- RegionRec rgnDst;
- int dx, dy;
- WindowPtr pwinRoot;
+ SetupS3(pDstDrawable->pScreen);
+
+ if (pSrcDrawable->type == DRAWABLE_WINDOW &&
+ pDstDrawable->type == DRAWABLE_WINDOW &&
+ ok24(pGC->planemask))
+ {
+ return fbDoCopy (pSrcDrawable, pDstDrawable, pGC,
+ srcx, srcy, width, height,
+ dstx, dsty, s3_24CopyNtoN, 0, 0);
+ }
+ return KdCheckCopyArea (pSrcDrawable, pDstDrawable, pGC,
+ srcx, srcy, width, height, dstx, dsty);
+}
- pwinRoot = WindowTable[pWin->drawable.pScreen->myNum];
- dx = ptOldOrg.x - pWin->drawable.x;
- dy = ptOldOrg.y - pWin->drawable.y;
- REGION_TRANSLATE(pWin->drawable.pScreen, prgnSrc, -dx, -dy);
+#define NUM_STACK_RECTS 1024
- REGION_INIT (pWin->drawable.pScreen, &rgnDst, NullBox, 0);
+void
+s3_24PolyFillRect (DrawablePtr pDrawable, GCPtr pGC,
+ int nrectFill, xRectangle *prectInit)
+{
+ s3GCPrivate(pGC);
+ xRectangle *prect;
+ RegionPtr prgnClip;
+ register BoxPtr pbox;
+ register BoxPtr pboxClipped;
+ BoxPtr pboxClippedBase;
+ BoxPtr pextent;
+ BoxRec stackRects[NUM_STACK_RECTS];
+ FbGCPrivPtr fbPriv = fbGetGCPrivate (pGC);
+ int numRects;
+ int n;
+ int xorg, yorg;
+ int x, y;
+
+ if (pGC->fillStyle != FillSolid || !ok24 (pGC->fgPixel) || !ok24(pGC->planemask))
+ {
+ KdCheckPolyFillRect (pDrawable, pGC, nrectFill, prectInit);
+ return;
+ }
- REGION_INTERSECT(pWin->drawable.pScreen, &rgnDst, &pWin->borderClip, prgnSrc);
+ prgnClip = fbGetCompositeClip(pGC);
+ xorg = pDrawable->x;
+ yorg = pDrawable->y;
+
+ if (xorg || yorg)
+ {
+ prect = prectInit;
+ n = nrectFill;
+ while(n--)
+ {
+ prect->x += xorg;
+ prect->y += yorg;
+ prect++;
+ }
+ }
+
+ prect = prectInit;
- fbCopyRegion ((DrawablePtr)pwinRoot, (DrawablePtr)pwinRoot,
- 0,
- &rgnDst, dx, dy, s3CopyWindowProc, 0, 0);
+ numRects = REGION_NUM_RECTS(prgnClip) * nrectFill;
+ if (numRects > NUM_STACK_RECTS)
+ {
+ pboxClippedBase = (BoxPtr)ALLOCATE_LOCAL(numRects * sizeof(BoxRec));
+ if (!pboxClippedBase)
+ return;
+ }
+ else
+ pboxClippedBase = stackRects;
+
+ pboxClipped = pboxClippedBase;
+
+ if (REGION_NUM_RECTS(prgnClip) == 1)
+ {
+ int x1, y1, x2, y2, bx2, by2;
+
+ pextent = REGION_RECTS(prgnClip);
+ x1 = pextent->x1;
+ y1 = pextent->y1;
+ x2 = pextent->x2;
+ y2 = pextent->y2;
+ while (nrectFill--)
+ {
+ if ((pboxClipped->x1 = prect->x) < x1)
+ pboxClipped->x1 = x1;
- REGION_UNINIT(pWin->drawable.pScreen, &rgnDst);
+ if ((pboxClipped->y1 = prect->y) < y1)
+ pboxClipped->y1 = y1;
+
+ bx2 = (int) prect->x + (int) prect->width;
+ if (bx2 > x2)
+ bx2 = x2;
+ pboxClipped->x2 = bx2;
+
+ by2 = (int) prect->y + (int) prect->height;
+ if (by2 > y2)
+ by2 = y2;
+ pboxClipped->y2 = by2;
+
+ prect++;
+ if ((pboxClipped->x1 < pboxClipped->x2) &&
+ (pboxClipped->y1 < pboxClipped->y2))
+ {
+ pboxClipped++;
+ }
+ }
+ }
+ else
+ {
+ int x1, y1, x2, y2, bx2, by2;
+
+ pextent = REGION_EXTENTS(pGC->pScreen, prgnClip);
+ x1 = pextent->x1;
+ y1 = pextent->y1;
+ x2 = pextent->x2;
+ y2 = pextent->y2;
+ while (nrectFill--)
+ {
+ BoxRec box;
+
+ if ((box.x1 = prect->x) < x1)
+ box.x1 = x1;
+
+ if ((box.y1 = prect->y) < y1)
+ box.y1 = y1;
+
+ bx2 = (int) prect->x + (int) prect->width;
+ if (bx2 > x2)
+ bx2 = x2;
+ box.x2 = bx2;
+
+ by2 = (int) prect->y + (int) prect->height;
+ if (by2 > y2)
+ by2 = y2;
+ box.y2 = by2;
+
+ prect++;
+
+ if ((box.x1 >= box.x2) || (box.y1 >= box.y2))
+ continue;
+
+ n = REGION_NUM_RECTS (prgnClip);
+ pbox = REGION_RECTS(prgnClip);
+
+ /* clip the rectangle to each box in the clip region
+ this is logically equivalent to calling Intersect()
+ */
+ while(n--)
+ {
+ pboxClipped->x1 = max(box.x1, pbox->x1);
+ pboxClipped->y1 = max(box.y1, pbox->y1);
+ pboxClipped->x2 = min(box.x2, pbox->x2);
+ pboxClipped->y2 = min(box.y2, pbox->y2);
+ pbox++;
+
+ /* see if clipping left anything */
+ if(pboxClipped->x1 < pboxClipped->x2 &&
+ pboxClipped->y1 < pboxClipped->y2)
+ {
+ pboxClipped++;
+ }
+ }
+ }
+ }
+ if (pboxClipped != pboxClippedBase)
+ {
+ s3_24FillBoxSolid(pDrawable,
+ pboxClipped-pboxClippedBase, pboxClippedBase,
+ pGC->fgPixel, pGC->alu, pGC->planemask);
+ }
+ if (pboxClippedBase != stackRects)
+ DEALLOCATE_LOCAL(pboxClippedBase);
+}
+
+void
+s3_24SolidBoxClipped (DrawablePtr pDrawable,
+ RegionPtr pClip,
+ int x1,
+ int y1,
+ int x2,
+ int y2,
+ FbBits fg)
+{
+ SetupS3 (pDrawable->pScreen);
+ BoxPtr pbox;
+ int nbox;
+ int partX1, partX2, partY1, partY2;
+
+ s3SetGlobalBitmap (pDrawable->pScreen, s3DrawMap (pDrawable));
+ _s3SetSolidFill(s3,fg,GXcopy,~0);
+
+ for (nbox = REGION_NUM_RECTS(pClip), pbox = REGION_RECTS(pClip);
+ nbox--;
+ pbox++)
+ {
+ partX1 = pbox->x1;
+ if (partX1 < x1)
+ partX1 = x1;
+
+ partX2 = pbox->x2;
+ if (partX2 > x2)
+ partX2 = x2;
+
+ if (partX2 <= partX1)
+ continue;
+
+ partY1 = pbox->y1;
+ if (partY1 < y1)
+ partY1 = y1;
+
+ partY2 = pbox->y2;
+ if (partY2 > y2)
+ partY2 = y2;
+
+ if (partY2 <= partY1)
+ continue;
+
+ partX1 *= 3;
+ partX2 *= 3;
+ _s3SolidRect(s3,partX1, partY1, partX2-partX1, partY2-partY1);
+ }
+ MarkSyncS3(pDrawable->pScreen);
+}
+
+void
+s3_24ImageGlyphBlt (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x,
+ int y,
+ unsigned int nglyph,
+ CharInfoPtr *ppciInit,
+ pointer pglyphBase)
+{
+ FbGCPrivPtr pPriv = fbGetGCPrivate(pGC);
+ CharInfoPtr *ppci;
+ CharInfoPtr pci;
+ unsigned char *pglyph; /* pointer bits in glyph */
+ int gWidth, gHeight; /* width and height of glyph */
+ FbStride gStride; /* stride of glyph */
+ Bool opaque;
+ int n;
+ int gx, gy;
+ FbBits *dst;
+ FbStride dstStride;
+ int dstBpp;
+ FbBits depthMask;
+ int xBack, widthBack;
+ int yBack, heightBack;
+
+ depthMask = FbFullMask(pDrawable->depth);
+ if (!ok24 (pGC->fgPixel) ||
+ !ok24(pGC->bgPixel) ||
+ !ok24(pGC->planemask))
+ {
+ KdCheckImageGlyphBlt(pDrawable, pGC, x, y, nglyph, ppciInit, pglyphBase);
+ return;
+ }
+ fbGetDrawable (pDrawable, dst, dstStride, dstBpp);
+
+ x += pDrawable->x;
+ y += pDrawable->y;
+
+ ppci = ppciInit;
+ n = nglyph;
+ widthBack = 0;
+ while (n--)
+ widthBack += (*ppci++)->metrics.characterWidth;
+
+ xBack = x;
+ if (widthBack < 0)
+ {
+ xBack += widthBack;
+ widthBack = -widthBack;
+ }
+ yBack = y - FONTASCENT(pGC->font);
+ heightBack = FONTASCENT(pGC->font) + FONTDESCENT(pGC->font);
+ s3_24SolidBoxClipped (pDrawable,
+ fbGetCompositeClip(pGC),
+ xBack,
+ yBack,
+ xBack + widthBack,
+ yBack + heightBack,
+ pPriv->bg);
+
+ KdCheckSync (pDrawable->pScreen);
+
+ ppci = ppciInit;
+ while (nglyph--)
+ {
+ pci = *ppci++;
+ pglyph = FONTGLYPHBITS(pglyphBase, pci);
+ gWidth = GLYPHWIDTHPIXELS(pci);
+ gHeight = GLYPHHEIGHTPIXELS(pci);
+ if (gWidth && gHeight)
+ {
+ gx = x + pci->metrics.leftSideBearing;
+ gy = y - pci->metrics.ascent;
+ if (gWidth <= sizeof (FbStip) * 8 &&
+ fbGlyphIn (fbGetCompositeClip(pGC), gx, gy, gWidth, gHeight))
+ {
+ fbGlyph24 (dst + gy * dstStride,
+ dstStride,
+ dstBpp,
+ (FbStip *) pglyph,
+ pPriv->fg,
+ gx,
+ gHeight);
+ }
+ else
+ {
+ gStride = GLYPHWIDTHBYTESPADDED(pci) / sizeof (FbStip);
+ fbPutXYImage (pDrawable,
+ fbGetCompositeClip(pGC),
+ pPriv->fg,
+ pPriv->bg,
+ pPriv->pm,
+ GXcopy,
+ FALSE,
+
+ gx,
+ gy,
+ gWidth, gHeight,
+
+ (FbStip *) pglyph,
+ gStride,
+ 0);
+ }
+ }
+ x += pci->metrics.characterWidth;
+ }
+}
+
+static const GCOps s3_24GCOps = {
+ s3_24FillSpans,
+ KdCheckSetSpans,
+ KdCheckPutImage,
+ KdCheckCopyArea,
+ KdCheckCopyPlane,
+ KdCheckPolyPoint,
+ KdCheckPolylines,
+ KdCheckPolySegment,
+ KdCheckPolyRectangle,
+ KdCheckPolyArc,
+ KdCheckFillPolygon,
+ s3_24PolyFillRect,
+ KdCheckPolyFillArc,
+ miPolyText8,
+ miPolyText16,
+ miImageText8,
+ miImageText16,
+ s3_24ImageGlyphBlt,
+ KdCheckPolyGlyphBlt,
+ KdCheckPushPixels,
+#ifdef NEED_LINEHELPER
+ ,NULL
+#endif
+};
+
+void
+s3_24ValidateGC (GCPtr pGC, Mask changes, DrawablePtr pDrawable)
+{
+ if (pDrawable->type != DRAWABLE_WINDOW)
+ pGC->ops = (GCOps *) &kdAsyncPixmapGCOps;
+ else
+ pGC->ops = (GCOps *) &s3_24GCOps;
+ fbValidateGC (pGC, changes, pDrawable);
+}
+
+GCFuncs s3_24GCFuncs = {
+ s3_24ValidateGC,
+ miChangeGC,
+ miCopyGC,
+ miDestroyGC,
+ miChangeClip,
+ miDestroyClip,
+ miCopyClip
+};
+
+Bool
+s3_24CreateGC (GCPtr pGC)
+{
+ if (!fbCreateGC (pGC))
+ return FALSE;
+
+ if (pGC->depth != 1)
+ pGC->funcs = &s3_24GCFuncs;
+
+ return TRUE;
+}
+
+Bool
+s3_24CreateWindow(WindowPtr pWin)
+{
+ return fbCreateWindow (pWin);
+}
+
+void
+s3_24PaintWindow(WindowPtr pWin, RegionPtr pRegion, int what)
+{
+ SetupS3(pWin->drawable.pScreen);
+ s3PatternPtr pPattern;
+
+ DRAW_DEBUG ((DEBUG_PAINT_WINDOW, "s3PaintWindow 0x%x extents %d %d %d %d n %d",
+ pWin->drawable.id,
+ pRegion->extents.x1, pRegion->extents.y1,
+ pRegion->extents.x2, pRegion->extents.y2,
+ REGION_NUM_RECTS(pRegion)));
+ if (!REGION_NUM_RECTS(pRegion))
+ return;
+ switch (what) {
+ case PW_BACKGROUND:
+ switch (pWin->backgroundState) {
+ case None:
+ return;
+ case ParentRelative:
+ do {
+ pWin = pWin->parent;
+ } while (pWin->backgroundState == ParentRelative);
+ (*pWin->drawable.pScreen->PaintWindowBackground)(pWin, pRegion,
+ what);
+ return;
+ case BackgroundPixel:
+ if (ok24(pWin->background.pixel))
+ {
+ s3_24FillBoxSolid((DrawablePtr)pWin,
+ (int)REGION_NUM_RECTS(pRegion),
+ REGION_RECTS(pRegion),
+ pWin->background.pixel, GXcopy, ~0);
+ return;
+ }
+ }
+ break;
+ case PW_BORDER:
+ if (pWin->borderIsPixel && ok24(pWin->border.pixel))
+ {
+ s3_24FillBoxSolid((DrawablePtr)pWin,
+ (int)REGION_NUM_RECTS(pRegion),
+ REGION_RECTS(pRegion),
+ pWin->border.pixel, GXcopy, ~0);
+ return;
+ }
+ break;
+ }
+ KdCheckPaintWindow (pWin, pRegion, what);
}
Bool
@@ -2319,25 +3049,20 @@ s3DrawInit (ScreenPtr pScreen)
int ncache_w, ncache_h, ncache;
int px, py;
S3PatternCache *cache;
+ Bool dumb = FALSE;
+ int ma;
- switch (pScreenPriv->screen->bitsPerPixel) {
+ switch (pScreenPriv->screen->fb[0].bitsPerPixel) {
case 8:
case 16:
case 32:
break;
+ case 24:
+ dumb = TRUE;
+ break;
default:
return FALSE;
}
- if (serverGeneration != s3Generation)
- {
- s3GCPrivateIndex = AllocateGCPrivateIndex ();
- s3WindowPrivateIndex = AllocateWindowPrivateIndex ();
- s3Generation = serverGeneration;
- }
- if (!AllocateWindowPrivate(pScreen, s3WindowPrivateIndex, 0))
- return FALSE;
- if (!AllocateGCPrivate(pScreen, s3GCPrivateIndex, sizeof (s3PrivGCRec)))
- return FALSE;
/*
* Hook up asynchronous drawing
*/
@@ -2345,38 +3070,75 @@ s3DrawInit (ScreenPtr pScreen)
/*
* Replace various fb screen functions
*/
- pScreen->CreateGC = s3CreateGC;
- pScreen->CreateWindow = s3CreateWindow;
- pScreen->ChangeWindowAttributes = s3ChangeWindowAttributes;
- pScreen->DestroyWindow = s3DestroyWindow;
- pScreen->PaintWindowBackground = s3PaintWindow;
- pScreen->PaintWindowBorder = s3PaintWindow;
- pScreen->CopyWindow = s3CopyWindow;
-
- /*
- * Initialize patterns
- */
- ncache_w = s3s->offscreen_width / S3_TILE_SIZE;
- ncache_h = s3s->offscreen_height / S3_TILE_SIZE;
- ncache = ncache_w * ncache_h;
- DRAW_DEBUG ((DEBUG_S3INIT, "ncache_w %d ncache_h %d ncache %d",
- ncache_w, ncache_h, ncache));
- s3s->patterns.cache = (S3PatternCache *) xalloc (ncache * sizeof (S3PatternCache));
- if (s3s->patterns.cache)
- {
- DRAW_DEBUG ((DEBUG_S3INIT, "Have pattern cache"));
- s3s->patterns.ncache = ncache;
- s3s->patterns.last_used = 0;
- s3s->patterns.last_id = 0;
- cache = s3s->patterns.cache;
- for (py = 0; py < ncache_h; py++)
- for (px = 0; px < ncache_w; px++)
+ if (dumb)
+ {
+ pScreen->CreateGC = s3_24CreateGC;
+ pScreen->CreateWindow = s3_24CreateWindow;
+ pScreen->PaintWindowBackground = s3_24PaintWindow;
+ pScreen->PaintWindowBorder = s3_24PaintWindow;
+ pScreen->CopyWindow = s3CopyWindow;
+ }
+ else
+ {
+ if (serverGeneration != s3Generation)
+ {
+ s3GCPrivateIndex = AllocateGCPrivateIndex ();
+ s3WindowPrivateIndex = AllocateWindowPrivateIndex ();
+ s3Generation = serverGeneration;
+ }
+ if (!AllocateWindowPrivate(pScreen, s3WindowPrivateIndex, 0))
+ return FALSE;
+ if (!AllocateGCPrivate(pScreen, s3GCPrivateIndex, sizeof (s3PrivGCRec)))
+ return FALSE;
+ pScreen->CreateGC = s3CreateGC;
+ pScreen->CreateWindow = s3CreateWindow;
+ pScreen->ChangeWindowAttributes = s3ChangeWindowAttributes;
+ pScreen->DestroyWindow = s3DestroyWindow;
+ pScreen->PaintWindowBackground = s3PaintWindow;
+ pScreen->PaintWindowBorder = s3PaintWindow;
+ pScreen->CopyWindow = s3CopyWindow;
+ pScreen->BackingStoreFuncs.RestoreAreas = s3RestoreAreas;
+#if 0
+ pScreen->PaintWindowBackground = s3DumbPaintWindow;
+ pScreen->PaintWindowBorder = s3DumbPaintWindow;
+ pScreen->CopyWindow = s3DumbCopyWindow;
+#endif
+
+ /*
+ * Initialize patterns
+ */
+#ifdef S3_TRIO
+ ma = 0;
+#else
+ for (ma = 0; s3s->fbmap[ma] >= 0; ma++)
+#endif
+ {
+ ncache_w = s3s->fb[ma].offscreen_width / S3_TILE_SIZE;
+ ncache_h = s3s->fb[ma].offscreen_height / S3_TILE_SIZE;
+ ncache = ncache_w * ncache_h;
+ if (ncache > 64)
+ ncache = 64;
+ DRAW_DEBUG ((DEBUG_S3INIT, "ncache_w %d ncache_h %d ncache %d",
+ ncache_w, ncache_h, ncache));
+ s3s->fb[ma].patterns.cache = (S3PatternCache *) xalloc (ncache * sizeof (S3PatternCache));
+ if (s3s->fb[ma].patterns.cache)
{
- cache->id = 0;
- cache->x = s3s->offscreen_x + px * S3_TILE_SIZE;
- cache->y = s3s->offscreen_y + py * S3_TILE_SIZE;
- cache++;
+ DRAW_DEBUG ((DEBUG_S3INIT, "Have pattern cache"));
+ s3s->fb[ma].patterns.ncache = ncache;
+ s3s->fb[ma].patterns.last_used = 0;
+ s3s->fb[ma].patterns.last_id = 0;
+ cache = s3s->fb[ma].patterns.cache;
+ for (py = 0; py < ncache_h && ncache; py++)
+ for (px = 0; px < ncache_w && ncache; px++)
+ {
+ cache->id = 0;
+ cache->x = s3s->fb[ma].offscreen_x + px * S3_TILE_SIZE;
+ cache->y = s3s->fb[ma].offscreen_y + py * S3_TILE_SIZE;
+ cache++;
+ ncache--;
+ }
}
+ }
}
return TRUE;
}
@@ -2387,18 +3149,37 @@ s3DrawEnable (ScreenPtr pScreen)
SetupS3(pScreen);
s3ScreenInfo(pScreenPriv);
int c;
+ int ma;
- /*
- * Flush pattern cache
- */
- for (c = 0; c < s3s->patterns.ncache; c++)
- s3s->patterns.cache[c].id = 0;
-
+ s3SetGlobalBitmap (pScreen, 0);
_s3WaitIdleEmpty (s3);
- _s3SetScissorsTl(s3, 0, 0);
- _s3SetScissorsBr(s3, pScreenPriv->screen->width - 1, pScreenPriv->screen->height - 1);
- _s3SetSolidFill(s3, pScreen->blackPixel, GXcopy, ~0);
- _s3SolidRect (s3, 0, 0, pScreenPriv->screen->width, pScreenPriv->screen->height);
+ if (pScreenPriv->screen->fb[0].bitsPerPixel == 24)
+ {
+ _s3SetScissorsTl(s3, 0, 0);
+ _s3SetScissorsBr(s3, pScreenPriv->screen->width*3 - 1, pScreenPriv->screen->height - 1);
+ _s3SetSolidFill(s3, pScreen->whitePixel, GXcopy, ~0);
+ _s3SolidRect (s3, 0, 0, pScreenPriv->screen->width*3, pScreenPriv->screen->height);
+ }
+ else
+ {
+ /*
+ * Flush pattern cache
+ */
+#ifdef S3_TRIO
+ ma = 0;
+#else
+ for (ma = 0; s3s->fbmap[ma] >= 0; ma++)
+#endif
+ {
+ for (c = 0; c < s3s->fb[ma].patterns.ncache; c++)
+ s3s->fb[ma].patterns.cache[c].id = 0;
+ }
+
+ _s3SetScissorsTl(s3, 0, 0);
+ _s3SetScissorsBr(s3, pScreenPriv->screen->width - 1, pScreenPriv->screen->height - 1);
+ _s3SetSolidFill(s3, pScreen->blackPixel, GXcopy, ~0);
+ _s3SolidRect (s3, 0, 0, pScreenPriv->screen->width, pScreenPriv->screen->height);
+ }
MarkSyncS3 (pScreen);
}
@@ -2414,12 +3195,20 @@ s3DrawFini (ScreenPtr pScreen)
{
SetupS3(pScreen);
s3ScreenInfo(pScreenPriv);
+ int ma;
- if (s3s->patterns.cache)
+#ifdef S3_TRIO
+ ma = 0;
+#else
+ for (ma = 0; s3s->fbmap[ma] >= 0; ma++)
+#endif
{
- xfree (s3s->patterns.cache);
- s3s->patterns.cache = 0;
- s3s->patterns.ncache = 0;
+ if (s3s->fb[ma].patterns.cache)
+ {
+ xfree (s3s->fb[ma].patterns.cache);
+ s3s->fb[ma].patterns.cache = 0;
+ s3s->fb[ma].patterns.ncache = 0;
+ }
}
}
diff --git a/hw/kdrive/savage/s3draw.h b/hw/kdrive/savage/s3draw.h
index f5b66e094..81bbad413 100644
--- a/hw/kdrive/savage/s3draw.h
+++ b/hw/kdrive/savage/s3draw.h
@@ -22,7 +22,7 @@
*
* Author: Keith Packard, SuSE, Inc.
*/
-/* $XFree86: xc/programs/Xserver/hw/kdrive/savage/s3draw.h,v 1.2 1999/12/30 03:03:12 robin Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/kdrive/savage/s3draw.h,v 1.3 2000/02/23 20:30:04 dawes Exp $ */
#ifndef _S3DRAW_H_
#define _S3DRAW_H_
@@ -41,6 +41,7 @@ typedef struct _s3Pattern {
typedef struct _s3PrivGC {
int type; /* type of drawable validated against */
+ int ma; /* stream descriptor */
s3PatternPtr pPattern; /* pattern */
} s3PrivGCRec, *s3PrivGCPtr;
@@ -55,8 +56,7 @@ typedef struct _s3PrivGC {
#define s3SetWindowPrivate(w,p) (\
(w)->devPrivates[s3WindowPrivateIndex].ptr = (pointer) p)
-
-void _s3LoadPattern (ScreenPtr pScreen, s3PatternPtr pPattern);
+void _s3LoadPattern (ScreenPtr pScreen, int fb, s3PatternPtr pPattern);
#define SetupS3(s) KdScreenPriv(s); \
s3CardInfo(pScreenPriv); \
@@ -82,6 +82,18 @@ void _s3LoadPattern (ScreenPtr pScreen, s3PatternPtr pPattern);
#define WIDEN(x) ((unsigned long) (x))
#define MERGE(a,b) ((WIDEN(a) << 16) | WIDEN(b))
+#define s3BitmapDescriptor(_stream) ((_stream) + 1)
+
+#ifdef S3_TRIO
+#define s3DrawMap(pDraw) 0
+#define s3SetGlobalBitmap(s,d)
+#else
+#define s3DrawMap(pDraw) ((pDraw)->depth == \
+ getS3ScreenInfo(pScreenPriv)->primary_depth ? 0 : 1)
+#endif
+
+#define s3GCMap(pGC) (s3GetGCPrivate(pGC)->ma)
+
/*
* Ok, so the S3 is broken -- it expects bitmaps to come MSB bit order,
* but it's willing to take them in LSB byte order. These macros
diff --git a/hw/kdrive/savage/s3reg.c b/hw/kdrive/savage/s3reg.c
index 0fac18b12..b2cb7a377 100644
--- a/hw/kdrive/savage/s3reg.c
+++ b/hw/kdrive/savage/s3reg.c
@@ -22,7 +22,7 @@
*
* Author: Keith Packard, SuSE, Inc.
*/
-/* $XFree86: xc/programs/Xserver/hw/kdrive/savage/s3reg.c,v 1.2 1999/12/30 03:03:12 robin Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/kdrive/savage/s3reg.c,v 1.3 2000/02/23 20:30:04 dawes Exp $ */
#include "s3reg.h"
@@ -403,6 +403,11 @@ VgaReg s3_line_compare[] = {
VGA_REG_END
};
+VgaReg s3_delay_primary_load[] = {
+ CR21, 1, 1,
+ VGA_REG_END
+};
+
VgaReg s3_device_id[] = {
CR2E, 0, 8,
CR2D, 0, 8,
@@ -654,16 +659,36 @@ VgaReg s3_pci_disconnect_enable[] = {
VGA_REG_END
};
+VgaReg s3_primary_load_control[] = {
+ CR66, 4, 1,
+ VGA_REG_END
+};
+
+VgaReg s3_secondary_load_control[] = {
+ CR66, 5, 1,
+ VGA_REG_END
+};
+
VgaReg s3_pci_retry_enable[] = {
CR66, 7, 1,
VGA_REG_END
};
+VgaReg s3_streams_mode[] = {
+ CR67, 2, 2,
+ VGA_REG_END
+};
+
VgaReg s3_color_mode[] = {
CR67, 4, 4,
VGA_REG_END
};
+VgaReg s3_primary_stream_definition[] = {
+ CR69, 7, 1,
+ VGA_REG_END
+};
+
VgaReg s3_primary_stream_timeout[] = {
CR71, 0, 8,
VGA_REG_END
@@ -714,6 +739,26 @@ VgaReg s3_dac_power_saving_disable[] = {
VGA_REG_END
};
+VgaReg s3_flat_panel_output_control_1[] = {
+ CR90, 3, 1,
+ VGA_REG_END
+};
+
+VgaReg s3_streams_fifo_delay[] = {
+ CR90, 4, 2,
+ VGA_REG_END
+};
+
+VgaReg s3_flat_panel_output_control_2[] = {
+ CR90, 6, 1,
+ VGA_REG_END
+};
+
+VgaReg s3_enable_l1_parameter[] = {
+ CR90, 7, 1,
+ VGA_REG_END
+};
+
VgaReg s3_primary_stream_l1[] = {
CR91, 0, 8,
CR90, 0, 3,
@@ -975,6 +1020,21 @@ VgaReg s3_dclk_control[] = {
VGA_REG_END
};
+VgaReg s3_eclk_n[] = {
+ SR32, 0, 5,
+ VGA_REG_END
+};
+
+VgaReg s3_eclk_r[] = {
+ SR32, 5, 2,
+ VGA_REG_END
+};
+
+VgaReg s3_eclk_m[] = {
+ SR32, 0, 5,
+ VGA_REG_END
+};
+
VgaReg s3_vga_dclk_n[] = {
SR36, 0, 6,
SR39, 4, 1,
diff --git a/hw/kdrive/savage/s3reg.h b/hw/kdrive/savage/s3reg.h
index 88a4c3c07..aec76e8b3 100644
--- a/hw/kdrive/savage/s3reg.h
+++ b/hw/kdrive/savage/s3reg.h
@@ -22,7 +22,7 @@
*
* Author: Keith Packard, SuSE, Inc.
*/
-/* $XFree86: xc/programs/Xserver/hw/kdrive/savage/s3reg.h,v 1.2 1999/12/30 03:03:12 robin Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/kdrive/savage/s3reg.h,v 1.3 2000/02/23 20:30:05 dawes Exp $ */
#ifndef _S3REG_H_
#define _S3REG_H_
@@ -74,6 +74,7 @@ extern VgaReg s3_word_mode[];
extern VgaReg s3_byte_mode[];
extern VgaReg s3_hardware_reset[];
extern VgaReg s3_line_compare[];
+extern VgaReg s3_delay_primary_load[];
extern VgaReg s3_device_id[];
extern VgaReg s3_revision[];
extern VgaReg s3_enable_vga_16bit[];
@@ -123,8 +124,12 @@ extern VgaReg s3_delay_blank[];
extern VgaReg s3_delay_h_enable[];
extern VgaReg s3_enable_2d_3d[];
extern VgaReg s3_pci_disconnect_enable[];
+extern VgaReg s3_primary_load_control[];
+extern VgaReg s3_secondary_load_control[];
extern VgaReg s3_pci_retry_enable[];
+extern VgaReg s3_streams_mode[];
extern VgaReg s3_color_mode[];
+extern VgaReg s3_primary_stream_definition[];
extern VgaReg s3_primary_stream_timeout[];
extern VgaReg s3_master_control_unit_timeout[];
extern VgaReg s3_command_buffer_timeout[];
@@ -135,6 +140,10 @@ extern VgaReg s3_fifo_drain_delay[];
extern VgaReg s3_fifo_fetch_timing[];
extern VgaReg s3_dac_power_up_time[];
extern VgaReg s3_dac_power_saving_disable[];
+extern VgaReg s3_flat_panel_output_control_1[];
+extern VgaReg s3_streams_fifo_delay[];
+extern VgaReg s3_flat_panel_output_control_2[];
+extern VgaReg s3_enable_l1_parameter[];
extern VgaReg s3_primary_stream_l1[];
extern VgaReg s3_dot_clock_8[];
@@ -165,6 +174,9 @@ extern VgaReg s3_dclk_double_15_16_invert[];
extern VgaReg s3_enable_gamma_correction[];
extern VgaReg s3_enable_8_bit_luts[];
extern VgaReg s3_dclk_control[];
+extern VgaReg s3_eclk_n[];
+extern VgaReg s3_eclk_r[];
+extern VgaReg s3_eclk_m[];
extern VgaReg s3_vga_dclk_n[];
extern VgaReg s3_vga_dclk_r[];
extern VgaReg s3_vga_dclk_m1[];
diff --git a/hw/kdrive/sis530/sis.c b/hw/kdrive/sis530/sis.c
index b889cc738..d0aa0a0bd 100644
--- a/hw/kdrive/sis530/sis.c
+++ b/hw/kdrive/sis530/sis.c
@@ -253,30 +253,30 @@ sisScreenInit (KdScreenInfo *screen)
screen->height = 600;
screen->rate = 72;
}
- if (!screen->depth)
- screen->depth = 8;
+ if (!screen->fb[0].depth)
+ screen->fb[0].depth = 8;
for (;;)
{
- if (screen->depth >= 24)
+ if (screen->fb[0].depth >= 24)
{
- screen->depth = 24;
- screen->bitsPerPixel = 24;
+ screen->fb[0].depth = 24;
+ screen->fb[0].bitsPerPixel = 24;
}
- else if (screen->depth >= 16)
+ else if (screen->fb[0].depth >= 16)
{
- screen->depth = 16;
- screen->bitsPerPixel = 16;
+ screen->fb[0].depth = 16;
+ screen->fb[0].bitsPerPixel = 16;
}
- else if (screen->depth >= 15)
+ else if (screen->fb[0].depth >= 15)
{
- screen->depth = 15;
- screen->bitsPerPixel = 16;
+ screen->fb[0].depth = 15;
+ screen->fb[0].bitsPerPixel = 16;
}
else
{
- screen->depth = 8;
- screen->bitsPerPixel = 8;
+ screen->fb[0].depth = 8;
+ screen->fb[0].bitsPerPixel = 8;
}
/* Normalize width to supported values */
@@ -294,10 +294,10 @@ sisScreenInit (KdScreenInfo *screen)
else
screen->width = 640;
- byte_width = screen->width * (screen->bitsPerPixel >> 3);
+ byte_width = screen->width * (screen->fb[0].bitsPerPixel >> 3);
pixel_width = screen->width;
- screen->pixelStride = pixel_width;
- screen->byteStride = byte_width;
+ screen->fb[0].pixelStride = pixel_width;
+ screen->fb[0].byteStride = byte_width;
screen_size = byte_width * screen->height;
@@ -307,10 +307,10 @@ sisScreenInit (KdScreenInfo *screen)
/*
* Fix requested depth and geometry until it works
*/
- if (screen->depth > 16)
- screen->depth = 16;
- else if (screen->depth > 8)
- screen->depth = 8;
+ if (screen->fb[0].depth > 16)
+ screen->fb[0].depth = 16;
+ else if (screen->fb[0].depth > 8)
+ screen->fb[0].depth = 8;
else if (screen->width > 1152)
{
screen->width = 1152;
@@ -346,30 +346,30 @@ sisScreenInit (KdScreenInfo *screen)
/*
* Take requested geometry and adjust to fit possible geometries
*/
- switch (screen->depth) {
+ switch (screen->fb[0].depth) {
case 4:
- screen->bitsPerPixel = 4;
+ screen->fb[0].bitsPerPixel = 4;
break;
case 8:
- screen->bitsPerPixel = 8;
+ screen->fb[0].bitsPerPixel = 8;
break;
case 15:
case 16:
- screen->bitsPerPixel = 16;
+ screen->fb[0].bitsPerPixel = 16;
break;
case 24:
case 32:
- screen->bitsPerPixel = 24;
+ screen->fb[0].bitsPerPixel = 24;
screen->dumb = TRUE;
break;
}
- screen->byteStride = screen->width * (screen->bitsPerPixel >> 3);
- screen->pixelStride = screen->width;
+ screen->fb[0].byteStride = screen->width * (screen->fb[0].bitsPerPixel >> 3);
+ screen->fb[0].pixelStride = screen->width;
memory = sisc->memory - screen_size;
- screen->frameBuffer = sisc->frameBuffer;
+ screen->fb[0].frameBuffer = sisc->frameBuffer;
/*
* Cursor lives in the last 16k of memory
@@ -389,7 +389,7 @@ sisScreenInit (KdScreenInfo *screen)
if (memory > 8192)
{
- siss->expand = screen->frameBuffer + screen_size;
+ siss->expand = screen->fb[0].frameBuffer + screen_size;
siss->expand_off = siss->expand - sisc->frameBuffer;
siss->expand_len = memory;
memory = 0;
@@ -400,35 +400,35 @@ sisScreenInit (KdScreenInfo *screen)
siss->expand_len = 0;
}
- switch (screen->depth) {
+ switch (screen->fb[0].depth) {
case 8:
- screen->visuals = ((1 << StaticGray) |
+ screen->fb[0].visuals = ((1 << StaticGray) |
(1 << GrayScale) |
(1 << StaticColor) |
(1 << PseudoColor) |
(1 << TrueColor) |
(1 << DirectColor));
- screen->blueMask = 0x00;
- screen->greenMask = 0x00;
- screen->redMask = 0x00;
+ screen->fb[0].blueMask = 0x00;
+ screen->fb[0].greenMask = 0x00;
+ screen->fb[0].redMask = 0x00;
break;
case 15:
- screen->visuals = (1 << TrueColor);
- screen->blueMask = 0x001f;
- screen->greenMask = 0x03e0;
- screen->redMask = 0x7c00;
+ screen->fb[0].visuals = (1 << TrueColor);
+ screen->fb[0].blueMask = 0x001f;
+ screen->fb[0].greenMask = 0x03e0;
+ screen->fb[0].redMask = 0x7c00;
break;
case 16:
- screen->visuals = (1 << TrueColor);
- screen->blueMask = 0x001f;
- screen->greenMask = 0x07e0;
- screen->redMask = 0xf800;
+ screen->fb[0].visuals = (1 << TrueColor);
+ screen->fb[0].blueMask = 0x001f;
+ screen->fb[0].greenMask = 0x07e0;
+ screen->fb[0].redMask = 0xf800;
break;
case 24:
- screen->visuals = (1 << TrueColor);
- screen->blueMask = 0x0000ff;
- screen->greenMask = 0x00ff00;
- screen->redMask = 0xff0000;
+ screen->fb[0].visuals = (1 << TrueColor);
+ screen->fb[0].blueMask = 0x0000ff;
+ screen->fb[0].greenMask = 0x00ff00;
+ screen->fb[0].redMask = 0xff0000;
break;
}
@@ -752,7 +752,7 @@ sisEnable (ScreenPtr pScreen)
pixel = (hactive + hblank) * (vactive + vblank) * t->rate;
- switch (screen->bitsPerPixel) {
+ switch (screen->fb[0].bitsPerPixel) {
case 8:
hactive /= 8;
hblank /= 8;
@@ -775,7 +775,7 @@ sisEnable (ScreenPtr pScreen)
crtc.color_mode_256 = 0;
- if (screen->depth == 15)
+ if (screen->fb[0].depth == 15)
crtc.graphics_mode_32k = 1;
else
crtc.graphics_mode_64k = 1;
@@ -826,7 +826,7 @@ sisEnable (ScreenPtr pScreen)
crtc.high_speed_dac_0 = crtc.high_speed_dac_1 = pixel > 135000000;
- sisEngThresh (&crtc, pixel, screen->bitsPerPixel);
+ sisEngThresh (&crtc, pixel, screen->fb[0].bitsPerPixel);
/*
* Compute horizontal register values from timings
diff --git a/hw/kdrive/sis530/sis.h b/hw/kdrive/sis530/sis.h
index 9ffc9d197..f4d7e750c 100644
--- a/hw/kdrive/sis530/sis.h
+++ b/hw/kdrive/sis530/sis.h
@@ -1102,8 +1102,8 @@ void sisDrawSync (ScreenPtr pScreen);
void sisDrawDisable (ScreenPtr pScreen);
void sisDrawFini (ScreenPtr pScreen);
-void sisGetColors (ScreenPtr pScreen, int ndef, xColorItem *pdefs);
-void sisPutColors (ScreenPtr pScreen, int ndef, xColorItem *pdefs);
+void sisGetColors (ScreenPtr pScreen, int fb, int ndef, xColorItem *pdefs);
+void sisPutColors (ScreenPtr pScreen, int fb, int ndef, xColorItem *pdefs);
void SISInitCard (KdCardAttr *attr);
diff --git a/hw/kdrive/sis530/siscmap.c b/hw/kdrive/sis530/siscmap.c
index a8b504135..28b218273 100644
--- a/hw/kdrive/sis530/siscmap.c
+++ b/hw/kdrive/sis530/siscmap.c
@@ -26,7 +26,7 @@
#include "sis.h"
void
-sisGetColors (ScreenPtr pScreen, int ndef, xColorItem *pdefs)
+sisGetColors (ScreenPtr pScreen, int fb, int ndef, xColorItem *pdefs)
{
KdScreenPriv(pScreen);
sisCardInfo(pScreenPriv);
@@ -44,7 +44,7 @@ sisGetColors (ScreenPtr pScreen, int ndef, xColorItem *pdefs)
}
void
-sisPutColors (ScreenPtr pScreen, int ndef, xColorItem *pdefs)
+sisPutColors (ScreenPtr pScreen, int fb, int ndef, xColorItem *pdefs)
{
KdScreenPriv(pScreen);
sisCardInfo(pScreenPriv);
diff --git a/hw/kdrive/sis530/sisdraw.c b/hw/kdrive/sis530/sisdraw.c
index a21f43d52..2461d3c4b 100644
--- a/hw/kdrive/sis530/sisdraw.c
+++ b/hw/kdrive/sis530/sisdraw.c
@@ -1636,8 +1636,8 @@ sisDrawEnable (ScreenPtr pScreen)
CARD32 base;
CARD16 stride;
- base = pScreenPriv->screen->frameBuffer - sisc->frameBuffer;
- stride = pScreenPriv->screen->byteStride;
+ base = pScreenPriv->screen->fb[0].frameBuffer - sisc->frameBuffer;
+ stride = pScreenPriv->screen->fb[0].byteStride;
sis->u.general.dst_base = base;
sis->u.general.dst_pitch = stride;
sis->u.general.dst_height = pScreenPriv->screen->height;
diff --git a/hw/kdrive/src/kcmap.c b/hw/kdrive/src/kcmap.c
index 669aca42f..76d2f1f53 100644
--- a/hw/kdrive/src/kcmap.c
+++ b/hw/kdrive/src/kcmap.c
@@ -21,7 +21,7 @@
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $XFree86: xc/programs/Xserver/hw/kdrive/kcmap.c,v 1.1 1999/11/19 13:53:48 hohndel Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/kdrive/kcmap.c,v 1.2 2000/02/23 20:29:52 dawes Exp $ */
#include "kdrive.h"
@@ -30,10 +30,10 @@
*/
void
-KdSetColormap (ScreenPtr pScreen)
+KdSetColormap (ScreenPtr pScreen, int fb)
{
KdScreenPriv(pScreen);
- ColormapPtr pCmap = pScreenPriv->pInstalledmap;
+ ColormapPtr pCmap = pScreenPriv->pInstalledmap[fb];
Pixel pixels[KD_MAX_PSEUDO_SIZE];
xrgb colors[KD_MAX_PSEUDO_SIZE];
xColorItem defs[KD_MAX_PSEUDO_SIZE];
@@ -41,7 +41,7 @@ KdSetColormap (ScreenPtr pScreen)
if (!pScreenPriv->card->cfuncs->putColors)
return;
- if (pScreenPriv->screen->depth > KD_MAX_PSEUDO_DEPTH)
+ if (pScreenPriv->screen->fb[fb].depth > KD_MAX_PSEUDO_DEPTH)
return;
if (!pScreenPriv->enabled)
@@ -55,12 +55,12 @@ KdSetColormap (ScreenPtr pScreen)
* true/direct as well as pseudo/static visuals
*/
- for (i = 0; i < (1 << pScreenPriv->screen->depth); i++)
+ for (i = 0; i < (1 << pScreenPriv->screen->fb[i].depth); i++)
pixels[i] = i;
- QueryColors (pCmap, (1 << pScreenPriv->screen->depth), pixels, colors);
+ QueryColors (pCmap, (1 << pScreenPriv->screen->fb[i].depth), pixels, colors);
- for (i = 0; i < (1 << pScreenPriv->screen->depth); i++)
+ for (i = 0; i < (1 << pScreenPriv->screen->fb[i].depth); i++)
{
defs[i].pixel = i;
defs[i].red = colors[i].red;
@@ -69,9 +69,9 @@ KdSetColormap (ScreenPtr pScreen)
defs[i].flags = DoRed|DoGreen|DoBlue;
}
- (*pScreenPriv->card->cfuncs->putColors) (pCmap->pScreen,
- (1 << pScreenPriv->screen->depth),
- defs);
+ (*pScreenPriv->card->cfuncs->putColors) (pCmap->pScreen, fb,
+ (1 << pScreenPriv->screen->fb[i].depth),
+ defs);
/* recolor hardware cursor */
if (pScreenPriv->card->cfuncs->recolorCursor)
@@ -87,33 +87,78 @@ KdEnableColormap (ScreenPtr pScreen)
{
KdScreenPriv(pScreen);
int i;
+ int fb;
+ Bool done = FALSE;
if (!pScreenPriv->card->cfuncs->putColors)
return;
- if (pScreenPriv->screen->depth <= KD_MAX_PSEUDO_DEPTH)
+ for (fb = 0; fb < KD_MAX_FB && pScreenPriv->screen->fb[fb].depth; fb++)
{
- for (i = 0; i < (1 << pScreenPriv->screen->depth); i++)
- pScreenPriv->systemPalette[i].pixel = i;
- (*pScreenPriv->card->cfuncs->getColors) (pScreen,
- (1 << pScreenPriv->screen->depth),
- pScreenPriv->systemPalette);
+ if (pScreenPriv->screen->fb[fb].depth <= KD_MAX_PSEUDO_DEPTH && !done)
+ {
+ for (i = 0; i < (1 << pScreenPriv->screen->fb[fb].depth); i++)
+ pScreenPriv->systemPalette[i].pixel = i;
+ (*pScreenPriv->card->cfuncs->getColors) (pScreen, fb,
+ (1 << pScreenPriv->screen->fb[fb].depth),
+ pScreenPriv->systemPalette);
+ done = TRUE;
+ }
+ KdSetColormap (pScreen, fb);
}
- KdSetColormap (pScreen);
}
void
KdDisableColormap (ScreenPtr pScreen)
{
KdScreenPriv(pScreen);
+ int fb;
if (!pScreenPriv->card->cfuncs->putColors)
return;
- if (pScreenPriv->screen->depth > KD_MAX_PSEUDO_DEPTH)
- return;
-
- (*pScreenPriv->card->cfuncs->putColors) (pScreen,
- (1 << pScreenPriv->screen->depth),
- pScreenPriv->systemPalette);
+ for (fb = 0; fb < KD_MAX_FB && pScreenPriv->screen->fb[fb].depth; fb++)
+ {
+ if (pScreenPriv->screen->fb[fb].depth <= KD_MAX_PSEUDO_DEPTH)
+ {
+ (*pScreenPriv->card->cfuncs->putColors) (pScreen, fb,
+ (1 << pScreenPriv->screen->fb[fb].depth),
+ pScreenPriv->systemPalette);
+ break;
+ }
+ }
+}
+
+int
+KdColormapFb (ColormapPtr pCmap)
+{
+ ScreenPtr pScreen = pCmap->pScreen;
+ KdScreenPriv (pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ int d;
+ DepthPtr depth;
+ int v, vi;
+ VisualPtr visual;
+ VisualID vid = pCmap->pVisual->vid;
+ int fb;
+
+ if (screen->fb[1].depth)
+ {
+ for (d = 0; d < pScreen->numDepths; d++)
+ {
+ depth = &pScreen->allowedDepths[d];
+ for (v = 0; v < depth->numVids; v++)
+ {
+ if (depth->vids[v] == vid)
+ {
+ for (fb = 0; fb < KD_MAX_FB && screen->fb[fb].depth; fb++)
+ {
+ if (depth->depth == screen->fb[fb].depth)
+ return fb;
+ }
+ }
+ }
+ }
+ }
+ return 0;
}
/*
@@ -129,19 +174,20 @@ void
KdInstallColormap (ColormapPtr pCmap)
{
KdScreenPriv(pCmap->pScreen);
+ int fb = KdColormapFb (pCmap);
- if (pCmap == pScreenPriv->pInstalledmap)
+ if (pCmap == pScreenPriv->pInstalledmap[fb])
return;
/* Tell X clients that the installed colormap is going away. */
- if (pScreenPriv->pInstalledmap)
- WalkTree(pScreenPriv->pInstalledmap->pScreen, TellLostMap,
- (pointer) &(pScreenPriv->pInstalledmap->mid));
+ if (pScreenPriv->pInstalledmap[fb])
+ WalkTree(pScreenPriv->pInstalledmap[fb]->pScreen, TellLostMap,
+ (pointer) &(pScreenPriv->pInstalledmap[fb]->mid));
/* Take note of the new installed colorscreen-> */
- pScreenPriv->pInstalledmap = pCmap;
+ pScreenPriv->pInstalledmap[fb] = pCmap;
- KdSetColormap (pCmap->pScreen);
+ KdSetColormap (pCmap->pScreen, fb);
/* Tell X clients of the new colorscreen-> */
WalkTree(pCmap->pScreen, TellGainedMap, (pointer) &(pCmap->mid));
@@ -157,8 +203,9 @@ void
KdUninstallColormap (ColormapPtr pCmap)
{
KdScreenPriv(pCmap->pScreen);
+ int fb = KdColormapFb (pCmap);
- if (pCmap == pScreenPriv->pInstalledmap)
+ if (pCmap == pScreenPriv->pInstalledmap[0])
{
Colormap defMapID = pCmap->pScreen->defColormap;
@@ -176,13 +223,18 @@ int
KdListInstalledColormaps (ScreenPtr pScreen, Colormap *pCmaps)
{
KdScreenPriv(pScreen);
+ int fb;
+ int n = 0;
- if (pScreenPriv->pInstalledmap)
+ for (fb = 0; fb < KD_MAX_FB && pScreenPriv->screen->fb[fb].depth; fb++)
{
- *pCmaps = pScreenPriv->pInstalledmap->mid;
- return 1;
+ if (pScreenPriv->pInstalledmap[fb])
+ {
+ *pCmaps++ = pScreenPriv->pInstalledmap[fb]->mid;
+ n++;
+ }
}
- return 0;
+ return n;
}
/*
@@ -198,14 +250,15 @@ KdStoreColors (ColormapPtr pCmap, int ndef, xColorItem *pdefs)
KdScreenPriv(pCmap->pScreen);
VisualPtr pVisual;
xColorItem expanddefs[KD_MAX_PSEUDO_SIZE];
+ int fb = KdColormapFb (pCmap);
- if (pCmap != pScreenPriv->pInstalledmap)
+ if (pCmap != pScreenPriv->pInstalledmap[fb])
return;
if (!pScreenPriv->card->cfuncs->putColors)
return;
- if (pScreenPriv->screen->depth > KD_MAX_PSEUDO_DEPTH)
+ if (pScreenPriv->screen->fb[fb].depth > KD_MAX_PSEUDO_DEPTH)
return;
if (!pScreenPriv->enabled)
@@ -223,7 +276,7 @@ KdStoreColors (ColormapPtr pCmap, int ndef, xColorItem *pdefs)
pdefs = expanddefs;
}
- (*pScreenPriv->card->cfuncs->putColors) (pCmap->pScreen, ndef, pdefs);
+ (*pScreenPriv->card->cfuncs->putColors) (pCmap->pScreen, fb, ndef, pdefs);
/* recolor hardware cursor */
if (pScreenPriv->card->cfuncs->recolorCursor)
diff --git a/hw/kdrive/src/kcurscol.c b/hw/kdrive/src/kcurscol.c
index 3327e9044..1e6e09b10 100644
--- a/hw/kdrive/src/kcurscol.c
+++ b/hw/kdrive/src/kcurscol.c
@@ -45,6 +45,7 @@ KdComputeCmapShift (unsigned long mask)
void
KdAllocateCursorPixels (ScreenPtr pScreen,
+ int fb,
CursorPtr pCursor,
Pixel *source,
Pixel *mask)
@@ -53,18 +54,18 @@ KdAllocateCursorPixels (ScreenPtr pScreen,
int r, g, b;
KdScreenPriv(pScreen);
- if (pScreenPriv->screen->redMask)
+ if (pScreenPriv->screen->fb[fb].redMask)
{
- r = KdComputeCmapShift (pScreenPriv->screen->redMask);
- g = KdComputeCmapShift (pScreenPriv->screen->greenMask);
- b = KdComputeCmapShift (pScreenPriv->screen->blueMask);
- *source = ((Shift(pCursor->foreRed,r) & pScreenPriv->screen->redMask) |
- (Shift(pCursor->foreGreen,g) & pScreenPriv->screen->greenMask) |
- (Shift(pCursor->foreBlue,b) & pScreenPriv->screen->blueMask));
- *mask = ((Shift(pCursor->backRed,r) & pScreenPriv->screen->redMask) |
- (Shift(pCursor->backGreen,g) & pScreenPriv->screen->greenMask) |
- (Shift(pCursor->backBlue,b) & pScreenPriv->screen->blueMask));
+ r = KdComputeCmapShift (pScreenPriv->screen->fb[fb].redMask);
+ g = KdComputeCmapShift (pScreenPriv->screen->fb[fb].greenMask);
+ b = KdComputeCmapShift (pScreenPriv->screen->fb[fb].blueMask);
+ *source = ((Shift(pCursor->foreRed,r) & pScreenPriv->screen->fb[fb].redMask) |
+ (Shift(pCursor->foreGreen,g) & pScreenPriv->screen->fb[fb].greenMask) |
+ (Shift(pCursor->foreBlue,b) & pScreenPriv->screen->fb[fb].blueMask));
+ *mask = ((Shift(pCursor->backRed,r) & pScreenPriv->screen->fb[fb].redMask) |
+ (Shift(pCursor->backGreen,g) & pScreenPriv->screen->fb[fb].greenMask) |
+ (Shift(pCursor->backBlue,b) & pScreenPriv->screen->fb[fb].blueMask));
}
else
{
@@ -79,13 +80,13 @@ KdAllocateCursorPixels (ScreenPtr pScreen,
sourceColor.red = pCursor->foreRed;
sourceColor.green = pCursor->foreGreen;
sourceColor.blue = pCursor->foreBlue;
- FakeAllocColor(pScreenPriv->pInstalledmap, &sourceColor);
+ FakeAllocColor(pScreenPriv->pInstalledmap[fb], &sourceColor);
maskColor.red = pCursor->backRed;
maskColor.green = pCursor->backGreen;
maskColor.blue = pCursor->backBlue;
- FakeAllocColor(pScreenPriv->pInstalledmap, &maskColor);
- FakeFreeColor(pScreenPriv->pInstalledmap, sourceColor.pixel);
- FakeFreeColor(pScreenPriv->pInstalledmap, maskColor.pixel);
+ FakeAllocColor(pScreenPriv->pInstalledmap[fb], &maskColor);
+ FakeFreeColor(pScreenPriv->pInstalledmap[fb], sourceColor.pixel);
+ FakeFreeColor(pScreenPriv->pInstalledmap[fb], maskColor.pixel);
*source = sourceColor.pixel;
*mask = maskColor.pixel;
}
diff --git a/hw/kdrive/src/kdrive.c b/hw/kdrive/src/kdrive.c
index 308179950..d636260e5 100644
--- a/hw/kdrive/src/kdrive.c
+++ b/hw/kdrive/src/kdrive.c
@@ -21,7 +21,7 @@
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $XFree86: xc/programs/Xserver/hw/kdrive/kdrive.c,v 1.2 1999/12/30 03:03:05 robin Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/kdrive/kdrive.c,v 1.3 2000/02/23 20:29:53 dawes Exp $ */
#include "kdrive.h"
#ifdef PSEUDO8
@@ -301,10 +301,14 @@ void
KdParseScreen (KdScreenInfo *screen,
char *arg)
{
+ char *bpp;
+ int fb;
+
screen->width = 0;
screen->height = 0;
- screen->depth = 0;
screen->rate = 0;
+ for (fb = 0; fb < KD_MAX_FB; fb++)
+ screen->fb[fb].depth = 0;
if (!arg)
return;
@@ -320,7 +324,27 @@ KdParseScreen (KdScreenInfo *screen,
return;
arg++;
- screen->depth = atoi(arg);
+ fb = 0;
+ while (fb < KD_MAX_FB)
+ {
+ screen->fb[fb].depth = atoi(arg);
+
+ bpp = strchr (arg, '/');
+ if (bpp)
+ {
+ bpp++;
+ screen->fb[fb].bitsPerPixel = atoi(bpp);
+ arg = bpp;
+ }
+ else
+ screen->fb[fb].bitsPerPixel = 0;
+ bpp = strchr (arg, ',');
+ if (!bpp)
+ break;
+ arg = bpp+1;
+ fb++;
+ }
+
arg = strchr (arg, 'x');
if (!arg)
return;
@@ -551,7 +575,7 @@ KdCreateWindow (WindowPtr pWin)
}
}
#endif
- return TRUE;
+ return fbCreateWindow (pWin);
}
/* Pass through AddScreen, which doesn't take any closure */
@@ -563,6 +587,7 @@ KdScreenInit(int index, ScreenPtr pScreen, int argc, char **argv)
KdScreenInfo *screen = kdCurrentScreen;
KdCardInfo *card = screen->card;
KdPrivScreenPtr pScreenPriv;
+ int fb;
KdAllocatePrivates (pScreen);
@@ -571,7 +596,8 @@ KdScreenInit(int index, ScreenPtr pScreen, int argc, char **argv)
screen->pScreen = pScreen;
pScreenPriv->screen = screen;
pScreenPriv->card = card;
- pScreenPriv->bytesPerPixel = screen->bitsPerPixel >> 3;
+ for (fb = 0; fb < KD_MAX_FB && screen->fb[fb].depth; fb++)
+ pScreenPriv->bytesPerPixel[fb] = screen->fb[fb].bitsPerPixel >> 3;
pScreenPriv->dpmsState = KD_DPMS_NORMAL;
/*
@@ -580,11 +606,11 @@ KdScreenInit(int index, ScreenPtr pScreen, int argc, char **argv)
* backing store
*/
if (!fbSetupScreen (pScreen,
- screen->frameBuffer,
+ screen->fb[0].frameBuffer,
screen->width, screen->height,
screen->dpix, screen->dpiy,
- screen->pixelStride,
- screen->bitsPerPixel))
+ screen->fb[0].pixelStride,
+ screen->fb[0].bitsPerPixel))
{
return FALSE;
}
@@ -608,14 +634,34 @@ KdScreenInit(int index, ScreenPtr pScreen, int argc, char **argv)
pScreenPriv->BackingStoreFuncs.GetSpansPixmap = 0;
#endif
- if (!fbFinishScreenInit (pScreen,
- screen->frameBuffer,
- screen->width, screen->height,
- screen->dpix, screen->dpiy,
- screen->pixelStride,
- screen->bitsPerPixel))
+ if (screen->fb[1].depth)
+ {
+ if (!fbOverlayFinishScreenInit (pScreen,
+ screen->fb[0].frameBuffer,
+ screen->fb[1].frameBuffer,
+ screen->width, screen->height,
+ screen->dpix, screen->dpiy,
+ screen->fb[0].pixelStride,
+ screen->fb[1].pixelStride,
+ screen->fb[0].bitsPerPixel,
+ screen->fb[1].bitsPerPixel,
+ screen->fb[0].depth,
+ screen->fb[1].depth))
+ {
+ return FALSE;
+ }
+ }
+ else
{
- return FALSE;
+ if (!fbFinishScreenInit (pScreen,
+ screen->fb[0].frameBuffer,
+ screen->width, screen->height,
+ screen->dpix, screen->dpiy,
+ screen->fb[0].pixelStride,
+ screen->fb[0].bitsPerPixel))
+ {
+ return FALSE;
+ }
}
/*
@@ -720,6 +766,8 @@ KdSetPixmapFormats (ScreenInfo *pScreenInfo)
KdCardInfo *card;
KdScreenInfo *screen;
int i;
+ int bpp;
+ int fb;
PixmapFormatRec *format;
for (i = 1; i <= 32; i++)
@@ -735,10 +783,16 @@ KdSetPixmapFormats (ScreenInfo *pScreenInfo)
{
for (screen = card->screenList; screen; screen = screen->next)
{
- if (!depthToBpp[screen->depth])
- depthToBpp[screen->depth] = screen->bitsPerPixel;
- else if (depthToBpp[screen->depth] != screen->bitsPerPixel)
- return FALSE;
+ for (fb = 0; fb < KD_MAX_FB && screen->fb[fb].depth; fb++)
+ {
+ bpp = screen->fb[fb].bitsPerPixel;
+ if (bpp == 24)
+ bpp = 32;
+ if (!depthToBpp[screen->fb[fb].depth])
+ depthToBpp[screen->fb[fb].depth] = bpp;
+ else if (depthToBpp[screen->fb[fb].depth] != bpp)
+ return FALSE;
+ }
}
}
@@ -784,18 +838,20 @@ KdAddScreen (ScreenInfo *pScreenInfo,
{
unsigned long visuals;
Pixel rm, gm, bm;
+ int fb;
- if (pScreenInfo->formats[i].depth == screen->depth)
+ visuals = 0;
+ rm = gm = bm = 0;
+ for (fb = 0; fb < KD_MAX_FB && screen->fb[fb].depth; fb++)
{
- visuals = screen->visuals;
- rm = screen->redMask;
- gm = screen->greenMask;
- bm = screen->blueMask;
- }
- else
- {
- visuals = 0;
- rm = gm = bm = 0;
+ if (pScreenInfo->formats[i].depth == screen->fb[fb].depth)
+ {
+ visuals = screen->fb[fb].visuals;
+ rm = screen->fb[fb].redMask;
+ gm = screen->fb[fb].greenMask;
+ bm = screen->fb[fb].blueMask;
+ break;
+ }
}
fbSetVisualTypesAndMasks (pScreenInfo->formats[i].depth,
visuals,
@@ -808,6 +864,17 @@ KdAddScreen (ScreenInfo *pScreenInfo,
AddScreen (KdScreenInit, argc, argv);
}
+int
+KdDepthToFb (ScreenPtr pScreen, int depth)
+{
+ KdScreenPriv(pScreen);
+ int fb;
+
+ for (fb = 0; fb <= KD_MAX_FB && pScreenPriv->screen->fb[fb].frameBuffer; fb++)
+ if (pScreenPriv->screen->fb[fb].depth == depth)
+ return fb;
+}
+
void
KdInitOutput (ScreenInfo *pScreenInfo,
int argc,
diff --git a/hw/kdrive/src/kdrive.h b/hw/kdrive/src/kdrive.h
index 9458512b4..4b6c06ed4 100644
--- a/hw/kdrive/src/kdrive.h
+++ b/hw/kdrive/src/kdrive.h
@@ -21,7 +21,7 @@
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $XFree86: xc/programs/Xserver/hw/kdrive/kdrive.h,v 1.3 2000/01/21 01:12:01 dawes Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/kdrive/kdrive.h,v 1.4 2000/02/23 20:29:53 dawes Exp $ */
#include <stdio.h>
#include "X.h"
@@ -40,6 +40,7 @@
#include "mi.h"
#include "dix.h"
#include "fb.h"
+#include "fboverlay.h"
extern WindowPtr *WindowTable;
@@ -49,10 +50,18 @@ extern WindowPtr *WindowTable;
#define KD_DPMS_POWERDOWN 3
#define KD_DPMS_MAX KD_DPMS_POWERDOWN
+#ifndef KD_MAX_FB
+#define KD_MAX_FB 2
+#endif
+
+#ifndef KD_MAX_CARD_ADDRESS
+#define KD_MAX_CARD_ADDRESS 8
+#endif
+
/*
* Configuration information per video card
*/
-#define KD_MAX_CARD_ADDRESS 8
+
typedef struct _KdCardAttr {
CARD32 io;
CARD32 address[KD_MAX_CARD_ADDRESS];
@@ -75,25 +84,30 @@ extern KdCardInfo *kdCardInfo;
/*
* Configuration information per X screen
*/
+typedef struct _KdFrameBuffer {
+ CARD8 *frameBuffer;
+ int depth;
+ int bitsPerPixel;
+ int pixelStride;
+ int byteStride;
+ unsigned long visuals;
+ Pixel redMask, greenMask, blueMask;
+ void *closure;
+} KdFrameBuffer;
+
typedef struct _KdScreenInfo {
struct _KdScreenInfo *next;
KdCardInfo *card;
ScreenPtr pScreen;
void *driver;
- CARD8 *frameBuffer;
int width;
int height;
- int depth;
int rate;
- int bitsPerPixel;
- int pixelStride;
- int byteStride;
int dpix, dpiy;
- unsigned long visuals;
- Pixel redMask, greenMask, blueMask;
Bool dumb;
Bool softCursor;
int mynum;
+ KdFrameBuffer fb[KD_MAX_FB];
} KdScreenInfo;
typedef struct _KdCardFuncs {
@@ -120,8 +134,8 @@ typedef struct _KdCardFuncs {
void (*disableAccel) (ScreenPtr);
void (*finiAccel) (ScreenPtr);
- void (*getColors) (ScreenPtr, int, xColorItem *);
- void (*putColors) (ScreenPtr, int, xColorItem *);
+ void (*getColors) (ScreenPtr, int, int, xColorItem *);
+ void (*putColors) (ScreenPtr, int, int, xColorItem *);
} KdCardFuncs;
#define KD_MAX_PSEUDO_DEPTH 8
@@ -133,11 +147,11 @@ typedef struct {
Bool enabled;
Bool closed;
- int bytesPerPixel;
+ int bytesPerPixel[KD_MAX_FB];
int dpmsState;
- ColormapPtr pInstalledmap; /* current colormap */
+ ColormapPtr pInstalledmap[KD_MAX_FB]; /* current colormap */
xColorItem systemPalette[KD_MAX_PSEUDO_SIZE];/* saved windows colors */
CloseScreenProcPtr CloseScreen;
@@ -341,7 +355,7 @@ extern GCOps kdNoopOps;
/* kcmap.c */
void
-KdSetColormap (ScreenPtr pScreen);
+KdSetColormap (ScreenPtr pScreen, int fb);
void
KdEnableColormap (ScreenPtr pScreen);
@@ -364,6 +378,7 @@ KdStoreColors (ColormapPtr pCmap, int ndef, xColorItem *pdefs);
/* kcurscol.c */
void
KdAllocateCursorPixels (ScreenPtr pScreen,
+ int fb,
CursorPtr pCursor,
Pixel *source,
Pixel *mask);
diff --git a/hw/kdrive/src/kinput.c b/hw/kdrive/src/kinput.c
index 2b3b13e3e..5f1886519 100644
--- a/hw/kdrive/src/kinput.c
+++ b/hw/kdrive/src/kinput.c
@@ -21,7 +21,7 @@
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $XFree86: xc/programs/Xserver/hw/kdrive/kinput.c,v 1.2 1999/12/30 03:03:06 robin Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/kdrive/kinput.c,v 1.3 2000/02/23 20:29:54 dawes Exp $ */
#include "kdrive.h"
#include "inputstr.h"
@@ -137,6 +137,9 @@ KdAddFd (int fd)
memset (&act, '\0', sizeof act);
act.sa_handler = KdSigio;
sigemptyset (&act.sa_mask);
+ sigaddset (&act.sa_mask, SIGIO);
+ sigaddset (&act.sa_mask, SIGALRM);
+ sigaddset (&act.sa_mask, SIGVTALRM);
sigaction (SIGIO, &act, 0);
sigemptyset (&set);
sigprocmask (SIG_SETMASK, &set, 0);
diff --git a/hw/kdrive/src/kmode.c b/hw/kdrive/src/kmode.c
index 73ef282f2..4c2116223 100644
--- a/hw/kdrive/src/kmode.c
+++ b/hw/kdrive/src/kmode.c
@@ -295,10 +295,12 @@ KdTuneMode (KdScreenInfo *screen,
/*
* Fix requested depth and geometry until it works
*/
- if (screen->depth > 16)
- screen->depth = 16;
- else if (screen->depth > 8)
- screen->depth = 8;
+ if (screen->fb[1].depth)
+ screen->fb[1].depth = 0;
+ else if (screen->fb[0].depth > 16)
+ screen->fb[0].depth = 16;
+ else if (screen->fb[0].depth > 8)
+ screen->fb[0].depth = 8;
else
{
t = kdFindPrevSize (KdFindMode (screen, supported));
diff --git a/hw/kdrive/trident/trident.c b/hw/kdrive/trident/trident.c
index 08e5ce46d..1a8509dbe 100644
--- a/hw/kdrive/trident/trident.c
+++ b/hw/kdrive/trident/trident.c
@@ -74,7 +74,7 @@ tridentScreenInit (KdScreenInfo *screen)
}
if (!tridentc->cop)
screen->dumb = TRUE;
- screen_size = screen->byteStride * screen->height;
+ screen_size = screen->fb[0].byteStride * screen->height;
memory = (2048 + 512) * 1024;
if (memory >= screen_size + 2048)
{
diff --git a/hw/kdrive/trident/tridentcurs.c b/hw/kdrive/trident/tridentcurs.c
index b10319d31..19b45c68b 100644
--- a/hw/kdrive/trident/tridentcurs.c
+++ b/hw/kdrive/trident/tridentcurs.c
@@ -88,9 +88,9 @@ tridentAllocCursorColors (ScreenPtr pScreen)
SetupCursor (pScreen);
CursorPtr pCursor = pCurPriv->pCursor;
- KdAllocateCursorPixels (pScreen, pCursor,
+ KdAllocateCursorPixels (pScreen, 0, pCursor,
&pCurPriv->source, &pCurPriv->mask);
- switch (pScreenPriv->screen->bitsPerPixel) {
+ switch (pScreenPriv->screen->fb[0].bitsPerPixel) {
case 4:
pCurPriv->source |= pCurPriv->source << 4;
pCurPriv->mask |= pCurPriv->mask << 4;
diff --git a/hw/kdrive/trident/tridentdraw.c b/hw/kdrive/trident/tridentdraw.c
index 4cdfb09e4..4ac0a627d 100644
--- a/hw/kdrive/trident/tridentdraw.c
+++ b/hw/kdrive/trident/tridentdraw.c
@@ -812,8 +812,8 @@ tridentDrawEnable (ScreenPtr pScreen)
CARD32 alpha;
int tries;
- stride = pScreenPriv->screen->pixelStride;
- switch (pScreenPriv->screen->bitsPerPixel) {
+ stride = pScreenPriv->screen->fb[0].pixelStride;
+ switch (pScreenPriv->screen->fb[0].bitsPerPixel) {
case 8:
format = COP_DEPTH_8;
break;
diff --git a/hw/kdrive/trio/s3.c b/hw/kdrive/trio/s3.c
index 489f5ce0f..07e6852b9 100644
--- a/hw/kdrive/trio/s3.c
+++ b/hw/kdrive/trio/s3.c
@@ -445,31 +445,31 @@ s3ModeUsable (KdScreenInfo *screen)
int pixel_width;
int byte_width;
- if (screen->depth >= 24)
+ if (screen->fb[0].depth >= 24)
{
- screen->depth = 24;
- screen->bitsPerPixel = 32;
+ screen->fb[0].depth = 24;
+ screen->fb[0].bitsPerPixel = 32;
}
- else if (screen->depth >= 16)
+ else if (screen->fb[0].depth >= 16)
{
- screen->depth = 16;
- screen->bitsPerPixel = 16;
+ screen->fb[0].depth = 16;
+ screen->fb[0].bitsPerPixel = 16;
}
- else if (screen->depth >= 15)
+ else if (screen->fb[0].depth >= 15)
{
- screen->depth = 15;
- screen->bitsPerPixel = 16;
+ screen->fb[0].depth = 15;
+ screen->fb[0].bitsPerPixel = 16;
}
else
{
- screen->depth = 8;
- screen->bitsPerPixel = 8;
+ screen->fb[0].depth = 8;
+ screen->fb[0].bitsPerPixel = 8;
}
- byte_width = screen->width * (screen->bitsPerPixel >> 3);
+ byte_width = screen->width * (screen->fb[0].bitsPerPixel >> 3);
pixel_width = screen->width;
- screen->pixelStride = pixel_width;
- screen->byteStride = byte_width;
+ screen->fb[0].pixelStride = pixel_width;
+ screen->fb[0].byteStride = byte_width;
screen_size = byte_width * screen->height;
@@ -505,8 +505,8 @@ s3ScreenInit (KdScreenInfo *screen)
screen->height = 600;
screen->rate = 72;
}
- if (!screen->depth)
- screen->depth = 8;
+ if (!screen->fb[0].depth)
+ screen->fb[0].depth = 8;
DRAW_DEBUG ((DEBUG_S3INIT, "Requested parameters %dx%dx%d",
screen->width, screen->height, screen->rate));
@@ -524,8 +524,8 @@ s3ScreenInit (KdScreenInfo *screen)
/*
* Can only operate in pixel-doubled mode at 8 bits per pixel
*/
- if (screen->depth > 8 && S3_CLOCK(m,n,r) > S3_MAX_CLOCK)
- screen->depth = 8;
+ if (screen->fb[0].depth > 8 && S3_CLOCK(m,n,r) > S3_MAX_CLOCK)
+ screen->fb[0].depth = 8;
if (!KdTuneMode (screen, s3ModeUsable, s3ModeSupported))
{
@@ -538,7 +538,7 @@ s3ScreenInit (KdScreenInfo *screen)
/*
* Stick frame buffer at start of memory
*/
- screen->frameBuffer = s3c->frameBuffer;
+ screen->fb[0].frameBuffer = s3c->frameBuffer;
/*
* Stick cursor at end of memory
@@ -557,25 +557,25 @@ s3ScreenInit (KdScreenInfo *screen)
*/
if (memory >= byte_width * S3_TILE_SIZE)
{
- s3s->offscreen = s3c->frameBuffer + screen_size;
- s3s->offscreen_x = 0;
- s3s->offscreen_y = screen_size / byte_width;
- s3s->offscreen_width = pixel_width;
- s3s->offscreen_height = memory / byte_width;
- memory -= s3s->offscreen_height * byte_width;
+ s3s->fb[0].offscreen = s3c->frameBuffer + screen_size;
+ s3s->fb[0].offscreen_x = 0;
+ s3s->fb[0].offscreen_y = screen_size / byte_width;
+ s3s->fb[0].offscreen_width = pixel_width;
+ s3s->fb[0].offscreen_height = memory / byte_width;
+ memory -= s3s->fb[0].offscreen_height * byte_width;
}
else if (pixel_width - screen->width >= S3_TILE_SIZE)
{
- s3s->offscreen = s3c->frameBuffer + screen->width;
- s3s->offscreen_x = screen->width;
- s3s->offscreen_y = 0;
- s3s->offscreen_width = pixel_width - screen->width;
- s3s->offscreen_height = screen->height;
+ s3s->fb[0].offscreen = s3c->frameBuffer + screen->width;
+ s3s->fb[0].offscreen_x = screen->width;
+ s3s->fb[0].offscreen_y = 0;
+ s3s->fb[0].offscreen_width = pixel_width - screen->width;
+ s3s->fb[0].offscreen_height = screen->height;
}
else
- s3s->offscreen = 0;
+ s3s->fb[0].offscreen = 0;
- DRAW_DEBUG ((DEBUG_S3INIT, "depth %d bits %d", screen->depth, screen->bitsPerPixel));
+ DRAW_DEBUG ((DEBUG_S3INIT, "depth %d bits %d", screen->fb[0].depth, screen->fb[0].bitsPerPixel));
DRAW_DEBUG ((DEBUG_S3INIT, "Screen size %dx%d memory %d",
screen->width, screen->height, s3c->memory));
@@ -585,35 +585,35 @@ s3ScreenInit (KdScreenInfo *screen)
s3s->offscreen_width, s3s->offscreen_height,
s3s->offscreen_x, s3s->offscreen_y));
- switch (screen->depth) {
+ switch (screen->fb[0].depth) {
case 8:
- screen->visuals = ((1 << StaticGray) |
+ screen->fb[0].visuals = ((1 << StaticGray) |
(1 << GrayScale) |
(1 << StaticColor) |
(1 << PseudoColor) |
(1 << TrueColor) |
(1 << DirectColor));
- screen->blueMask = 0x00;
- screen->greenMask = 0x00;
- screen->redMask = 0x00;
+ screen->fb[0].blueMask = 0x00;
+ screen->fb[0].greenMask = 0x00;
+ screen->fb[0].redMask = 0x00;
break;
case 15:
- screen->visuals = (1 << TrueColor);
- screen->blueMask = 0x001f;
- screen->greenMask = 0x03e0;
- screen->redMask = 0x7c00;
+ screen->fb[0].visuals = (1 << TrueColor);
+ screen->fb[0].blueMask = 0x001f;
+ screen->fb[0].greenMask = 0x03e0;
+ screen->fb[0].redMask = 0x7c00;
break;
case 16:
- screen->visuals = (1 << TrueColor);
- screen->blueMask = 0x001f;
- screen->greenMask = 0x07e0;
- screen->redMask = 0xf800;
+ screen->fb[0].visuals = (1 << TrueColor);
+ screen->fb[0].blueMask = 0x001f;
+ screen->fb[0].greenMask = 0x07e0;
+ screen->fb[0].redMask = 0xf800;
break;
case 24:
- screen->visuals = (1 << TrueColor);
- screen->blueMask = 0x0000ff;
- screen->greenMask = 0x00ff00;
- screen->redMask = 0xff0000;
+ screen->fb[0].visuals = (1 << TrueColor);
+ screen->fb[0].blueMask = 0x0000ff;
+ screen->fb[0].greenMask = 0x00ff00;
+ screen->fb[0].redMask = 0xff0000;
break;
}
@@ -712,7 +712,7 @@ s3Enable (ScreenPtr pScreen)
/*
* Compute character lengths for horizontal timing values
*/
- switch (screen->bitsPerPixel) {
+ switch (screen->fb[0].bitsPerPixel) {
case 8:
hactive = screen->width / 8;
hblank /= 8;
@@ -830,7 +830,7 @@ s3Enable (ScreenPtr pScreen)
*/
if (!screen->softCursor)
{
- cursor_address = (s3s->cursor_base - screen->frameBuffer) / 1024;
+ cursor_address = (s3s->cursor_base - screen->fb[0].frameBuffer) / 1024;
crtc->cursor_address_0_7 = cursor_address;
crtc->cursor_address_8_15 = cursor_address >> 8;
@@ -855,8 +855,8 @@ s3Enable (ScreenPtr pScreen)
/*
* Set depth values
*/
- crtc->bits_per_pixel = screen->bitsPerPixel;
- crtc->depth = screen->depth;
+ crtc->bits_per_pixel = screen->fb[0].bitsPerPixel;
+ crtc->depth = screen->fb[0].depth;
crtc->l_parm_0_7 = screen->width / 4; /* Undocumented. */
diff --git a/hw/kdrive/trio/s3.h b/hw/kdrive/trio/s3.h
index 41a94d2eb..c5492ab62 100644
--- a/hw/kdrive/trio/s3.h
+++ b/hw/kdrive/trio/s3.h
@@ -1097,15 +1097,22 @@ typedef struct _s3CardInfo {
Bool need_sync;
} S3CardInfo;
-typedef struct _s3ScreenInfo {
- CARD8 *cursor_base; /* pointer to cursor area */
+typedef struct _s3FbInfo {
CARD8 *offscreen; /* pointer to offscreen area */
int offscreen_y; /* top y coordinate of offscreen area */
int offscreen_x; /* top x coordinate of offscreen area */
int offscreen_width; /* width of offscreen area */
int offscreen_height; /* height of offscreen area */
- S3Cursor cursor;
S3Patterns patterns;
+ CARD32 bitmap_offset;
+ int accel_stride;
+ int accel_bpp;
+} S3FBInfo;
+
+typedef struct _s3ScreenInfo {
+ CARD8 *cursor_base; /* pointer to cursor area */
+ S3Cursor cursor;
+ S3FBInfo fb[1];
} S3ScreenInfo;
#define LockS3(s3c)
@@ -1135,8 +1142,8 @@ void s3DrawSync (ScreenPtr pScreen);
void s3DrawDisable (ScreenPtr pScreen);
void s3DrawFini (ScreenPtr pScreen);
-void s3GetColors (ScreenPtr pScreen, int ndef, xColorItem *pdefs);
-void s3PutColors (ScreenPtr pScreen, int ndef, xColorItem *pdefs);
+void s3GetColors (ScreenPtr pScreen, int fb, int ndef, xColorItem *pdefs);
+void s3PutColors (ScreenPtr pScreen, int fb, int ndef, xColorItem *pdefs);
void S3InitCard (KdCardAttr *attr);
diff --git a/hw/kdrive/trio/s3cmap.c b/hw/kdrive/trio/s3cmap.c
index fd213869e..01035e8d7 100644
--- a/hw/kdrive/trio/s3cmap.c
+++ b/hw/kdrive/trio/s3cmap.c
@@ -26,7 +26,7 @@
#include "s3.h"
void
-s3GetColors (ScreenPtr pScreen, int ndef, xColorItem *pdefs)
+s3GetColors (ScreenPtr pScreen, int fb, int ndef, xColorItem *pdefs)
{
KdScreenPriv(pScreen);
s3CardInfo(pScreenPriv);
@@ -47,7 +47,7 @@ s3GetColors (ScreenPtr pScreen, int ndef, xColorItem *pdefs)
}
void
-s3PutColors (ScreenPtr pScreen, int ndef, xColorItem *pdefs)
+s3PutColors (ScreenPtr pScreen, int fb, int ndef, xColorItem *pdefs)
{
KdScreenPriv(pScreen);
s3CardInfo(pScreenPriv);
diff --git a/hw/kdrive/trio/s3curs.c b/hw/kdrive/trio/s3curs.c
index 2c17b341a..f67b77b4a 100644
--- a/hw/kdrive/trio/s3curs.c
+++ b/hw/kdrive/trio/s3curs.c
@@ -95,9 +95,9 @@ s3AllocCursorColors (ScreenPtr pScreen)
CursorPtr pCursor = pCurPriv->pCursor;
xColorItem sourceColor, maskColor;
- KdAllocateCursorPixels (pScreen, pCursor,
+ KdAllocateCursorPixels (pScreen, 0, pCursor,
&pCurPriv->source, &pCurPriv->mask);
- switch (pScreenPriv->screen->bitsPerPixel) {
+ switch (pScreenPriv->screen->fb[0].bitsPerPixel) {
case 4:
pCurPriv->source |= pCurPriv->source << 4;
pCurPriv->mask |= pCurPriv->mask << 4;