diff options
author | Keith Packard <keithp@keithp.com> | 2000-05-06 22:17:53 +0000 |
---|---|---|
committer | Keith Packard <keithp@keithp.com> | 2000-05-06 22:17:53 +0000 |
commit | 3731c184d69e3c1face0c731926433d522d48067 (patch) | |
tree | 687fa152bbb27d72d12e64b248f71b255311d087 /hw | |
parent | 4b54f22b6accf438f31fbbe79877545c38375351 (diff) |
Lots of Tiny-X changes:
Add overlay support in the Tiny-X Savage4 driver (required changing lots of
Tiny-X code). Savage4 now support 8/16, 8/32 overlays.
Add IGS Cyberpro 5050 driver. This chip has bus support for embeded
systems.
Diffstat (limited to 'hw')
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; |