summaryrefslogtreecommitdiff
path: root/xc/programs/Xserver/hw/xfree86/drivers/tdfx
diff options
context:
space:
mode:
Diffstat (limited to 'xc/programs/Xserver/hw/xfree86/drivers/tdfx')
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx.h35
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_dga.c47
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_dri.c43
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_driver.c210
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_priv.c58
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_video.c1587
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfxdefs.h8
7 files changed, 1253 insertions, 735 deletions
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx.h b/xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx.h
index 62ee2add7..beee925a7 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx.h
+++ b/xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx.h
@@ -12,6 +12,7 @@
#include "xf86PciInfo.h"
#include "xf86Pci.h"
+#include "xf86xv.h"
#include "tdfxdefs.h"
#ifdef XF86DRI
@@ -35,16 +36,11 @@
struct _TDFXRec;
typedef struct _TDFXRec *TDFXPtr;
-#ifdef XF86DRI
-#define PIXMAP_CACHE_LINES 750
-#else
-#define PIXMAP_CACHE_LINES 2048
-#endif
-
-
#include "tdfx_priv.h"
extern void TDFXSwapContextFifo(ScreenPtr pScreen);
extern void TDFXLostContext(ScreenPtr pScreen);
+extern Bool TDFXSetupSLI(ScrnInfoPtr pScrn, Bool sliEnable, int aaSamples);
+extern Bool TDFXDisableSLI(TDFXPtr pTDFX);
#ifdef XF86DRI
extern void FillPrivateDRI(TDFXPtr pTDFX, TDFXDRIPtr pTDFXDRI);
@@ -205,7 +201,19 @@ typedef struct _TDFXRec {
* shadow everything and make it happen automatically for every write. */
INT32 sst2DSrcFmtShadow;
INT32 sst2DDstFmtShadow;
- int pixmapCacheLines;
+ int pixmapCacheLinesMin;
+ int pixmapCacheLinesMax;
+ FBAreaPtr reservedArea;
+ Bool ShowCache;
+ Bool OverlayXvideo;
+ Bool TextureXvideo;
+ int videoKey;
+ void (*VideoTimerCallback)(ScrnInfoPtr, Time);
+ FBLinearPtr overlayBuffer;
+ FBAreaPtr textureBuffer;
+ XF86VideoAdaptorPtr overlayAdaptor;
+ XF86VideoAdaptorPtr textureAdaptor;
+ ScreenBlockHandlerProcPtr BlockHandler;
} TDFXRec;
typedef struct {
@@ -215,6 +223,15 @@ typedef struct {
int TexOwner;
} TDFXSAREAPriv;
+typedef struct {
+ RegionRec clip;
+ CARD32 colorKey;
+ int filterQuality;
+ CARD32 videoStatus;
+ Time offTime;
+ Time freeTime;
+} TDFXPortPrivRec, *TDFXPortPrivPtr;
+
#define TDFXPTR(p) ((TDFXPtr)((p)->driverPrivate))
#define DRAW_STATE_CLIPPING 0x1
@@ -269,5 +286,3 @@ extern void TDFXSelectBuffer(TDFXPtr pTDFX, int which);
#endif
-
-
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_dga.c b/xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_dga.c
index 896add046..d97363b57 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_dga.c
+++ b/xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_dga.c
@@ -6,6 +6,7 @@
#include "dgaproc.h"
#include "tdfx.h"
+#include "vgaHW.h"
static Bool TDFX_OpenFramebuffer(ScrnInfoPtr, char **, unsigned char **,
int *, int *, int *);
@@ -93,24 +94,20 @@ SECOND_PASS:
currentMode->imageHeight = pScrn->virtualY;
currentMode->pixmapWidth = currentMode->imageWidth;
currentMode->pixmapHeight = currentMode->imageHeight;
- currentMode->maxViewportX = currentMode->imageWidth -
- currentMode->viewportWidth;
+ currentMode->maxViewportX = currentMode->imageWidth - currentMode->viewportWidth;
/* this might need to get clamped to some maximum */
- currentMode->maxViewportY = currentMode->imageHeight -
- currentMode->viewportHeight;
+ currentMode->maxViewportY = currentMode->imageHeight - currentMode->viewportHeight;
oneMore = FALSE;
goto SECOND_PASS;
} else {
currentMode->bytesPerScanline = ((pScrn->displayWidth * pTDFX->cpp) + 3) & ~3L;
currentMode->imageWidth = pScrn->displayWidth;
- currentMode->imageHeight = pScrn->virtualY;
+ currentMode->imageHeight = pScrn->virtualY;
currentMode->pixmapWidth = currentMode->imageWidth;
currentMode->pixmapHeight = currentMode->imageHeight;
- currentMode->maxViewportX = currentMode->imageWidth -
- currentMode->viewportWidth;
+ currentMode->maxViewportX = currentMode->imageWidth - currentMode->viewportWidth;
/* this might need to get clamped to some maximum */
- currentMode->maxViewportY = currentMode->imageHeight -
- currentMode->viewportHeight;
+ currentMode->maxViewportY = currentMode->imageHeight - currentMode->viewportHeight;
}
pMode = pMode->next;
@@ -125,25 +122,26 @@ SECOND_PASS:
static Bool
TDFX_SetMode(ScrnInfoPtr pScrn, DGAModePtr pMode)
{
- static int OldDisplayWidth[MAXSCREENS];
+ static DisplayModePtr OldModes[MAXSCREENS];
int index = pScrn->pScreen->myNum;
TDFXPtr pTDFX = TDFXPTR(pScrn);
if (!pMode) { /* restore the original mode */
/* put the ScreenParameters back */
- pScrn->displayWidth = OldDisplayWidth[index];
- TDFXSwitchMode(index, pScrn->currentMode, 0);
- pTDFX->DGAactive = FALSE;
+ if (pTDFX->DGAactive) {
+ TDFXSwitchMode(index, OldModes[index], 0);
+ TDFXAdjustFrame(pScrn->pScreen->myNum, 0, 0, 0);
+ pTDFX->DGAactive = FALSE;
+ }
} else {
- if (!pTDFX->DGAactive) { /* save the old parameters */
- OldDisplayWidth[index] = pScrn->displayWidth;
-
+ /* save the old ScreenParameters */
+ if (!pTDFX->DGAactive) {
+ OldModes[index] = pScrn->currentMode;
pTDFX->DGAactive = TRUE;
}
pScrn->displayWidth = pMode->bytesPerScanline / pTDFX->cpp;
-
TDFXSwitchMode(index, pMode->mode, 0);
}
@@ -162,9 +160,14 @@ static void
TDFX_SetViewport(ScrnInfoPtr pScrn, int x, int y, int flags)
{
TDFXPtr pTDFX = TDFXPTR(pScrn);
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
TDFXAdjustFrame(pScrn->pScreen->myNum, x, y, flags);
- pTDFX->DGAViewportStatus = 0; /* TDFXAdjustFrame loops until finished */
+
+ while (hwp->readST01(hwp) & 0x08);
+ while (!(hwp->readST01(hwp) & 0x08));
+
+ pTDFX->DGAViewportStatus = 0;
}
static void
@@ -189,10 +192,8 @@ TDFX_BlitRect(ScrnInfoPtr pScrn, int srcx, int srcy, int w, int h,
int xdir = ((srcx < dstx) && (srcy == dsty)) ? -1 : 1;
int ydir = (srcy < dsty) ? -1 : 1;
- (*pTDFX->AccelInfoRec->SetupForScreenToScreenCopy)(pScrn, xdir, ydir,
- GXcopy, ~0, -1);
- (*pTDFX->AccelInfoRec->SubsequentScreenToScreenCopy)(pScrn, srcx, srcy,
- dstx, dsty, w, h);
+ (*pTDFX->AccelInfoRec->SetupForScreenToScreenCopy)(pScrn, xdir, ydir, GXcopy, ~0, -1);
+ (*pTDFX->AccelInfoRec->SubsequentScreenToScreenCopy)(pScrn, srcx, srcy, dstx, dsty, w, h);
}
}
@@ -224,7 +225,7 @@ TDFX_OpenFramebuffer(
*name = NULL; /* no special device */
*mem = (unsigned char*)pTDFX->LinearAddr[0];
*size = pTDFX->FbMapSize;
- *offset = 0;
+ *offset = 0;
*flags = DGA_NEED_ROOT;
return TRUE;
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_dri.c b/xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_dri.c
index 8c5831420..f5e7306a2 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_dri.c
+++ b/xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_dri.c
@@ -31,6 +31,8 @@ static Bool TDFXDRICloseFullScreen(ScreenPtr pScreen);
static void TDFXDRIInitBuffers(WindowPtr pWin, RegionPtr prgn, CARD32 index);
static void TDFXDRIMoveBuffers(WindowPtr pParent, DDXPointRec ptOldOrg,
RegionPtr prgnSrc, CARD32 index);
+static void TDFXDRITransitionTo2d(ScreenPtr pScreen);
+static void TDFXDRITransitionTo3d(ScreenPtr pScreen);
static Bool
TDFXInitVisualConfigs(ScreenPtr pScreen)
@@ -375,6 +377,8 @@ Bool TDFXDRIScreenInit(ScreenPtr pScreen)
pDRIInfo->MoveBuffers = TDFXDRIMoveBuffers;
pDRIInfo->OpenFullScreen = TDFXDRIOpenFullScreen;
pDRIInfo->CloseFullScreen = TDFXDRICloseFullScreen;
+ pDRIInfo->TransitionTo2d = TDFXDRITransitionTo2d;
+ pDRIInfo->TransitionTo3d = TDFXDRITransitionTo3d;
pDRIInfo->bufferRequests = DRI_ALL_WINDOWS;
if (!DRIScreenInit(pScreen, pDRIInfo, &pTDFX->drmSubFD)) {
@@ -704,3 +708,42 @@ TDFXDRICloseFullScreen(ScreenPtr pScreen)
return TRUE;
}
+
+static void
+TDFXDRITransitionTo2d(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ TDFXPtr pTDFX = TDFXPTR(pScrn);
+
+ xf86FreeOffscreenArea(pTDFX->reservedArea);
+}
+
+
+static void
+TDFXDRITransitionTo3d(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ TDFXPtr pTDFX = TDFXPTR(pScrn);
+ FBAreaPtr pArea;
+
+ if(pTDFX->overlayBuffer) {
+ xf86FreeOffscreenLinear(pTDFX->overlayBuffer);
+ pTDFX->overlayBuffer = NULL;
+ }
+
+ if(pTDFX->textureBuffer) {
+ xf86FreeOffscreenArea(pTDFX->textureBuffer);
+ pTDFX->textureBuffer = NULL;
+ }
+
+ xf86PurgeUnlockedOffscreenAreas(pScreen);
+
+ /* this is an ugly hack! isnt there a resize? */
+ pArea = xf86AllocateOffscreenArea(pScreen, pScrn->displayWidth,
+ pTDFX->pixmapCacheLinesMin,
+ pScrn->displayWidth, NULL, NULL, NULL);
+ pTDFX->reservedArea = xf86AllocateOffscreenArea(pScreen, pScrn->displayWidth,
+ pTDFX->pixmapCacheLinesMax - pTDFX->pixmapCacheLinesMin,
+ pScrn->displayWidth, NULL, NULL, NULL);
+ xf86FreeOffscreenArea(pArea);
+}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_driver.c b/xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_driver.c
index a39c9b780..e3c72918d 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_driver.c
+++ b/xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_driver.c
@@ -89,6 +89,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "tdfx.h"
#include "miscstruct.h"
+#include "dixstruct.h"
#include "xf86xv.h"
#include "Xv.h"
@@ -135,6 +136,8 @@ static void TDFXFreeScreen(int scrnIndex, int flags);
static int TDFXValidMode(int scrnIndex, DisplayModePtr mode, Bool
verbose, int flags);
+static void TDFXBlockHandler(int, pointer, pointer, pointer);
+
#ifdef DPMSExtension
/* Switch to various Display Power Management System levels */
static void TDFXDisplayPowerManagementSet(ScrnInfoPtr pScrn,
@@ -178,14 +181,22 @@ typedef enum {
OPTION_NOACCEL,
OPTION_SW_CURSOR,
OPTION_USE_PIO,
- OPTION_NO_SLI
+ OPTION_SHOWCACHE,
+ OPTION_VIDEO_KEY,
+ OPTION_NO_SLI,
+ OPTION_OVERLAY_XV,
+ OPTION_TEXTURE_XV
} TDFXOpts;
static OptionInfoRec TDFXOptions[] = {
{ OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE },
{ OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE },
{ OPTION_USE_PIO, "UsePIO", OPTV_BOOLEAN, {0}, FALSE},
+ { OPTION_SHOWCACHE, "ShowCache", OPTV_BOOLEAN, {0}, FALSE},
+ { OPTION_VIDEO_KEY, "VideoKey", OPTV_INTEGER, {0}, FALSE},
{ OPTION_NO_SLI, "NoSLI", OPTV_BOOLEAN, {0}, FALSE},
+ { OPTION_OVERLAY_XV, "OverlayXvideo", OPTV_BOOLEAN, {1}, TRUE},
+ { OPTION_TEXTURE_XV, "TextureXvideo", OPTV_BOOLEAN, {1}, TRUE},
{ -1, NULL, OPTV_NONE, {0}, FALSE}
};
@@ -399,7 +410,7 @@ TDFXProbeDDC(ScrnInfoPtr pScrn, int index)
#endif
{
pVbe = VBEInit(NULL,index);
- vbeDoEDID(pVbe, NULL);
+ ConfiguredMonitor = vbeDoEDID(pVbe, NULL);
}
}
@@ -949,6 +960,30 @@ TDFXPreInit(ScrnInfoPtr pScrn, int flags)
}
}
+ if (!xf86GetOptValBool(TDFXOptions, OPTION_SHOWCACHE, &(pTDFX->ShowCache))) {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ShowCache %s\n", pTDFX->ShowCache ? "Enabled" : "Disabled");
+ } else {
+ pTDFX->ShowCache = FALSE;
+ }
+
+ if (xf86GetOptValBool(TDFXOptions, OPTION_OVERLAY_XV, &(pTDFX->OverlayXvideo))) {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Overlay Xvideo Adaptor %s\n", pTDFX->OverlayXvideo ? "Enabled" : "Disabled");
+ } else {
+ pTDFX->OverlayXvideo = TRUE;
+ }
+
+ if (xf86GetOptValBool(TDFXOptions, OPTION_TEXTURE_XV, &(pTDFX->TextureXvideo))) {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Texture Xvideo Adaptor %s\n", pTDFX->TextureXvideo ? "Enabled" : "Disabled");
+ } else {
+ pTDFX->TextureXvideo = TRUE;
+ }
+
+ if (xf86GetOptValInteger(TDFXOptions, OPTION_VIDEO_KEY, &(pTDFX->videoKey))) {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "video key set to 0x%x\n", pTDFX->videoKey);
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "video key default 0x%x\n", pTDFX->videoKey = 0x1E);
+ }
+
if (!xf86ReturnOptValBool(TDFXOptions, OPTION_SW_CURSOR, FALSE)) {
if (!xf86LoadSubModule(pScrn, "ramdac")) {
TDFXFreeRec(pScrn);
@@ -1440,6 +1475,7 @@ TDFXModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
int hd, hbs, hss, hse, hbe, ht, hskew;
Bool dbl;
+ hd = hbs = hss = hse = hbe = ht = hskew = 0;
hwp = VGAHWPTR(pScrn);
pTDFX = TDFXPTR(pScrn);
@@ -1500,35 +1536,35 @@ TDFXModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
static void
TDFXLoadPalette16(ScrnInfoPtr pScrn, int numColors, int *indices, LOCO *colors,
- short visualClass) {
+ VisualPtr pVisual) {
TDFXPtr pTDFX;
int i, j, index, v, repeat, max;
TDFXTRACE("TDFXLoadPalette16 start\n");
pTDFX = TDFXPTR(pScrn);
+
for (i=0; i<numColors; i++) {
index=indices[i];
v=(colors[index/2].red<<16)|(colors[index].green<<8)|colors[index/2].blue;
- if (i<numColors-1) max=indices[i+1]<<2;
- else max=256;
- for (j=index<<2; j<max; j++) {
+ max=min((index+1)<<2, 256);
+ for (j = index<<2; j < max; j++)
+ {
repeat=100;
do {
TDFXWriteLongMMIO(pTDFX, DACADDR, j);
} while (--repeat && TDFXReadLongMMIO(pTDFX, DACADDR)!=j);
if (!repeat) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Failed to set dac index, "
- "bypassing CLUT\n");
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Failed to set dac index, bypassing CLUT\n");
pTDFX->ModeReg.vidcfg |= SST_DESKTOP_CLUT_BYPASS;
return;
}
+
repeat=100;
do {
TDFXWriteLongMMIO(pTDFX, DACDATA, v);
} while (--repeat && TDFXReadLongMMIO(pTDFX, DACDATA)!=v);
if (!repeat) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Failed to set dac value, "
- "bypassing CLUT\n");
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Failed to set dac value, bypassing CLUT\n");
pTDFX->ModeReg.vidcfg |= SST_DESKTOP_CLUT_BYPASS;
return;
}
@@ -1538,7 +1574,7 @@ TDFXLoadPalette16(ScrnInfoPtr pScrn, int numColors, int *indices, LOCO *colors,
static void
TDFXLoadPalette24(ScrnInfoPtr pScrn, int numColors, int *indices, LOCO *colors,
- short visualClass) {
+ VisualPtr pVisual) {
TDFXPtr pTDFX;
int i, index, v, repeat;
@@ -1635,11 +1671,8 @@ calcBufferSize(int xres, int yres, Bool tiled, int cpp)
} /* calcBufferSize */
static void allocateMemory(ScrnInfoPtr pScrn) {
- TDFXPtr pTDFX;
- int memRemaining, texSize, fifoSize, screenSizeInTiles;
-
- pTDFX = TDFXPTR(pScrn);
- pTDFX->stride = pScrn->displayWidth*pTDFX->cpp;
+ TDFXPtr pTDFX = TDFXPTR(pScrn);
+ int memRemaining, fbSize, cursorSize, fifoSize, screenSizeInTiles;
if (pTDFX->cpp!=3) {
screenSizeInTiles=calcBufferSize(pScrn->virtualX, pScrn->virtualY,
@@ -1658,7 +1691,7 @@ static void allocateMemory(ScrnInfoPtr pScrn) {
/* it to be on an *odd* page boundary. */
pTDFX->depthOffset = (memRemaining - screenSizeInTiles) &~ 0xFFF;
if ((pTDFX->depthOffset & (0x1 << 12)) == 0) {
-#if 0
+#if 1
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"Changing depth offset from 0x%08x to 0x%08x\n",
pTDFX->depthOffset,
@@ -1670,7 +1703,7 @@ static void allocateMemory(ScrnInfoPtr pScrn) {
/* to be on an *even* page boundary. */
pTDFX->backOffset = (pTDFX->depthOffset - screenSizeInTiles) &~ 0xFFF;
if (pTDFX->backOffset & (0x1 << 12)) {
-#if 0
+#if 1
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"Changing back offset from 0x%08x to 0x%08x\n",
pTDFX->backOffset,
@@ -1678,52 +1711,59 @@ static void allocateMemory(ScrnInfoPtr pScrn) {
#endif
pTDFX->backOffset -= (0x1 << 12);
}
- /* Now, place the front buffer, forcing */
- /* it to be on a page boundary too, just */
- /* for giggles. */
- pTDFX->fbOffset
- = (pTDFX->backOffset - (pScrn->virtualY+PIXMAP_CACHE_LINES)*pTDFX->stride) &~ 0xFFF;
/* Give the cmd fifo at least */
/* CMDFIFO_PAGES pages, but no more than */
/* 255. */
fifoSize = ((255 <= CMDFIFO_PAGES) ? 255 : CMDFIFO_PAGES) << 12;
+ fbSize = (pScrn->virtualY + pTDFX->pixmapCacheLinesMin) * pTDFX->stride;
+ cursorSize = 4096;
/* We give 4096 bytes to the cursor, fifoSize to the */
/* FIFO, and everything to textures. */
/* Bump everything by 64k to move it past VGA memory */
- texSize = (pTDFX->fbOffset - fifoSize - 4096 - 64*1024);
- pTDFX->texOffset = pTDFX->fbOffset - texSize + 64*1024;
- pTDFX->texSize = texSize;
- pTDFX->fifoOffset = 4096+64*1024;
+ pTDFX->cursorOffset = 64*1024;
+ pTDFX->fifoOffset = pTDFX->cursorOffset + cursorSize;
pTDFX->fifoSize = fifoSize;
- pTDFX->cursorOffset = 0+64*1024;
-#if 0
+ /* Now, place the front buffer, forcing */
+ /* it to be on a page boundary too, just */
+ /* for giggles. */
+ pTDFX->fbOffset = (pTDFX->fifoOffset + pTDFX->fifoSize) &~ 0xFFF;
+ pTDFX->texOffset = pTDFX->fbOffset + fbSize;
+ pTDFX->texSize = pTDFX->backOffset - pTDFX->texOffset;
+
+ if (pTDFX->texSize <= 0) {
+ pTDFX->backOffset = -1;
+ pTDFX->depthOffset = -1;
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "No Texture Memory available, disabling DRI\n");
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Texture Memory %0.02f MB\n", pTDFX->texSize / 1024.0 / 1024.0);
+ }
+
+#if 1
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"Cursor Offset: [0x%08X,0x%08X)\n",
pTDFX->cursorOffset,
- pTDFX->cursorOffset+1024);
+ pTDFX->cursorOffset + cursorSize);
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"Fifo Offset: [0x%08X, 0x%08X)\n",
pTDFX->fifoOffset,
- pTDFX->fifoOffset+fifoSize);
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Texture Offset: [0x%08X, 0x%08X)\n",
- pTDFX->texOffset,
- pTDFX->texOffset + texSize);
+ pTDFX->fifoOffset + pTDFX->fifoSize);
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"Front Buffer Offset: [0x%08X, 0x%08X)\n",
pTDFX->fbOffset,
- pTDFX->fbOffset + (pScrn->virtualY+PIXMAP_CHACHE_LINES)*pTDFX->stride);
+ pTDFX->fbOffset + fbSize);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Texture Offset: [0x%08X, 0x%08X)\n",
+ pTDFX->texOffset,
+ pTDFX->texOffset + pTDFX->texSize);
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"BackOffset: [0x%08X, 0x%08X)\n",
pTDFX->backOffset,
- pTDFX->backOffset+screenSizeInTiles);
+ pTDFX->backOffset + screenSizeInTiles);
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"DepthOffset: [0x%08X, 0x%08X)\n",
pTDFX->depthOffset,
- pTDFX->depthOffset+screenSizeInTiles);
+ pTDFX->depthOffset + screenSizeInTiles);
#endif /* 0/1 */
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Textures Memory %0.02f MB\n",
- (float)texSize/1024.0/1024.0);
}
static Bool
@@ -1734,7 +1774,6 @@ TDFXScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) {
VisualPtr visual;
int maxy;
BoxRec MemBox;
- RegionRec MemRegion;
TDFXTRACE("TDFXScreenInit start\n");
pScrn = xf86Screens[pScreen->myNum];
@@ -1748,6 +1787,10 @@ TDFXScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) {
vgaHWGetIOBase(hwp);
if (!vgaHWMapMem(pScrn)) return FALSE;
+ /* we want at least enough pixmap cache to do DVD */
+ pTDFX->stride = pScrn->displayWidth*pTDFX->cpp;
+ pTDFX->pixmapCacheLinesMin = ((720*480*2) + pTDFX->stride - 1) / pTDFX->stride;
+
allocateMemory(pScrn);
#if 0
@@ -1769,13 +1812,30 @@ TDFXScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) {
return FALSE;
}
- maxy=pScrn->virtualY+PIXMAP_CACHE_LINES;
- MemBox.y1 = pScrn->virtualY;
+ pTDFX->pixmapCacheLinesMax = (pTDFX->backOffset - pTDFX->fbOffset) / pTDFX->stride;
+ if(pTDFX->ChipType < PCI_CHIP_VOODOO5) {
+ if (pTDFX->pixmapCacheLinesMax > 2048)
+ pTDFX->pixmapCacheLinesMax = 2048;
+ } else {
+ if (pTDFX->pixmapCacheLinesMax > 4095)
+ pTDFX->pixmapCacheLinesMax = 4095;
+ }
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "%d pixmap cache lines for 2D/video when 3D inactive\n",
+ pTDFX->pixmapCacheLinesMax);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "%d pixmap cache lines for 2D/video when 3D active\n",
+ pTDFX->pixmapCacheLinesMin);
+
+ /* region the whole memory (framebuffer+pixmapcache) and let
+ * xf86InitFBManager do the visible region subtraction
+ */
MemBox.x1 = 0;
+ MemBox.y1 = 0;
MemBox.x2 = pScrn->displayWidth;
- MemBox.y2 = maxy;
-
- pTDFX->maxClip=((pScrn->virtualX+1)&0xFFF) | (((maxy+1)&0xFFF)<<16);
+ MemBox.y2 = pTDFX->pixmapCacheLinesMax;
+ pTDFX->maxClip = (MemBox.x2) | (MemBox.y2 << 16);
TDFXSave(pScrn);
if (!TDFXModeInit(pScrn, pScrn->currentMode)) return FALSE;
@@ -1797,8 +1857,11 @@ TDFXScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) {
* is called. fbScreenInit will eventually call into the drivers
* InitGLXVisuals call back.
*/
- if (!pTDFX->NoAccel)
- pTDFX->directRenderingEnabled = TDFXDRIScreenInit(pScreen);
+ if (!pTDFX->NoAccel) {
+ if ((pTDFX->backOffset != -1) && (pTDFX->depthOffset != -1)) {
+ pTDFX->directRenderingEnabled = TDFXDRIScreenInit(pScreen);
+ }
+ }
#endif
switch (pScrn->bitsPerPixel) {
@@ -1840,13 +1903,7 @@ TDFXScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) {
TDFXDGAInit(pScreen);
- REGION_INIT(pScreen, &MemRegion, &MemBox, 1);
- if (!xf86InitFBManagerRegion(pScreen, &MemRegion)) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to init memory manager\n");
- REGION_UNINIT(pScreen, &MemRegion);
- return FALSE;
- }
- REGION_UNINIT(pScreen, &MemRegion);
+ xf86InitFBManager(pScreen, &MemBox);
if (!pTDFX->NoAccel) {
if (!TDFXAccelInit(pScreen)) {
@@ -1912,6 +1969,9 @@ TDFXScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) {
pTDFX->CloseScreen = pScreen->CloseScreen;
pScreen->CloseScreen = TDFXCloseScreen;
+ pTDFX->BlockHandler = pScreen->BlockHandler;
+ pScreen->BlockHandler = TDFXBlockHandler;
+
if (serverGeneration == 1)
xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
@@ -1936,6 +1996,10 @@ TDFXAdjustFrame(int scrnIndex, int x, int y, int flags) {
TDFXTRACE("TDFXAdjustFrame start\n");
pScrn = xf86Screens[scrnIndex];
pTDFX = TDFXPTR(pScrn);
+
+ if (pTDFX->ShowCache && y && pScrn->vtSema)
+ y += pScrn->virtualY - 1;
+
tdfxReg = &pTDFX->ModeReg;
tdfxReg->startaddr = pTDFX->fbOffset+y*pTDFX->stride+(x*pTDFX->cpp);
TDFXTRACE("TDFXAdjustFrame to x=%d y=%d offset=%d\n", x, y, tdfxReg->startaddr);
@@ -1945,14 +2009,15 @@ TDFXAdjustFrame(int scrnIndex, int x, int y, int flags) {
static Bool
TDFXEnterVT(int scrnIndex, int flags) {
ScrnInfoPtr pScrn;
-#ifdef XF86DRI
ScreenPtr pScreen;
+#ifdef XF86DRI
TDFXPtr pTDFX;
#endif
TDFXTRACE("TDFXEnterVT start\n");
pScrn = xf86Screens[scrnIndex];
- InstallFifo(pScrn);
+ pScreen = screenInfo.screens[scrnIndex];
+ TDFXInitFifo(pScreen);
#ifdef XF86DRI
pTDFX = TDFXPTR(pScrn);
if (pTDFX->directRenderingEnabled) {
@@ -2029,9 +2094,22 @@ TDFXCloseScreen(int scrnIndex, ScreenPtr pScreen)
if (pTDFX->scanlineColorExpandBuffers[1])
xfree(pTDFX->scanlineColorExpandBuffers[1]);
pTDFX->scanlineColorExpandBuffers[1]=0;
+
+ if (pTDFX->overlayAdaptor) {
+ xfree(pTDFX->overlayAdaptor->pPortPrivates[0].ptr);
+ xf86XVFreeVideoAdaptorRec(pTDFX->overlayAdaptor);
+ pTDFX->overlayAdaptor = NULL;
+ }
+
+ if (pTDFX->textureAdaptor) {
+ xfree(pTDFX->textureAdaptor->pPortPrivates[0].ptr); /* FIXME: use loop */
+ xf86XVFreeVideoAdaptorRec(pTDFX->textureAdaptor);
+ pTDFX->textureAdaptor = NULL;
+ }
pScrn->vtSema=FALSE;
+ pScreen->BlockHandler = pTDFX->BlockHandler;
pScreen->CloseScreen = pTDFX->CloseScreen;
return (*pScreen->CloseScreen)(scrnIndex, pScreen);
}
@@ -2077,7 +2155,7 @@ TDFXBlankScreen(ScrnInfoPtr pScrn, Bool unblank)
scrn |= 0x20; /* blank screen */
}
- vgaHWSeqReset(hwp, TRUE);
+ vgaHWSeqReset(hwp, TRUE);
hwp->writeSeq(hwp, 0x01, scrn); /* change mode */
vgaHWSeqReset(hwp, FALSE);
}
@@ -2101,6 +2179,22 @@ TDFXSaveScreen(ScreenPtr pScreen, int mode)
return TRUE;
}
+static void
+TDFXBlockHandler(int i, pointer blockData, pointer pTimeout, pointer pReadmask)
+{
+ ScreenPtr pScreen = screenInfo.screens[i];
+ ScrnInfoPtr pScrn = xf86Screens[i];
+ TDFXPtr pTDFX = TDFXPTR(pScrn);
+
+ pScreen->BlockHandler = pTDFX->BlockHandler;
+ (*pScreen->BlockHandler) (i, blockData, pTimeout, pReadmask);
+ pScreen->BlockHandler = TDFXBlockHandler;
+
+ if(pTDFX->VideoTimerCallback) {
+ (*pTDFX->VideoTimerCallback)(pScrn, currentTime.milliseconds);
+ }
+}
+
#ifdef DPMSExtension
static void
TDFXDisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode,
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_priv.c b/xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_priv.c
index 58e49d1cf..1e590d546 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_priv.c
+++ b/xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_priv.c
@@ -1,4 +1,4 @@
-/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_priv.c,v 1.13 2000/12/15 15:19:35 dawes Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_priv.c,v 1.11 2000/12/01 14:29:00 dawes Exp $ */
#include "xf86.h"
@@ -11,13 +11,19 @@
/*
Memory layout of card is as follows:
- 000000-003fff: Cursor
- 001000-xxxxxx: Fifo (Min of CMDFIFO pages)
- xxxxxx-420fff: Texture maps
- 421000- A-1 : Framebuffer
- A - B-1 : Offscreen pixmaps
- B - C-1 : Back buffer
- C - D-1 : Z buffer
+ 000000-00ffff: VGA memory
+ 010000-013fff: Cursor
+ 011000-xxxxxx: Fifo (Min of CMDFIFO pages)
+ xxxxxx- A-1 : Front Buffer (framebuffer)
+ A - B-1 : Pixmap Cache (framebuffer)
+ B - C-1 : Texture Memory
+ C - D-1 : Back Buffer
+ D - E-1 : Depth Buffer
+
+ NB: pixmap cache usually butts right up against texture memory. when
+ 3d is disabled (via Transition2D) then the pixmap cache is increased
+ to overlap the texture memory. maximum pixmap cache of 4095 lines on
+ voodoo5 and 2048 on voodoo3/4 applies.
*/
void TDFXSendNOPFifo3D(ScrnInfoPtr pScrn)
@@ -117,9 +123,9 @@ void TDFXResetFifo(ScrnInfoPtr pScrn)
static void TDFXSyncFifo(ScrnInfoPtr pScrn)
{
TDFXPtr pTDFX;
- int i, cnt;
+ int i, cnt, resets=0;
int stat;
- long start_sec, end_sec, dummy;
+ long start_sec, end_sec, dummy, readptr;
TDFXTRACEACCEL("TDFXSyncFifo start\n");
pTDFX=TDFXPTR(pScrn);
@@ -127,7 +133,9 @@ static void TDFXSyncFifo(ScrnInfoPtr pScrn)
i=0;
cnt=0;
start_sec=0;
+ readptr=TDFXReadLongMMIO(pTDFX, SST_FIFO_RDPTRL0);
do {
+ readptr=TDFXReadLongMMIO(pTDFX, SST_FIFO_RDPTRL0);
stat=TDFXReadLongMMIO(pTDFX, 0);
if (stat&SST_BUSY) i=0; else i++;
cnt++;
@@ -137,7 +145,17 @@ static void TDFXSyncFifo(ScrnInfoPtr pScrn)
} else {
getsecs(&end_sec, &dummy);
if (end_sec-start_sec>3) {
- TDFXResetFifo(pScrn);
+ dummy=TDFXReadLongMMIO(pTDFX, SST_FIFO_RDPTRL0);
+ if (dummy==readptr) {
+ TDFXResetFifo(pScrn);
+ readptr=dummy;
+ resets++;
+ if (resets==3) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Board is not responding.\n");
+ return;
+ }
+ }
start_sec=0;
}
}
@@ -237,24 +255,6 @@ void TDFXSwapContextFifo(ScreenPtr pScreen)
pTDFX->fifoSlots = pTDFX->fifoEnd-pTDFX->fifoPtr-8;
}
-void TDFXLostContext(ScreenPtr pScreen)
-{
- ScrnInfoPtr pScrn;
- TDFXPtr pTDFX;
- TDFXSAREAPriv *sPriv;
-
- pScrn = xf86Screens[pScreen->myNum];
- pTDFX=TDFXPTR(pScrn);
- sPriv=(TDFXSAREAPriv*)DRIGetSAREAPrivate(pScreen);
- if (!sPriv) return;
- if (sPriv->fifoPtr!=(((unsigned char*)pTDFX->fifoPtr)-pTDFX->FbBase) ||
- sPriv->fifoRead!=(((unsigned char*)pTDFX->fifoRead)-pTDFX->FbBase)) {
- sPriv->fifoPtr=(((unsigned char*)pTDFX->fifoPtr)-pTDFX->FbBase);
- sPriv->fifoRead=(((unsigned char*)pTDFX->fifoRead)-pTDFX->FbBase);
- sPriv->fifoOwner=DRIGetContext(pScreen);
- /* ErrorF("Out FifoPtr=%d FifoRead=%d\n", sPriv->fifoPtr, sPriv->fifoRead); */
- }
-}
#endif
static void
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_video.c b/xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_video.c
index 8480de20a..d63592085 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_video.c
+++ b/xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_video.c
@@ -1,85 +1,134 @@
-/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_video.c,v 1.5 2000/12/08 21:53:37 mvojkovi Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_video.c,v 1.2 2000/12/02 15:30:57 tsi Exp $ */
-/* Adapted from ../mga/mga_video.c */
+#ifndef XvExtension
+void TDFXInitVideo(ScreenPtr pScreen) {}
+void TDFXCloseVideo(ScreenPtr pScreen) {}
+#else
#include "xf86.h"
-#include "xf86_OSproc.h"
-#include "xf86Resources.h"
-#include "xf86_ansic.h"
-#include "compiler.h"
-#include "xf86PciInfo.h"
-#include "xf86Pci.h"
-#include "xf86fbman.h"
-#include "regionstr.h"
-
#include "tdfx.h"
+#include "dixstruct.h"
-#include "xf86xv.h"
#include "Xv.h"
-#include "xaa.h"
-#include "xaalocal.h"
-#include "dixstruct.h"
#include "fourcc.h"
+static Atom xvColorKey, xvFilterQuality;
+
/* These should move into tdfxdefs.h with better names */
-#define YUV_Y_BASE 0xC00000
-#define YUV_U_BASE 0xD00000
-#define YUV_V_BASE 0xE00000
+#define YUV_Y_BASE 0xC00000
+#define YUV_U_BASE 0xD00000
+#define YUV_V_BASE 0xE00000
-#define SST_2D_FORMAT_YUYV 0x8
-#define SST_2D_FORMAT_UYVY 0x9
+#define SST_2D_FORMAT_YUYV 0x8
+#define SST_2D_FORMAT_UYVY 0x9
#define YUVBASEADDR 0x80100
-/* This should move to tdfx.h
- * Only one port for now due to need for better memory allocation. */
-#define TDFX_MAX_PORTS 1
-
#define YUVSTRIDE 0x80104
+#define VIDPROCCFGMASK 0xa2e3eb6c
-#ifndef XvExtension
-void TDFXInitVideo(ScreenPtr pScreen) {}
-#else
+#define OFF_DELAY 250 /* milliseconds */
+#define FREE_DELAY 15000
+
+#define OFF_TIMER 0x01
+#define FREE_TIMER 0x02
+#define CLIENT_VIDEO_ON 0x04
+#define TIMER_MASK (OFF_TIMER | FREE_TIMER)
+
+#define TDFX_MAX_OVERLAY_PORTS 1
+#define TDFX_MAX_TEXTURE_PORTS 32
+
+/* Doesn't matter what screen we use */
+#define DummyScreen screenInfo.screens[0]
+/* Needed for attribute atoms */
+#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE)
+
+/*
+ * PROTOTYPES
+ */
void TDFXInitVideo(ScreenPtr pScreen);
-void TDFXCloseVideo (ScreenPtr pScreen);
-
-static XF86VideoAdaptorPtr TDFXSetupImageVideo(ScreenPtr);
-static int TDFXSetPortAttribute(ScrnInfoPtr, Atom, INT32, pointer);
-static int TDFXGetPortAttribute(ScrnInfoPtr, Atom ,INT32 *, pointer);
-
-static void TDFXStopVideo(ScrnInfoPtr, pointer, Bool);
-static void TDFXQueryBestSize(ScrnInfoPtr, Bool, short, short, short, short,
- unsigned int *, unsigned int *, pointer);
-static int TDFXPutImage(ScrnInfoPtr, short, short, short, short, short,
- short, short, short, int, unsigned char*, short,
- short, Bool, RegionPtr, pointer);
-#if 0
-/* This isn't done yet, but eventually it will put images to the
- * video overlay. */
-static int TDFXPutImageOverlay(ScrnInfoPtr pScrn, short, short,
- short, short, short, short,
- short, short, int, unsigned char*,
- short, short, Bool, RegionPtr , pointer);
-#endif
-
-static int TDFXQueryImageAttributes(ScrnInfoPtr, int, unsigned short *,
- unsigned short *, int *, int *);
-
-/* These function is from tdfx_accel.c */
-extern void TDFXFirstSync(ScrnInfoPtr pScrn);
+void TDFXCloseVideo(ScreenPtr pScreen);
-static FBAreaPtr
-TDFXAllocateOffscreenBuffer (ScrnInfoPtr pScrn, int id, int width, int height);
+static FBAreaPtr TDFXAllocateMemoryArea (ScrnInfoPtr pScrn, FBAreaPtr area, int width, int height);
+static FBLinearPtr TDFXAllocateMemoryLinear (ScrnInfoPtr pScrn, FBLinearPtr linear, int size);
+static void TDFXVideoTimerCallback(ScrnInfoPtr pScrn, Time time);
-static void
-TDFXDeallocateOffscreenBuffer (ScrnInfoPtr pScrn, int id);
+static XF86VideoAdaptorPtr TDFXSetupImageVideoTexture(ScreenPtr);
+static int TDFXSetPortAttributeTexture(ScrnInfoPtr, Atom, INT32, pointer);
+static int TDFXGetPortAttributeTexture(ScrnInfoPtr, Atom ,INT32 *, pointer);
+static int TDFXPutImageTexture(ScrnInfoPtr, short, short, short, short, short, short, short, short, int, unsigned char*, short, short, Bool, RegionPtr, pointer);
+static void TDFXStopVideoTexture(ScrnInfoPtr, pointer, Bool);
+
+static XF86VideoAdaptorPtr TDFXSetupImageVideoOverlay(ScreenPtr);
+static int TDFXSetPortAttributeOverlay(ScrnInfoPtr, Atom, INT32, pointer);
+static int TDFXGetPortAttributeOverlay(ScrnInfoPtr, Atom ,INT32 *, pointer);
+static int TDFXPutImageOverlay(ScrnInfoPtr, short, short, short, short, short, short, short, short, int, unsigned char*, short, short, Bool, RegionPtr, pointer);
+static void TDFXStopVideoOverlay(ScrnInfoPtr, pointer, Bool);
+static void TDFXResetVideoOverlay(ScrnInfoPtr);
+
+static void TDFXQueryBestSize(ScrnInfoPtr, Bool, short, short, short, short, unsigned int *, unsigned int *, pointer);
+static int TDFXQueryImageAttributes(ScrnInfoPtr, int, unsigned short *, unsigned short *, int *, int *);
+
+/*
+ * ADAPTOR INFORMATION
+ */
+
+static XF86VideoEncodingRec OverlayEncoding[] =
+{
+ { 0, "XV_IMAGE", 2048, 2048, {1, 1} }
+};
+
+static XF86VideoEncodingRec TextureEncoding[] =
+{
+ { 0, "XV_IMAGE", 1024, 1024, {1, 1} }
+};
+
+static XF86VideoFormatRec OverlayFormats[] =
+{
+ {8, TrueColor}, {8, DirectColor}, {8, PseudoColor},
+ {8, GrayScale}, {8, StaticGray}, {8, StaticColor},
+ {15, TrueColor}, {16, TrueColor}, {24, TrueColor},
+ {15, DirectColor}, {16, DirectColor}, {24, DirectColor}
+};
+
+static XF86VideoFormatRec TextureFormats[] =
+{
+ {15, TrueColor}, {16, TrueColor}, {24, TrueColor}
+};
+
+static XF86AttributeRec OverlayAttributes[] =
+{
+ {XvSettable | XvGettable, 0, (1 << 24) - 1, "XV_COLORKEY"},
+ {XvSettable | XvGettable, 0, 1, "XV_FILTER_QUALITY"}
+};
+
+static XF86AttributeRec TextureAttributes[] =
+{
+ {XvSettable | XvGettable, 0, (1 << 24) - 1, "XV_COLORKEY"},
+ {XvSettable | XvGettable, 0, 1, "XV_FILTER_QUALITY"}
+};
+
+static XF86ImageRec OverlayImages[] =
+{
+ XVIMAGE_YUY2, XVIMAGE_UYVY, XVIMAGE_YV12, XVIMAGE_I420
+};
+
+static XF86ImageRec TextureImages[] =
+{
+ XVIMAGE_YV12, XVIMAGE_I420
+};
+
+/*
+ * COMMON SETUP FUNCTIONS
+ */
void TDFXInitVideo(ScreenPtr pScreen)
{
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
XF86VideoAdaptorPtr *adaptors, *newAdaptors = NULL;
- XF86VideoAdaptorPtr newAdaptor = NULL;
+ XF86VideoAdaptorPtr newOverlayAdaptor = NULL;
+ XF86VideoAdaptorPtr newTextureAdaptor = NULL;
TDFXPtr pTDFX = TDFXPTR(pScrn);
int num_adaptors;
@@ -87,685 +136,997 @@ void TDFXInitVideo(ScreenPtr pScreen)
if(pTDFX->cpp == 1)
return;
- newAdaptor = TDFXSetupImageVideo(pScreen);
-
- /* Initialize the offscreen buffer */
- pTDFX->offscreenYUVBuf = 0;
-
+ /* Start with the generic adaptors */
num_adaptors = xf86XVListGenericAdaptors(pScrn, &adaptors);
- if(newAdaptor) {
- if(!num_adaptors) {
- num_adaptors = 1;
- adaptors = &newAdaptor;
- } else {
- newAdaptors = /* need to free this someplace */
- xalloc((num_adaptors + 1) * sizeof(XF86VideoAdaptorPtr*));
- if(newAdaptors) {
- memcpy(newAdaptors, adaptors, num_adaptors *
- sizeof(XF86VideoAdaptorPtr));
- newAdaptors[num_adaptors] = newAdaptor;
- adaptors = newAdaptors;
- num_adaptors++;
- }
- }
+ /* Overlay adaptor */
+ if(pTDFX->AccelInfoRec && pTDFX->AccelInfoRec->FillSolidRects)
+ newOverlayAdaptor = TDFXSetupImageVideoOverlay(pScreen);
+
+ /* Texture adaptor */
+ if(pTDFX->AccelInfoRec && pTDFX->AccelInfoRec->FillSolidRects)
+ newTextureAdaptor = TDFXSetupImageVideoTexture(pScreen);
+
+ /* Add the overlay adaptor to the list */
+ if(newOverlayAdaptor) {
+ newAdaptors = xalloc((num_adaptors + 1) * sizeof(XF86VideoAdaptorPtr*));
+ if(newAdaptors) {
+ if (num_adaptors) memcpy(newAdaptors, adaptors, num_adaptors * sizeof(XF86VideoAdaptorPtr));
+ newAdaptors[num_adaptors] = newOverlayAdaptor;
+ adaptors = newAdaptors; /* FIXME: leak? */
+ num_adaptors++;
+ }
}
- if(num_adaptors)
- {
- xf86XVScreenInit(pScreen, adaptors, num_adaptors);
+ /* Add the texture adaptor to the list */
+ if(newTextureAdaptor) {
+ newAdaptors = xalloc((num_adaptors + 1) * sizeof(XF86VideoAdaptorPtr*));
+ if(newAdaptors) {
+ if (num_adaptors) memcpy(newAdaptors, adaptors, num_adaptors * sizeof(XF86VideoAdaptorPtr));
+ newAdaptors[num_adaptors] = newTextureAdaptor;
+ adaptors = newAdaptors; /* FIXME: leak? */
+ num_adaptors++;
+ }
}
+ if(num_adaptors)
+ xf86XVScreenInit(pScreen, adaptors, num_adaptors);
+
if(newAdaptors)
- xfree(newAdaptors);
+ xfree(newAdaptors);
}
+
void TDFXCloseVideo (ScreenPtr pScreen)
{
-
}
-/* client libraries expect an encoding */
-static XF86VideoEncodingRec DummyEncoding[1] =
+
+static XF86VideoAdaptorPtr
+TDFXAllocAdaptor(ScrnInfoPtr pScrn, int numberPorts)
{
- { /* blit limit */
- 0,
- "XV_IMAGE",
- 1024, 0, /* Height is a limitation of pixmap space, and filled in later. */
- {1, 1}
- }
-};
+ XF86VideoAdaptorPtr adapt;
+ TDFXPtr pTDFX = TDFXPTR(pScrn);
+ TDFXPortPrivPtr pPriv;
+ int i;
-#define NUM_FORMATS_OVERLAY 3
+ if(!(adapt = xf86XVAllocateVideoAdaptorRec(pScrn)))
+ return NULL;
-static XF86VideoFormatRec Formats[NUM_FORMATS_OVERLAY] =
-{
- {15, TrueColor}, {16, TrueColor}, {24, TrueColor},
-};
+ if(!(pPriv = xcalloc(1, sizeof(TDFXPortPrivRec) + numberPorts * sizeof(DevUnion))))
+ {
+ xfree(adapt);
+ return NULL;
+ }
-/* #define NUM_IMAGES 4*/
-#define NUM_IMAGES 2
+ adapt->pPortPrivates = (DevUnion*)(&pPriv[1]);
+ for(i = 0; i < numberPorts; i++)
+ adapt->pPortPrivates[i].val = i;
-static XF86ImageRec Images[NUM_IMAGES] =
-{
- XVIMAGE_YV12, /* YVU planar */
- XVIMAGE_I420 /* YUV planar */
-#if 0
- /* These could be supported (without a temp bufer) using the
- * host-to-screen-stretch */
- XVIMAGE_YUY2, /* YUYV packed */
- XVIMAGE_UYVY /* UYVY packed */
-#endif
-};
+ xvColorKey = MAKE_ATOM("XV_COLORKEY"); /* FIXME: twice, leak */
+ xvFilterQuality = MAKE_ATOM("XV_FILTER_QUALITY"); /* FIXME: twice, leak */
+
+ pPriv->colorKey = pTDFX->videoKey;
+ pPriv->videoStatus = 0;
+ pPriv->filterQuality = 1;
+
+ return adapt;
+}
static XF86VideoAdaptorPtr
-TDFXAllocAdaptor(ScrnInfoPtr pScrn)
+TDFXSetupImageVideoOverlay(ScreenPtr pScreen)
{
- DevUnion *devUnions;
- int i;
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ TDFXPtr pTDFX = TDFXPTR(pScrn);
+ TDFXPortPrivPtr pPriv;
XF86VideoAdaptorPtr adapt;
- if(!(adapt = xf86XVAllocateVideoAdaptorRec(pScrn)))
- return NULL;
- /* Allocate a TDFX private structure */
- /* There is no need for a TDFX private structure at this time. But a
- * DevUnion has to be provided to the core Xv code. */
- if (!(devUnions = xcalloc (1, sizeof (DevUnion) * TDFX_MAX_PORTS)))
- {
- xfree (adapt);
- return NULL;
- }
- adapt->pPortPrivates = &devUnions[0];
-
- /* Fill in some of the DevUnion */
- for (i = 0; i < TDFX_MAX_PORTS; i++)
- {
- adapt->pPortPrivates[i].val = i;
- adapt->pPortPrivates[i].ptr = NULL; /* No private data */
- }
-
- return adapt;
-}
+ if (!pTDFX->OverlayXvideo)
+ return NULL;
+ if(!(adapt = TDFXAllocAdaptor(pScrn, TDFX_MAX_OVERLAY_PORTS)))
+ return NULL;
+ adapt->type = XvWindowMask | XvInputMask | XvImageMask;
+ adapt->flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT;
+ adapt->name = "3dfx Video Overlay";
+ adapt->nPorts = TDFX_MAX_OVERLAY_PORTS;
+ adapt->nEncodings = sizeof(OverlayEncoding) / sizeof(XF86VideoEncodingRec);
+ adapt->pEncodings = OverlayEncoding;
+ adapt->nFormats = sizeof(OverlayFormats) / sizeof(XF86VideoFormatRec);
+ adapt->pFormats = OverlayFormats;
+ adapt->nAttributes = sizeof(OverlayAttributes) / sizeof(XF86AttributeRec);
+ adapt->pAttributes = OverlayAttributes;
+ adapt->nImages = sizeof(OverlayImages) / sizeof(XF86ImageRec);
+ adapt->pImages = OverlayImages;
+ adapt->PutVideo = NULL;
+ adapt->PutStill = NULL;
+ adapt->GetVideo = NULL;
+ adapt->GetStill = NULL;
+ adapt->StopVideo = TDFXStopVideoOverlay;
+ adapt->SetPortAttribute = TDFXSetPortAttributeOverlay;
+ adapt->GetPortAttribute = TDFXGetPortAttributeOverlay;
+ adapt->QueryBestSize = TDFXQueryBestSize;
+ adapt->PutImage = TDFXPutImageOverlay;
+ adapt->QueryImageAttributes = TDFXQueryImageAttributes;
-static XF86VideoAdaptorPtr
-TDFXSetupImageVideo(ScreenPtr pScreen)
+ pPriv = (TDFXPortPrivPtr)(adapt->pPortPrivates[0].ptr);
+ REGION_INIT(pScreen, &(pPriv->clip), NullBox, 0);
+
+ pTDFX->overlayAdaptor = adapt;
+
+ TDFXResetVideoOverlay(pScrn);
+
+ return adapt;
+}
+
+static XF86VideoAdaptorPtr
+TDFXSetupImageVideoTexture(ScreenPtr pScreen)
{
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- XF86VideoAdaptorPtr adapt;
TDFXPtr pTDFX = TDFXPTR(pScrn);
+ XF86VideoAdaptorPtr adapt;
- DummyEncoding[0].height = pTDFX->pixmapCacheLines;
+ if (!pTDFX->TextureXvideo)
+ return NULL;
- adapt = TDFXAllocAdaptor(pScrn);
+ if(!(adapt = TDFXAllocAdaptor(pScrn, TDFX_MAX_TEXTURE_PORTS)))
+ return NULL;
adapt->type = XvWindowMask | XvInputMask | XvImageMask;
- /* Add VIDEO_OVERLAID_IMAGES if using the overlay */
adapt->flags = 0;
- adapt->name = "3dfx Accelerated Video Engine";
- adapt->nEncodings = 1;
- adapt->pEncodings = &DummyEncoding[0];
- adapt->nFormats = NUM_FORMATS_OVERLAY;
- adapt->pFormats = Formats;
- adapt->nPorts = TDFX_MAX_PORTS;
- adapt->nAttributes = 0;
- adapt->pAttributes = NULL;
- adapt->nImages = NUM_IMAGES;
- adapt->pImages = Images;
-
- /* XXX For now all I'm implementing is PutImage so that programs like OMS
- * will work. More will follow as I have time and need. */
+ adapt->name = "3dfx Video Texture";
+ adapt->nPorts = TDFX_MAX_TEXTURE_PORTS;
+ adapt->nEncodings = sizeof(TextureEncoding) / sizeof(XF86VideoEncodingRec);
+ adapt->pEncodings = TextureEncoding;
+ adapt->nFormats = sizeof(TextureFormats) / sizeof(XF86VideoFormatRec);
+ adapt->pFormats = TextureFormats;
+ adapt->nAttributes = sizeof(TextureAttributes) / sizeof(XF86AttributeRec);
+ adapt->pAttributes = TextureAttributes;
+ adapt->nImages = sizeof(TextureImages) / sizeof(XF86ImageRec);
+ adapt->pImages = TextureImages;
adapt->PutVideo = NULL;
adapt->PutStill = NULL;
adapt->GetVideo = NULL;
adapt->GetStill = NULL;
- adapt->StopVideo = TDFXStopVideo;
- adapt->SetPortAttribute = TDFXSetPortAttribute;
- adapt->GetPortAttribute = TDFXGetPortAttribute;
+ adapt->StopVideo = TDFXStopVideoTexture;
+ adapt->SetPortAttribute = TDFXSetPortAttributeTexture;
+ adapt->GetPortAttribute = TDFXGetPortAttributeTexture;
adapt->QueryBestSize = TDFXQueryBestSize;
- adapt->PutImage = TDFXPutImage;
- /*adapt->PutImage = TDFXPutImageOverlay; */
+ adapt->PutImage = TDFXPutImageTexture;
adapt->QueryImageAttributes = TDFXQueryImageAttributes;
+ pTDFX->textureAdaptor = adapt;
+
return adapt;
}
-static void
-TDFXStopVideo(ScrnInfoPtr pScrn, pointer data, Bool cleanup)
-{
- if (cleanup)
- {
- /* Deallocate the offscreen temporary buffer. */
- TDFXDeallocateOffscreenBuffer (pScrn, 0);
- }
+/*
+ * MISCELLANEOUS ROUTINES
+ */
+
+
+static int
+TDFXQueryImageAttributes(
+ ScrnInfoPtr pScrn,
+ int id,
+ unsigned short *w, unsigned short *h,
+ int *pitches, int *offsets
+){
+ int size, tmp;
+
+ if(*w > 1024) *w = 1024;
+ if(*h > 1024) *h = 1024;
+
+ *w = (*w + 1) & ~1;
+ if(offsets) offsets[0] = 0;
+
+ switch(id) {
+ case FOURCC_YV12:
+ case FOURCC_I420:
+ *h = (*h + 1) & ~1;
+ size = (*w + 3) & ~3;
+ if(pitches) pitches[0] = size;
+ size *= *h;
+ if(offsets) offsets[1] = size;
+ tmp = ((*w >> 1) + 3) & ~3;
+ if(pitches) pitches[1] = pitches[2] = tmp;
+ tmp *= (*h >> 1);
+ size += tmp;
+ if(offsets) offsets[2] = size;
+ size += tmp;
+ break;
+ case FOURCC_UYVY:
+ case FOURCC_YUY2:
+ default:
+ size = *w << 1;
+ if(pitches) pitches[0] = size;
+ size *= *h;
+ break;
+ }
+
+ return size;
}
-static int
-TDFXSetPortAttribute (ScrnInfoPtr pScrn,
- Atom attribute,
- INT32 value,
- pointer data)
-{
- return BadMatch;
+static int
+TDFXSetPortAttributeOverlay(
+ ScrnInfoPtr pScrn,
+ Atom attribute,
+ INT32 value,
+ pointer data
+){
+
+ TDFXPortPrivPtr pPriv = (TDFXPortPrivPtr)data;
+ TDFXPtr pTDFX = TDFXPTR(pScrn);
+
+ if(attribute == xvColorKey) {
+ pPriv->colorKey = value;
+ pTDFX->writeLong(pTDFX, VIDCHROMAMIN, pPriv->colorKey);
+ pTDFX->writeLong(pTDFX, VIDCHROMAMAX, pPriv->colorKey);
+ REGION_EMPTY(pScrn->pScreen, &pPriv->clip);
+ } else if(attribute == xvFilterQuality) {
+ if((value < 0) || (value > 1))
+ return BadValue;
+ pPriv->filterQuality = value;
+ } else return BadMatch;
+
+ return Success;
+}
+
+static int
+TDFXGetPortAttributeOverlay(
+ ScrnInfoPtr pScrn,
+ Atom attribute,
+ INT32 *value,
+ pointer data
+){
+ TDFXPortPrivPtr pPriv = (TDFXPortPrivPtr)data;
+
+ if(attribute == xvColorKey) {
+ *value = pPriv->colorKey;
+ } else if(attribute == xvFilterQuality) {
+ *value = pPriv->filterQuality;
+ } else return BadMatch;
+
+ return Success;
}
static int
-TDFXGetPortAttribute(ScrnInfoPtr pScrn,
- Atom attribute,
- INT32 *value,
- pointer data)
-{
- return BadMatch;
+TDFXSetPortAttributeTexture(
+ ScrnInfoPtr pScrn,
+ Atom attribute,
+ INT32 value,
+ pointer data
+) {
+ return Success;
}
+static int
+TDFXGetPortAttributeTexture(
+ ScrnInfoPtr pScrn,
+ Atom attribute,
+ INT32 *value,
+ pointer data
+){
+ return Success;
+}
-static void
-TDFXQueryBestSize(ScrnInfoPtr pScrn,
- Bool motion,
- short vid_w, short vid_h,
- short drw_w, short drw_h,
- unsigned int *p_w, unsigned int *p_h,
- pointer data)
-{
- /* No alignment restrictions */
+
+static void
+TDFXQueryBestSize(
+ ScrnInfoPtr pScrn,
+ Bool motion,
+ short vid_w, short vid_h,
+ short drw_w, short drw_h,
+ unsigned int *p_w, unsigned int *p_h,
+ pointer data
+){
+ if(vid_w > drw_w) drw_w = vid_w;
+ if(vid_h > drw_h) drw_h = vid_h;
+
*p_w = drw_w;
- *p_h = drw_h;
+ *p_h = drw_h;
}
-
-/* This performs a screen to screen stretch blit. All coordinates are
- * in screen memory. This function assumes that the src and dst format
- * registers have been setup already. This function does not save
- * the registers it trashes. */
static void
-TDFXScreenToScreenYUVStretchBlit (ScrnInfoPtr pScrn,
- short src_x1, short src_y1,
- short src_x2, short src_y2,
- short dst_x1, short dst_y1,
- short dst_x2, short dst_y2)
-{
- TDFXPtr pTDFX = TDFXPTR(pScrn);
+TDFXCopyData(
+ unsigned char *src,
+ unsigned char *dst,
+ int srcPitch,
+ int dstPitch,
+ int h,
+ int w
+){
+ while(h--) {
+ memcpy(dst, src, w);
+ src += srcPitch;
+ dst += dstPitch;
+ }
+}
- /* reformulate the paramaters the way the hardware wants them */
- INT32
- src_x = src_x1 & 0x1FFF,
- src_y = src_y1 & 0x1FFF,
- dst_x = dst_x1 & 0x1FFF,
- dst_y = dst_y1 & 0x1FFF,
- src_w = (src_x2 - src_x) & 0x1FFF,
- src_h = (src_y2 - src_y) & 0x1FFF,
- dst_w = (dst_x2 - dst_x) & 0x1FFF,
- dst_h = (dst_y2 - dst_y) & 0x1FFF;
-
- /* Setup for blit src and dest */
- TDFXMakeRoom(pTDFX, 5);
- DECLARE(SSTCP_DSTSIZE|SSTCP_SRCSIZE|SSTCP_DSTXY|
- SSTCP_COMMAND|SSTCP_COMMANDEXTRA);
- /* We want the blit to wait for vsync. */
- TDFXWriteLong(pTDFX, SST_2D_COMMANDEXTRA, 4);
- TDFXWriteLong(pTDFX, SST_2D_SRCSIZE, src_w | (src_h<<16));
- TDFXWriteLong(pTDFX, SST_2D_DSTSIZE, dst_w | (dst_h<<16));
- TDFXWriteLong(pTDFX, SST_2D_DSTXY, dst_x | (dst_y<<16));
- /* XXX find the ROP table and figure out why CC is the right choice. */
- TDFXWriteLong(pTDFX, SST_2D_COMMAND,
- (0xCC<<24)|SST_2D_SCRNTOSCRNSTRETCH);
- /* Write to the launch area to start the blit */
- TDFXMakeRoom(pTDFX, 1);
- DECLARE_LAUNCH (1, 0);
- TDFXWriteLong(pTDFX, SST_2D_LAUNCH, src_x | (src_y<<16));
+static void
+TDFXCopyMungedData(
+ unsigned char *src1,
+ unsigned char *src2,
+ unsigned char *src3,
+ unsigned char *dst1,
+ int srcPitch,
+ int srcPitch2,
+ int dstPitch,
+ int h,
+ int w
+){
+ CARD32 *dst;
+ CARD8 *s1, *s2, *s3;
+ int i, j;
+
+ w >>= 1;
+
+ for(j = 0; j < h; j++) {
+ dst = (CARD32*)dst1;
+ s1 = src1; s2 = src2; s3 = src3;
+ i = w;
+ while(i > 4) {
+ dst[0] = s1[0] | (s1[1] << 16) | (s3[0] << 8) | (s2[0] << 24);
+ dst[1] = s1[2] | (s1[3] << 16) | (s3[1] << 8) | (s2[1] << 24);
+ dst[2] = s1[4] | (s1[5] << 16) | (s3[2] << 8) | (s2[2] << 24);
+ dst[3] = s1[6] | (s1[7] << 16) | (s3[3] << 8) | (s2[3] << 24);
+ dst += 4; s2 += 4; s3 += 4; s1 += 8;
+ i -= 4;
+ }
+ while(i--) {
+ dst[0] = s1[0] | (s1[1] << 16) | (s3[0] << 8) | (s2[0] << 24);
+ dst++; s2++; s3++;
+ s1 += 2;
+ }
+
+ dst1 += dstPitch;
+ src1 += srcPitch;
+ if(j & 1) {
+ src2 += srcPitch2;
+ src3 += srcPitch2;
+ }
+ }
}
+
+/*
+ * TEXTURE DRAWING FUNCTIONS
+ */
+
+
static void
-YUVPlanarToPacked (ScrnInfoPtr pScrn,
- short src_x, short src_y,
- short src_h, short src_w,
- int id, char *buf,
- short width, short height,
- FBAreaPtr fbarea)
+TDFXStopVideoTexture(ScrnInfoPtr pScrn, pointer data, Bool cleanup)
{
TDFXPtr pTDFX = TDFXPTR(pScrn);
+ TDFXPortPrivPtr pPriv = (TDFXPortPrivPtr)data;
- INT32 y;
- void *dst;
- char *psrc = buf,
- *pdst = 0;
- int count = 0;
-
- /* Register saves */
- INT32
- yuvBaseAddr,
- yuvStride;
-
- /* Save these registers so I can restore them when we are done. */
- yuvBaseAddr = TDFXReadLongMMIO(pTDFX, YUVBASEADDR);
- yuvStride = TDFXReadLongMMIO(pTDFX, YUVSTRIDE);
-
-
- dst = 0;
-
- /* Set yuvBaseAddress register to point to the buffer. */
- TDFXWriteLongMMIO (pTDFX, YUVBASEADDR, pTDFX->fbOffset +
- pTDFX->stride * (fbarea->box.y1 + pScrn->virtualY)
- + fbarea->box.x1);
- /* Set yuvStride register to reflect stride of U and V planes */
- /* There is a subtle issue involved with copying the Y plane. Y is
- * sampled at twice the rate of the U and V data, in both
- * directions. But when packing their needs to be two Y values for
- * each U,V pair. So if src_x is odd we will end up missing on
- * of the Y values. To correct for this we will always adjust the src
- * x value. This adjust is done both in computing the address of the
- * pixels to copy and when determining the amount of pixels to copy.
- * Note that care needs to be taken to insure that the offscreen
- * temporary buffer is allocated with enough space to hold the possible
- * extra column of data.
- */
- TDFXWriteLongMMIO (pTDFX, YUVSTRIDE, pTDFX->stride);
- psrc = (char*)buf;
-
- /* psrc points to the base of the Y plane, move out to src_x, src_y */
- psrc += (src_x & ~0x1) + src_y * width;
- pdst = (char *)pTDFX->MMIOBase[0] + YUV_Y_BASE;
- for (y = 0; y < src_h; y++)
- {
- memcpy (pdst, psrc, src_w + (src_x & 0x1));
- psrc += width;
- /* YUV planar region is always 1024 bytes wide */
- pdst += 1024;
- }
+ REGION_EMPTY(pScrn->pScreen, &pPriv->clip);
- /* The difference between FOURCC_YV12 and FOURCC_I420 is the order
- * that the U and V planes appear in the buffer. But at this point
- * I just send the second buffer as V and the third buffer as U.
- * Depending on the format, the packing will be different and we
- * handle it in the the way we pick the source format for the blit
- * later on. */
-
- pdst = (char *)pTDFX->MMIOBase[0] + YUV_V_BASE;
- psrc = (char*)buf + width * height;
- /* psrc now points to the base of the V plane, move out to src_x/2,
- * src_y/2 */
- psrc += (src_x >> 1) + (src_y >> 1) * (width >> 1);
- for (y = 0; y < src_h >> 1; y++)
- {
- /* YUV planar region is always 1024 bytes wide */
- memcpy (pdst, psrc, src_w >> 1);
- psrc += width >> 1;
- pdst += 1024;
- }
- pdst = (char *)pTDFX->MMIOBase[0] + YUV_U_BASE;
- psrc = (char*)buf + width * height + (width >> 1) * (height >> 1);
- /* psrc now points to the base of the U plane, move out to src_x/2,
- * src_y/2 */
- psrc += (src_x >> 1) + (src_y >> 1) * (width >> 1);
- for (y = 0; y < src_h >> 1; y++)
- {
- /* YUV planar region is always 1024 bytes wide */
- memcpy (pdst, psrc, src_w >> 1);
- psrc += width >> 1;
- pdst += 1024;
+ if (cleanup) {
+ if(pTDFX->textureBuffer) {
+ xf86FreeOffscreenArea(pTDFX->textureBuffer);
+ pTDFX->textureBuffer = NULL;
+ }
}
+}
- /* Before restoring trashed registers we have to wait for the conversion
- * to finish. We aren't using the FIFO for this but the hardware can
- * take a little extra time even after we finish all the writes. If we
- * restore the registers before it finishes it can store some of the YUV
- * data to the wrong place. One particular wrong place is often on top
- * of the hardware cursor data. So we wait for the status register
- * to go idle. */
- /* XXX Right now wait for the whole chip to go idle. This is more than
- * is required. Find out which subsystem is handles the YUV packing and
- * wait only on that status bit. */
- count = 0;
- do
- {
- count++;
- } while ((TDFXReadLongMMIO(pTDFX, 0) & SST_BUSY) && count < 1000);
-
- /* Restore trashed registers */
- TDFXWriteLongMMIO(pTDFX, YUVBASEADDR, yuvBaseAddr);
- TDFXWriteLongMMIO(pTDFX, YUVSTRIDE, yuvStride);
+
+static void
+TDFXScreenToScreenYUVStretchBlit (ScrnInfoPtr pScrn,
+ short src_x1, short src_y1,
+ short src_x2, short src_y2,
+ short dst_x1, short dst_y1,
+ short dst_x2, short dst_y2)
+{
+ TDFXPtr pTDFX = TDFXPTR(pScrn);
+ /* reformulate the paramaters the way the hardware wants them */
+ INT32 src_x = src_x1 & 0x1FFF;
+ INT32 src_y = src_y1 & 0x1FFF;
+ INT32 dst_x = dst_x1 & 0x1FFF;
+ INT32 dst_y = dst_y1 & 0x1FFF;
+ INT32 src_w = (src_x2 - src_x1) & 0x1FFF;
+ INT32 src_h = (src_y2 - src_y1) & 0x1FFF;
+ INT32 dst_w = (dst_x2 - dst_x1) & 0x1FFF;
+ INT32 dst_h = (dst_y2 - dst_y1) & 0x1FFF;
+ /* Setup for blit src and dest */
+ TDFXMakeRoom(pTDFX, 4);
+ DECLARE(SSTCP_DSTSIZE|SSTCP_SRCSIZE|SSTCP_DSTXY|SSTCP_COMMAND/*|SSTCP_COMMANDEXTRA*/);
+ /* TDFXWriteLong(pTDFX, SST_2D_COMMANDEXTRA, SST_COMMANDEXTRA_VSYNC);*/
+ TDFXWriteLong(pTDFX, SST_2D_SRCSIZE, src_w | (src_h<<16));
+ TDFXWriteLong(pTDFX, SST_2D_DSTSIZE, dst_w | (dst_h<<16));
+ TDFXWriteLong(pTDFX, SST_2D_DSTXY, dst_x | (dst_y<<16));
+ TDFXWriteLong(pTDFX, SST_2D_COMMAND, SST_2D_SCRNTOSCRNSTRETCH | 0xCC000000);
+ /* Write to the launch area to start the blit */
+ TDFXMakeRoom(pTDFX, 1);
+ DECLARE_LAUNCH(1, 0);
+ TDFXWriteLong(pTDFX, SST_2D_LAUNCH, (src_x<<1) | (src_y<<16));
+ /* Wait for it to happen */
+ TDFXSendNOPFifo2D(pScrn);
}
-static int
-TDFXPutImage(
- 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
- )
+
+static void
+YUVPlanarToPacked (ScrnInfoPtr pScrn,
+ short src_x, short src_y,
+ short src_h, short src_w,
+ int id, char *buf,
+ short width, short height,
+ FBAreaPtr fbarea)
{
TDFXPtr pTDFX = TDFXPTR(pScrn);
+ char *psrc, *pdst;
+ int count;
+ int baseaddr;
+ INT32 yuvBaseAddr, yuvStride;
+
+ /* Save these registers so I can restore them when we are done. */
+ yuvBaseAddr = TDFXReadLongMMIO(pTDFX, YUVBASEADDR);
+ yuvStride = TDFXReadLongMMIO(pTDFX, YUVSTRIDE);
+
+ /* Set yuvBaseAddress and yuvStride. */
+ baseaddr = pTDFX->fbOffset + pTDFX->cpp * fbarea->box.x1 + pTDFX->stride * fbarea->box.y1;
+ TDFXWriteLongMMIO(pTDFX, YUVSTRIDE, pTDFX->stride);
+ TDFXWriteLongMMIO(pTDFX, YUVBASEADDR, baseaddr);
+
+ /* Copy Y plane (twice as much Y as U or V) */
+ psrc = (char *)buf;
+ psrc += (src_x & ~0x1) + src_y * width;
+ pdst = (char *)pTDFX->MMIOBase[0] + YUV_Y_BASE;
+ TDFXCopyData(psrc, pdst, width, 1024, src_h, src_w + (src_x & 0x1));
+
+ /* Copy V plane */
+ psrc = (char*)buf + width * height;
+ psrc += (src_x >> 1) + (src_y >> 1) * (width >> 1);
+ pdst = (char *)pTDFX->MMIOBase[0] + YUV_V_BASE;
+ TDFXCopyData(psrc, pdst, width >> 1, 1024, src_h >> 1, src_w >> 1);
+
+ /* Copy U plane */
+ psrc = (char*)buf + width * height + (width >> 1) * (height >> 1);
+ psrc += (src_x >> 1) + (src_y >> 1) * (width >> 1);
+ pdst = (char *)pTDFX->MMIOBase[0] + YUV_U_BASE;
+ TDFXCopyData(psrc, pdst, width >> 1, 1024, src_h >> 1, src_w >> 1);
+
+ /* IDLE until the copy finished, timeout for safety */
+ for (count = 0; count < 1000; count++)
+ if (!((TDFXReadLongMMIO(pTDFX, STATUS) & SST_BUSY)))
+ break;
+
+ /* Restore trashed registers */
+ TDFXWriteLongMMIO(pTDFX, YUVBASEADDR, yuvBaseAddr);
+ TDFXWriteLongMMIO(pTDFX, YUVSTRIDE, yuvStride);
+
+ /* Wait for it to happen */
+ TDFXSendNOPFifo2D(pScrn);
+}
+
+static int
+TDFXPutImageTexture(
+ 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
+ )
+{
+ TDFXPtr pTDFX = TDFXPTR(pScrn);
BoxPtr pbox;
int nbox;
+ int format;
+
+ /* Check the source format */
+ if (id == FOURCC_YV12) format = SST_2D_FORMAT_YUYV;
+ else if (id == FOURCC_UYVY) format = SST_2D_FORMAT_UYVY;
+ else return BadAlloc;
+
+ /* Get a buffer to store the packed YUV data */
+ if (!(pTDFX->textureBuffer = TDFXAllocateMemoryArea(pScrn, pTDFX->textureBuffer, src_w, src_h)))
+ return BadAlloc;
+
+ /* Pack the YUV data in offscreen memory using YUV framebuffer (0x[CDE]0000) */
+ YUVPlanarToPacked (pScrn, src_x, src_y, src_h, src_w,
+ id, (char *)buf, width, height,
+ pTDFX->textureBuffer);
+
+ /* Setup source and destination pixel formats (yuv -> rgb) */
+ TDFXMakeRoom(pTDFX, 2);
+ DECLARE(SSTCP_SRCFORMAT|SSTCP_DSTFORMAT);
+ TDFXWriteLong(pTDFX, SST_2D_DSTFORMAT, pTDFX->stride|((pTDFX->cpp+1)<<16));
+ TDFXWriteLong(pTDFX, SST_2D_SRCFORMAT, pTDFX->stride|((format)<<16));
+
+ /* Blit packed YUV data from offscreen memory, respecting clips */
+#define SRC_X1 (pTDFX->textureBuffer->box.x1)
+#define SRC_Y1 (pTDFX->textureBuffer->box.y1)
+#define SCALEX(dx) ((int)(((dx) * src_w) / drw_w))
+#define SCALEY(dy) ((int)(((dy) * src_h) / drw_h))
+ for (nbox = REGION_NUM_RECTS(clipBoxes),
+ pbox = REGION_RECTS(clipBoxes); nbox > 0; nbox--, pbox++)
+ {
+ TDFXScreenToScreenYUVStretchBlit (pScrn,
+ SRC_X1 + SCALEX(pbox->x1 - drw_x),
+ SRC_Y1 + SCALEY(pbox->y1 - drw_y),
+ SRC_X1 + SCALEX(pbox->x2 - drw_x),
+ SRC_Y1 + SCALEY(pbox->y2 - drw_y),
+ pbox->x1, pbox->y1,
+ pbox->x2, pbox->y2);
+ }
- FBAreaPtr fbarea;
+ /* Restore the WAX registers we trashed */
+ TDFXMakeRoom(pTDFX, 2);
+ DECLARE(SSTCP_SRCFORMAT|SSTCP_DSTFORMAT);
+ TDFXWriteLong(pTDFX, SST_2D_DSTFORMAT, pTDFX->sst2DDstFmtShadow);
+ TDFXWriteLong(pTDFX, SST_2D_SRCFORMAT, pTDFX->sst2DSrcFmtShadow);
- /* Make sure we are synced up (this really means, lock and find the
- * fifo pointer. */
- TDFXFirstSync (pScrn);
+ /* Wait for it to happen */
+ TDFXSendNOPFifo2D(pScrn);
- /* Do the right thing for the given format */
- switch (id)
- {
- case FOURCC_YV12:
- case FOURCC_I420:
- /* Get a buffer to use to store the packed YUV data */
- fbarea = TDFXAllocateOffscreenBuffer (pScrn, id, src_w, src_h);
-
- if (!fbarea)
- {
- return Success;
- }
+ return Success;
+}
- YUVPlanarToPacked (pScrn, src_x, src_y, src_h, src_w,
- id, (char *)buf, width, height,
- fbarea);
- /* Don't know what executed last so we need to send a NOP */
- TDFXSendNOP(pScrn);
-
- /* Setup the dst and src format once, they don't change for all the
- * blits. */
- TDFXMakeRoom(pTDFX, 2);
- DECLARE(SSTCP_SRCFORMAT|SSTCP_DSTFORMAT);
- TDFXWriteLong(pTDFX, SST_2D_DSTFORMAT,
- pTDFX->stride|((pTDFX->cpp+1)<<16));
- if (id == FOURCC_YV12)
- {
- /* Packed format is YUYV */
- TDFXWriteLong(pTDFX, SST_2D_SRCFORMAT,
- pTDFX->stride|((SST_2D_FORMAT_YUYV)<<16));
- }
- else
- {
- /* Packed format is UYVY */
- TDFXWriteLong(pTDFX, SST_2D_SRCFORMAT,
- pTDFX->stride|((SST_2D_FORMAT_UYVY)<<16));
- }
- /* Traverse the clip boxes */
- nbox = REGION_NUM_RECTS(clipBoxes);
- pbox = REGION_RECTS(clipBoxes);
-
- while (nbox--)
- {
- /* The destination clip regions come with the clip boxes, but
- * the src coordinates have to be computed because we are doing
- * a stretch blit. These macros perform that compuation, but
- * they could use some work. When testing with still images these
- * computations caused some jitter in the resulting output, but
- * with actual video playback I haven't noticed any problems. */
-#define SRC_X1 (fbarea->box.x1)
-#define SRC_Y1 (fbarea->box.y1 + pScrn->virtualY)
-#define SCALEX(dx) ((int)(((dx) * src_w + (drw_w>>1)) / drw_w))
-#define SCALEY(dy) ((int)(((dy) * src_h + (drw_h>>1)) / drw_h))
-
- /* Do the screen-to-screen blit clipped to the clip boxes. */
- TDFXScreenToScreenYUVStretchBlit
- (pScrn,
- SRC_X1 + SCALEX(pbox->x1 - drw_x),
- SRC_Y1 + SCALEY(pbox->y1 - drw_y),
- SRC_X1 + SCALEX(pbox->x2 - drw_x),
- SRC_Y1 + SCALEY(pbox->y2 - drw_y),
- /* these destination coordinates come
- * right from the clip box. */
- pbox->x1, pbox->y1,
- pbox->x2, pbox->y2);
- pbox++;
- }
+/*
+ * COMMON DRAWING FUNCTIONS
+ */
- /* Restore the WAX registers we trashed */
- TDFXMakeRoom(pTDFX, 2);
- DECLARE(SSTCP_SRCFORMAT|SSTCP_DSTFORMAT);
- TDFXWriteLong(pTDFX, SST_2D_DSTFORMAT, pTDFX->sst2DDstFmtShadow);
- TDFXWriteLong(pTDFX, SST_2D_SRCFORMAT, pTDFX->sst2DSrcFmtShadow);
+static Bool
+RegionsEqual(RegionPtr A, RegionPtr B)
+{
+ int *dataA, *dataB;
+ int num;
+
+ num = REGION_NUM_RECTS(A);
+ if(num != REGION_NUM_RECTS(B))
+ return FALSE;
+
+ if((A->extents.x1 != B->extents.x1) ||
+ (A->extents.x2 != B->extents.x2) ||
+ (A->extents.y1 != B->extents.y1) ||
+ (A->extents.y2 != B->extents.y2))
+ return FALSE;
+
+ dataA = (int*)REGION_RECTS(A);
+ dataB = (int*)REGION_RECTS(B);
+
+ while(num--) {
+ if((dataA[0] != dataB[0]) || (dataA[1] != dataB[1]))
+ return FALSE;
+ dataA += 2;
+ dataB += 2;
+ }
- /* The rest of the driver won't know what I have done so I do a stall to
- * make sure the next command sent will work. */
- TDFXSendNOP(pScrn);
- break;
- /* XXX What am I supposed to do about the sync flag? */
+ return TRUE;
+}
- }
- return Success;
+static Bool
+TDFXClipVideo(
+ BoxPtr dst,
+ INT32 *xa,
+ INT32 *xb,
+ INT32 *ya,
+ INT32 *yb,
+ RegionPtr reg,
+ INT32 width,
+ INT32 height
+){
+ INT32 vscale, hscale, delta;
+ BoxPtr extents = REGION_EXTENTS(DummyScreen, reg);
+ int diff;
+
+ hscale = ((*xb - *xa) << 16) / (dst->x2 - dst->x1);
+ vscale = ((*yb - *ya) << 16) / (dst->y2 - dst->y1);
+
+ *xa <<= 16; *xb <<= 16;
+ *ya <<= 16; *yb <<= 16;
+
+ diff = extents->x1 - dst->x1;
+ if(diff > 0) {
+ dst->x1 = extents->x1;
+ *xa += diff * hscale;
+ }
+ diff = dst->x2 - extents->x2;
+ if(diff > 0) {
+ dst->x2 = extents->x2;
+ *xb -= diff * hscale;
+ }
+ diff = extents->y1 - dst->y1;
+ if(diff > 0) {
+ dst->y1 = extents->y1;
+ *ya += diff * vscale;
+ }
+ diff = dst->y2 - extents->y2;
+ if(diff > 0) {
+ dst->y2 = extents->y2;
+ *yb -= diff * vscale;
+ }
+
+ if(*xa < 0) {
+ diff = (- *xa + hscale - 1)/ hscale;
+ dst->x1 += diff;
+ *xa += diff * hscale;
+ }
+ delta = *xb - (width << 16);
+ if(delta > 0) {
+ diff = (delta + hscale - 1)/ hscale;
+ dst->x2 -= diff;
+ *xb -= diff * hscale;
+ }
+ if(*xa >= *xb) return FALSE;
+
+ if(*ya < 0) {
+ diff = (- *ya + vscale - 1)/ vscale;
+ dst->y1 += diff;
+ *ya += diff * vscale;
+ }
+ delta = *yb - (height << 16);
+ if(delta > 0) {
+ diff = (delta + vscale - 1)/ vscale;
+ dst->y2 -= diff;
+ *yb -= diff * vscale;
+ }
+ if(*ya >= *yb) return FALSE;
+
+ if((dst->x1 != extents->x1) || (dst->x2 != extents->x2) ||
+ (dst->y1 != extents->y1) || (dst->y2 != extents->y2))
+ {
+ RegionRec clipReg;
+ REGION_INIT(DummyScreen, &clipReg, dst, 1);
+ REGION_INTERSECT(DummyScreen, reg, reg, &clipReg);
+ REGION_UNINIT(DummyScreen, &clipReg);
+ }
+ return TRUE;
}
-/* This code doesn't work yet. Eventually this should use the video overlay
- * instead of the YUV-stretch-blit. The overlay is better because it uses
- * bilinear filtering when scaling. */
-#if 0
-static int
-TDFXPutImageOverlay(
- 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
- )
-{
- TDFXPtr pTDFX = TDFXPTR(pScrn);
- BoxPtr pbox;
- int nbox;
+/*
+ * OVERLAY DRAWING FUNCTIONS
+ */
- /* Computed Register values */
- INT32
- vidInFormat;
- static FBAreaPtr fbarea;
+static void
+TDFXResetVideoOverlay(ScrnInfoPtr pScrn)
+{
+ TDFXPtr pTDFX = TDFXPTR(pScrn);
+ TDFXPortPrivPtr pPriv = pTDFX->overlayAdaptor->pPortPrivates[0].ptr;
+
+ /* reset the video */
+ pTDFX->ModeReg.vidcfg &= ~VIDPROCCFGMASK;
+ pTDFX->writeLong(pTDFX, VIDPROCCFG, pTDFX->ModeReg.vidcfg);
+ pTDFX->writeLong(pTDFX, RGBMAXDELTA, 0x0080808);
+ pTDFX->writeLong(pTDFX, VIDCHROMAMIN, pPriv->colorKey);
+ pTDFX->writeLong(pTDFX, VIDCHROMAMAX, pPriv->colorKey);
+}
- /* Do the right thing for the given format */
- switch (id)
- {
- case FOURCC_YV12:
- case FOURCC_I420:
-
- /* Get a buffer to use to store the packed YUV data */
- fbarea = TDFXAllocateOffscreenBuffer (pScrn, id, src_w, src_h);
-
- if (!fbarea)
- return Success;
-
- YUVPlanarToPacked (pScrn,
- src_x, src_y, src_h, src_w,
- id, buf, width, height,
- fbarea);
-
- /* Setup the overlay */
- TDFXWriteLongMMIO(pTDFX, VIDOVERLAYSTARTCOORDS,
- (drw_x&0x7FF) | ((drw_y & 0x7FF) << 12)
- /* XXX Lower 2 bits of X and Y? */);
- TDFXWriteLongMMIO(pTDFX, VIDOVERLAYENDSCREENCOORDS,
- ((drw_x+drw_w)&0x7FF) | (((drw_y+drw_h)&0x7FF) << 12));
-
- /* Set the Video in format */
- vidInFormat = 0;
- /* These magic numbers come from the spec on page 151 */
- if (id == FOURCC_YV12)
- {
- /* Packed format is YUYV */
- vidInFormat = 0x9 << 1;
- }
- else
- {
- /* Packed format is UYVY */
- vidInFormat = 0xA << 1;
- }
+static void
+TDFXStopVideoOverlay(ScrnInfoPtr pScrn, pointer data, Bool cleanup)
+{
+ TDFXPtr pTDFX = TDFXPTR(pScrn);
+ TDFXPortPrivPtr pPriv = (TDFXPortPrivPtr)data;
- TDFXWriteLongMMIO (pTDFX, VIDINFORMAT, vidInFormat);
- TDFXWriteLongMMIO (pTDFX, VIDINSTRIDE, src_w);
+ REGION_EMPTY(pScrn->pScreen, &pPriv->clip);
- /* Use magenta as the chroma color */
- if (pTDFX->cpp == 2)
- {
- TDFXWriteLongMMIO(pTDFX, VIDCHROMAMIN,
- 0x0000F71F);
- TDFXWriteLongMMIO(pTDFX, VIDCHROMAMAX,
- 0x0000F71F);
+ if(cleanup) {
+ if(pPriv->videoStatus & CLIENT_VIDEO_ON) {
+ pTDFX->ModeReg.vidcfg &= ~VIDPROCCFGMASK;
+ pTDFX->writeLong(pTDFX, VIDPROCCFG, pTDFX->ModeReg.vidcfg);
}
- else /* (pTDFX->cpp == 3) */
- {
- TDFXWriteLongMMIO(pTDFX, VIDCHROMAMIN,
- 0x00FF00FF);
- TDFXWriteLongMMIO(pTDFX, VIDCHROMAMAX,
- 0x00FF00FF);
+ if(pTDFX->overlayBuffer) {
+ xf86FreeOffscreenLinear(pTDFX->overlayBuffer);
+ pTDFX->overlayBuffer = NULL;
}
-
- /* Set the src address */
- TDFXWriteLongMMIO (pTDFX, VIDINADDR0,
- pTDFX->fbOffset
- + pTDFX->stride * (fbarea->box.y1 + pScrn->virtualY)
- + fbarea->box.x1);
-
- /* Traverse the clip boxes */
- nbox = REGION_NUM_RECTS(clipBoxes);
- pbox = REGION_RECTS(clipBoxes);
-
- while (nbox--)
- {
- pbox++;
+ pPriv->videoStatus = 0;
+ } else {
+ if(pPriv->videoStatus & CLIENT_VIDEO_ON) {
+ pPriv->videoStatus |= OFF_TIMER;
+ pPriv->offTime = currentTime.milliseconds + OFF_DELAY;
}
- break;
+ }
+}
+
+
+static void
+TDFXDisplayVideoOverlay(
+ ScrnInfoPtr pScrn,
+ int id,
+ int offset,
+ short width, short height,
+ int pitch,
+ int left, int right, int top,
+ BoxPtr dstBox,
+ short src_w, short src_h,
+ short drw_w, short drw_h
+){
+ TDFXPtr pTDFX = TDFXPTR(pScrn);
+ TDFXPortPrivPtr pPriv = pTDFX->overlayAdaptor->pPortPrivates[0].ptr;
+ int dudx, dvdy;
+
+ dudx = (src_w << 20) / drw_w;
+ dvdy = (src_h << 20) / drw_h;
+
+ offset += ((left >> 16) & ~1) << 1;
+ left = (left & 0x0001ffff) << 3;
+
+ pTDFX->ModeReg.vidcfg &= ~VIDPROCCFGMASK;
+ pTDFX->ModeReg.vidcfg |= 0x00000320;
+
+ if(drw_w != src_w) pTDFX->ModeReg.vidcfg |= (1 << 14);
+ if(drw_h != src_h) pTDFX->ModeReg.vidcfg |= (1 << 15);
+ if(id == FOURCC_UYVY) pTDFX->ModeReg.vidcfg |= (6 << 21);
+ else pTDFX->ModeReg.vidcfg |= (5 << 21);
+ if(pScrn->depth == 8) pTDFX->ModeReg.vidcfg |= (1 << 11);
+ if(pPriv->filterQuality) pTDFX->ModeReg.vidcfg |= (3 << 16);
+ pTDFX->writeLong(pTDFX, VIDPROCCFG, pTDFX->ModeReg.vidcfg);
+
+ pTDFX->writeLong(pTDFX, VIDOVERLAYSTARTCOORDS, dstBox->x1 | (dstBox->y1 << 12));
+ pTDFX->writeLong(pTDFX, VIDOVERLAYENDSCREENCOORDS, (dstBox->x2 - 1) | ((dstBox->y2 - 1) << 12));
+ pTDFX->writeLong(pTDFX, VIDOVERLAYDUDX, dudx);
+ pTDFX->writeLong(pTDFX, VIDOVERLAYDUDXOFFSETSRCWIDTH, left | (src_w << 20));
+ pTDFX->writeLong(pTDFX, VIDOVERLAYDVDY, dvdy);
+ pTDFX->writeLong(pTDFX, VIDOVERLAYDVDYOFFSET, (top & 0x0000ffff) << 3);
+
+ pTDFX->ModeReg.stride &= 0x0000ffff;
+ pTDFX->ModeReg.stride |= pitch << 16;
+ pTDFX->writeLong(pTDFX, VIDDESKTOPOVERLAYSTRIDE, pTDFX->ModeReg.stride);
+ pTDFX->writeLong(pTDFX, SST_3D_LEFTOVERLAYBUF, offset & ~3);
+ pTDFX->writeLong(pTDFX, VIDINADDR0, offset & ~3);
+}
+
+
+static int
+TDFXPutImageOverlay(
+ 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
+){
+ TDFXPtr pTDFX = TDFXPTR(pScrn);
+ TDFXPortPrivPtr pPriv = (TDFXPortPrivPtr)data;
+ INT32 xa, xb, ya, yb;
+ unsigned char *dst_start;
+ int pitch, new_size, offset;
+ int s2offset = 0, s3offset = 0;
+ int srcPitch = 0, srcPitch2 = 0;
+ int dstPitch;
+ int top, left, npixels, nlines, bpp;
+ BoxRec dstBox;
+ CARD32 tmp;
+
+ /*
+ * s2offset, s3offset - byte offsets into U and V plane of the
+ * source where copying starts. Y plane is
+ * done by editing "buf".
+ *
+ * offset - byte offset to the first line of the destination.
+ *
+ * dst_start - byte address to the first displayed pel.
+ *
+ */
+
+ if(src_w > drw_w) drw_w = src_w;
+ if(src_h > drw_h) drw_h = src_h;
+
+ /* Clip */
+ xa = src_x;
+ xb = src_x + src_w;
+ ya = src_y;
+ yb = 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(!TDFXClipVideo(&dstBox, &xa, &xb, &ya, &yb, clipBoxes, width, height))
+ return Success;
+
+ dstBox.x1 -= pScrn->frameX0;
+ dstBox.x2 -= pScrn->frameX0;
+ dstBox.y1 -= pScrn->frameY0;
+ dstBox.y2 -= pScrn->frameY0;
+
+ bpp = pScrn->bitsPerPixel >> 3;
+ pitch = bpp * pScrn->displayWidth;
+
+ switch(id) {
+ case FOURCC_YV12:
+ case FOURCC_I420:
+ dstPitch = ((width << 1) + 3) & ~3;
+ new_size = ((dstPitch * height) + bpp - 1) / bpp;
+ srcPitch = (width + 3) & ~3;
+ s2offset = srcPitch * height;
+ srcPitch2 = ((width >> 1) + 3) & ~3;
+ s3offset = (srcPitch2 * (height >> 1)) + s2offset;
+ break;
+ case FOURCC_UYVY:
+ case FOURCC_YUY2:
+ default:
+ dstPitch = ((width << 1) + 3) & ~3;
+ new_size = ((dstPitch * height) + bpp - 1) / bpp;
+ srcPitch = (width << 1);
+ break;
}
- return Success;
+
+ if(!(pTDFX->overlayBuffer = TDFXAllocateMemoryLinear(pScrn, pTDFX->overlayBuffer, new_size)))
+ return BadAlloc;
+
+ /* copy data */
+ top = ya >> 16;
+ left = (xa >> 16) & ~1;
+ npixels = ((((xb + 0xffff) >> 16) + 1) & ~1) - left;
+
+ offset = (pTDFX->overlayBuffer->offset * bpp) + (top * dstPitch) + pTDFX->fbOffset;
+ dst_start = pTDFX->FbBase + offset;
+
+ switch(id) {
+ case FOURCC_YV12:
+ case FOURCC_I420:
+ top &= ~1;
+ dst_start += left << 1;
+ tmp = ((top >> 1) * srcPitch2) + (left >> 1);
+ s2offset += tmp;
+ s3offset += tmp;
+ if(id == FOURCC_I420) {
+ tmp = s2offset;
+ s2offset = s3offset;
+ s3offset = tmp;
+ }
+ nlines = ((((yb + 0xffff) >> 16) + 1) & ~1) - top;
+ TDFXCopyMungedData(buf + (top * srcPitch) + left, buf + s2offset,
+ buf + s3offset, dst_start, srcPitch, srcPitch2,
+ dstPitch, nlines, npixels);
+ break;
+ case FOURCC_UYVY:
+ case FOURCC_YUY2:
+ default:
+ left <<= 1;
+ buf += (top * srcPitch) + left;
+ nlines = ((yb + 0xffff) >> 16) - top;
+ dst_start += left;
+ TDFXCopyData(buf, dst_start, srcPitch, dstPitch, nlines, npixels << 1);
+ break;
+ }
+
+ if(!RegionsEqual(&pPriv->clip, clipBoxes)) {
+ REGION_COPY(pScreen, &pPriv->clip, clipBoxes);
+ (*pTDFX->AccelInfoRec->FillSolidRects)(pScrn, pPriv->colorKey,
+ GXcopy, ~0,
+ REGION_NUM_RECTS(clipBoxes),
+ REGION_RECTS(clipBoxes));
+ }
+
+ TDFXDisplayVideoOverlay(pScrn, id, offset, width, height, dstPitch, xa, xb, ya, &dstBox, src_w, src_h, drw_w, drw_h);
+
+ pPriv->videoStatus = CLIENT_VIDEO_ON;
+
+ pTDFX->VideoTimerCallback = TDFXVideoTimerCallback;
+
+ return Success;
}
-#endif
static void
-TDFXDeallocateOffscreenBuffer (ScrnInfoPtr pScrn, int id)
+TDFXVideoTimerCallback(ScrnInfoPtr pScrn, Time time)
{
- TDFXPtr pTDFX = TDFXPTR(pScrn);
-
- /* There is only one buffer so just deallocate it */
- if (pTDFX->offscreenYUVBuf)
- xf86FreeOffscreenArea (pTDFX->offscreenYUVBuf);
+ TDFXPtr pTDFX = TDFXPTR(pScrn);
+ TDFXPortPrivPtr pPriv = pTDFX->overlayAdaptor->pPortPrivates[0].ptr;
+
+ if(pPriv->videoStatus & TIMER_MASK) {
+ if(pPriv->videoStatus & OFF_TIMER) {
+ if(pPriv->offTime < time) {
+ pTDFX->ModeReg.vidcfg &= ~VIDPROCCFGMASK;
+ pTDFX->writeLong(pTDFX, VIDPROCCFG, pTDFX->ModeReg.vidcfg);
+ pPriv->videoStatus = FREE_TIMER;
+ pPriv->freeTime = time + FREE_DELAY;
+ }
+ } else
+ if(pPriv->videoStatus & FREE_TIMER) {
+ if(pPriv->freeTime < time) {
+ if(pTDFX->overlayBuffer) {
+ xf86FreeOffscreenLinear(pTDFX->overlayBuffer);
+ pTDFX->overlayBuffer = NULL;
+ }
+ pPriv->videoStatus = 0;
+ pTDFX->VideoTimerCallback = NULL;
+ }
+ }
+ } else /* shouldn't get here */
+ pTDFX->VideoTimerCallback = NULL;
}
+
+/*
+ * MEMORY MANAGEMENT
+ */
+
+
static FBAreaPtr
-TDFXAllocateOffscreenBuffer (ScrnInfoPtr pScrn, int id, int width, int height)
+TDFXAllocateMemoryArea (ScrnInfoPtr pScrn, FBAreaPtr area, int width, int height)
{
- int myWidth;
TDFXPtr pTDFX = TDFXPTR(pScrn);
+ ScreenPtr pScreen;
+ FBAreaPtr new_area;
- if (!pTDFX)
- return NULL;
-
- /* We tweak the width slightly */
- myWidth = width;
- /* We tweak the width slightly */
- myWidth = width;
-
- /* width is measured in pixels. The pixels in the YUV image are alway
- * 8 bit YUV data. But, the xf86 offscreen manager allocates in terms of
- * desktop pixels, so we adjust. */
- myWidth = myWidth / pTDFX->cpp;
- if (width % pTDFX->cpp)
- myWidth++;
-
- /* If we are putting up a subimage then we need an extra column of data
- * if the source width is odd, instead of checkin the width just always
- * allocate an extra column. */
- /* XXX is this really necessary? */
- myWidth++;
-
- if (pTDFX->offscreenYUVBuf != NULL &&
- myWidth == pTDFX->offscreenYUVBufWidth &&
- height == pTDFX->offscreenYUVBufHeight)
- {
- /* we already have a buffer, don't do anything. */
- return pTDFX->offscreenYUVBuf;
- }
-
- /* We have a buffer, but its not the right size so resize it */
- if (pTDFX->offscreenYUVBuf != NULL)
- {
- if (!xf86ResizeOffscreenArea (pTDFX->offscreenYUVBuf,
- myWidth,
- height))
- {
- return (NULL);
- }
+ if (area) {
+ if ((area->box.x2 - area->box.x1 >= width) &&
+ (area->box.y2 - area->box.y1 >= height))
+ return area;
+
+ if (xf86ResizeOffscreenArea(area, width, height))
+ return area;
+
+ xf86FreeOffscreenArea(area);
}
- else
- {
- /* Allocate a brand new buffer */
- pTDFX->offscreenYUVBuf =
- xf86AllocateOffscreenArea (pScrn->pScreen,
- myWidth,
- height,
- 0,
- NULL, NULL, NULL);
+
+ pScreen = screenInfo.screens[pScrn->scrnIndex];
+
+ new_area = xf86AllocateOffscreenArea(pScreen, width, height, pTDFX->cpp, NULL, NULL, NULL);
+
+ if (!new_area) {
+ int max_width, max_height;
+
+ xf86QueryLargestOffscreenArea(pScreen, &max_width, &max_height, pTDFX->cpp, 0, PRIORITY_EXTREME);
+
+ if (max_width < width || max_height < height)
+ return NULL;
+
+ xf86PurgeUnlockedOffscreenAreas(pScreen);
+ new_area = xf86AllocateOffscreenArea(pScreen, width, height, pTDFX->cpp, NULL, NULL, NULL);
}
- /* Return the buffer */
- pTDFX->offscreenYUVBufWidth = myWidth;
- pTDFX->offscreenYUVBufHeight = height;
- return (pTDFX->offscreenYUVBuf);
+ return new_area;
}
-static int
-TDFXQueryImageAttributes(
- ScrnInfoPtr pScrn,
- int id,
- unsigned short *w, unsigned short *h,
- int *pitches, int *offsets)
+static FBLinearPtr
+TDFXAllocateMemoryLinear (ScrnInfoPtr pScrn, FBLinearPtr linear, int size)
{
+ ScreenPtr pScreen;
+ FBLinearPtr new_linear;
- int size;
- TDFXPtr pTDFX = TDFXPTR(pScrn);
+ if(linear) {
+ if(linear->size >= size)
+ return linear;
- /* The Maximum size for 3dfx YUV planar space
- * but our temporary buffer has to fit in the pixmap region which
- * is the same width as the desktop and pTDFX->pixmapCacheLines
- * pixels high.
- */
- if(*w > 1024) *w = 1024;
- if (*w > pTDFX->stride) *w = pTDFX->stride;
- if(*h > pTDFX->pixmapCacheLines) *h = pTDFX->pixmapCacheLines;
+ if(xf86ResizeOffscreenLinear(linear, size))
+ return linear;
+ xf86FreeOffscreenLinear(linear);
+ }
+ pScreen = screenInfo.screens[pScrn->scrnIndex];
- if (offsets) offsets[0] = 0;
- switch(id) {
- case FOURCC_YV12:
- case FOURCC_I420:
- if (pitches) pitches[0] = *w;
- /* Size of Y plane plus the size of U and V planes */
- size = *w * *h;
- if (offsets) offsets[1] = size;
- size += ((*w >> 1) * (*h >> 1));
- if (offsets) offsets[2] = size;
- size += ((*w >> 1) * (*h >> 1));
- break;
- case FOURCC_UYVY:
- case FOURCC_YUY2:
- default:
- size = *w << 1;
- if(pitches) pitches[0] = size;
- size *= *h;
- break;
- }
- return size;
+ new_linear = xf86AllocateOffscreenLinear(pScreen, size, 4, NULL, NULL, NULL);
+
+ if(!new_linear) {
+ int max_size;
+
+ xf86QueryLargestOffscreenLinear(pScreen, &max_size, 4, PRIORITY_EXTREME);
+
+ if(max_size < size)
+ return NULL;
+
+ xf86PurgeUnlockedOffscreenAreas(pScreen);
+ new_linear = xf86AllocateOffscreenLinear(pScreen, size, 4, NULL, NULL, NULL);
+ }
+
+ return new_linear;
}
#endif /* !XvExtension */
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfxdefs.h b/xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfxdefs.h
index c77566b78..a925b22ca 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfxdefs.h
+++ b/xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfxdefs.h
@@ -1,4 +1,4 @@
-/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfxdefs.h,v 1.9 2000/12/15 15:19:35 dawes Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfxdefs.h,v 1.8 2000/12/01 14:29:00 dawes Exp $ */
/*
Voodoo Banshee driver version 1.0.1
@@ -47,8 +47,10 @@
#define SST_DESKTOP_CLUT_BYPASS BIT(10)
#define SST_HALF_MODE BIT(4)
#define SST_CURSOR_EN BIT(27)
+#define SST_FBI_BUSY BIT(7)
#define SST_BUSY BIT(9)
#define SST_RETRACE BIT(6)
+#define SST_COMMANDEXTRA_VSYNC BIT(2)
#define MEM_TYPE_SGRAM 0
#define MEM_TYPE_SDRAM 1
@@ -198,9 +200,11 @@
#define SST_3D_COMMAND SST_3D_OFFSET+0x120
#define SST_3D_SLICTRL SST_3D_OFFSET+0x20C
#define SST_3D_AACTRL SST_3D_OFFSET+0x210
-#define SST_3D_CHIPMASK SST_3D_OFFSET+0x214
+#define SST_3D_LEFTOVERLAYBUF SST_3D_OFFSET+0x250
+#define SST_3D_RIGHTOVERLAYBUF SST_3D_OFFSET+0x254
/* NAPALM REGISTERS */
+#define CFG_PCI_COMMAND 4
#define CFG_MEM0BASE 16
#define CFG_MEM1BASE 20
#define CFG_INIT_ENABLE 64