summaryrefslogtreecommitdiff
path: root/src/savage_driver.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/savage_driver.c')
-rw-r--r--src/savage_driver.c458
1 files changed, 324 insertions, 134 deletions
diff --git a/src/savage_driver.c b/src/savage_driver.c
index 4a6cc2c..4a0ec2b 100644
--- a/src/savage_driver.c
+++ b/src/savage_driver.c
@@ -24,6 +24,7 @@
#include "savage_driver.h"
#include "savage_bci.h"
+#define TRANSPARENCY_KEY 0xff;
/*
* prototypes
@@ -60,6 +61,7 @@ static void SavageLoadPalette(ScrnInfoPtr pScrn, int numColors,
static void SavageLoadPaletteSavage4(ScrnInfoPtr pScrn, int numColors,
int *indicies, LOCO *colors,
VisualPtr pVisual);
+static void SavageUpdateKey(ScrnInfoPtr pScrn, int r, int g, int b);
static void SavageCalcClock(long freq, int min_m, int min_n1, int max_n1,
int min_n2, int max_n2, long freq_min,
long freq_max, unsigned int *mdiv,
@@ -175,24 +177,26 @@ static PciChipsets SavagePciChipsets[] = {
};
typedef enum {
- OPTION_PCI_BURST
- ,OPTION_PCI_RETRY
- ,OPTION_NOACCEL
- ,OPTION_LCD_CENTER
- ,OPTION_LCDCLOCK
- ,OPTION_MCLK
- ,OPTION_REFCLK
- ,OPTION_SHOWCACHE
- ,OPTION_SWCURSOR
- ,OPTION_HWCURSOR
- ,OPTION_SHADOW_FB
- ,OPTION_ROTATE
- ,OPTION_USEBIOS
- ,OPTION_SHADOW_STATUS
- ,OPTION_CRT_ONLY
- ,OPTION_TV_ON
- ,OPTION_TV_PAL
- ,OPTION_FORCE_INIT
+ OPTION_PCI_BURST,
+ OPTION_PCI_RETRY,
+ OPTION_NOACCEL,
+ OPTION_LCD_CENTER,
+ OPTION_LCDCLOCK,
+ OPTION_MCLK,
+ OPTION_REFCLK,
+ OPTION_SHOWCACHE,
+ OPTION_SWCURSOR,
+ OPTION_HWCURSOR,
+ OPTION_SHADOW_FB,
+ OPTION_ROTATE,
+ OPTION_USEBIOS,
+ OPTION_SHADOW_STATUS,
+ OPTION_CRT_ONLY,
+ OPTION_TV_ON,
+ OPTION_TV_PAL,
+ OPTION_FORCE_INIT,
+ OPTION_OVERLAY,
+ OPTION_T_KEY
} SavageOpts;
@@ -210,6 +214,8 @@ static const OptionInfoRec SavageOptions[] =
{ OPTION_TV_ON, "TvOn", OPTV_BOOLEAN, {0}, FALSE },
{ OPTION_TV_PAL, "PAL", OPTV_BOOLEAN, {0}, FALSE },
{ OPTION_FORCE_INIT,"ForceInit", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_OVERLAY, "Overlay", OPTV_ANYSTR, {0}, FALSE },
+ { OPTION_T_KEY, "TransparencyKey", OPTV_ANYSTR, {0}, FALSE },
{ -1, NULL, OPTV_NONE, {0}, FALSE }
};
@@ -247,6 +253,13 @@ static const char *ramdacSymbols[] = {
NULL
};
+static const char *int10Symbols[] = {
+ "xf86ExecX86int10",
+ "xf86Int10AllocPages",
+ "xf86int10Addr",
+ "xf86Int10FreePages"
+};
+
static const char *vbeSymbols[] = {
"VBEInit",
"vbeDoEDID",
@@ -288,6 +301,7 @@ static const char *xaaSymbols[] = {
"XAAHelpPatternROP",
"XAAHelpSolidROP",
"XAAInit",
+ "XAAScreenIndex",
NULL
};
@@ -296,18 +310,6 @@ static const char *shadowSymbols[] = {
NULL
};
-static const char *int10Symbols[] = {
- "xf86ExecX86int10",
-#if 0
- "xf86FreeInt10",
-#endif
- "xf86InitInt10",
- "xf86Int10AllocPages",
- "xf86Int10FreePages",
- "xf86int10Addr",
- NULL
-};
-
static const char *fbSymbols[] = {
"fbPictureInit",
"fbScreenInit",
@@ -398,7 +400,7 @@ ShadowWait( SavagePtr psav )
BCI_SEND( 0x98000000 + psav->ShadowCounter );
while(
- (psav->ShadowVirtual[1] & 0x7fff) != psav->ShadowCounter &&
+ (int)(psav->ShadowVirtual[1] & 0x7fff) != psav->ShadowCounter &&
(loop++ < MAXLOOP)
)
;
@@ -419,7 +421,7 @@ static int
WaitQueue3D( SavagePtr psav, int v )
{
int loop = 0;
- int slots = MAXFIFO - v;
+ CARD32 slots = MAXFIFO - v;
mem_barrier();
if( psav->ShadowVirtual )
@@ -440,7 +442,7 @@ static int
WaitQueue4( SavagePtr psav, int v )
{
int loop = 0;
- int slots = MAXFIFO - v;
+ CARD32 slots = MAXFIFO - v;
if( !psav->NoPCIRetry )
return 0;
@@ -460,7 +462,7 @@ static int
WaitQueue2K( SavagePtr psav, int v )
{
int loop = 0;
- int slots = MAXFIFO - v;
+ CARD32 slots = MAXFIFO - v;
if( !psav->NoPCIRetry )
return 0;
@@ -828,6 +830,8 @@ static Bool SavagePreInit(ScrnInfoPtr pScrn, int flags)
xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Option: shadow FB enabled\n");
}
+ psav->primStreamBpp = pScrn->bitsPerPixel;
+
if ((s = xf86GetOptValString(psav->Options, OPTION_ROTATE))) {
if(!xf86NameCmp(s, "CW")) {
/* accel is disabled below for shadowFB */
@@ -858,6 +862,48 @@ static Bool SavagePreInit(ScrnInfoPtr pScrn, int flags)
psav->NoAccel = TRUE;
}
+ if ((s = xf86GetOptValString(psav->Options, OPTION_OVERLAY))) {
+
+ if (psav->shadowFB) {
+ xf86DrvMsg(pScrn->scrnIndex,X_INFO,
+ "Option \"Overlay\" not supported with shadowFB\n");
+ } else {
+ if (pScrn->depth == 8) {
+ if (!*s || !xf86NameCmp(s, "24")) {
+ psav->overlayDepth = 24;
+ psav->NoAccel = TRUE; /* Preliminary */
+ pScrn->colorKey = TRANSPARENCY_KEY;
+ pScrn->overlayFlags = OVERLAY_8_32_DUALFB;
+ } else if (!xf86NameCmp(s, "16")) {
+ psav->overlayDepth = 16;
+ psav->NoAccel = TRUE; /* Preliminary */
+ pScrn->colorKey = TRANSPARENCY_KEY;
+ pScrn->overlayFlags = OVERLAY_8_32_DUALFB;
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex,X_WARNING,"Wrong argument: "
+ "\"%s\" Ingnoring\n",s);
+ }
+ } else if (pScrn->depth != 15) {
+ psav->overlayDepth = 8;
+ psav->NoAccel = TRUE; /* Preliminary */
+ pScrn->colorKey = TRANSPARENCY_KEY;
+ pScrn->overlayFlags = OVERLAY_8_32_DUALFB;
+ if (*s && (xf86NameCmp(s, "8")))
+ xf86DrvMsg(pScrn->scrnIndex,X_WARNING,"Wrong argument: "
+ "\"%s\" for depth %i overlay depth must be 8\n",
+ s,pScrn->depth);
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex,X_WARNING,"Overlay not "
+ "supported for depth 15\n");
+ }
+ if (psav->overlayDepth) {
+ xf86DrvMsg(pScrn->scrnIndex,X_INFO,"%i/%i Overlay enabled\n",
+ pScrn->depth,psav->overlayDepth);
+ psav->primStreamBpp = 8;
+ }
+ }
+ }
+
if (pScrn->bitsPerPixel == 24 && !psav->NoAccel) {
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
"HW acceleration not possible with depth 32 and bpp 24.\n");
@@ -937,15 +983,10 @@ static Bool SavagePreInit(ScrnInfoPtr pScrn, int flags)
return FALSE;
}
psav->EntityIndex = pEnt->index;
-
- if (xf86LoadSubModule(pScrn, "int10")) {
- xf86LoaderReqSymLists(int10Symbols, NULL);
- psav->pInt10 = xf86InitInt10(pEnt->index);
- }
-
+
if (xf86LoadSubModule(pScrn, "vbe")) {
xf86LoaderReqSymLists(vbeSymbols, NULL);
- psav->pVbe = VBEInit(psav->pInt10, pEnt->index);
+ psav->pVbe = VBEInit(NULL, pEnt->index);
}
@@ -1002,6 +1043,7 @@ static Bool SavagePreInit(ScrnInfoPtr pScrn, int flags)
if (!SavageMapMMIO(pScrn)) {
SavageFreeRec(pScrn);
vbeFree(psav->pVbe);
+ psav->pVbe = NULL;
return FALSE;
}
@@ -1032,6 +1074,7 @@ static Bool SavagePreInit(ScrnInfoPtr pScrn, int flags)
if (!xf86SetGamma(pScrn, zeros)) {
vbeFree(psav->pVbe);
+ psav->pVbe = NULL;
SavageFreeRec(pScrn);
return FALSE;
}
@@ -1103,6 +1146,41 @@ static Bool SavagePreInit(ScrnInfoPtr pScrn, int flags)
pScrn->videoRam);
}
+ /* Do the DDC dance. */
+
+ {
+ ddc = xf86LoadSubModule(pScrn, "ddc");
+ if (ddc) {
+ xf86MonPtr pMon = NULL;
+
+ xf86LoaderReqSymLists(ddcSymbols, NULL);
+/*
+ * On many machines, the attempt to read DDC information via VBE puts the
+ * BIOS access into a state which prevents me from reading mode information.
+ * This is a complete mystery to me.
+ */
+ if ((psav->pVbe)
+ && ((pMon = xf86PrintEDID(vbeDoEDID(psav->pVbe, ddc))) != NULL))
+ xf86SetDDCproperties(pScrn,pMon);
+ else if (( psav->Chipset != S3_PROSAVAGE )
+ && !SavageDDC1(pScrn->scrnIndex)) {
+ if ( xf86LoadSubModule(pScrn, "i2c") ) {
+ xf86LoaderReqSymLists(i2cSymbols,NULL);
+ if (SavageI2CInit(pScrn)) {
+ unsigned char tmp;
+
+ InI2CREG(psav,tmp);
+ OutI2CREG(psav,tmp | 0x13);
+ xf86SetDDCproperties(pScrn,xf86PrintEDID(
+ xf86DoEDID_DDC2(pScrn->scrnIndex,psav->I2C)));
+ OutI2CREG(psav,tmp);
+ }
+ }
+ }
+ }
+ }
+
+ /* Get video RAM */
if( !pScrn->videoRam && psav->pVbe )
{
/* If VBE is available, ask it about onboard memory. */
@@ -1202,44 +1280,6 @@ static Bool SavagePreInit(ScrnInfoPtr pScrn, int flags)
break;
}
- /* Do the DDC dance. */
-
- if( psav->Chipset != S3_PROSAVAGE ) {
- ddc = xf86LoadSubModule(pScrn, "ddc");
- if (ddc) {
-#if 0
- xf86MonPtr pMon = NULL;
-#endif
-
- xf86LoaderReqSymLists(ddcSymbols, NULL);
-#if 0
-/*
- * On many machines, the attempt to read DDC information via VBE puts the
- * BIOS access into a state which prevents me from reading mode information.
- * This is a complete mystery to me.
- */
- if ((psav->pVbe)
- && ((pMon = xf86PrintEDID(vbeDoEDID(psav->pVbe, ddc))) != NULL))
- xf86SetDDCproperties(pScrn,pMon);
- else
-#endif
- if (!SavageDDC1(pScrn->scrnIndex)) {
- if ( xf86LoadSubModule(pScrn, "i2c") ) {
- xf86LoaderReqSymLists(i2cSymbols,NULL);
- if (SavageI2CInit(pScrn)) {
- unsigned char tmp;
-
- InI2CREG(psav,tmp);
- OutI2CREG(psav,tmp | 0x13);
- xf86SetDDCproperties(pScrn,xf86PrintEDID(
- xf86DoEDID_DDC2(pScrn->scrnIndex,psav->I2C)));
- OutI2CREG(psav,tmp);
- }
- }
- }
- }
- }
-
/* Savage ramdac speeds */
pScrn->numClocks = 4;
pScrn->clock[0] = 250000;
@@ -1374,6 +1414,7 @@ static Bool SavagePreInit(ScrnInfoPtr pScrn, int flags)
xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "xf86ValidateModes failure\n");
SavageFreeRec(pScrn);
vbeFree(psav->pVbe);
+ psav->pVbe = NULL;
return FALSE;
}
@@ -1383,6 +1424,7 @@ static Bool SavagePreInit(ScrnInfoPtr pScrn, int flags)
xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n");
SavageFreeRec(pScrn);
vbeFree(psav->pVbe);
+ psav->pVbe = NULL;
return FALSE;
}
@@ -1395,7 +1437,7 @@ static Bool SavagePreInit(ScrnInfoPtr pScrn, int flags)
SavageFreeBIOSModeTable( psav, &psav->ModeTable );
}
- psav->ModeTable = SavageGetBIOSModeTable( psav, pScrn->bitsPerPixel );
+ psav->ModeTable = SavageGetBIOSModeTable( psav, psav->primStreamBpp );
if( !psav->ModeTable || !psav->ModeTable->NumModes ) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
@@ -1436,6 +1478,7 @@ static Bool SavagePreInit(ScrnInfoPtr pScrn, int flags)
if (xf86LoadSubModule(pScrn, "fb") == NULL) {
SavageFreeRec(pScrn);
vbeFree(psav->pVbe);
+ psav->pVbe = NULL;
return FALSE;
}
@@ -1445,6 +1488,7 @@ static Bool SavagePreInit(ScrnInfoPtr pScrn, int flags)
if( !xf86LoadSubModule(pScrn, "xaa") ) {
SavageFreeRec(pScrn);
vbeFree(psav->pVbe);
+ psav->pVbe = NULL;
return FALSE;
}
xf86LoaderReqSymLists(xaaSymbols, NULL );
@@ -1454,6 +1498,7 @@ static Bool SavagePreInit(ScrnInfoPtr pScrn, int flags)
if (!xf86LoadSubModule(pScrn, "ramdac")) {
SavageFreeRec(pScrn);
vbeFree(psav->pVbe);
+ psav->pVbe = NULL;
return FALSE;
}
xf86LoaderReqSymLists(ramdacSymbols, NULL);
@@ -1463,12 +1508,15 @@ static Bool SavagePreInit(ScrnInfoPtr pScrn, int flags)
if (!xf86LoadSubModule(pScrn, "shadowfb")) {
SavageFreeRec(pScrn);
vbeFree(psav->pVbe);
+ psav->pVbe = NULL;
return FALSE;
}
xf86LoaderReqSymLists(shadowSymbols, NULL);
}
vbeFree(psav->pVbe);
+ psav->pVbe = NULL;
+
return TRUE;
}
@@ -1501,6 +1549,7 @@ static void SavageLeaveVT(int scrnIndex, int flags)
TRACE(("SavageLeaveVT(%d)\n", flags));
gpScrn = pScrn;
+ SavageStreamsOff(pScrn);
SavageWriteMode(pScrn, vgaSavePtr, SavageSavePtr, FALSE);
SavageDisableMMIO(pScrn);
}
@@ -1746,6 +1795,10 @@ static void SavageWriteMode(ScrnInfoPtr pScrn, vgaRegPtr vgaSavePtr,
VGAOUT8(vgaCRIndex, 0x53);
VGAOUT8(vgaCRReg, VGAIN8(vgaCRReg) & ~0x10);
+ /* Disable HW cursor */
+
+ VGAOUT16(vgaCRIndex, 0x0045);
+
/* Set the color mode. */
VGAOUT8(vgaCRIndex, 0x67);
@@ -1754,7 +1807,8 @@ static void SavageWriteMode(ScrnInfoPtr pScrn, vgaRegPtr vgaSavePtr,
/* Enable gamma correction. */
VGAOUT8(0x3c4, 0x1b);
- if( (pScrn->bitsPerPixel == 32) && !psav->DGAactive )
+ if( (pScrn->bitsPerPixel == 32) && !psav->DGAactive
+ && ! psav->FBStart2nd )
VGAOUT8(0x3c5, 0x28 );
else
VGAOUT8(0x3c5, 0x00 );
@@ -1776,7 +1830,7 @@ static void SavageWriteMode(ScrnInfoPtr pScrn, vgaRegPtr vgaSavePtr,
if( pScrn->displayWidth >= 1024 )
{
- if(pScrn->bitsPerPixel == 32 )
+ if(psav->primStreamBpp == 32 )
{
if( restore->refresh >= 130 )
cr79 = 0x03;
@@ -1793,7 +1847,7 @@ static void SavageWriteMode(ScrnInfoPtr pScrn, vgaRegPtr vgaSavePtr,
cr79 = 0x08;
}
}
- else if( pScrn->bitsPerPixel == 16)
+ else if( psav->primStreamBpp == 16)
{
/* The windows driver uses 0x13 for 16-bit 130Hz, but I see terrible
@@ -1830,7 +1884,7 @@ static void SavageWriteMode(ScrnInfoPtr pScrn, vgaRegPtr vgaSavePtr,
VGAOUT8(vgaCRIndex, 0x50);
VGAOUT8(vgaCRReg, VGAIN8(vgaCRReg) | 0xC1);
- width = (pScrn->displayWidth * (pScrn->bitsPerPixel / 8)) >> 3;
+ width = (pScrn->displayWidth * (psav->primStreamBpp / 8)) >> 3;
VGAOUT16(vgaCRIndex, ((width & 0xff) << 8) | 0x13 );
VGAOUT16(vgaCRIndex, ((width & 0x300) << 4) | 0x51 );
@@ -1901,7 +1955,7 @@ static void SavageWriteMode(ScrnInfoPtr pScrn, vgaRegPtr vgaSavePtr,
* switch to mode 3 here seems to eliminate the issue.
*/
- if( ((restore->CR31 & 0x0a) == 0) && psav->pInt10 ) {
+ if( ((restore->CR31 & 0x0a) == 0) && psav->pVbe ) {
SavageSetTextMode( psav );
}
@@ -2173,7 +2227,7 @@ static Bool SavageMapMMIO(ScrnInfoPtr pScrn)
return TRUE;
}
-
+#define TRANSPARENCY_KEY 0xff;
static Bool SavageMapFB(ScrnInfoPtr pScrn)
{
@@ -2246,6 +2300,7 @@ static Bool SavageScreenInit(int scrnIndex, ScreenPtr pScreen,
SavagePtr psav;
EntityInfoPtr pEnt;
int ret;
+ int colormapFlags;
TRACE(("SavageScreenInit()\n"));
@@ -2253,13 +2308,27 @@ static Bool SavageScreenInit(int scrnIndex, ScreenPtr pScreen,
psav = SAVPTR(pScrn);
pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
- psav->pVbe = VBEInit(NULL, pEnt->index);
+ if (!psav->pVbe)
+ psav->pVbe = VBEInit(NULL, pEnt->index);
SavageEnableMMIO(pScrn);
if (!SavageMapFB(pScrn))
return FALSE;
+ psav->FBStart2nd = 0;
+
+ if (psav->overlayDepth) {
+ if ((pScrn->virtualX * pScrn->virtualY *
+ (DEPTH_BPP(DEPTH_2ND(pScrn))) >> 3)
+ > (psav->CursorKByte * 1024))
+ xf86DrvMsg(pScrn->scrnIndex,X_WARNING,
+ "Not enough memory for overlay mode: disabling\n");
+ else psav->FBStart2nd = psav->FBStart
+ + ((pScrn->virtualX * pScrn->virtualY + 0xff) & ~0xff);
+
+ }
+
if( psav->ShadowStatus ) {
psav->ShadowPhysical =
psav->FrameBufferBase + psav->CursorKByte*1024 + 4096 - 32;
@@ -2291,19 +2360,27 @@ static Bool SavageScreenInit(int scrnIndex, ScreenPtr pScreen,
miClearVisualTypes();
- if (pScrn->bitsPerPixel == 16) {
- if (!miSetVisualTypes(pScrn->depth, TrueColorMask,
- pScrn->rgbBits, pScrn->defaultVisual))
- return FALSE;
- if (!miSetPixmapDepths ())
- return FALSE;
- } else {
- if (!miSetVisualTypes(pScrn->depth, miGetDefaultVisualMask(pScrn->depth),
- pScrn->rgbBits, pScrn->defaultVisual))
- return FALSE;
- if (!miSetPixmapDepths ())
- return FALSE;
- }
+ {
+ int visual;
+
+ visual = ((psav->FBStart2nd && pScrn->bitsPerPixel > 8)
+ || pScrn->bitsPerPixel == 16) ? TrueColorMask
+ : miGetDefaultVisualMask(DEPTH_BPP(pScrn->depth));
+ if (!miSetVisualTypes(pScrn->depth, visual,
+ pScrn->rgbBits, pScrn->defaultVisual))
+ return FALSE;
+
+ if (psav->FBStart2nd) {/* we have overlay */
+ visual = psav->overlayDepth > 8 ? TrueColorMask :
+ miGetDefaultVisualMask(DEPTH_BPP(psav->overlayDepth));
+ if (!miSetVisualTypes(psav->overlayDepth, visual,
+ psav->overlayDepth > 8 ? 8 : 6,
+ pScrn->defaultVisual))
+ return FALSE;
+ }
+ }
+ if (!miSetPixmapDepths ())
+ return FALSE;
ret = SavageInternalScreenInit(scrnIndex, pScreen);
if (!ret)
@@ -2311,18 +2388,61 @@ static Bool SavageScreenInit(int scrnIndex, ScreenPtr pScreen,
xf86SetBlackWhitePixels(pScreen);
- if (pScrn->bitsPerPixel > 8) {
+ {
VisualPtr visual;
-
visual = pScreen->visuals + pScreen->numVisuals;
while (--visual >= pScreen->visuals) {
- if ((visual->class | DynamicClass) == DirectColor) {
- visual->offsetRed = pScrn->offset.red;
- visual->offsetGreen = pScrn->offset.green;
- visual->offsetBlue = pScrn->offset.blue;
- visual->redMask = pScrn->mask.red;
- visual->greenMask = pScrn->mask.green;
- visual->blueMask = pScrn->mask.blue;
+ if ((visual->class | DynamicClass) == DirectColor
+ && visual->nplanes > MAX_PSEUDO_DEPTH) {
+ if (visual->nplanes == pScrn->depth) {
+ visual->offsetRed = pScrn->offset.red;
+ visual->offsetGreen = pScrn->offset.green;
+ visual->offsetBlue = pScrn->offset.blue;
+ visual->redMask = pScrn->mask.red;
+ visual->greenMask = pScrn->mask.green;
+ visual->blueMask = pScrn->mask.blue;
+ } else if (visual->offsetRed > 8
+ || visual->offsetGreen > 8
+ || visual->offsetBlue > 8) {
+ /*
+ * mi has set these wrong. fix it here -- we cannot use pScrn
+ * as this is set up for the default depth 8.
+ */
+ int tmp;
+ int c_s = 0;
+
+ tmp = visual->offsetBlue;
+ visual->offsetBlue = visual->offsetRed;
+ visual->offsetRed = tmp;
+ tmp = visual->blueMask;
+ visual->blueMask = visual->redMask;
+ visual->redMask = tmp;
+ switch (DEPTH_2ND(pScrn)) {
+ case 16:
+ visual->offsetRed = 11;
+ visual->offsetGreen = 5;
+ visual->offsetBlue = 0;
+ visual->redMask = 0xF800;
+ visual->greenMask = 0x7E0;
+ visual->blueMask = 0x1F;
+ break;
+ case 24:
+ visual->offsetRed = 16;
+ visual->offsetGreen = 8;
+ visual->offsetBlue = 0;
+ visual->redMask = 0xFF0000;
+ visual->greenMask = 0xFF00;
+ visual->blueMask = 0xFF;
+ c_s = 2;
+ break;
+ }
+ psav->overlay.redMask = visual->redMask;
+ psav->overlay.greenMask = visual->greenMask;
+ psav->overlay.blueMask = visual->blueMask;
+ psav->overlay.redShift = visual->offsetRed + c_s;
+ psav->overlay.greenShift = visual->offsetGreen + c_s;
+ psav->overlay.blueShift = visual->offsetBlue + c_s;
+ }
}
}
}
@@ -2370,19 +2490,17 @@ static Bool SavageScreenInit(int scrnIndex, ScreenPtr pScreen,
if (!miCreateDefColormap(pScreen))
return FALSE;
+ colormapFlags = CMAP_RELOAD_ON_MODE_SWITCH
+ | ((psav->FBStart2nd) ? 0 : CMAP_PALETTED_TRUECOLOR);
+
if (psav->Chipset == S3_SAVAGE4) {
if (!xf86HandleColormaps(pScreen, 256, 6, SavageLoadPaletteSavage4,
- NULL,
- CMAP_RELOAD_ON_MODE_SWITCH
- | CMAP_PALETTED_TRUECOLOR
- ))
+ NULL, colormapFlags ))
return FALSE;
} else {
if (!xf86HandleColormaps(pScreen, 256, 6, SavageLoadPalette, NULL,
- CMAP_RELOAD_ON_MODE_SWITCH
- | CMAP_PALETTED_TRUECOLOR
- ))
- return FALSE;
+ colormapFlags ))
+ return FALSE;
}
vgaHWBlankScreen(pScrn, FALSE);
@@ -2394,7 +2512,7 @@ static Bool SavageScreenInit(int scrnIndex, ScreenPtr pScreen,
if (xf86DPMSInit(pScreen, SavageDPMS, 0) == FALSE)
xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "DPMS initialization failed\n");
- if( !psav->NoAccel && !SavagePanningCheck(pScrn) )
+ if( !psav->FBStart2nd && !SavagePanningCheck(pScrn) )
SavageInitVideo( pScreen );
if (serverGeneration == 1)
@@ -2438,10 +2556,38 @@ static int SavageInternalScreenInit(int scrnIndex, ScreenPtr pScreen)
FBStart = psav->FBStart;
}
- ret = fbScreenInit(pScreen, FBStart, width, height,
- pScrn->xDpi, pScrn->yDpi,
- displayWidth,
- pScrn->bitsPerPixel);
+ if (!psav->FBStart2nd) {
+ ret = fbScreenInit(pScreen, FBStart, width, height,
+ pScrn->xDpi, pScrn->yDpi,
+ displayWidth,
+ pScrn->bitsPerPixel);
+ } else {
+ FbOverlayScrPrivPtr pScrPriv;
+ int Depth2nd = DEPTH_2ND(pScrn);
+ if (!fbSetupScreen (pScreen, FBStart, width, height,
+ pScrn->xDpi, pScrn->yDpi, displayWidth, 8))
+ return FALSE;
+ if (pScrn->depth == 8) {
+ ret = fbOverlayFinishScreenInit (pScreen, FBStart,
+ psav->FBStart2nd, width,
+ height,pScrn->xDpi, pScrn->yDpi,
+ displayWidth,displayWidth,
+ 8, DEPTH_BPP(Depth2nd),
+ 8, Depth2nd);
+ pScrPriv = fbOverlayGetScrPriv(pScreen);
+ pScrPriv->layer[0].key = pScrn->colorKey;
+ } else {
+ ret = fbOverlayFinishScreenInit (pScreen, psav->FBStart2nd,
+ FBStart,
+ width, height,pScrn->xDpi,
+ pScrn->yDpi,
+ displayWidth,displayWidth,
+ DEPTH_BPP(Depth2nd), 8,
+ Depth2nd, 8);
+ pScrPriv = fbOverlayGetScrPriv(pScreen);
+ pScrPriv->layer[1].key = pScrn->colorKey;
+ }
+ }
return ret;
}
@@ -2556,7 +2702,7 @@ static Bool SavageModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
new->CR67 = 0x40; /* 16bpp, 1 pixels/clock */
break;
case 24:
- if (pScrn->bitsPerPixel == 24 )
+ if (psav->primStreamBpp == 24 )
new->CR67 = 0x70;
else
new->CR67 = 0xd0;
@@ -2697,12 +2843,12 @@ static Bool SavageModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
new->SR29 = (r & 4) | (m & 0x100) >> 5 | (n & 0x40) >> 2;
if (psav->fifo_moderate) {
- if (pScrn->bitsPerPixel < 24)
+ if (psav->primStreamBpp < 24)
new->MMPR0 -= 0x8000;
else
new->MMPR0 -= 0x4000;
} else if (psav->fifo_aggressive) {
- if (pScrn->bitsPerPixel < 24)
+ if (psav->primStreamBpp < 24)
new->MMPR0 -= 0xc000;
else
new->MMPR0 -= 0x6000;
@@ -2742,7 +2888,7 @@ static Bool SavageModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
(((mode->CrtcVDisplay - 1) & 0x400) >> 9) |
(((mode->CrtcVSyncStart) & 0x400) >> 8) |
(((mode->CrtcVSyncStart) & 0x400) >> 6) | 0x40;
- width = (pScrn->displayWidth * (pScrn->bitsPerPixel / 8)) >> 3;
+ width = (pScrn->displayWidth * (psav->primStreamBpp / 8)) >> 3;
new->CR91 = vganew->CRTC[19] = 0xff & width;
new->CR51 = (0x300 & width) >> 4;
new->CR90 = 0x80 | (width >> 8);
@@ -2750,9 +2896,9 @@ static Bool SavageModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
/* Set frame buffer description. */
- if (pScrn->bitsPerPixel <= 8)
+ if (psav->primStreamBpp <= 8)
new->CR50 = 0;
- else if (pScrn->bitsPerPixel <= 16)
+ else if (psav->primStreamBpp <= 16)
new->CR50 = 0x10;
else
new->CR50 = 0x30;
@@ -2798,6 +2944,11 @@ static Bool SavageModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
/* do it! */
SavageWriteMode(pScrn, vganew, new, TRUE);
+ SavageStreamsOn(pScrn);
+
+ if (psav->FBStart2nd)
+ SavageInitSecondaryStream(pScrn);
+
SavageAdjustFrame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
return TRUE;
@@ -2830,6 +2981,7 @@ static Bool SavageCloseScreen(int scrnIndex, ScreenPtr pScreen)
}
if (pScrn->vtSema) {
+ SavageStreamsOff(pScrn);
SavageWriteMode(pScrn, vgaSavePtr, SavageSavePtr, FALSE);
vgaHWLock(hwp);
SavageUnmapMem(pScrn, 0);
@@ -2853,7 +3005,7 @@ static Bool SavageSaveScreen(ScreenPtr pScreen, int mode)
SavageShowCursor( pScrn );
else
SavageHideCursor( pScrn );
- SAVPTR(pScrn)->hwc_on = TRUE;
+ SAVPTR(pScrn)->hwc_on = TRUE; /*restore */
}
return vgaHWSaveScreen(pScreen, mode);
@@ -2877,7 +3029,7 @@ void SavageAdjustFrame(int scrnIndex, int x, int y, int flags)
y += pScrn->virtualY - 1;
Base = ((y * pScrn->displayWidth + (x&~1)) *
- (pScrn->bitsPerPixel / 8)) >> 2;
+ (psav->primStreamBpp / 8)) >> 2;
/* now program the start address registers */
VGAOUT16(vgaCRIndex, (Base & 0x00ff00) | 0x0c);
VGAOUT16(vgaCRIndex, ((Base & 0x00ff) << 8) | 0x0d);
@@ -2891,6 +3043,7 @@ void SavageAdjustFrame(int scrnIndex, int x, int y, int flags)
Bool SavageSwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
{
TRACE(("SavageSwitchMode\n"));
+ SavageStreamsOff(xf86Screens[scrnIndex]);
return SavageModeInit(xf86Screens[scrnIndex], mode);
}
@@ -2953,14 +3106,48 @@ void SavageLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indicies,
{
SavagePtr psav = SAVPTR(pScrn);
int i, index;
-
+ int updateKey = -1;
+
for (i=0; i<numColors; i++) {
index = indicies[i];
+ if (index == pScrn->colorKey) updateKey = index;
VGAOUT8(0x3c8, index);
VGAOUT8(0x3c9, colors[index].red);
VGAOUT8(0x3c9, colors[index].green);
VGAOUT8(0x3c9, colors[index].blue);
}
+ if (updateKey != -1)
+ SavageUpdateKey(pScrn, colors[updateKey].red, colors[updateKey].green,
+ colors[updateKey].blue);
+}
+
+#define Shift(v,d) ((d) < 0 ? ((v) >> (-d)) : ((v) << (d)))
+
+static void
+SavageUpdateKey(ScrnInfoPtr pScrn, int r, int g, int b)
+{
+ ScreenPtr pScreen;
+ SavagePtr psav = SAVPTR(pScrn);
+ FbOverlayScrPrivPtr pScrOvlPriv;
+ CARD32 key;
+ int ul = 0, ol = 1;
+
+ if (pScrn->depth != 8) {
+ ul = 1;
+ ol = 0;
+ }
+ if (!(pScreen = pScrn->pScreen)
+ || !(pScrOvlPriv = fbOverlayGetScrPriv(pScreen)))
+ return;
+ key = ((Shift(r,psav->overlay.redShift) & psav->overlay.redMask)
+ | (Shift(g,psav->overlay.greenShift) & psav->overlay.greenMask)
+ | (Shift(b,psav->overlay.blueShift) & psav->overlay.blueMask));
+ if (pScrOvlPriv->layer[ol].key != key) {
+ pScrOvlPriv->layer[ol].key = key;
+ (*pScrOvlPriv->PaintKey) (&pScrOvlPriv->layer[ol].u.run.pixmap->drawable,
+ &pScrOvlPriv->layer[ul].u.run.region,
+ pScrOvlPriv->layer[ol].key, ol);
+ }
}
#define inStatus1() (hwp->readST01( hwp ))
@@ -2970,7 +3157,8 @@ void SavageLoadPaletteSavage4(ScrnInfoPtr pScrn, int numColors, int *indicies,
{
SavagePtr psav = SAVPTR(pScrn);
int i, index;
-
+ int updateKey = -1;
+
vgaHWPtr hwp = VGAHWPTR(pScrn);
VerticalRetraceWait(psav);
@@ -2982,11 +3170,13 @@ void SavageLoadPaletteSavage4(ScrnInfoPtr pScrn, int numColors, int *indicies,
VGAOUT8(0x3c9, colors[index].red);
VGAOUT8(0x3c9, colors[index].green);
VGAOUT8(0x3c9, colors[index].blue);
+ if (index == pScrn->colorKey) updateKey = index;
}
+ if (updateKey != -1)
+ SavageUpdateKey(pScrn, colors[updateKey].red, colors[updateKey].green,
+ colors[updateKey].blue);
}
-
-
static void SavageCalcClock(long freq, int min_m, int min_n1, int max_n1,
/* Make sure linear addressing is enabled after the BIOS call. */