summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Romanick <idr@us.ibm.com>2007-08-20 15:20:39 -0700
committerIan Romanick <idr@us.ibm.com>2007-08-20 15:20:39 -0700
commit707d3adbc7d9ee918d6c70083f51ad851ce68852 (patch)
treeca70f5609de3d2aa2311e3cc0fecf638707c0de8
parent741c50c162986a14647301c2c5f8e080a7664efd (diff)
parent489e007a29de63716ab550eacb3e98a91975d1d5 (diff)
Merge branch 'master' of git+ssh://git.freedesktop.org/git/xorg/driver/xf86-video-mga into pci-rework
-rw-r--r--mga_PInS.txt28
-rw-r--r--src/mga.h29
-rw-r--r--src/mga_dacG.c13
-rw-r--r--src/mga_dri.c219
-rw-r--r--src/mga_driver.c91
-rw-r--r--src/mga_exa.c133
-rw-r--r--src/mga_storm.c182
-rw-r--r--src/mga_vga.c207
-rw-r--r--src/mga_video.c780
-rw-r--r--util/stormdwg.c10
10 files changed, 1423 insertions, 269 deletions
diff --git a/mga_PInS.txt b/mga_PInS.txt
index bd2ec80..eda6cf9 100644
--- a/mga_PInS.txt
+++ b/mga_PInS.txt
@@ -221,7 +221,33 @@ Offset Type Description
9 Has DLL?
10 Core uses MCTLWTST?
11 - 15 MCTLWTST values for core?
-116 char[5] Unknown?
+116 uint16_t Display Info.
+ Bits Meaning
+ 0-3 Primary display info (see below)
+ 4-7 Secondary display info (see below)
+ 8-10 Primary modes (see below)
+ 13 Default output
+ 0 = default output is secondary connector
+ 1 = default output is primary connector
+ 12-14 Secondary modes (see below)
+ 15 Primary hardware dectect
+ 0 = hardware detection is off
+ 1 = use hardware detection to determine main output
+
+ Display info values:
+ 0000 None
+ 0001 HD15
+ 0010 DVI
+ 0011 TV
+ x1xx Reserved
+ 1xxx Reserved
+
+ Modes values:
+ xx1 Analog
+ x1x Digital
+ 1xx TV
+
+118 char[3] Unknown?
121 uint8_t VCO min for system PLL. Stored using standard clock
encoding (see above).
122 uint8_t VCO min for video PLL. Stored using standard clock
diff --git a/src/mga.h b/src/mga.h
index 4be0fbb..00f4741 100644
--- a/src/mga.h
+++ b/src/mga.h
@@ -148,6 +148,32 @@ void MGAdbg_outreg32(ScrnInfoPtr, int,int, char*);
outMGAdreg(MGA1064_DATA, tmp | (val)); \
} while (0)
+#define MGAWAITVSYNC() \
+ do { \
+ unsigned int count = 0; \
+ unsigned int status = 0; \
+ do { \
+ status = INREG( MGAREG_Status ); \
+ count++; \
+ } while( ( status & 0x08 ) && (count < 250000) );\
+ count = 0; \
+ status = 0; \
+ do { \
+ status = INREG( MGAREG_Status ); \
+ count++; \
+ } while( !( status & 0x08 ) && (count < 250000) );\
+ } while (0)
+
+#define MGAWAITBUSY() \
+ do { \
+ unsigned int count = 0; \
+ unsigned int status = 0; \
+ do { \
+ status = INREG8( MGAREG_Status + 2 ); \
+ count++; \
+ } while( ( status & 0x01 ) && (count < 500000) ); \
+ } while (0)
+
#define PORT_OFFSET (0x1F00 - 0x300)
#define MGA_VERSION 4000
@@ -730,6 +756,9 @@ long MGAG450SavePLLFreq(ScrnInfoPtr pScrn);
void MGAprintDac(ScrnInfoPtr pScrn);
void MGAG200SESaveFonts(ScrnInfoPtr, vgaRegPtr);
void MGAG200SERestoreFonts(ScrnInfoPtr, vgaRegPtr);
+void MGAG200SESaveMode(ScrnInfoPtr, vgaRegPtr);
+void MGAG200SERestoreMode(ScrnInfoPtr, vgaRegPtr);
+void MGAG200SEHWProtect(ScrnInfoPtr, Bool);
#ifdef USEMGAHAL
/************ ESC Call Definition ***************/
diff --git a/src/mga_dacG.c b/src/mga_dacG.c
index cd68cb1..350c160 100644
--- a/src/mga_dacG.c
+++ b/src/mga_dacG.c
@@ -416,11 +416,9 @@ MGAGInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
MGA1064_MISC_CTL_VGA8 |
MGA1064_MISC_CTL_DAC_RAM_CS;
- if(pMga->HasSDRAM)
- pReg->Option = 0x40499121;
- else
- pReg->Option = 0x4049cd21;
- pReg->Option2 = 0x00008000;
+ if (pMga->HasSDRAM)
+ pReg->Option = 0x40049120;
+ pReg->Option2 = 0x00008000;
break;
case PCI_CHIP_MGAG200:
case PCI_CHIP_MGAG200_PCI:
@@ -810,7 +808,7 @@ MGA_NOT_HAL(
/* This handles restoring the generic VGA registers. */
if (pMga->is_G200SE) {
- vgaHWRestore(pScrn, vgaReg, VGA_SR_MODE);
+ MGAG200SERestoreMode(pScrn, vgaReg);
if (restoreFonts)
MGAG200SERestoreFonts(pScrn, vgaReg);
} else {
@@ -910,7 +908,7 @@ MGAGSave(ScrnInfoPtr pScrn, vgaRegPtr vgaReg, MGARegPtr mgaReg,
* in the generic VGA portion.
*/
if (pMga->is_G200SE) {
- vgaHWSave(pScrn, vgaReg, VGA_SR_MODE);
+ MGAG200SESaveMode(pScrn, vgaReg);
if (saveFonts)
MGAG200SESaveFonts(pScrn, vgaReg);
} else {
@@ -965,6 +963,7 @@ MGAGSave(ScrnInfoPtr pScrn, vgaRegPtr vgaReg, MGARegPtr mgaReg,
OUTREG8(MGAREG_CRTCEXT_INDEX, i);
mgaReg->ExtVga[i] = INREG8(MGAREG_CRTCEXT_DATA);
}
+
#ifdef DEBUG
ErrorF("Saved values:\nDAC:");
for (i=0; i<DACREGSIZE; i++) {
diff --git a/src/mga_dri.c b/src/mga_dri.c
index dd0c2fd..bb2cc39 100644
--- a/src/mga_dri.c
+++ b/src/mga_dri.c
@@ -76,13 +76,6 @@
static char MGAKernelDriverName[] = "mga";
static char MGAClientDriverName[] = "mga";
-/* DRI buffer management
- */
-extern void mgaDRIInitBuffers( WindowPtr pWin, RegionPtr prgn, CARD32 index );
-extern void mgaDRIMoveBuffers( WindowPtr pParent, DDXPointRec ptOldOrg,
- RegionPtr prgnSrc, CARD32 index );
-
-
/* Initialize the visual configs that are supported by the hardware.
* These are combined with the visual configs that the indirect
* rendering core supports, and the intersection is exported to the
@@ -496,7 +489,6 @@ MGADRISwapContextShared( ScreenPtr pScreen, DRISyncType syncType,
}
}
-#ifdef USE_XAA
void MGASelectBuffer( ScrnInfoPtr pScrn, int which )
{
MGAPtr pMga = MGAPTR(pScrn);
@@ -518,8 +510,6 @@ void MGASelectBuffer( ScrnInfoPtr pScrn, int which )
break;
}
}
-#endif
-
static unsigned int mylog2( unsigned int n )
{
@@ -903,6 +893,200 @@ static Bool MGADRIBuffersInit( ScreenPtr pScreen )
return TRUE;
}
+#ifdef USE_XAA
+static void MGADRIInitBuffersXAA(WindowPtr pWin, RegionPtr prgn,
+ CARD32 index)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ MGAPtr pMga = MGAPTR(pScrn);
+ BoxPtr pbox = REGION_RECTS(prgn);
+ int nbox = REGION_NUM_RECTS(prgn);
+ XAAInfoRecPtr xaa = pMga->AccelInfoRec;
+
+ CHECK_DMA_QUIESCENT(MGAPTR(pScrn), pScrn);
+
+ xaa->SetupForSolidFill(pScrn, 0, GXcopy, -1);
+
+ while (nbox--) {
+ MGASelectBuffer(pScrn, MGA_BACK);
+ xaa->SubsequentSolidFillRect(pScrn, pbox->x1, pbox->y1,
+ pbox->x2-pbox->x1, pbox->y2-pbox->y1);
+ MGASelectBuffer(pScrn, MGA_DEPTH);
+ xaa->SubsequentSolidFillRect(pScrn, pbox->x1, pbox->y1,
+ pbox->x2-pbox->x1, pbox->y2-pbox->y1);
+ pbox++;
+ }
+
+ MGASelectBuffer(pScrn, MGA_FRONT);
+
+ pMga->AccelInfoRec->NeedToSync = TRUE;
+}
+#endif
+
+#ifdef USE_EXA
+static void MGADRIInitBuffersEXA(WindowPtr pWin, RegionPtr prgn,
+ CARD32 index)
+{
+ /* FIXME */
+}
+#endif
+
+#ifdef USE_XAA
+/*
+ This routine is a modified form of XAADoBitBlt with the calls to
+ ScreenToScreenBitBlt built in. My routine has the prgnSrc as source
+ instead of destination. My origin is upside down so the ydir cases
+ are reversed.
+*/
+static void MGADRIMoveBuffersXAA(WindowPtr pParent, DDXPointRec ptOldOrg,
+ RegionPtr prgnSrc, CARD32 index)
+{
+ ScreenPtr pScreen = pParent->drawable.pScreen;
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ MGAPtr pMga = MGAPTR(pScrn);
+ int nbox;
+ BoxPtr pbox, pboxTmp, pboxNext, pboxBase, pboxNew1, pboxNew2;
+ DDXPointPtr pptTmp, pptNew1, pptNew2;
+ int xdir, ydir;
+ int dx, dy;
+ DDXPointPtr pptSrc;
+ int screenwidth = pScrn->virtualX;
+ int screenheight = pScrn->virtualY;
+ XAAInfoRecPtr xaa = pMga->AccelInfoRec;
+
+ CHECK_DMA_QUIESCENT(pMga, pScrn);
+
+ pbox = REGION_RECTS(prgnSrc);
+ nbox = REGION_NUM_RECTS(prgnSrc);
+ pboxNew1 = 0;
+ pptNew1 = 0;
+ pboxNew2 = 0;
+ pboxNew2 = 0;
+ pptSrc = &ptOldOrg;
+
+ dx = pParent->drawable.x - ptOldOrg.x;
+ dy = pParent->drawable.y - ptOldOrg.y;
+
+ /* If the copy will overlap in Y, reverse the order */
+ if (dy>0) {
+ ydir = -1;
+
+ if (nbox>1) {
+ /* Keep ordering in each band, reverse order of bands */
+ pboxNew1 = (BoxPtr)ALLOCATE_LOCAL(sizeof(BoxRec)*nbox);
+ if (!pboxNew1) return;
+ pptNew1 = (DDXPointPtr)ALLOCATE_LOCAL(sizeof(DDXPointRec)*nbox);
+ if (!pptNew1) {
+ DEALLOCATE_LOCAL(pboxNew1);
+ return;
+ }
+ pboxBase = pboxNext = pbox+nbox-1;
+ while (pboxBase >= pbox) {
+ while ((pboxNext >= pbox) && (pboxBase->y1 == pboxNext->y1))
+ pboxNext--;
+ pboxTmp = pboxNext+1;
+ pptTmp = pptSrc + (pboxTmp - pbox);
+ while (pboxTmp <= pboxBase) {
+ *pboxNew1++ = *pboxTmp++;
+ *pptNew1++ = *pptTmp++;
+ }
+ pboxBase = pboxNext;
+ }
+ pboxNew1 -= nbox;
+ pbox = pboxNew1;
+ pptNew1 -= nbox;
+ pptSrc = pptNew1;
+ }
+ } else {
+ /* No changes required */
+ ydir = 1;
+ }
+
+ /* If the regions will overlap in X, reverse the order */
+ if (dx>0) {
+ xdir = -1;
+
+ if (nbox > 1) {
+ /*reverse orderof rects in each band */
+ pboxNew2 = (BoxPtr)ALLOCATE_LOCAL(sizeof(BoxRec)*nbox);
+ pptNew2 = (DDXPointPtr)ALLOCATE_LOCAL(sizeof(DDXPointRec)*nbox);
+ if (!pboxNew2 || !pptNew2) {
+ if (pptNew2) DEALLOCATE_LOCAL(pptNew2);
+ if (pboxNew2) DEALLOCATE_LOCAL(pboxNew2);
+ if (pboxNew1) {
+ DEALLOCATE_LOCAL(pptNew1);
+ DEALLOCATE_LOCAL(pboxNew1);
+ }
+ return;
+ }
+ pboxBase = pboxNext = pbox;
+ while (pboxBase < pbox+nbox) {
+ while ((pboxNext < pbox+nbox) &&
+ (pboxNext->y1 == pboxBase->y1))
+ pboxNext++;
+ pboxTmp = pboxNext;
+ pptTmp = pptSrc + (pboxTmp - pbox);
+ while (pboxTmp != pboxBase) {
+ *pboxNew2++ = *--pboxTmp;
+ *pptNew2++ = *--pptTmp;
+ }
+ pboxBase = pboxNext;
+ }
+ pboxNew2 -= nbox;
+ pbox = pboxNew2;
+ pptNew2 -= nbox;
+ pptSrc = pptNew2;
+ }
+ } else {
+ /* No changes are needed */
+ xdir = 1;
+ }
+
+ xaa->SetupForScreenToScreenCopy(pScrn, xdir, ydir, GXcopy, -1, -1);
+ for ( ; nbox-- ; pbox++) {
+ int x1 = pbox->x1;
+ int y1 = pbox->y1;
+ int destx = x1 + dx;
+ int desty = y1 + dy;
+ int w = pbox->x2 - x1 + 1;
+ int h = pbox->y2 - y1 + 1;
+
+ if ( destx < 0 ) x1 -= destx, w += destx, destx = 0;
+ if ( desty < 0 ) y1 -= desty, h += desty, desty = 0;
+ if ( destx + w > screenwidth ) w = screenwidth - destx;
+ if ( desty + h > screenheight ) h = screenheight - desty;
+ if ( w <= 0 ) continue;
+ if ( h <= 0 ) continue;
+
+ MGASelectBuffer(pScrn, MGA_BACK);
+ xaa->SubsequentScreenToScreenCopy(pScrn, x1, y1, destx, desty, w, h);
+ MGASelectBuffer(pScrn, MGA_DEPTH);
+ xaa->SubsequentScreenToScreenCopy(pScrn, x1, y1, destx, desty, w, h);
+ }
+ MGASelectBuffer(pScrn, MGA_FRONT);
+
+ if (pboxNew2) {
+ DEALLOCATE_LOCAL(pptNew2);
+ DEALLOCATE_LOCAL(pboxNew2);
+ }
+ if (pboxNew1) {
+ DEALLOCATE_LOCAL(pptNew1);
+ DEALLOCATE_LOCAL(pboxNew1);
+ }
+
+ pMga->AccelInfoRec->NeedToSync = TRUE;
+
+}
+#endif
+
+#ifdef USE_EXA
+static void MGADRIMoveBuffersEXA(WindowPtr pParent, DDXPointRec ptOldOrg,
+ RegionPtr prgnSrc, CARD32 index)
+{
+ /* FIXME */
+}
+#endif
Bool MGADRIScreenInit( ScreenPtr pScreen )
{
@@ -1044,8 +1228,19 @@ Bool MGADRIScreenInit( ScreenPtr pScreen )
pDRIInfo->SwapContext = MGADRISwapContext;
}
- pDRIInfo->InitBuffers = mgaDRIInitBuffers;
- pDRIInfo->MoveBuffers = mgaDRIMoveBuffers;
+#ifdef USE_EXA
+ if (pMga->Exa) {
+ pDRIInfo->InitBuffers = MGADRIInitBuffersEXA;
+ pDRIInfo->MoveBuffers = MGADRIMoveBuffersEXA;
+ } else {
+#endif
+#ifdef USE_XAA
+ pDRIInfo->InitBuffers = MGADRIInitBuffersXAA;
+ pDRIInfo->MoveBuffers = MGADRIMoveBuffersXAA;
+#endif
+#ifdef USE_EXA
+ }
+#endif
pDRIInfo->bufferRequests = DRI_ALL_WINDOWS;
diff --git a/src/mga_driver.c b/src/mga_driver.c
index 866e46a..2c9c6ef 100644
--- a/src/mga_driver.c
+++ b/src/mga_driver.c
@@ -755,6 +755,7 @@ MGACountRam(ScrnInfoPtr pScrn)
int ProbeSize = 8192;
int SizeFound = 2048;
CARD32 biosInfo = 0;
+ CARD8 seq1;
#if 0
/* This isn't correct. It looks like this can have arbitrary
@@ -832,6 +833,16 @@ MGACountRam(ScrnInfoPtr pScrn)
base = pMga->FbBase;
+ if (pMga->is_G200SE) {
+ OUTREG8(MGAREG_SEQ_INDEX, 0x01);
+ seq1 = INREG8(MGAREG_SEQ_DATA);
+ seq1 |= 0x20;
+ MGAWAITVSYNC();
+ MGAWAITBUSY();
+ OUTREG8(MGAREG_SEQ_DATA, seq1);
+ usleep(20000);
+ }
+
/* turn MGA mode on - enable linear frame buffer (CRTCEXT3) */
OUTREG8(MGAREG_CRTCEXT_INDEX, 3);
tmp = INREG8(MGAREG_CRTCEXT_DATA);
@@ -852,7 +863,7 @@ MGACountRam(ScrnInfoPtr pScrn)
base[1] = 0;
for (Offset = 0x100000; Offset < (ProbeSize * 1024);
- Offset += 0x1000) {
+ Offset += 0x1000) {
FirstMemoryVal1 = base[Offset];
FirstMemoryVal2 = base[Offset+1];
SecondMemoryVal1 = base[Offset+0x100];
@@ -907,8 +918,17 @@ MGACountRam(ScrnInfoPtr pScrn)
OUTREG8(MGAREG_CRTCEXT_INDEX, 3);
OUTREG8(MGAREG_CRTCEXT_DATA, tmp);
+ if (pMga->is_G200SE) {
+ OUTREG8(MGAREG_SEQ_INDEX, 0x01);
+ seq1 = INREG8(MGAREG_SEQ_DATA);
+ seq1 &= ~0x20;
+ MGAWAITVSYNC();
+ MGAWAITBUSY();
+ OUTREG8(MGAREG_SEQ_DATA, seq1);
+ usleep(20000);
+ }
MGAUnmapMem(pScrn);
- }
+ }
return SizeFound;
}
@@ -1409,6 +1429,9 @@ MGAPreInit(ScrnInfoPtr pScrn, int flags)
if (pMga->SecondCrtc)
flags24 = Support32bppFb;
+ if (pMga->is_G200SE)
+ pScrn->confScreen->defaultdepth = 16;
+
if (!xf86SetDepthBpp(pScrn, 0, 0, 0, flags24)) {
return FALSE;
} else {
@@ -1459,6 +1482,14 @@ MGAPreInit(ScrnInfoPtr pScrn, int flags)
memcpy(pMga->Options, MGAOptions, sizeof(MGAOptions));
xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pMga->Options);
+ if (pMga->is_G200SE) {
+ /* Disable MTRR support on PCIe systems */
+ CARD32 temp = pciReadLong(pMga->PciTag, 0xDC);
+ if ((temp & 0x0000FF00) != 0x0) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Disabling MTRR support.\n");
+ pScrn->options = xf86ReplaceBoolOption(pScrn->options, "MTRR", FALSE);
+ }
+ }
#if !defined(__powerpc__)
pMga->softbooted = FALSE;
@@ -1890,6 +1921,21 @@ MGAPreInit(ScrnInfoPtr pScrn, int flags)
pScrn->monitor->DDC = MGAdoDDC(pScrn);
#endif /* !__powerpc__ */
+ if (!pScrn->monitor->DDC && pMga->is_G200SE) {
+ /* Jam in ranges big enough for 1024x768 */
+ if (!pScrn->monitor->nHsync) {
+ pScrn->monitor->nHsync = 1;
+ pScrn->monitor->hsync[0].lo = 31.5;
+ pScrn->monitor->hsync[0].hi = 48.0;
+ }
+ if (!pScrn->monitor->nVrefresh) {
+ pScrn->monitor->nVrefresh = 1;
+ pScrn->monitor->vrefresh[0].lo = 56.0;
+ pScrn->monitor->vrefresh[0].hi = 75.0;
+ }
+ }
+
+
/*
* If the driver can do gamma correction, it should call xf86SetGamma()
* here.
@@ -1907,7 +1953,7 @@ MGAPreInit(ScrnInfoPtr pScrn, int flags)
/* XXX Set HW cursor use */
/* Set the min pixel clock */
- pMga->MinClock = 12000; /* XXX Guess, need to check this */
+ pMga->MinClock = 17750;
xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT, "Min pixel clock is %d MHz\n",
pMga->MinClock / 1000);
/*
@@ -2686,7 +2732,11 @@ MGAModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
return FALSE;
/* Program the registers */
- vgaHWProtect(pScrn, TRUE);
+ if (pMga->is_G200SE) {
+ MGAG200SEHWProtect(pScrn, TRUE);
+ } else {
+ vgaHWProtect(pScrn, TRUE);
+ }
vgaReg = &hwp->ModeReg;
mgaReg = &pMga->ModeReg;
#ifdef USEMGAHAL
@@ -2790,7 +2840,11 @@ MGA_HAL(
MGAStormSync(pScrn);
MGAStormEngineInit(pScrn);
- vgaHWProtect(pScrn, FALSE);
+ if (pMga->is_G200SE) {
+ MGAG200SEHWProtect(pScrn,FALSE);
+ } else {
+ vgaHWProtect(pScrn, FALSE);
+ }
if (xf86IsPc98()) {
if (pMga->Chipset == PCI_CHIP_MGA2064)
@@ -2799,6 +2853,13 @@ MGA_HAL(
outb(0xfac, 0x02);
}
+ MGA_NOT_HAL(
+ if (pMga->is_G200SE) {
+ OUTREG8(0x1FDE, 0x06);
+ OUTREG8(0x1FDF, 0x14);
+ }
+ );
+
pMga->CurrentLayout.mode = mode;
if(pMga->MergedFB && mode->Private && (mode->PrivSize == 0)) {
@@ -2895,7 +2956,11 @@ MGARestore(ScrnInfoPtr pScrn)
}
/* Only restore text mode fonts/text for the primary card */
- vgaHWProtect(pScrn, TRUE);
+ if (pMga->is_G200SE) {
+ MGAG200SEHWProtect(pScrn,TRUE);
+ } else {
+ vgaHWProtect(pScrn, TRUE);
+ }
if (pMga->Primary) {
#ifdef USEMGAHAL
MGA_HAL(
@@ -2909,7 +2974,12 @@ MGARestore(ScrnInfoPtr pScrn)
} else {
vgaHWRestore(pScrn, vgaReg, VGA_SR_MODE);
}
- vgaHWProtect(pScrn, FALSE);
+
+ if (pMga->is_G200SE) {
+ MGAG200SEHWProtect(pScrn,FALSE);
+ } else {
+ vgaHWProtect(pScrn,FALSE);
+ }
}
@@ -3202,8 +3272,7 @@ MGAScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
* InitGLXVisuals call back.
* The DRI does not work when textured video is enabled at this time.
*/
- if ((pMga->Chipset == PCI_CHIP_MGAG200_SE_A_PCI) ||
- (pMga->Chipset == PCI_CHIP_MGAG200_SE_B_PCI)) {
+ if (pMga->is_G200SE) {
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
"Not supported by hardware, not initializing the DRI\n");
pMga->directRenderingEnabled = FALSE;
@@ -3933,10 +4002,14 @@ MGADisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode,
crtcext1 = 0x30;
break;
}
+
/* XXX Prefer an implementation that doesn't depend on VGA specifics */
OUTREG8(MGAREG_SEQ_INDEX, 0x01); /* Select SEQ1 */
seq1 |= INREG8(MGAREG_SEQ_DATA) & ~0x20;
+ MGAWAITVSYNC();
+ MGAWAITBUSY();
OUTREG8(MGAREG_SEQ_DATA, seq1);
+ usleep(20000);
OUTREG8(MGAREG_CRTCEXT_INDEX, 0x01); /* Select CRTCEXT1 */
crtcext1 |= INREG8(MGAREG_CRTCEXT_DATA) & ~0x30;
OUTREG8(MGAREG_CRTCEXT_DATA, crtcext1);
diff --git a/src/mga_exa.c b/src/mga_exa.c
index 17618f5..bfb78e7 100644
--- a/src/mga_exa.c
+++ b/src/mga_exa.c
@@ -227,11 +227,6 @@ mgaPrepareCopy(PixmapPtr pSrc, PixmapPtr pDst, int xdir, int ydir, int alu,
*/
QUIESCE_DMA(pSrc);
- DEBUG_MSG(("s: %x@%x d: %x@%x xdir %d ydir %d alu %d pm %d\n",
- exaGetPixmapOffset(pSrc), exaGetPixmapPitch(pSrc),
- exaGetPixmapOffset(pDst), exaGetPixmapPitch(pDst),
- xdir, ydir, alu, planemask));
-
if (xdir < 0)
blit_direction |= BLIT_LEFT;
@@ -261,8 +256,6 @@ mgaCopy(PixmapPtr pDst, int srcx, int srcy, int dstx, int dsty, int w, int h)
PMGA(pDst);
int start, end;
- DEBUG_MSG((" %d,%d -> %d,%d %dx%d\n", srcx, srcy, dstx,dsty, w, h));
-
w--;
if (pMga->BltScanDirection & BLIT_UP) {
@@ -277,9 +270,6 @@ mgaCopy(PixmapPtr pDst, int srcx, int srcy, int dstx, int dsty, int w, int h)
else
end += w;
- DEBUG_MSG((" end %d start %d dstx %d dsty %d w %d h %d\n",
- end, start, dstx, dsty, w, h));
-
WAITFIFO(4);
OUTREG(MGAREG_AR0, end);
OUTREG(MGAREG_AR3, start);
@@ -360,6 +350,8 @@ static Bool
mgaCheckComposite(int op, PicturePtr pSrcPict, PicturePtr pMaskPict,
PicturePtr pDstPict)
{
+ MGAPtr pMga = xf86Screens[pSrcPict->pDrawable->pScreen->myNum]->driverPrivate;
+
if (op >= sizeof(mgaBlendOp) / sizeof(mgaBlendOp[0])) {
DEBUG_MSG(("unsupported op %x\n", op));
return FALSE;
@@ -383,10 +375,9 @@ mgaCheckComposite(int op, PicturePtr pSrcPict, PicturePtr pMaskPict,
return FALSE;
}
- /* FIXME
- * Doing this operation in hardware is broken atm :/
- */
- if (op == PictOpAdd && pSrcPict->format == PICT_a8 &&
+ /* Only the G550 can perform Add on A8 textures, it seems. */
+ if (pMga->Chipset != PCI_CHIP_MGAG550 &&
+ op == PictOpAdd && pSrcPict->format == PICT_a8 &&
pDstPict->format == PICT_a8)
return FALSE;
@@ -594,15 +585,6 @@ mgaPrepareComposite(int op, PicturePtr pSrcPict, PicturePtr pMaskPict,
blendcntl = (blendcntl & ~MGA_SRC_BLEND_MASK) | MGA_SRC_ZERO;
}
- if (!PICT_FORMAT_A(pSrcPict->format) && mgaBlendOp[op].src_alpha) {
- int dblend = blendcntl & MGA_DST_BLEND_MASK;
-
- if (dblend == MGA_DST_SRC_ALPHA)
- blendcntl = (blendcntl & ~MGA_DST_BLEND_MASK) | MGA_DST_ONE;
- else if (dblend == MGA_DST_ONE_MINUS_SRC_ALPHA)
- blendcntl = (blendcntl & ~MGA_DST_BLEND_MASK) | MGA_DST_ZERO;
- }
-
WAITFIFO(5);
OUTREG(MGAREG_FCOL, fcol);
OUTREG(MGAREG_TDUALSTAGE0, ds0);
@@ -732,6 +714,33 @@ mgaUploadToScreen(PixmapPtr pDst, int x, int y, int w, int h,
src += src_pitch;
}
+ exaMarkSync(pDst->drawable.pScreen);
+
+ return TRUE;
+}
+
+static Bool
+mgaDownloadFromScreen(PixmapPtr pSrc, int x, int y, int w, int h,
+ char *dst, int dst_pitch)
+{
+ PMGA(pSrc);
+
+ char *src = pSrc->devPrivate.ptr;
+ int src_pitch = exaGetPixmapPitch(pSrc);
+
+ int cpp = (pSrc->drawable.bitsPerPixel + 7) / 8;
+ int bytes = w * cpp;
+
+ src += y * src_pitch + x * cpp;
+
+ QUIESCE_DMA(pSrc);
+
+ while (h--) {
+ memcpy (dst, src, bytes);
+ src += src_pitch;
+ dst += dst_pitch;
+ }
+
return TRUE;
}
@@ -749,6 +758,80 @@ mgaWaitMarker(ScreenPtr pScreen, int marker)
while (INREG (MGAREG_Status) & 0x10000);
}
+static void
+init_dri(ScrnInfoPtr pScrn)
+{
+ MGAPtr pMga = MGAPTR(pScrn);
+ MGADRIServerPrivatePtr dri = pMga->DRIServerInfo;
+ int cpp = pScrn->bitsPerPixel / 8;
+ int widthBytes = pScrn->displayWidth * cpp;
+ int bufferSize = ((pScrn->virtualY * widthBytes + MGA_BUFFER_ALIGN)
+ & ~MGA_BUFFER_ALIGN);
+ int maxlines, mb;
+
+ switch (pMga->Chipset) {
+ case PCI_CHIP_MGAG200_SE_A_PCI:
+ case PCI_CHIP_MGAG200_SE_B_PCI:
+ mb = 1;
+ break;
+ default:
+ mb = 16;
+ break;
+ }
+
+ maxlines = (min(pMga->FbUsableSize, mb * 1024 * 1024)) /
+ (pScrn->displayWidth * pMga->CurrentLayout.bitsPerPixel / 8);
+
+ dri->frontOffset = 0;
+ dri->frontPitch = widthBytes;
+
+ /* Try for front, back, depth, and two framebuffers worth of
+ * pixmap cache. Should be enough for a fullscreen background
+ * image plus some leftovers.
+ */
+ dri->textureSize = pMga->FbMapSize - 5 * bufferSize;
+
+ /* If that gives us less than half the available memory, let's
+ * be greedy and grab some more. Sorry, I care more about 3D
+ * performance than playing nicely, and you'll get around a full
+ * framebuffer's worth of pixmap cache anyway.
+ */
+ if (dri->textureSize < (int)pMga->FbMapSize / 2) {
+ dri->textureSize = pMga->FbMapSize - 4 * bufferSize;
+ }
+
+ /* Check to see if there is more room available after the maximum
+ * scanline for textures.
+ */
+ if ((int) pMga->FbMapSize - maxlines * widthBytes - bufferSize * 2
+ > dri->textureSize) {
+ dri->textureSize = pMga->FbMapSize - maxlines * widthBytes -
+ bufferSize * 2;
+ }
+
+ /* Set a minimum usable local texture heap size. This will fit
+ * two 256x256x32bpp textures.
+ */
+ if (dri->textureSize < 512 * 1024) {
+ dri->textureOffset = 0;
+ dri->textureSize = 0;
+ }
+
+ /* Reserve space for textures */
+ dri->textureOffset = (pMga->FbMapSize - dri->textureSize +
+ MGA_BUFFER_ALIGN) & ~MGA_BUFFER_ALIGN;
+
+ /* Reserve space for the shared depth buffer */
+ dri->depthOffset = (dri->textureOffset - bufferSize +
+ MGA_BUFFER_ALIGN) & ~MGA_BUFFER_ALIGN;
+ dri->depthPitch = widthBytes;
+
+ /* Reserve space for the shared back buffer */
+ dri->backOffset = (dri->depthOffset - bufferSize +
+ MGA_BUFFER_ALIGN) & ~MGA_BUFFER_ALIGN;
+ dri->backPitch = widthBytes;
+}
+
Bool
mgaExaInit(ScreenPtr pScreen)
{
@@ -806,6 +889,10 @@ mgaExaInit(ScreenPtr pScreen)
}
pExa->UploadToScreen = mgaUploadToScreen;
+ pExa->DownloadFromScreen = mgaDownloadFromScreen;
+
+ if (pMga->directRenderingEnabled)
+ init_dri(pScrn);
return exaDriverInit(pScreen, pExa);
}
diff --git a/src/mga_storm.c b/src/mga_storm.c
index 23801ac..dfdebeb 100644
--- a/src/mga_storm.c
+++ b/src/mga_storm.c
@@ -143,12 +143,6 @@ static void mgaSubsequentDashedTwoPointLine( ScrnInfoPtr pScrn,
static void mgaRestoreAccelState( ScrnInfoPtr pScrn );
-#ifdef XF86DRI
-void mgaDRIInitBuffers(WindowPtr pWin, RegionPtr prgn, CARD32 index);
-void mgaDRIMoveBuffers(WindowPtr pParent, DDXPointRec ptOldOrg,
- RegionPtr prgnSrc, CARD32 index);
-#endif
-
static void MGASetClippingRectangle(ScrnInfoPtr pScrn, int x1, int y1,
int x2, int y2);
static void MGADisableClipping(ScrnInfoPtr pScrn);
@@ -2543,179 +2537,3 @@ MGAFillCacheBltRects(
SET_SYNC_FLAG(infoRec);
}
-
-
-#if defined(XF86DRI)
-void
-mgaDRIInitBuffers(WindowPtr pWin, RegionPtr prgn, CARD32 index)
-{
- ScreenPtr pScreen = pWin->drawable.pScreen;
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- MGAPtr pMga = MGAPTR(pScrn);
- BoxPtr pbox = REGION_RECTS(prgn);
- int nbox = REGION_NUM_RECTS(prgn);
-
- CHECK_DMA_QUIESCENT(MGAPTR(pScrn), pScrn);
-
- mgaSetupForSolidFill(pScrn, 0, GXcopy, -1);
- while (nbox--) {
- MGASelectBuffer(pScrn, MGA_BACK);
- mgaSubsequentSolidFillRect(pScrn, pbox->x1, pbox->y1,
- pbox->x2-pbox->x1, pbox->y2-pbox->y1);
- MGASelectBuffer(pScrn, MGA_DEPTH);
- mgaSubsequentSolidFillRect(pScrn, pbox->x1, pbox->y1,
- pbox->x2-pbox->x1, pbox->y2-pbox->y1);
- pbox++;
- }
- MGASelectBuffer(pScrn, MGA_FRONT);
-
- pMga->AccelInfoRec->NeedToSync = TRUE;
-}
-
-/*
- This routine is a modified form of XAADoBitBlt with the calls to
- ScreenToScreenBitBlt built in. My routine has the prgnSrc as source
- instead of destination. My origin is upside down so the ydir cases
- are reversed.
-*/
-
-void
-mgaDRIMoveBuffers(WindowPtr pParent, DDXPointRec ptOldOrg,
- RegionPtr prgnSrc, CARD32 index)
-{
- ScreenPtr pScreen = pParent->drawable.pScreen;
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- MGAPtr pMga = MGAPTR(pScrn);
- int nbox;
- BoxPtr pbox, pboxTmp, pboxNext, pboxBase, pboxNew1, pboxNew2;
- DDXPointPtr pptTmp, pptNew1, pptNew2;
- int xdir, ydir;
- int dx, dy;
- DDXPointPtr pptSrc;
- int screenwidth = pScrn->virtualX;
- int screenheight = pScrn->virtualY;
-
- CHECK_DMA_QUIESCENT(MGAPTR(pScrn), pScrn);
-
- pbox = REGION_RECTS(prgnSrc);
- nbox = REGION_NUM_RECTS(prgnSrc);
- pboxNew1 = 0;
- pptNew1 = 0;
- pboxNew2 = 0;
- pboxNew2 = 0;
- pptSrc = &ptOldOrg;
-
- dx = pParent->drawable.x - ptOldOrg.x;
- dy = pParent->drawable.y - ptOldOrg.y;
-
- /* If the copy will overlap in Y, reverse the order */
- if (dy>0) {
- ydir = -1;
-
- if (nbox>1) {
- /* Keep ordering in each band, reverse order of bands */
- pboxNew1 = (BoxPtr)ALLOCATE_LOCAL(sizeof(BoxRec)*nbox);
- if (!pboxNew1) return;
- pptNew1 = (DDXPointPtr)ALLOCATE_LOCAL(sizeof(DDXPointRec)*nbox);
- if (!pptNew1) {
- DEALLOCATE_LOCAL(pboxNew1);
- return;
- }
- pboxBase = pboxNext = pbox+nbox-1;
- while (pboxBase >= pbox) {
- while ((pboxNext >= pbox) && (pboxBase->y1 == pboxNext->y1))
- pboxNext--;
- pboxTmp = pboxNext+1;
- pptTmp = pptSrc + (pboxTmp - pbox);
- while (pboxTmp <= pboxBase) {
- *pboxNew1++ = *pboxTmp++;
- *pptNew1++ = *pptTmp++;
- }
- pboxBase = pboxNext;
- }
- pboxNew1 -= nbox;
- pbox = pboxNew1;
- pptNew1 -= nbox;
- pptSrc = pptNew1;
- }
- } else {
- /* No changes required */
- ydir = 1;
- }
-
- /* If the regions will overlap in X, reverse the order */
- if (dx>0) {
- xdir = -1;
-
- if (nbox > 1) {
- /*reverse orderof rects in each band */
- pboxNew2 = (BoxPtr)ALLOCATE_LOCAL(sizeof(BoxRec)*nbox);
- pptNew2 = (DDXPointPtr)ALLOCATE_LOCAL(sizeof(DDXPointRec)*nbox);
- if (!pboxNew2 || !pptNew2) {
- if (pptNew2) DEALLOCATE_LOCAL(pptNew2);
- if (pboxNew2) DEALLOCATE_LOCAL(pboxNew2);
- if (pboxNew1) {
- DEALLOCATE_LOCAL(pptNew1);
- DEALLOCATE_LOCAL(pboxNew1);
- }
- return;
- }
- pboxBase = pboxNext = pbox;
- while (pboxBase < pbox+nbox) {
- while ((pboxNext < pbox+nbox) &&
- (pboxNext->y1 == pboxBase->y1))
- pboxNext++;
- pboxTmp = pboxNext;
- pptTmp = pptSrc + (pboxTmp - pbox);
- while (pboxTmp != pboxBase) {
- *pboxNew2++ = *--pboxTmp;
- *pptNew2++ = *--pptTmp;
- }
- pboxBase = pboxNext;
- }
- pboxNew2 -= nbox;
- pbox = pboxNew2;
- pptNew2 -= nbox;
- pptSrc = pptNew2;
- }
- } else {
- /* No changes are needed */
- xdir = 1;
- }
-
- mgaSetupForScreenToScreenCopy(pScrn, xdir, ydir, GXcopy, -1, -1);
- for ( ; nbox-- ; pbox++) {
- int x1 = pbox->x1;
- int y1 = pbox->y1;
- int destx = x1 + dx;
- int desty = y1 + dy;
- int w = pbox->x2 - x1 + 1;
- int h = pbox->y2 - y1 + 1;
-
- if ( destx < 0 ) x1 -= destx, w += destx, destx = 0;
- if ( desty < 0 ) y1 -= desty, h += desty, desty = 0;
- if ( destx + w > screenwidth ) w = screenwidth - destx;
- if ( desty + h > screenheight ) h = screenheight - desty;
- if ( w <= 0 ) continue;
- if ( h <= 0 ) continue;
-
- MGASelectBuffer(pScrn, MGA_BACK);
- mgaSubsequentScreenToScreenCopy(pScrn, x1, y1, destx, desty, w, h);
- MGASelectBuffer(pScrn, MGA_DEPTH);
- mgaSubsequentScreenToScreenCopy(pScrn, x1, y1, destx, desty, w, h);
- }
- MGASelectBuffer(pScrn, MGA_FRONT);
-
- if (pboxNew2) {
- DEALLOCATE_LOCAL(pptNew2);
- DEALLOCATE_LOCAL(pboxNew2);
- }
- if (pboxNew1) {
- DEALLOCATE_LOCAL(pptNew1);
- DEALLOCATE_LOCAL(pboxNew1);
- }
-
- pMga->AccelInfoRec->NeedToSync = TRUE;
-}
-
-#endif /* XF86DRI */
diff --git a/src/mga_vga.c b/src/mga_vga.c
index fbbfc60..8dfc08f 100644
--- a/src/mga_vga.c
+++ b/src/mga_vga.c
@@ -4,6 +4,8 @@
#include "vgaHW.h"
#include "compiler.h"
#include "xf86cmap.h"
+#include "mga.h"
+#include "mga_reg.h"
#define TEXT_AMOUNT 16384
#define FONT_AMOUNT (8*8192)
@@ -12,9 +14,11 @@ void
MGAG200SERestoreFonts(ScrnInfoPtr scrninfp, vgaRegPtr restore)
{
vgaHWPtr hwp = VGAHWPTR(scrninfp);
+ MGAPtr pMga = MGAPTR(scrninfp);
int savedIOBase;
unsigned char miscOut, attr10, gr1, gr3, gr4, gr5, gr6, gr8, seq2, seq4;
Bool doMap = FALSE;
+ unsigned char scrn;
/* If nothing to do, return now */
if (!hwp->FontInfo1 && !hwp->FontInfo2 && !hwp->TextInfo)
@@ -48,7 +52,14 @@ MGAG200SERestoreFonts(ScrnInfoPtr scrninfp, vgaRegPtr restore)
/* Force into colour mode */
hwp->writeMiscOut(hwp, miscOut | 0x01);
- vgaHWBlankScreen(scrninfp, FALSE);
+ scrn = hwp->readSeq(hwp, 0x01);
+ scrn |= 0x20;/* blank screen */
+ vgaHWSeqReset(hwp, TRUE);
+ MGAWAITVSYNC();
+ MGAWAITBUSY();
+ hwp->writeSeq(hwp, 0x01, scrn);/* change mode */
+ usleep(20000);
+ vgaHWSeqReset(hwp, FALSE);
/*
* here we temporarily switch to 16 colour planar mode, to simply
@@ -66,36 +77,28 @@ MGAG200SERestoreFonts(ScrnInfoPtr scrninfp, vgaRegPtr restore)
hwp->writeGr(hwp, 0x01, 0x00); /* all planes come from CPU */
}
+ hwp->writeSeq(hwp, 0x04, 0x06); /* enable plane graphics */
+ hwp->writeGr(hwp, 0x05, 0x00); /* write mode 0, read mode 0 */
+ hwp->writeGr(hwp, 0x06, 0x05); /* set graphics */
+
if (hwp->FontInfo1) {
hwp->writeSeq(hwp, 0x02, 0x04); /* write to plane 2 */
- hwp->writeSeq(hwp, 0x04, 0x06); /* enable plane graphics */
hwp->writeGr(hwp, 0x04, 0x02); /* read plane 2 */
- hwp->writeGr(hwp, 0x05, 0x00); /* write mode 0, read mode 0 */
- hwp->writeGr(hwp, 0x06, 0x05); /* set graphics */
slowbcopy_tobus(hwp->FontInfo1, hwp->Base, FONT_AMOUNT);
}
if (hwp->FontInfo2) {
hwp->writeSeq(hwp, 0x02, 0x08); /* write to plane 3 */
- hwp->writeSeq(hwp, 0x04, 0x06); /* enable plane graphics */
hwp->writeGr(hwp, 0x04, 0x03); /* read plane 3 */
- hwp->writeGr(hwp, 0x05, 0x00); /* write mode 0, read mode 0 */
- hwp->writeGr(hwp, 0x06, 0x05); /* set graphics */
slowbcopy_tobus(hwp->FontInfo2, hwp->Base, FONT_AMOUNT);
}
if (hwp->TextInfo) {
hwp->writeSeq(hwp, 0x02, 0x01); /* write to plane 0 */
- hwp->writeSeq(hwp, 0x04, 0x06); /* enable plane graphics */
hwp->writeGr(hwp, 0x04, 0x00); /* read plane 0 */
- hwp->writeGr(hwp, 0x05, 0x00); /* write mode 0, read mode 0 */
- hwp->writeGr(hwp, 0x06, 0x05); /* set graphics */
slowbcopy_tobus(hwp->TextInfo, hwp->Base, TEXT_AMOUNT);
hwp->writeSeq(hwp, 0x02, 0x02); /* write to plane 1 */
- hwp->writeSeq(hwp, 0x04, 0x06); /* enable plane graphics */
hwp->writeGr(hwp, 0x04, 0x01); /* read plane 1 */
- hwp->writeGr(hwp, 0x05, 0x00); /* write mode 0, read mode 0 */
- hwp->writeGr(hwp, 0x06, 0x05); /* set graphics */
slowbcopy_tobus((unsigned char *)hwp->TextInfo + TEXT_AMOUNT,
hwp->Base, TEXT_AMOUNT);
}
@@ -113,7 +116,14 @@ MGAG200SERestoreFonts(ScrnInfoPtr scrninfp, vgaRegPtr restore)
hwp->writeSeq(hwp, 0x04, seq4);
hwp->IOBase = savedIOBase;
- vgaHWBlankScreen(scrninfp, TRUE);
+ scrn = hwp->readSeq(hwp, 0x01);
+ scrn &= ~0x20;/* enable screen */
+ vgaHWSeqReset(hwp, TRUE);
+ MGAWAITVSYNC();
+ MGAWAITBUSY();
+ hwp->writeSeq(hwp, 0x01, scrn);/* change mode */
+ usleep(20000);
+ vgaHWSeqReset(hwp, FALSE);
if (doMap)
vgaHWUnmapMem(scrninfp);
@@ -124,9 +134,11 @@ void
MGAG200SESaveFonts(ScrnInfoPtr scrninfp, vgaRegPtr save)
{
vgaHWPtr hwp = VGAHWPTR(scrninfp);
+ MGAPtr pMga = MGAPTR(scrninfp);
int savedIOBase;
unsigned char miscOut, attr10, gr4, gr5, gr6, seq2, seq4;
Bool doMap = FALSE;
+ unsigned char scrn;
if (hwp->Base == NULL) {
doMap = TRUE;
@@ -157,7 +169,14 @@ MGAG200SESaveFonts(ScrnInfoPtr scrninfp, vgaRegPtr save)
/* Force into colour mode */
hwp->writeMiscOut(hwp, miscOut | 0x01);
- vgaHWBlankScreen(scrninfp, FALSE);
+ scrn = hwp->readSeq(hwp, 0x01);
+ scrn |= 0x20;/* blank screen */
+ vgaHWSeqReset(hwp, TRUE);
+ MGAWAITVSYNC();
+ MGAWAITBUSY();
+ hwp->writeSeq(hwp, 0x01, scrn);/* change mode */
+ usleep(20000);
+ vgaHWSeqReset(hwp, FALSE);
/*
* get the character sets, and text screen if required
@@ -171,34 +190,25 @@ MGAG200SESaveFonts(ScrnInfoPtr scrninfp, vgaRegPtr save)
#if 0
hwp->writeAttr(hwp, 0x10, 0x01); /* graphics mode */
#endif
+ hwp->writeSeq(hwp, 0x04, 0x06); /* enable plane graphics */
+ hwp->writeGr(hwp, 0x05, 0x00); /* write mode 0, read mode 0 */
+ hwp->writeGr(hwp, 0x06, 0x05); /* set graphics */
if (hwp->FontInfo1 || (hwp->FontInfo1 = xalloc(FONT_AMOUNT))) {
hwp->writeSeq(hwp, 0x02, 0x04); /* write to plane 2 */
- hwp->writeSeq(hwp, 0x04, 0x06); /* enable plane graphics */
hwp->writeGr(hwp, 0x04, 0x02); /* read plane 2 */
- hwp->writeGr(hwp, 0x05, 0x00); /* write mode 0, read mode 0 */
- hwp->writeGr(hwp, 0x06, 0x05); /* set graphics */
slowbcopy_frombus(hwp->Base, hwp->FontInfo1, FONT_AMOUNT);
}
if (hwp->FontInfo2 || (hwp->FontInfo2 = xalloc(FONT_AMOUNT))) {
hwp->writeSeq(hwp, 0x02, 0x08); /* write to plane 3 */
- hwp->writeSeq(hwp, 0x04, 0x06); /* enable plane graphics */
hwp->writeGr(hwp, 0x04, 0x03); /* read plane 3 */
- hwp->writeGr(hwp, 0x05, 0x00); /* write mode 0, read mode 0 */
- hwp->writeGr(hwp, 0x06, 0x05); /* set graphics */
slowbcopy_frombus(hwp->Base, hwp->FontInfo2, FONT_AMOUNT);
}
if (hwp->TextInfo || (hwp->TextInfo = xalloc(2 * TEXT_AMOUNT))) {
hwp->writeSeq(hwp, 0x02, 0x01); /* write to plane 0 */
- hwp->writeSeq(hwp, 0x04, 0x06); /* enable plane graphics */
hwp->writeGr(hwp, 0x04, 0x00); /* read plane 0 */
- hwp->writeGr(hwp, 0x05, 0x00); /* write mode 0, read mode 0 */
- hwp->writeGr(hwp, 0x06, 0x05); /* set graphics */
slowbcopy_frombus(hwp->Base, hwp->TextInfo, TEXT_AMOUNT);
hwp->writeSeq(hwp, 0x02, 0x02); /* write to plane 1 */
- hwp->writeSeq(hwp, 0x04, 0x06); /* enable plane graphics */
hwp->writeGr(hwp, 0x04, 0x01); /* read plane 1 */
- hwp->writeGr(hwp, 0x05, 0x00); /* write mode 0, read mode 0 */
- hwp->writeGr(hwp, 0x06, 0x05); /* set graphics */
slowbcopy_frombus(hwp->Base,
(unsigned char *)hwp->TextInfo + TEXT_AMOUNT, TEXT_AMOUNT);
}
@@ -213,8 +223,149 @@ MGAG200SESaveFonts(ScrnInfoPtr scrninfp, vgaRegPtr save)
hwp->writeMiscOut(hwp, miscOut);
hwp->IOBase = savedIOBase;
- vgaHWBlankScreen(scrninfp, TRUE);
+ scrn = hwp->readSeq(hwp, 0x01);
+ scrn &= ~0x20;/* enable screen */
+ vgaHWSeqReset(hwp, TRUE);
+ MGAWAITVSYNC();
+ MGAWAITBUSY();
+ hwp->writeSeq(hwp, 0x01, scrn);/* change mode */
+ usleep(20000);
+ vgaHWSeqReset(hwp, FALSE);
if (doMap)
vgaHWUnmapMem(scrninfp);
}
+
+void
+MGAG200SERestoreMode(ScrnInfoPtr scrninfp, vgaRegPtr restore)
+{
+ vgaHWPtr hwp = VGAHWPTR(scrninfp);
+ MGAPtr pMga = MGAPTR(scrninfp);
+ int i;
+ unsigned char scrn;
+
+ if (restore->MiscOutReg & 0x01)
+ hwp->IOBase = VGA_IOBASE_COLOR;
+ else
+ hwp->IOBase = VGA_IOBASE_MONO;
+
+ hwp->writeMiscOut(hwp, restore->MiscOutReg);
+
+
+ for (i = 1; i < restore->numSequencer; i++)
+ {
+ MGAWAITVSYNC();
+ MGAWAITBUSY();
+ hwp->writeSeq(hwp, i, restore->Sequencer[i]);
+ usleep(20000);
+ }
+
+ scrn = hwp->readSeq(hwp, 0x01);
+ scrn |= 0x20;/* blank screen */
+ vgaHWSeqReset(hwp, TRUE);
+ MGAWAITVSYNC();
+ MGAWAITBUSY();
+ hwp->writeSeq(hwp, 0x01, scrn);/* change mode */
+ usleep(20000);
+
+ /* Ensure CRTC registers 0-7 are unlocked by clearing bit 7 of CRTC[17] */
+ hwp->writeCrtc(hwp, 17, restore->CRTC[17] & ~0x80);
+
+ for (i = 0; i < restore->numCRTC; i++)
+ hwp->writeCrtc(hwp, i, restore->CRTC[i]);
+
+ for (i = 0; i < restore->numGraphics; i++)
+ hwp->writeGr(hwp, i, restore->Graphics[i]);
+
+ hwp->enablePalette(hwp);
+ for (i = 0; i < restore->numAttribute; i++)
+ hwp->writeAttr(hwp, i, restore->Attribute[i]);
+ hwp->disablePalette(hwp);
+
+ MGAWAITVSYNC();
+ MGAWAITBUSY();
+ hwp->writeSeq(hwp, 1, restore->Sequencer[1]);
+ usleep(20000);
+}
+
+void
+MGAG200SESaveMode(ScrnInfoPtr scrninfp, vgaRegPtr save)
+{
+ vgaHWPtr hwp = VGAHWPTR(scrninfp);
+ int i;
+
+ save->MiscOutReg = hwp->readMiscOut(hwp);
+ if (save->MiscOutReg & 0x01)
+ hwp->IOBase = VGA_IOBASE_COLOR;
+ else
+ hwp->IOBase = VGA_IOBASE_MONO;
+
+ for (i = 0; i < save->numCRTC; i++) {
+ save->CRTC[i] = hwp->readCrtc(hwp, i);
+#ifdef DEBUG
+ ErrorF("CRTC[0x%02x] = 0x%02x\n", i, save->CRTC[i]);
+#endif
+ }
+
+ hwp->enablePalette(hwp);
+ for (i = 0; i < save->numAttribute; i++) {
+ save->Attribute[i] = hwp->readAttr(hwp, i);
+#ifdef DEBUG
+ ErrorF("Attribute[0x%02x] = 0x%02x\n", i, save->Attribute[i]);
+#endif
+ }
+ hwp->disablePalette(hwp);
+
+ for (i = 0; i < save->numGraphics; i++) {
+ save->Graphics[i] = hwp->readGr(hwp, i);
+#ifdef DEBUG
+ ErrorF("Graphics[0x%02x] = 0x%02x\n", i, save->Graphics[i]);
+#endif
+ }
+
+ for (i = 1; i < save->numSequencer; i++) {
+ save->Sequencer[i] = hwp->readSeq(hwp, i);
+#ifdef DEBUG
+ ErrorF("Sequencer[0x%02x] = 0x%02x\n", i, save->Sequencer[i]);
+#endif
+ }
+}
+
+void
+MGAG200SEHWProtect(ScrnInfoPtr pScrn, Bool on)
+{
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ MGAPtr pMga = MGAPTR(pScrn);
+
+ unsigned char tmp;
+
+ if (pScrn->vtSema) {
+ if (on) {
+ /*
+ * Turn off screen and disable sequencer.
+ */
+ tmp = hwp->readSeq(hwp, 0x01);
+
+ vgaHWSeqReset(hwp, TRUE); /* start synchronous reset */
+ MGAWAITVSYNC();
+ MGAWAITBUSY();
+ hwp->writeSeq(hwp, 0x01, tmp | 0x20); /* disable the display */
+ usleep(20000);
+ hwp->enablePalette(hwp);
+ } else {
+ /*
+ * Reenable sequencer, then turn on screen.
+ */
+
+ tmp = hwp->readSeq(hwp, 0x01);
+
+ MGAWAITVSYNC();
+ MGAWAITBUSY();
+ hwp->writeSeq(hwp, 0x01, tmp & ~0x20); /* reenable display */
+ usleep(20000);
+ vgaHWSeqReset(hwp, FALSE); /* clear synchronousreset */
+
+ hwp->disablePalette(hwp);
+ }
+ }
+}
diff --git a/src/mga_video.c b/src/mga_video.c
index 30ae6fc..a2d7979 100644
--- a/src/mga_video.c
+++ b/src/mga_video.c
@@ -63,6 +63,10 @@ static void MGAResetVideoOverlay(ScrnInfoPtr);
static void MGAVideoTimerCallback(ScrnInfoPtr pScrn, Time time);
+static XF86VideoAdaptorPtr MGASetupImageVideoILOAD(ScreenPtr);
+static int MGAPutImageILOAD(ScrnInfoPtr, short, short, short, short, short,
+ short, short, short, int, unsigned char*, short,
+ short, Bool, RegionPtr, pointer, DrawablePtr);
#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE)
@@ -91,12 +95,27 @@ void MGAInitVideo(ScreenPtr pScreen)
if((pScrn->bitsPerPixel != 8) && !pMga->NoAccel &&
(pMga->SecondCrtc == FALSE) &&
- ((pMga->Chipset == PCI_CHIP_MGAG200) ||
+ ((pMga->Chipset == PCI_CHIP_MGA2164) ||
+ (pMga->Chipset == PCI_CHIP_MGA2164_AGP) ||
+/* (pMga->Chipset == PCI_CHIP_MGA2064) || */
+ (pMga->Chipset == PCI_CHIP_MGAG200) ||
(pMga->Chipset == PCI_CHIP_MGAG200_PCI) ||
(pMga->Chipset == PCI_CHIP_MGAG400) ||
(pMga->Chipset == PCI_CHIP_MGAG550)))
{
- if((pMga->Overlay8Plus24 || pMga->TexturedVideo) &&
+ if( (pMga->Chipset == PCI_CHIP_MGA2164) ||
+/* (pMga->Chipset == PCI_CHIP_MGA2064) || */
+ (pMga->Chipset == PCI_CHIP_MGA2164_AGP)
+ ) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using MGA 2164W ILOAD video\n");
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "This is an experimental driver and may not work on your machine.\n");
+
+ newAdaptor = MGASetupImageVideoILOAD(pScreen);
+ pMga->TexturedVideo = TRUE;
+ /* ^^^ this is not really true but the ILOAD scaler shares
+ much more code with the textured video than the overlay */
+ } else if((pMga->Overlay8Plus24 || pMga->TexturedVideo) &&
(pScrn->bitsPerPixel != 24))
{
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using texture video\n");
@@ -1258,3 +1277,760 @@ MGAInitOffscreenImages(ScreenPtr pScreen)
xf86XVRegisterOffscreenImages(pScreen, offscreenImages, num);
}
+
+
+/* Matrox MGA 2164W Xv extension support.
+* The extension is implemented as a HOST->FB image load in YUV format.
+* I decided not to use real hardware overlay since on the Millennium II
+* it would limit the size of the frame buffer to 4Mb (even on a 16Mb
+* card) due to an hardware limitation.
+* Author: Gabriele Gorla (gorlik@yahoo.com)
+* Based on the MGA-Gxxx Xv extension by: Mark Vojkovich
+ */
+
+/* This code is still in alpha stage. Only YUV->RGB conversion
+ and horizontal scaling are hardware accelerated.
+ All 4 FOURCC formats supported by X should be supported.
+ It has been tested only on my DEC XP1000 at 1024x768x32 under
+ linux 2.6.18 with X.org 7.1.1 (debian alpha)
+
+ Bug reports and success/failure stories are greatly appreciated.
+*/
+
+/* #define DEBUG_MGA2164 */
+/* #define CUSTOM_MEMCOPY */
+#define MGA2164_SWFILTER
+
+
+static XF86VideoAdaptorPtr
+MGASetupImageVideoILOAD(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ XF86VideoAdaptorPtr adapt;
+ MGAPtr pMga = MGAPTR(pScrn);
+
+ adapt = MGAAllocAdaptor(pScrn, FALSE);
+
+ adapt->type = XvWindowMask | XvInputMask | XvImageMask;
+ adapt->flags = 0;
+ adapt->name = "Matrox Millennium II ILOAD Video Engine";
+ adapt->nEncodings = 1;
+ adapt->pEncodings = &DummyEncoding[1];
+ adapt->nFormats = NUM_FORMATS;
+ adapt->pFormats = Formats;
+ adapt->nPorts = MGA_MAX_PORTS;
+ adapt->pAttributes = NULL;
+ adapt->nAttributes = 0;
+
+ /* number of supported color formats */
+ adapt->pImages = Images;
+ adapt->nImages = 4;
+
+ adapt->PutVideo = NULL;
+ adapt->PutStill = NULL;
+ adapt->GetVideo = NULL;
+ adapt->GetStill = NULL;
+ adapt->StopVideo = MGAStopVideo;
+
+ adapt->SetPortAttribute = MGASetPortAttributeTexture;
+ adapt->GetPortAttribute = MGAGetPortAttributeTexture;
+ adapt->QueryBestSize = MGAQueryBestSize;
+ adapt->PutImage = MGAPutImageILOAD;
+ adapt->QueryImageAttributes = MGAQueryImageAttributes;
+
+ REGION_INIT(pScreen, &(pMga->portPrivate->clip), NullBox, 0);
+
+ return adapt;
+}
+
+/* this function is optimized for alpha. It might be better also for
+other load/store risc architectures but I never tested on anything else
+than my ev56 */
+static void CopyMungedScanline_AXP(CARD32 *fb_ptr, short src_w,
+ CARD32 *tsp, CARD32 *tpu, CARD32 *tpv)
+{
+ CARD32 k,y0,y1,u,v;
+
+ for(k=src_w/8;k;k--) {
+ y0=*tsp;
+ y1=*(tsp+1);
+ u=*tpu;
+ v=*tpv;
+
+ *(fb_ptr)=(y1&0x000000ff)|((y1&0x0000ff00)<<8) |
+ (v&0x00ff0000)<<8 | (u&0x00ff0000)>>8;
+ *(fb_ptr+1)=(y1&0x000000ff)|((y1&0x0000ff00)<<8) |
+ (v&0x00ff0000)<<8 | (u&0x00ff0000)>>8;
+
+ *(fb_ptr+2)=(y0&0x000000ff)|((y0&0x0000ff00)<<8) |
+ (v&0x000000ff)<<24 | (u&0x000000ff)<<8;
+ *(fb_ptr+3)=(y0&0x000000ff)|((y0&0x0000ff00)<<8) |
+ (v&0x000000ff)<<24 | (u&0x000000ff)<<8;
+
+ /*correct below*/
+ /* *(fb_ptr)=(y0&0x000000ff)|((y0&0x0000ff00)<<8) |
+ (v&0x000000ff)<<24 | (u&0x000000ff)<<8;
+ *(fb_ptr+1)=((y0&0x00ff0000)>>16)|((y0&0xff000000)>>8) |
+ (v&0x0000ff00)<<16 | (u&0x0000ff00);
+ *(fb_ptr+2)=(y1&0x000000ff)|((y1&0x0000ff00)<<8) |
+ (v&0x00ff0000)<<8 | (u&0x00ff0000)>>8;
+ *(fb_ptr+3)=((y1&0x00ff0000)>>16)|((y1&0xff000000)>>8) |
+ (v&0xff000000) | (u&0xff000000)>>16; */
+
+ tsp+=2; tpu++; tpv++;
+ fb_ptr+=4;
+ }
+}
+
+static void CopyMungedScanline_AXP2(CARD32 *fb_ptr, short src_w,
+ CARD32 *tsp, CARD32 *tpu, CARD32 *tpv)
+{
+ CARD8 *y, *u, *v;
+ int k;
+ y=(CARD8 *)tsp;
+ u=(CARD8 *)tpu;
+ v=(CARD8 *)tpv;
+
+ for(k=src_w/8;k;k--) {
+ fb_ptr[0]=y[0] | y[1]<<16 | v[0]<<24 | u[0]<<8;
+ fb_ptr[1]=y[2] | y[3]<<16 | v[1]<<24 | u[1]<<8;
+ fb_ptr[2]=y[4] | y[5]<<16 | v[2]<<24 | u[2]<<8;
+ fb_ptr[3]=y[6] | y[7]<<16 | v[3]<<24 | u[3]<<8;
+
+ y+=8; u+=4; v+=4;
+ fb_ptr+=4;
+ }
+}
+
+
+static void CopyMungedScanlineFilter_AXP(CARD32 *fb_ptr, short src_w,
+ CARD32 *tsp1, CARD32 *tpu1, CARD32 *tpv1,
+ CARD32 *tsp2, CARD32 *tpu2, CARD32 *tpv2,
+ int beta, int xds )
+{
+ unsigned int k,y0_1,y1_1,y0_2,y1_2,u,v;
+ int yf[8], uf[4], vf[4];
+ int oneminbeta = 0xff - beta;
+
+ for(k=xds*src_w/8;k;k--) {
+ y0_1=*tsp1;
+ y1_1=*(tsp1+1);
+ y0_2=*tsp2;
+ y1_2=*(tsp2+1);
+ u=*tpu1;
+ v=*tpv1;
+
+ tsp1+=2; tsp2+=2; tpu1++; tpv1++;
+ yf[0] = ((y0_1&0x000000ff)*oneminbeta + (y0_2&0x000000ff)*beta )>>8;
+ yf[1] = (((y0_1&0x0000ff00)>>8)*oneminbeta + ((y0_2&0x0000ff00)>>8)*beta )>>8;
+ yf[2] = (((y0_1&0x00ff0000)>>16)*oneminbeta + ((y0_2&0x00ff0000)>>16)*beta )>>8;
+ yf[3] = (((y0_1&0xff000000)>>24)*oneminbeta + ((y0_2&0xff000000)>>24)*beta )>>8;
+ yf[4] = ((y1_1&0x000000ff)*oneminbeta + (y1_2&0x000000ff)*beta )>>8;
+ yf[5] = (((y1_1&0x0000ff00)>>8)*oneminbeta + ((y1_2&0x0000ff00)>>8)*beta )>>8;
+ yf[6] = (((y1_1&0x00ff0000)>>16)*oneminbeta + ((y1_2&0x00ff0000)>>16)*beta )>>8;
+ yf[7] = (((y1_1&0xff000000)>>24)*oneminbeta + ((y1_2&0xff000000)>>24)*beta )>>8;
+
+ /* FIXME: there is still no filtering on u and v */
+ uf[0]=(u&0x000000ff);
+ uf[1]=(u&0x0000ff00)>>8;
+ uf[2]=(u&0x00ff0000)>>16;
+ uf[3]=(u&0xff000000)>>24;
+
+ vf[0]=(v&0x000000ff);
+ vf[1]=(v&0x0000ff00)>>8;
+ vf[2]=(v&0x00ff0000)>>16;
+ vf[3]=(v&0xff000000)>>24;
+
+ switch(xds) {
+ case 1:
+ *(fb_ptr)=(yf[0]) | (yf[1]<<16) |
+ vf[0]<<24 | uf[0]<<8;
+ *(fb_ptr+1)=(yf[2]) | (yf[3]<<16) |
+ vf[1]<<24 | uf[1]<<8;
+ *(fb_ptr+2)=(yf[4]) | (yf[5]<<16) |
+ vf[2]<<24 | uf[2]<<8;
+ *(fb_ptr+3)=(yf[6]) | (yf[7]<<16) |
+ vf[3]<<24 | uf[3]<<8;
+ fb_ptr+=4;
+ break;
+
+ case 2:
+ *(fb_ptr)=(yf[0]+yf[1])/2 | (((yf[2]+yf[3])/2)<<16) |
+ ((vf[0]+vf[1])/2 )<<24 | ((uf[0]+uf[1])/2)<<8;
+ *(fb_ptr+1)=(yf[4]+yf[5])/2 | ( ((yf[6]+yf[7])/2) <<16) |
+ ((vf[2]+vf[3])/2 )<<24 | ((uf[2]+uf[3])/2)<<8;
+ fb_ptr+=2;
+ break;
+
+ case 4:
+ *(fb_ptr)=(yf[0]+yf[1]+yf[2]+yf[3])/4 | (((yf[4]+yf[5]+yf[6]+yf[7])/4)<<16) |
+ ((vf[0]+vf[1]+vf[2]+vf[3])/4 )<<24 | ((uf[0]+uf[1]+uf[2]+uf[3])/4)<<8;
+ fb_ptr+=1;
+ break;
+
+ default:
+ break;
+ }
+ }
+}
+
+static void CopyMungedScanlineFilterDown_AXP(CARD32 *fb_ptr, short src_w,
+ CARD32 *tsp1, CARD32 *tpu1, CARD32 *tpv1,
+ CARD32 *tsp2, CARD32 *tpu2, CARD32 *tpv2,
+ int beta , int xds)
+{
+ unsigned int k,y0_1,y1_1,y0_2,y1_2,u,v;
+ int yf[8], uf[4], vf[4];
+
+ for(k=src_w/8;k;k--) {
+ y0_1=*tsp1;
+ y1_1=*(tsp1+1);
+ y0_2=*tsp2;
+ y1_2=*(tsp2+1);
+ u=*tpu1;
+ v=*tpv1;
+
+ tsp1+=2; tsp2+=2; tpu1++; tpv1++;
+ yf[0] = ((y0_1&0x000000ff) + (y0_2&0x000000ff))>>8;
+ yf[1] = (((y0_1&0x0000ff00)>>8) + ((y0_2&0x0000ff00)>>8))>>8;
+ yf[2] = (((y0_1&0x00ff0000)>>16) + ((y0_2&0x00ff0000)>>16))>>8;
+ yf[3] = (((y0_1&0x000000ff)>>24) + ((y0_2&0x000000ff)>>24))>>8;
+ yf[4] = ((y1_1&0x000000ff) + (y1_2&0x000000ff))>>8;
+ yf[5] = (((y1_1&0x0000ff00)>>8) + ((y1_2&0x0000ff00)>>8))>>8;
+ yf[6] = (((y1_1&0x00ff0000)>>16) + ((y1_2&0x00ff0000)>>16))>>8;
+ yf[7] = (((y1_1&0x000000ff)>>24) + ((y1_2&0x000000ff)>>24))>>8;
+
+ *(fb_ptr)=(yf[0]) | (yf[1]<<16) |
+ (v&0x000000ff)<<24 | (u&0x000000ff)<<8;
+ *(fb_ptr+1)=(yf[2]) | (yf[3]<<16) |
+ (v&0x0000ff00)<<16 | (u&0x0000ff00);
+ *(fb_ptr+2)=(yf[4]) | (yf[5]<<16) |
+ (v&0x00ff0000)<<8 | (u&0x00ff0000)>>8;
+ *(fb_ptr+3)=(yf[6]) | (yf[7]<<16) |
+ (v&0xff000000) | (u&0xff000000)>>16;
+
+ fb_ptr+=4;
+ }
+}
+
+static void MGACopyScaledILOAD(
+ ScrnInfoPtr pScrn,
+ int id, unsigned char *buf,
+ BoxPtr pbox,
+ int width, int height, int pitch,
+ short src_x, short src_y,
+ short src_w, short src_h,
+ short drw_x, short drw_y,
+ short drw_w, short drw_h
+ )
+{
+ MGAPtr pMga = MGAPTR(pScrn);
+ CARD32 *fb_ptr;
+ unsigned char *ubuf, *vbuf, *tbuf;
+ CARD32 *pu, *pv;
+ int k,l, pl, dl, xds, yds;
+ short box_h;
+ short scr_pitch = ( pScrn->virtualX + 15) & ~15;
+
+#ifdef DEBUG_MGA2164
+ char sbuf[255];
+
+ sprintf(sbuf,"---- PBOX: x1=%d y1=%d w=%d h=%d (x2=%d y2=%d)\n",
+ pbox->x1,pbox->y1,pbox->x2-pbox->x1,pbox->y2-pbox->y1,
+ pbox->x2,pbox->y2);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, sbuf);
+
+ sprintf(sbuf,"in src: src_x=%d src_y=%d src_w=%d src_h=%d\n",
+ src_x,src_y,src_w,src_h);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, sbuf);
+ sprintf(sbuf,"in drw: drw_x=%d drw_y=%d drw_w=%d drw_h=%d\n",
+ drw_x,drw_y,drw_w,drw_h);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, sbuf);
+#endif
+
+ /* scaling yuv->rgb */
+
+ /* hack to force width and src image to be 8 pixel aligned */
+ src_x&=~0x7;
+ src_w&=~0x7;
+
+ box_h=pbox->y2-pbox->y1;
+
+ /* compute X down scaling factor */
+ if(src_w>drw_w) {
+ if(src_w/2<drw_w) {
+ xds=2;
+ } else if(src_w/4<drw_w) {
+ xds=4;
+ } else { xds=8; }
+ } else xds = 1;
+
+ /* prevent crashing when dragging window outside left boundary of screen */
+ /* FIXME: need to implement per pixel left start to avoid undesired
+ effects when dragging window outside left screen boundary */
+
+ if(drw_x<0) {
+ src_x=( -(drw_x*src_w)/drw_w + 0x7)&~0x7;
+ src_w-=src_x;
+ drw_w+=drw_x;
+ drw_x=0;
+ }
+
+ src_w/=xds;
+
+ /* compute X down scaling factor */
+ if(src_h>drw_h) {
+ if(src_h/2<drw_h) {
+ yds=2;
+ } else if(src_h/4<drw_h) {
+ yds=4;
+ } else { yds=8; }
+ } else yds = 1;
+
+
+#ifdef DEBUG_MGA2164
+ char sbuf[255];
+
+ sprintf(sbuf,"---- xds = %d\n",
+ xds);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, sbuf);
+#endif
+
+
+#ifdef DEBUG_MGA2164
+ sprintf(sbuf,"out src: src_x=%d src_y=%d src_w=%d src_h=%d\n",
+ src_x,src_y,src_w,src_h);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, sbuf);
+ sprintf(sbuf,"out drw: drw_x=%d drw_y=%d drw_w=%d drw_h=%d\n",
+ drw_x,drw_y,drw_w,drw_h);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, sbuf);
+#endif
+
+ CHECK_DMA_QUIESCENT(pMga, pScrn);
+
+ /* scaling ILOAD */
+
+ vbuf=buf+width*height;
+ ubuf=vbuf+width*height/4;
+ pu = (CARD32 *)(ubuf+(src_y/2)*(width/2));
+ pv = (CARD32 *)(vbuf+(src_y/2)*(width/2));
+
+ for(pl=-1,dl=0;dl<box_h;dl++) {
+ int beta;
+ l=(dl+(pbox->y1-drw_y))*src_h/drw_h;
+ /* FIXME: check the math */
+ beta = ((dl+(pbox->y1-drw_y))*src_h*0xff/drw_h) - ((dl+(pbox->y1-drw_y))*src_h/drw_h*0xff);
+
+#ifdef MGA2164_BLIT_DUP
+ if(l!=pl)
+#else
+ if(1)
+#endif
+ {
+
+ /*
+ #ifdef DEBUG_MGA2164
+ sprintf(sbuf,"new line: scr_dst %d img_src %d prev %d\n",
+ dl,l,pl);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, sbuf);
+ #endif
+ */
+
+ OUTREG(MGAREG_DWGCTL, MGADWG_ILOAD_HIQH | MGADWG_BUYUV | MGADWG_SHIFTZERO
+ | MGADWG_SGNZERO | 0xc0000);
+
+ OUTREG(MGAREG_AR0, pbox->x1 + drw_w -1); /* SRC LINE END why -1 ? */
+ OUTREG(MGAREG_AR2, ( ( (src_w-1)<<16) / (drw_w-1)) + 1 ); /* ((SRC_X_DIM -1)<<16) / (DST_X_DIM-1) +1 */
+ OUTREG(MGAREG_AR3, pbox->x1 ); /* SRC LINE START*/
+ OUTREG(MGAREG_AR5, scr_pitch); /* DST_Y_INCR = PITCH? */
+ OUTREG(MGAREG_AR6, ((src_w-drw_w)<<16) / (drw_w-1) ); /* */
+ OUTREG(MGAREG_FXBNDRY, drw_x|((drw_x+drw_w-1)<<16) ); /* why -1 ? */
+ OUTREG(MGAREG_CXBNDRY, pbox->x1 | ((pbox->x2-1)<<16 ) );
+ OUTREG(MGAREG_YDST , pbox->y1+dl ); /* Y_START_POS */
+ OUTREG(MGAREG_LEN + MGAREG_EXEC , 1); /* # of LINES */
+
+ /* xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Data finished\n"); */
+
+ fb_ptr=(CARD32 *)pMga->ILOADBase;
+
+ switch(id) {
+ case FOURCC_YV12:
+ case FOURCC_I420:
+ tbuf=buf+(l+src_y)*width;
+ {
+ CARD32 *tpu=pu+src_x/8+l/2*width/8;
+ CARD32 *tpv=pv+src_x/8+l/2*width/8;
+ CARD32 *tsp=(CARD32 *)(tbuf+src_x), *tsp2;
+
+ if((l+src_y)<(src_h-1))
+ tsp2=(CARD32 *)(tbuf+src_x+width);
+ else
+ tsp2=(CARD32 *)(tbuf+src_x);
+
+ /* it is not clear if waiting is actually good for performance */
+ /* WAITFIFO(pMga->FifoSize);*/
+ /* should try to get MGACopyMunged data to work here */
+ /* CopyMungedScanline_AXP(fb_ptr,src_w,tsp,tpu,tpv); */
+
+ /* Filter does not work yet */
+ CopyMungedScanlineFilter_AXP(fb_ptr,src_w,tsp,tpu,tpv,tsp2,tpu,tpv, beta, xds);
+ /* if(l&1) {
+ pu+=width/8;
+ pv+=width/8;
+ } */
+ }
+ break;
+ case FOURCC_UYVY:
+ case FOURCC_YUY2:
+ tbuf=buf+(l+src_y)*width*2;
+
+#ifndef MGA2164_SWFILTER
+ WAITFIFO(pMga->FifoSize/2);
+ memcpy(fb_ptr, tbuf+src_x*2, src_w*2);
+ fb_ptr+=src_w*2; /* pointer in the pseudo dma window */
+#else
+ {
+ CARD32 *tsp=(CARD32 *)(tbuf+src_x*2), *tsp2;
+
+ if((l+src_y)<(src_h-1))
+ tsp2=(CARD32 *)(tbuf+src_x*2+width*2);
+ else
+ tsp2=(CARD32 *)(tbuf+src_x*2);
+ /* {
+ char sbuf [256];
+ sprintf(sbuf,"dst line: %d src_line: %d beta: %x\n",
+ dl, l, beta );
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, sbuf);
+ } */
+
+ WAITFIFO(pMga->FifoSize/4);
+ for(k=xds*src_w/8;k;k--) {
+ int oneminbeta = 0xff-beta;
+ int y[8], u[4], v[4], ya[4], ua[2], va[2], p;
+
+ switch(yds) {
+ case 1:
+ /* upscale y filter */
+ for(p=0;p<4;p++) {
+ y[2*p]=(((*(tsp+p)&0x000000ff))*oneminbeta+((*(tsp2+p)&0x000000ff))*beta)>>8;
+ y[2*p+1]=(((*(tsp+p)&0x00ff0000)>>16)*oneminbeta+((*(tsp2+p)&0x00ff0000)>>16)*beta)>>8;
+ u[p]=(((*(tsp+p)&0x0000ff00)>>8)*oneminbeta+((*(tsp2+p)&0x0000ff00)>>8)*beta)>>8;
+ v[p]=(((*(tsp+p)&0xff000000)>>24)*oneminbeta+((*(tsp2+p)&0xff000000)>>24)*beta)>>8;
+ }
+ break;
+ /* downscale y filter */
+ case 2:
+ case 3:
+ case 4:
+ default:
+ for(p=0;p<4;p++) {
+ y[2*p]=(((*(tsp+p)&0x000000ff)));
+ y[2*p+1]=(((*(tsp+p)&0x00ff0000)>>16));
+ u[p]=(((*(tsp+p)&0x0000ff00)>>8));
+ v[p]=(((*(tsp+p)&0xff000000)>>24));
+ }
+ break;
+ }
+
+ switch (xds) {
+ case 1: /* simple copy */
+ *(fb_ptr++)=y[0]|y[1]<<16|u[0]<<8|v[0]<<24;
+ *(fb_ptr++)=y[2]|y[3]<<16|u[1]<<8|v[1]<<24;
+ *(fb_ptr++)=y[4]|y[5]<<16|u[2]<<8|v[2]<<24;
+ *(fb_ptr++)=y[6]|y[7]<<16|u[3]<<8|v[3]<<24;
+ break;
+ case 2: /* dowscale by 2 */
+ ya[0]=(y[0]+y[1])>>1;
+ ya[1]=(y[2]+y[3])>>1;
+ ya[2]=(y[4]+y[5])>>1;
+ ya[3]=(y[6]+y[7])>>1;
+ ua[0]=(u[0]+u[1])>>1;
+ ua[1]=(u[2]+u[3])>>1;
+ va[0]=(v[0]+v[1])>>1;
+ va[1]=(v[2]+v[3])>>1;
+ *(fb_ptr++)=ya[0]|ya[1]<<16|ua[0]<<8|va[0]<<24;
+ *(fb_ptr++)=ya[2]|ya[3]<<16|ua[1]<<8|va[1]<<24;
+ break;
+ case 4: /* downscale by 4 */
+ ya[0]=(y[0]+y[1]+y[2]+y[3])>>2;
+ ya[1]=(y[4]+y[5]+y[6]+y[7])>>2;
+ ua[0]=(u[0]+u[1]+u[2]+u[3])>>2;
+ va[0]=(v[0]+v[1]+v[2]+v[3])>>2;
+ *(fb_ptr++)=ya[0]|ya[1]<<16|ua[0]<<8|va[0]<<24;
+ break;
+ case 8:
+ default:
+ break;
+ }
+
+ /* fb_ptr+=4; */
+ tsp+=4; tsp2+=4;
+ }
+ }
+#endif /* MGA2164_SWFILTER */
+ break;
+ default:
+ break;
+ }
+ pl=l;
+ } else {
+ /* dup lines */
+
+#ifdef DEBUG_MGA2164
+ sprintf(sbuf,"dup line: scr_src %d scr_dst %d\n",
+ dl-1,dl);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, sbuf);
+#endif
+
+ OUTREG(MGAREG_DWGCTL, 0x040C6008);
+ OUTREG(MGAREG_FXBNDRY, pbox->x1|((pbox->x2-1)<<16) ); /* why -1 ? */
+ OUTREG(MGAREG_AR3, (pbox->y1+dl-1)*scr_pitch+pbox->x1 ); /* SRC LINE START*/
+ OUTREG(MGAREG_AR0, (pbox->y1+dl-1)*scr_pitch+pbox->x2 -1); /* SRC LINE END why -1 ? */
+ OUTREG(MGAREG_AR5, scr_pitch); /* DST_Y_INCR = PITCH? */
+ OUTREG(MGAREG_YDST , pbox->y1+dl); /* Y_START_POS */
+ OUTREG(MGAREG_LEN + MGAREG_EXEC , 1); /* # of LINES */
+ }
+ }
+ OUTREG(MGAREG_CXBNDRY, 0xFFFF0000);
+}
+
+static void MGACopyILOAD(
+ ScrnInfoPtr pScrn,
+ int id, unsigned char *buf,
+ BoxPtr pbox,
+ int width, int height, int pitch,
+ short src_x, short src_y,
+ short src_w, short src_h,
+ short drw_x, short drw_y,
+ short drw_w, short drw_h
+ )
+{
+ MGAPtr pMga = MGAPTR(pScrn);
+ CARD32 *fb_ptr;
+ CARD8 *ubuf, *vbuf;
+ CARD32 *pu, *pv;
+ int k,l;
+ short clip_x1, clip_x2, tmp_w;
+
+#ifdef DEBUG_MGA2164
+ char sbuf[255];
+
+ sprintf(sbuf,"---- PBOX: x1=%d y1=%d w=%d h=%d (x2=%d y2=%d)\n",
+ pbox->x1,pbox->y1,pbox->x2-pbox->x1,pbox->y2-pbox->y1,
+ pbox->x2,pbox->y2);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, sbuf);
+
+ sprintf(sbuf,"in src: src_x=%d src_y=%d src_w=%d src_h=%d\n",
+ src_x,src_y,src_w,src_h);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, sbuf);
+ sprintf(sbuf,"in drw: drw_x=%d drw_y=%d drw_w=%d drw_h=%d\n",
+ drw_x,drw_y,drw_w,drw_h);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, sbuf);
+#endif
+
+ /* non-scaling yuv->rgb */
+
+ /* hack to force width and src image to be 8 pixel aligned */
+ src_x&=~0x7;
+ src_w&=~0x7;
+ drw_w&=~0x7;
+ tmp_w=drw_w;
+ clip_x1=drw_x;
+ clip_x2=drw_x+drw_w;
+
+ /* hack for clipping in non scaling version */
+ /* this works only if no scaling */
+ if(pbox->x1 > drw_x) { /* left side X clipping*/
+ src_x+=((pbox->x1-drw_x)&~0x7);
+ src_w-=((pbox->x1-drw_x)&~0x7);
+ clip_x1=pbox->x1;
+ drw_x+=src_x;
+ drw_w=src_w;
+ }
+
+ if( (pbox->x2) < (drw_x+drw_w) ) { /* right side X clipping */
+ tmp_w=( (pbox->x2) - drw_x );
+ drw_w= tmp_w & (~0x7);
+ if(drw_w!=tmp_w) drw_w+=8;
+ clip_x2=drw_x+tmp_w-1; /* not sure why needs -1 */
+ src_w=drw_w;
+ }
+
+ if(pbox->y1 > drw_y) { /* top side Y clipping */
+ src_y+=(pbox->y1-drw_y);
+ src_h-=(pbox->y1-drw_y);
+ drw_y+=src_y;
+ drw_h=src_h;
+ }
+ if((pbox->y2)<(drw_y+drw_h)) { /* bottom side Y clipping */
+ drw_h=(pbox->y2)-drw_y;
+ src_h=drw_h;
+ }
+
+ if(drw_x<0) drw_x=0;
+
+#ifdef DEBUG_MGA2164
+ sprintf(sbuf,"out src: src_x=%d src_y=%d src_w=%d src_h=%d\n",
+ src_x,src_y,src_w,src_h);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, sbuf);
+ sprintf(sbuf,"out drw: drw_x=%d drw_y=%d drw_w=%d drw_h=%d\n",
+ drw_x,drw_y,drw_w,drw_h);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, sbuf);
+#endif
+
+ /* ready to draw */
+ if(drw_w==0||drw_h==0) return;
+
+ if(drw_w<0||drw_h<0) {
+ /* actually until scaling is working this might happen
+ during normal operation */
+ /* sprintf(sbuf,"drw_w or drw_h are negative (this should never
+ happen)\n");
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, sbuf); */
+ return;
+ }
+
+ CHECK_DMA_QUIESCENT(pMga, pScrn);
+
+ /* non scaling ILOAD */
+ WAITFIFO(6);
+ OUTREG(MGAREG_AR5, 0);
+ OUTREG(MGAREG_DWGCTL, MGADWG_ILOAD | MGADWG_BUYUV | MGADWG_SHIFTZERO
+ | MGADWG_SGNZERO | 0xc0000);
+ OUTREG(MGAREG_AR0, (drw_w)-1 );
+ OUTREG(MGAREG_AR3, 0);
+ OUTREG(MGAREG_CXBNDRY, clip_x1|(clip_x2<<16));
+ OUTREG(MGAREG_FXBNDRY, drw_x|((drw_x+drw_w-1)<<16));
+ OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC , (drw_y<<16)|drw_h);
+
+ fb_ptr=(CARD32 *)pMga->ILOADBase;
+ vbuf=buf+width*height;
+ ubuf=vbuf+width*height/4;
+
+ switch(id) {
+ case FOURCC_YV12:
+ case FOURCC_I420:
+ pu = (CARD32 *)(ubuf+(src_y/2)*(width/2));
+ pv = (CARD32 *)(vbuf+(src_y/2)*(width/2));
+ buf+=src_y*width;
+
+ for(l=0;l<drw_h;l++) {
+ CARD32 *tpu=pu+src_x/8;
+ CARD32 *tpv=pv+src_x/8;
+ CARD32 *tsp=(CARD32 *)(buf+src_x);
+
+ /* it is not clear if waiting is actually good for performance */
+ /* WAITFIFO(pMga->FifoSize);*/
+ /* should try to get MGACopyMunged data to work here */
+ CopyMungedScanline_AXP(fb_ptr,src_w,tsp,tpu,tpv);
+ buf+=width;
+ if(l&1) {
+ pu+=width/8;
+ pv+=width/8;
+ }
+ }
+ break;
+ case FOURCC_UYVY:
+ case FOURCC_YUY2:
+ buf+=src_y*width*2;
+ for(l=0;l<drw_h;l++) {
+
+#ifndef CUSTOM_MEMCOPY
+ WAITFIFO(pMga->FifoSize/2); /* not sure what's the value for best performance */
+ memcpy(fb_ptr, buf+src_x*2, src_w*2);
+ fb_ptr+=src_w*2;
+#else
+ CARD32 *tsp=(CARD32 *)(buf+src_x*2);
+ WAITFIFO(pMga->FifoSize/4);
+ for(k=src_w/8;k;k--) {
+ *(fb_ptr)=*(tsp);
+ *(fb_ptr+1)=*(tsp+1);
+ *(fb_ptr+2)=*(tsp+2);
+ *(fb_ptr+3)=*(tsp+3);
+ fb_ptr+=4; tsp+=4;
+ }
+#endif /* CUSTOM_MEMCOPY */
+ buf+=width*2;
+ }
+ break;
+ default:
+ break;
+ }
+ OUTREG(MGAREG_CXBNDRY, 0xFFFF0000); /* put clipping back to normal */
+}
+
+static int
+MGAPutImageILOAD(
+ ScrnInfoPtr pScrn,
+ short src_x, short src_y,
+ short drw_x, short drw_y,
+ short src_w, short src_h,
+ short drw_w, short drw_h,
+ int id, unsigned char* buf,
+ short width, short height,
+ Bool Sync,
+ RegionPtr clipBoxes, pointer data,
+ DrawablePtr pDraw
+ ){
+ MGAPtr pMga = MGAPTR(pScrn);
+ MGAPortPrivPtr pPriv = pMga->portPrivate;
+ INT32 x1, x2, y1, y2;
+ int dstPitch = 0;
+ int bpp;
+ BoxRec dstBox;
+ int nbox;
+ BoxPtr pbox;
+
+ /* Clip */
+ x1 = src_x; x2 = src_x + src_w;
+ y1 = src_y; y2 = src_y + src_h;
+
+ dstBox.x1 = drw_x; dstBox.x2 = drw_x + drw_w;
+ dstBox.y1 = drw_y; dstBox.y2 = drw_y + drw_h;
+
+ if(!xf86XVClipVideoHelper(&dstBox, &x1, &x2, &y1, &y2,
+ clipBoxes, width, height))
+ return Success;
+
+ bpp = pScrn->bitsPerPixel >> 3;
+
+ if( pMga->AccelInfoRec->NeedToSync && ((long)data != pPriv->lastPort) ) {
+ MGAStormSync(pScrn);
+ }
+
+ pPriv->lastPort = (long)data;
+ nbox=REGION_NUM_RECTS(clipBoxes);
+ pbox=REGION_RECTS(clipBoxes);
+
+ while(nbox--) {
+
+ if ( (drw_w==src_w) && (drw_h==src_h) && (drw_x >= 0 ) ) {
+ /* special case 1: non scaling optimization */
+ MGACopyILOAD(pScrn,id,buf,pbox,
+ width, height, dstPitch, src_x, src_y, src_w, src_h,
+ drw_x, drw_y, drw_w, drw_h);
+#if 0
+ } else if ( (drw_w>src_w) && (drw_h>src_h) && (drw_x >= 0 ) ) {
+ /* special case 2: upscaling for full screen apps */
+ /* FIXME: to do */
+ MGACopyScaledILOAD(pScrn,id,buf,pbox,
+ width, height, dstPitch, src_x, src_y, src_w, src_h,
+ drw_x, drw_y, drw_w, drw_h);
+
+#endif
+ } else /* generic fallback case */
+ MGACopyScaledILOAD(pScrn,id,buf,pbox,
+ width, height, dstPitch, src_x, src_y, src_w, src_h,
+ drw_x, drw_y, drw_w, drw_h);
+ /* FIXME: when the generic is perfect I will enable the optimizations */
+ pbox++;
+ }
+
+
+ pMga->AccelInfoRec->NeedToSync = TRUE;
+ pPriv->videoStatus = FREE_TIMER;
+ pPriv->freeTime = currentTime.milliseconds + FREE_DELAY;
+ pMga->VideoTimerCallback = MGAVideoTimerCallback;
+
+ return Success;
+}
diff --git a/util/stormdwg.c b/util/stormdwg.c
index 8f04e0e..99f76cc 100644
--- a/util/stormdwg.c
+++ b/util/stormdwg.c
@@ -7,7 +7,7 @@
#include <stdio.h>
#include <stdlib.h>
-char *opcodes[] = {
+const char *opcodes[] = {
"line_open", /* 0000 */
"autoline_open", /* 0001 */
"line_close", /* 0010 */
@@ -29,7 +29,7 @@ char *opcodes[] = {
"iload filter" /* 1111 */
};
-char *atype[] = {
+const char *atype[] = {
"rpl - Write (Replace)", /* 000 */
"rstr - read-modify-write (raster)", /* 001 */
"reserved", /* 010 */
@@ -40,7 +40,7 @@ char *atype[] = {
"I - Gouraud (with depth compare)" /* 111 */
};
-char *zmode[] = {
+const char *zmode[] = {
"NOZCMP - always", /* 000 */
"reserved", /* 001 */
"ZE - depth =", /* 010 */
@@ -51,7 +51,7 @@ char *zmode[] = {
"zgte" /* 111 */
};
-char *bop[] = {
+const char *bop[] = {
"0", /* 0000 */
"~(D|S)", /* 0001 */
"D & ~S", /* 0010 */
@@ -73,7 +73,7 @@ char *bop[] = {
"1" /* 1111 */
};
-char *bitmod[] = {
+const char *bitmod[] = {
"BMONOLEF - Source is mono, or if iload, source is little endian", /* 0000 */
"BPLAN - source is mono from one plane", /* 0001 */
"BFCOL - source is colour, and is formatted from host", /* 0010 */