summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuc Verhaegen <libv@skynet.be>2005-10-04 06:26:04 +0000
committerLuc Verhaegen <libv@skynet.be>2005-10-04 06:26:04 +0000
commit4e33b3848da771678a68d826fbe1483f70dec15f (patch)
tree4e2beb9e884d2e3965cf39656275696e8004ff3e
parenta65a7ef1b7d2674e249486b166a71577070fc80b (diff)
[devel-swov_restructure_via_video] Sanitize ordering of via_video.c.
-rw-r--r--src/via_video.c2308
1 files changed, 1177 insertions, 1131 deletions
diff --git a/src/via_video.c b/src/via_video.c
index 3fb8369..61d8d06 100644
--- a/src/via_video.c
+++ b/src/via_video.c
@@ -54,10 +54,45 @@ void viaInitVideo(ScreenPtr pScreen) {}
#define VIA_MAX_XVIMAGE_X 1920
#define VIA_MAX_XVIMAGE_Y 1200
-#define XV_IMAGE 0
+#define ALIGN_TO(f, alignment) (((f) + ((alignment)-1)) & ~((alignment)-1))
+
+#define XV_IMAGE 0
+
+static XF86VideoEncodingRec DummyEncoding[1] = {
+ {XV_IMAGE, "XV_IMAGE", VIA_MAX_XVIMAGE_X, VIA_MAX_XVIMAGE_Y, {1, 1}},
+};
+
+#define NUM_FORMATS_G 9
+
+static XF86VideoFormatRec FormatsG[NUM_FORMATS_G] =
+{
+ { 8, TrueColor }, /* Dithered */
+ { 8, PseudoColor }, /* Using .. */
+ { 8, StaticColor },
+ { 8, GrayScale },
+ { 8, StaticGray }, /* .. TexelLUT */
+ {16, TrueColor},
+ {24, TrueColor},
+ {16, DirectColor},
+ {24, DirectColor}
+};
+
#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE)
+static Atom xvBrightness, xvContrast, xvColorKey, xvHue, xvSaturation,
+ xvAutoPaint, xvOpacity;
-#define ALIGN_TO(f, alignment) (((f) + ((alignment)-1)) & ~((alignment)-1))
+#define NUM_ATTRIBUTES_G 7
+
+static XF86AttributeRec AttributesG[NUM_ATTRIBUTES_G] =
+{
+ {XvSettable | XvGettable, 0, 0x00FFFFFF, "XV_COLORKEY"},
+ {XvSettable | XvGettable, 0, 10000, "XV_BRIGHTNESS"},
+ {XvSettable | XvGettable, 0, 20000, "XV_CONTRAST"},
+ {XvSettable | XvGettable, 0, 20000, "XV_SATURATION"},
+ {XvSettable | XvGettable, -180, 180, "XV_HUE"},
+ {XvSettable | XvGettable, 0, 1, "XV_AUTOPAINT_COLORKEY"},
+ {XvSettable | XvGettable, 0, 0x0F, "XV_OPACITY"}
+};
/*
* I'm unable to set the ordering of packed YUV, so only YUY2 is possible.
@@ -175,7 +210,7 @@ static XF86ImageRec ImagesG[NUM_IMAGES_G] =
#ifdef HAVE_DEBUG
/*
*
- * Dump Video registers for debugging purposes.
+ * Dump Video registers.
*
*/
static void
@@ -265,267 +300,6 @@ ViaSwovPrintRegs(struct ViaSwov *Swov)
#endif /* HAVE_DEBUG */
/*
- * Hardware level stuff. Actual Xv infrastructural stuff comes later.
- */
-
-/*
- * Only needs to be altered when the Front buffer size changes.
- */
-static void
-ViaHQVFetch(struct ViaSwov *Swov, struct ViaXvPort *Port)
-{
- CARD32 Fetch = Port->Width;
- CARD32 Height = Port->Height;
-
- switch (Port->FourCC) {
- case FOURCC_YV12:
- case FOURCC_I420:
- /* Fetch is ok */
- break;
- case FOURCC_YUY2:
- case FOURCC_RV15:
- case FOURCC_RV16:
- Fetch *= 2;
- break;
- case FOURCC_RV32:
- Fetch *= 4;
- break;
- default:
- xf86DrvMsg(Swov->scrnIndex, X_ERROR, "%s: Unhandled FourCC.\n",
- __FUNCTION__);
- }
-
- if (Swov->HQVFetchByteUnit) /* CLE266A */
- Fetch >>= 3;
-
- if ((Port->Deinterlace & VIA_DEINT_BOB) &&
- !(Port->Deinterlace & VIA_DEINT_INTERLEAVE))
- Height <<= 1;
-
- Swov->HQV->SrcFetch = ((Fetch - 1) << 16) | (Height - 1);
-}
-
-/*
- * Only needs to be altered when the Back buffer size changes.
- */
-static void
-ViaSwovStride(struct ViaSwov *Swov, struct ViaXvPort *Port)
-{
- switch (Port->FourCC) {
- case FOURCC_YV12:
- case FOURCC_I420:
- /* planar YUV */
- Swov->HQV->SrcStride = ((Port->Width >> 1) << 16) | Port->Width;
- Swov->HQV->DstStride = Port->Width << 1;
- Swov->Video->Video3Stride = Port->Width << 1;
- break;
- case FOURCC_YUY2:
- case FOURCC_RV15:
- case FOURCC_RV16:
- Swov->HQV->SrcStride = Port->Width << 1;
- Swov->HQV->DstStride = Port->Width << 1;
- Swov->Video->Video3Stride = Port->Width << 1;
- break;
- case FOURCC_RV32:
- Swov->HQV->SrcStride = Port->Width << 2;
- Swov->HQV->DstStride = Port->Width << 2;
- Swov->Video->Video3Stride = Port->Width << 2;
- break;
- default:
- xf86DrvMsg(Swov->scrnIndex, X_ERROR, "%s: Unhandled FourCC.\n",
- __FUNCTION__);
- }
-}
-
-/*
- *
- */
-static Bool
-ViaSwovSurfaceCreate(ScrnInfoPtr pScrn, CARD32 FourCC, CARD16 Width, CARD16 Height)
-{
- VIAPtr pVia = VIAPTR(pScrn);
- struct ViaSwov *Swov = pVia->Swov;
- struct ViaXvPort *Port = Swov->Port;
- int FrontSize, BackSize;
-
- VIAFUNC(pScrn->scrnIndex);
- ViaDebug(pScrn->scrnIndex, "%s: FourCC 0x%08X, Width %d, Height %d\n",
- __FUNCTION__, FourCC, Width, Height);
-
- switch (FourCC) {
- case FOURCC_YV12:
- case FOURCC_I420:
- if (FourCC == FOURCC_I420) { /* YUV */
- Port->CbOffset = Width * Height;
- Port->CrOffset = Port->CbOffset + (Width >> 1) * (Height >> 1);
- } else { /* YVU */
- Port->CrOffset = Width * Height;
- Port->CbOffset = Port->CrOffset + (Width >> 1) * (Height >> 1);
- }
-
- FrontSize = (Width * Height * 3) >> 1;
- BackSize = Width * Height * 2;
- break;
- case FOURCC_YUY2:
- case FOURCC_RV15:
- case FOURCC_RV16:
- Port->CrOffset = 0;
- Port->CbOffset = 0;
-
- FrontSize = Width * Height * 2;
- BackSize = FrontSize;
- break;
- case FOURCC_RV32:
- Port->CrOffset = 0;
- Port->CbOffset = 0;
-
- FrontSize = Width * Height * 4;
- BackSize = FrontSize;
- break;
- default:
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "%s: unhandled FourCC: 0x%08X\n",
- __FUNCTION__, FourCC);
- return FALSE;
- }
-
- Port->FourCC = FourCC;
- Port->Width = Width;
- Port->Height = Height;
-
- /* Front buffer, where the HQV sources its video. */
- Port->Front[0] = ViaMemAlloc(pScrn, FrontSize, 16);
- if (!Port->Front[0])
- return FALSE;
-
- ViaHQVFetch(Swov, Port);
-
- /* Back Buffer: HQV destination and Video3 source. */
- Port->Back[0] = ViaMemAlloc(pScrn, BackSize, 16);
- Port->Back[1] = ViaMemAlloc(pScrn, BackSize, 16);
- if (!Port->Back[0] || !Port->Back[1])
- return FALSE;
-
- /* This one may fail. */
- Port->Front[1] = ViaMemAlloc(pScrn, FrontSize, 16);
- if (!Port->Front[1]) {
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "%s: Not enough memory available.\n",
- __FUNCTION__);
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "%s: Using only a single front buffer.\n",
- __FUNCTION__);
-
- Swov->HQV->SrcAddressY = Port->Front[0]->Base;
- if (Port->CrOffset) {
- Swov->HQV->SrcAddressU = Port->Front[0]->Base + Port->CbOffset;
- Swov->HQV->SrcAddressV = Port->Front[0]->Base + Port->CrOffset;
- }
- }
-
- /* This one may fail too. */
- if (Swov->ThreeHQVBuffer) {
- Port->Back[2] = ViaMemAlloc(pScrn, BackSize, 16);
- if (!Port->Back[2]) {
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "%s: Not enough memory available.\n",
- __FUNCTION__);
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "%s: Using only 2 back buffers.\n",
- __FUNCTION__);
- }
- }
-
- Swov->HQV->DstAddress0 = Port->Back[0]->Base;
- Swov->HQV->DstAddress1 = Port->Back[1]->Base;
- if (Port->Back[2])
- Swov->HQV->DstAddress2 = Port->Back[2]->Base;
-
- ViaSwovStride(Swov, Port);
-
- return TRUE;
-}
-
-/*
- *
- */
-static void
-ViaSwovSurfaceDestroy(ScrnInfoPtr pScrn)
-{
- struct ViaSwov *Swov = VIAPTR(pScrn)->Swov;
- struct ViaXvPort *Port = Swov->Port;
-
- VIAFUNC(pScrn->scrnIndex);
-
- Port->FourCC = 0;
- Port->Width = 0;
- Port->Height = 0;
-
- if (Port->Front[0])
- ViaMemFree(pScrn, Port->Front[0]);
- if (Port->Front[1])
- ViaMemFree(pScrn, Port->Front[1]);
- if (Port->Back[0])
- ViaMemFree(pScrn, Port->Back[0]);
- if (Port->Back[1])
- ViaMemFree(pScrn, Port->Back[1]);
- if (Port->Back[2])
- ViaMemFree(pScrn, Port->Back[2]);
- if (Port->Alpha[0])
- ViaMemFree(pScrn, Port->Alpha[0]);
- if (Port->Alpha[1])
- ViaMemFree(pScrn, Port->Alpha[1]);
-
- Port->Front[0] = NULL;
- Port->Front[1] = NULL;
- Port->Back[0] = NULL;
- Port->Back[1] = NULL;
- Port->Back[2] = NULL;
- Port->Alpha[0] = NULL;
- Port->Alpha[1] = NULL;
-}
-
-/*
- * I've ditched all the FourCC stuff here. It's HQV->Video3 anyway.
- * When not YV12 (amazingly), the FIFO was set set to
- * (depth, prethreshold, threshhold) (1,0,0) when Width <= 8
- */
-static void
-ViaSwovFIFO(VIAPtr pVia, struct ViaSwov *Swov)
-{
- CARD8 depth, prethreshold, threshold;
-
- switch (pVia->Chipset) {
- case VIA_CLE266:
- if (CLE266_REV_IS_CX(pVia->ChipRev)) {
- depth = 64;
- prethreshold = 56;
- threshold = 56;
- Swov->Video->Video3Control |= V3_EXPIRE_NUM_F;
- } else { /* CLE266Ax */
- depth = 32;
- prethreshold = 16;
- threshold = 8;
- Swov->Video->Video3Control |= V3_EXPIRE_NUM;
- }
- break;
- case VIA_KM400:
- case VIA_K8M800:
- depth = 32;
- prethreshold = 29;
- threshold = 29;
- Swov->Video->Video3Control |= V3_EXPIRE_NUM_3205;
- break;
- default:
- depth = 1;
- prethreshold = 0;
- threshold = 0;
- break;
- }
-
- Swov->Video->Video3AlphaFifo &= ~V3_FIFO_MASK;
- Swov->Video->Video3AlphaFifo |= ((depth - 1) & 0xff) | ((threshold & 0xff) << 8);
-
- Swov->Video->Video3AlphaPreFifo &= ~V3_PREFIFO_MASK;
- Swov->Video->Video3AlphaPreFifo |= (prethreshold & 0x7f);
-}
-
-/*
* Another bloody ugly mess.
*
*
@@ -535,29 +309,32 @@ ViaSwovFIFO(VIAPtr pVia, struct ViaSwov *Swov)
/*
* This function uses quadratic mapping to adjust the midpoint of the scaling.
*/
-static float rangeEqualize(float inLow,float inHigh,float outLow,float outHigh,float outMid,
- float inValue)
+static float
+rangeEqualize(float inLow,float inHigh,float outLow,float outHigh,float outMid,
+ float inValue)
{
- float
- inRange = inHigh - inLow,
- outRange = outHigh - outLow,
- normIn = ((inValue - inLow) / inRange)*2.-1.,
- delta = outMid - outRange*0.5 - outLow;
+ float inRange = inHigh - inLow;
+ float outRange = outHigh - outLow;
+ float normIn = ((inValue - inLow) / inRange)*2.-1.;
+ float delta = outMid - outRange*0.5 - outLow;
+
return (inValue - inLow) * outRange / inRange + outLow + (1. - normIn*normIn)*delta;
}
-static unsigned vPackFloat(float val, float hiLimit, float loLimit, float mult, int shift,
- Bool doSign)
+static unsigned
+vPackFloat(float val, float hiLimit, float loLimit, float mult, int shift,
+ Bool doSign)
{
unsigned packed,mask,sign;
+
val = (val > hiLimit) ? hiLimit : val;
val = (val < loLimit) ? loLimit : val;
sign = (val < 0) ? 1:0;
val = (sign) ? -val : val;
packed = ((unsigned)(val*mult + 1.)) >> 1;
mask = (1 << shift) - 1;
- return (((packed >= mask) ? mask : packed) | ((doSign) ? (sign << shift) : 0));
+ return (((packed >= mask) ? mask : packed) | ((doSign) ? (sign << shift) : 0));
}
/*
@@ -687,6 +464,9 @@ VIASetColorSpace(VIAPtr pVia)
pVia->Swov->Video->Video3ColorSpace2 = col2;
}
+/*
+ *
+ */
static void
ViaSwovColorKey(ScrnInfoPtr pScrn, CARD32 Key)
{
@@ -704,6 +484,9 @@ ViaSwovColorKey(ScrnInfoPtr pScrn, CARD32 Key)
}
#ifdef UNUSED
+/*
+ *
+ */
static void
ViaSwovChromaKey(struct ViaSwov *Swov, CARD32 chromaLow, CARD32 chromaHigh)
{
@@ -721,323 +504,6 @@ ViaSwovChromaKey(struct ViaSwov *Swov, CARD32 chromaLow, CARD32 chromaHigh)
}
#endif /* UNUSED */
-static void
-ViaHQVInit(struct ViaSwov *Swov)
-{
- struct ViaXvPort *Port = Swov->Port;
-
- Swov->HQV->Control = HQV_SRC_SW;
- /* not CLE266Ax could need |= HQV_ENABLE | HQV_SW_FLIP */
-
- switch (Port->FourCC) {
- case FOURCC_YV12:
- case FOURCC_I420:
- Swov->HQV->Control |= HQV_YUV420;
- break;
- case FOURCC_YUY2:
- Swov->HQV->Control |= HQV_YUV422;
- break;
- case FOURCC_RV15:
- Swov->HQV->Control |= HQV_RGB15;
- break;
- case FOURCC_RV16:
- Swov->HQV->Control |= HQV_RGB16;
- break;
- case FOURCC_RV32:
- Swov->HQV->Control |= HQV_RGB32;
- break;
- default:
- xf86DrvMsg(Swov->scrnIndex, X_ERROR, "%s: Unhandled FourCC.\n",
- __FUNCTION__);
- }
-
- /* why this flip stuff? -- Luc */
- if (Port->Back[2]) {
- Swov->HQV->Control &= ~HQV_SW_FLIP;
- Swov->HQV->Control |= HQV_TRIPLE_BUFF | HQV_FLIP_STATUS;
- }
-
- /* For DCT450 test-BOB INTERLEAVE */
- if ((Port->Deinterlace & VIA_DEINT_BOB)) {
- Swov->HQV->Control |= HQV_FIELD_2_FRAME | HQV_DEINTERLACE;
- if ((Port->Deinterlace & VIA_DEINT_INTERLEAVE))
- Swov->HQV->Control |= HQV_FRAME_2_FIELD;
- }
-
- Swov->HQV->Control |= HQV_ENABLE;
-}
-
-static void
-ViaHQVSwovIdle(struct ViaSwov *Swov)
-{
- int i;
-
- for (i = 0; i < 10; i++)
- if (!(Swov->Video->Compose & V3_COMMAND_FIRE) &&
- (Swov->HQV->Control & HQV_IDLE))
- break;
- else
- usleep(1);
-
- if (i) {
- ViaDebug(Swov->scrnIndex, "%s: idle/fire wait: %d.\n", __FUNCTION__, i);
- if (!(Swov->HQV->Control & HQV_IDLE))
- xf86DrvMsg(Swov->scrnIndex, X_WARNING, "%s: HQV not idle.\n",
- __FUNCTION__);
- if ((Swov->Video->Compose & V3_COMMAND_FIRE))
- xf86DrvMsg(Swov->scrnIndex, X_WARNING, "%s: Video3 still firing.\n",
- __FUNCTION__);
- }
-
-}
-
-/*
- * Minify is done by the HQV entirely.
- * Zoom is done by V3.
- *
- */
-static void
-ViaSwovZoomH(struct ViaSwov *Swov, struct ViaXvPort *Port)
-{
- unsigned long tmp;
-
- Swov->HQV->Minify &= 0xFFFF0000;
- Swov->HQV->Filter &= 0xFFFF0000;
- Swov->Video->Video3Zoom &= 0x0000FFFF;
- Swov->Video->Video3Minify &= 0xF8FFFFFD;
-
- if (Port->Src_W == Port->Drw_W) { /* No zoom */
- Swov->HQV->Filter |= HQV_H_HIPASS_F1_DEFAULT;
- } else if (Port->Src_W < Port->Drw_W) { /* Zoom in */
-
- tmp = Port->Src_W * 0x800 / Port->Drw_W;
- Swov->Video->Video3Zoom |= ((tmp & 0x7ff) << 16) | V3_X_ZOOM_ENABLE;
-
- Swov->Video->Video3Minify |= V3_X_INTERPOLY;
- Swov->HQV->Filter |= HQV_H_HIPASS_F1_DEFAULT;
-
- } else { /* Zoom out */
- tmp = Port->Drw_W * 0x800 * 0x400 / Port->Src_W;
- tmp = tmp / 0x400 + ((tmp & 0x3ff) ? 1 : 0);
-
- Swov->HQV->Minify |= (tmp & 0x7ff) | HQV_H_MINIFY_ENABLE;
-
- if (Port->Src_W > (4 * Port->Drw_W))
- Swov->HQV->Filter |= HQV_H_TAP8_12221;
- else
- Swov->HQV->Filter |= HQV_H_TAP4_121;
- Swov->HQV->Minify |= HQV_HDEBLOCK_FILTER;
- }
-}
-
-/*
- *
- */
-static void
-ViaSwovZoomV(struct ViaSwov *Swov, struct ViaXvPort *Port)
-{
- unsigned long tmp;
- short Src_H = Port->Src_H;
-
- if ((Port->Deinterlace & VIA_DEINT_BOB) &&
- !(Port->Deinterlace & VIA_DEINT_INTERLEAVE))
- Src_H <<= 1;
-
- Swov->HQV->Minify &= 0x0000FFFF;
- Swov->HQV->Filter &= 0x0000FFFF;
- Swov->Video->Video3Zoom &= 0xFFFF0000;
- Swov->Video->Video3Minify &= 0xFFF8FFFA;
-
- /* Setup Y zoom factor */
- if (Src_H == Port->Drw_H) { /* No zoom */
- Swov->HQV->Filter |= HQV_V_TAP4_121;
- } else if (Src_H < Port->Drw_H) { /* Zoom in */
- ScrnInfoPtr pScrn = xf86Screens[Swov->scrnIndex];
-
- tmp = Src_H * 0x0400 / Port->Drw_H;
- Swov->Video->Video3Zoom |= ((tmp & 0x3ff) | V3_Y_ZOOM_ENABLE);
-
- if ((VIAPTR(pScrn)->Chipset == VIA_CLE266) && (pScrn->currentMode->HDisplay > 1024))
- /* Temporary fix for 2D bandwidth problem. 2002/08/01*/
- Swov->Video->Video3Minify |= V3_YCBCR_INTERPOLY;
- else
- Swov->Video->Video3Minify |= V3_Y_INTERPOLY | V3_YCBCR_INTERPOLY;
-
- Swov->HQV->Filter |= HQV_V_TAP4_121;
- Swov->HQV->Filter &= ~HQV_V_LOWPASS_4TAP;
- } else { /* Zoom out */
- tmp = Port->Drw_H * 0x0800 * 0x400 / Src_H;
- tmp = tmp / 0x400 + ((tmp & 0x3ff) ? 1 : 0);
- Swov->HQV->Minify |= ((tmp & 0x7ff) << 16) | HQV_V_MINIFY_ENABLE;
-
- if (Src_H > (4 * Port->Drw_H))
- Swov->HQV->Filter |= HQV_V_TAP8_12221;
- else
- Swov->HQV->Filter |= HQV_V_TAP4_121;
- Swov->HQV->Minify |= HQV_VDEBLOCK_FILTER;
- }
-}
-
-/*
- * Returns FALSE when the overlay is not currently visible.
- */
-static Bool
-ViaSwovVisibleH(ScrnInfoPtr pScrn, struct ViaXvPort *Port)
-{
- struct ViaSwov *Swov = VIAPTR(pScrn)->Swov;
- short limit;
- long temp;
- CARD32 Fetch;
- short Src_X, Src_W, Dst_X, Dst_W;
-
- /* Horizontal */
- if (pScrn->currentMode->HDisplay < 2047)
- limit = pScrn->currentMode->HDisplay;
- else
- limit = 2047;
-
- if (((Port->Drw_X + Port->Drw_W) < pScrn->frameX0) ||
- (Port->Drw_X > (limit + pScrn->frameX0)))
- return FALSE;
-
- Src_X = Port->Src_X;
- Dst_W = Port->Drw_W;
-
- if (Port->Drw_X < pScrn->frameX0) {
- temp = (pScrn->frameX0 - Port->Drw_X) * Port->Src_W;
- temp += Port->Drw_W >> 1;
- Src_X += temp / Port->Drw_W;
-
- Dst_W -= pScrn->frameX0 - Port->Drw_X;
- Dst_X = 0;
- } else
- Dst_X = Port->Drw_X - pScrn->frameX0;
-
- if ((Dst_X + Dst_W) > limit)
- Dst_W = limit - Dst_X;
-
- if (Dst_W != Port->Drw_W) {
- temp = Dst_W * Port->Src_W;
- temp += Port->Drw_W >> 1;
- Src_W = temp / Port->Drw_W;
- } else
- Src_W = Port->Src_W;
-
- /* set up window */
- Swov->Video->Video3WindowEnd &= 0x0000FFFF;
- Swov->Video->Video3WindowEnd |= (Dst_X + Dst_W - 1) << 16;
-
- Swov->Video->Video3WindowStart &= 0x0000FFFF;
- Swov->Video->Video3WindowStart |= Dst_X << 16;
-
- /* set up Fetch */
- if (Port->FourCC == FOURCC_RV32) {
- if (Dst_W >= Src_W)
- Fetch = (ALIGN_TO(Src_W << 2, 16) >> 4) + 1;
- else
- Fetch = (ALIGN_TO(Dst_W << 2, 16) >> 4) + 1;
- } else {
- if (Dst_W >= Src_W)
- Fetch = (ALIGN_TO(Src_W << 1, 16) >> 4) + 1;
- else
- Fetch = (ALIGN_TO(Dst_W << 1, 16) >> 4) + 1;
- }
-
- /* Fix planar mode problem. */
- if (Fetch < 4)
- Fetch = 4;
-
- Swov->Video->Video3AlphaFetch &= ~V3_FETCH_COUNT;
- Swov->Video->Video3AlphaFetch |= Fetch << 20;
-
- Swov->Video->Video3SrcWidth = Src_W - 1;
-
- /* for startAddress offset */
- Port->Offset_X = Src_X;
-
- /* for alpha */
- Port->Win_X = Dst_X;
- Port->Win_W = Dst_W;
-
- return TRUE;
-}
-
-/*
- *
- */
-static Bool
-ViaSwovVisibleV(ScrnInfoPtr pScrn, struct ViaXvPort *Port)
-{
- struct ViaSwov *Swov = VIAPTR(pScrn)->Swov;
- short limit;
- long temp;
- short Src_Y, Dst_Y, Dst_H;
-
- if (pScrn->currentMode->VDisplay < 2047)
- limit = pScrn->currentMode->VDisplay;
- else
- limit = 2047;
-
- if (((Port->Drw_Y + Port->Drw_H) < pScrn->frameY0) ||
- (Port->Drw_Y > (limit + pScrn->frameY0)))
- return FALSE;
-
- Src_Y = Port->Src_Y;
- Dst_H = Port->Drw_H;
-
- if (Port->Drw_Y < pScrn->frameY0) {
- /* Round down. */
- temp = (pScrn->frameY0 - Port->Drw_Y) * Port->Src_H;
- Src_Y += temp / Port->Drw_H;
-
- Dst_H -= pScrn->frameY0 - Port->Drw_Y;
- Dst_Y = 0;
- } else
- Dst_Y = Port->Drw_Y - pScrn->frameY0;
-
- if ((Dst_Y + Dst_H) > limit)
- Dst_H = limit - Dst_Y;
-
- /* set up window */
- Swov->Video->Video3WindowEnd &= 0xFFFF0000;
- Swov->Video->Video3WindowEnd |= Dst_Y + Dst_H - 1;
-
- Swov->Video->Video3WindowStart &= 0xFFFF0000;
- Swov->Video->Video3WindowStart |= Dst_Y;
-
- /* for startAddress offset */
- Port->Offset_Y = Src_Y;
-
- /* for alpha */
- Port->Win_Y = Dst_Y;
- Port->Win_H = Dst_H;
-
- return TRUE;
-}
-
-/*
- *
- */
-static void
-ViaSwovStartAddress(struct ViaSwov *Swov, struct ViaXvPort *Port)
-{
- unsigned long Offset;
-
- Offset = Port->Offset_Y * Port->Width + Port->Offset_X;
-
- if (Port->FourCC == FOURCC_RV32)
- Offset <<= 2;
- else
- Offset <<= 1;
-
- /* Warning: hardware rounds down to the nearest 16bytes */
-
- Swov->Video->Video3Address0 = Port->Back[0]->Base + Offset;
- Swov->Video->Video3Address1 = Port->Back[1]->Base + Offset;
- if (Port->Back[2])
- Swov->Video->Video3Address2 = Port->Back[2]->Base + Offset;
-}
-
/*
* Eyecandy: alpha blended overlay.
*
@@ -1053,6 +519,9 @@ ViaSwovStartAddress(struct ViaSwov *Swov, struct ViaXvPort *Port)
*/
#define VIA_ALPHAADDRESS_ALIGN 16
+/*
+ *
+ */
static void
ViaSwovAlphaFillRectangle(struct ViaXvPort *Port, CARD8 *Base, BoxRec Box)
{
@@ -1075,6 +544,9 @@ ViaSwovAlphaFillRectangle(struct ViaXvPort *Port, CARD8 *Base, BoxRec Box)
(Box.x2 - Box.x1) / 2);
}
+/*
+ *
+ */
static void
ViaSwovAlphaFill(ScrnInfoPtr pScrn, struct ViaMem *Mem)
{
@@ -1239,11 +711,11 @@ ViaSwovAlphaEnable(ScrnInfoPtr pScrn)
struct ViaXvPort *Port = Swov->Port;
ViaSwovAlphaSize(pScrn, Port->Drw_W, Port->Drw_H);
-
+
if (ViaSwovAlphaSurface(pScrn)) {
/* enable alpha */
Swov->Video->AlphaControl = 0x0000F001;
-
+
/* disable colorkey */
Swov->Video->Compose &= ~0x0F;
Swov->Video->Compose |= V3_COMMAND_FIRE;
@@ -1253,6 +725,9 @@ ViaSwovAlphaEnable(ScrnInfoPtr pScrn)
}
}
+/*
+ *
+ */
static void
ViaSwovAlphaDisable(ScrnInfoPtr pScrn)
{
@@ -1262,11 +737,11 @@ ViaSwovAlphaDisable(ScrnInfoPtr pScrn)
if (Port->Alpha[0])
ViaMemFree(pScrn, Port->Alpha[0]);
Port->Alpha[0] = NULL;
-
+
if (Port->Alpha[1])
ViaMemFree(pScrn, Port->Alpha[1]);
Port->Alpha[1] = NULL;
-
+
Swov->Video->Video3AlphaFifo &= 0x0000FFFF;
Swov->Video->Video3AlphaPreFifo &= 0x8000007F;
@@ -1288,6 +763,9 @@ ViaSwovAlphaDisable(ScrnInfoPtr pScrn)
xf86XVFillKeyHelper(pScrn->pScreen, Port->ColorKey, &Port->clip);
}
+/*
+ *
+ */
static void
ViaSwovAlphaSet(ScrnInfoPtr pScrn, INT32 value)
{
@@ -1308,226 +786,100 @@ ViaSwovAlphaSet(ScrnInfoPtr pScrn, INT32 value)
}
}
-static void
-ViaSwovCopy(VIAPtr pVia, struct ViaMem *Mem, unsigned char *buf)
-{
-#if 0
- xf86memcpy(pVia->FBBase + Mem->Base, buf, Mem->Size);
-#else
- {
- CARD32 *Dst = (CARD32 *) (pVia->FBBase + Mem->Base);
- CARD32 *End = (CARD32 *) (pVia->FBBase + Mem->Base + Mem->Size);
- CARD32 *Src = (CARD32 *) buf;
-
- while (Dst < End) {
- *Dst = *Src;
- Dst++;
- Src++;
- }
- }
-#endif
-}
-
/*
*
*/
-static void
-ViaHQVFlip(VIAPtr pVia, unsigned char* buf)
+static int
+viaSetPortAttribute(ScrnInfoPtr pScrn, Atom attribute, INT32 value, pointer data)
{
- struct ViaSwov *Swov = pVia->Swov;
- struct ViaXvPort *Port = Swov->Port;
- int i;
-
- for (i = 0; i < 15; i++)
- if (!(Swov->HQV->Control & HQV_SW_FLIP))
- break;
- else
- usleep(1);
+ VIAPtr pVia = VIAPTR(pScrn);
+ struct ViaXvPort *Port = (struct ViaXvPort *) data;
- if (i) {
- ViaDebug(Swov->scrnIndex, "%s: flip wait: %d.\n", __FUNCTION__, i);
- if ((Swov->HQV->Control & HQV_SW_FLIP))
- xf86DrvMsg(Swov->scrnIndex, X_WARNING, "%s: HQV is still flipping.\n",
- __FUNCTION__);
- }
+ if (attribute == xvColorKey) {
+ Port->ColorKey = value;
- if (!Port->Front[1]) /* single buffering */
- ViaSwovCopy(pVia, Port->Front[0], buf);
- else { /* We only need to set the address */
- Swov->HQV->SrcAddressY = Port->Front[0]->Base;
- if (Port->CrOffset) {
- Swov->HQV->SrcAddressU = Port->Front[0]->Base + Port->CbOffset;
- Swov->HQV->SrcAddressV = Port->Front[0]->Base + Port->CrOffset;
+ if (!Port->Opacity) {
+ ViaSwovColorKey(pScrn, value);
+ REGION_EMPTY(pScrn->pScreen, &Port->clip);
}
- }
-
- Swov->HQV->Control |= HQV_SW_FLIP | HQV_FLIP_STATUS;
+ return Success;
+ } else if (attribute == xvAutoPaint) {
+ if (value)
+ Port->autoPaint = TRUE;
+ else
+ Port->autoPaint = FALSE;
+ return Success;
+ } else if (attribute == xvBrightness) {
+ Port->brightness = value;
+ VIASetColorSpace(pVia);
+ return Success;
+ } else if (attribute == xvContrast) {
+ Port->contrast = value;
+ VIASetColorSpace(pVia);
+ return Success;
+ } else if (attribute == xvSaturation) {
+ Port->saturation = value;
+ VIASetColorSpace(pVia);
+ return Success;
+ } else if (attribute == xvHue) {
+ Port->hue = value;
+ VIASetColorSpace(pVia);
+ return Success;
+ } else if (attribute == xvOpacity) {
+ if ((value < 0) || (value > 15))
+ return BadValue;
- /* Before we fire V3 for the first time, wait. */
- if (!Swov->Active) {
- for (i = 0; i < 15; i++)
- if ((Swov->HQV->Control & HQV_FLIP_STATUS))
- break;
- else
- usleep(1);
- if (i) {
- ViaDebug(Swov->scrnIndex, "%s: status wait: %d.\n", __FUNCTION__, i);
- if (!(Swov->HQV->Control & HQV_FLIP_STATUS))
- xf86DrvMsg(Swov->scrnIndex, X_WARNING, "%s: Unable to initialise"
- " the HQV. (Status still not set)\n", __FUNCTION__);
- }
+ if (pVia->Swov->Active)
+ ViaSwovAlphaSet(pScrn, value);
+ else
+ Port->Opacity = value;
+ return Success;
}
-}
-
-/*
- *
- */
-static void
-ViaSwovStop(ScrnInfoPtr pScrn)
-{
- struct ViaSwov *Swov = VIAPTR(pScrn)->Swov;
- vgaHWPtr hwp = VGAHWPTR(pScrn);
-
- VIAFUNC(pScrn->scrnIndex);
-
- if (Swov->HQVDisablePatch)
- ViaSeqMask(hwp, 0x2E, 0x00, 0x10);
-
- Swov->Video->Video3AlphaFifo = ALPHA_FIFO_THRESHOLD4 | ALPHA_FIFO_DEPTH8
- | 0x00002431; /* threshold 24, depth 32 */
-
- Swov->HQV->Control &= ~HQV_ENABLE;
-
- if (Swov->HQVDisablePatch)
- ViaSeqMask(hwp, 0x2E, 0x10, 0x10);
- /* disable alpha too */
- Swov->Video->AlphaControl = 0x001FF000;
-
- Swov->Active = FALSE;
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "%s: Unhandled attribute.\n",
+ __FUNCTION__);
+ return BadMatch;
}
/*
*
*/
-static void
-ViaSwovInit(VIAPtr pVia)
+static int
+viaGetPortAttribute(ScrnInfoPtr pScrn, Atom attribute, INT32 *value, pointer data)
{
- struct ViaSwov *Swov = pVia->Swov;
-
- VIAFUNC(pVia->scrnIndex);
-
- Swov->scrnIndex = pVia->scrnIndex;
-
- Swov->Allowed = FALSE;
- Swov->Active = FALSE;
-
- Swov->Adaptor = NULL;
- Swov->Adaptors = NULL;
-
- /* Set up memory Map */
- Swov->Video = (struct ViaVideoRegs *) (pVia->MapBase + 0x200);
- Swov->HQV = (struct ViaHQVRegs *) (pVia->MapBase + 0x3D0);
-
-#ifdef HAVE_DEBUG
- if (pVia->PrintSwovRegs)
- ViaSwovPrintRegs(Swov);
-#endif
-
- /* make sure that nothing is active -- we might have an unclean state */
- Swov->Video->Video1Control &= ~0x00000001;
- Swov->Video->Video3Control &= ~0x00000001;
- Swov->HQV->Control &= ~0x08000000;
- Swov->Video->AlphaControl = 0x001FF000;
+ struct ViaXvPort *Port = (struct ViaXvPort *) data;
- /* old HWDiff stuff */
- switch(pVia->Chipset) {
- case VIA_CLE266:
- if (CLE266_REV_IS_AX(pVia->ChipRev)) {
- Swov->ThreeHQVBuffer = FALSE;
- Swov->HQVFetchByteUnit = TRUE;
- Swov->HQVDisablePatch = FALSE;
- } else {
- Swov->ThreeHQVBuffer = TRUE;
- Swov->HQVFetchByteUnit = FALSE;
- Swov->HQVDisablePatch = TRUE;
- }
- break;
- case VIA_KM400:
- Swov->ThreeHQVBuffer = TRUE;
- Swov->HQVFetchByteUnit = FALSE;
- Swov->HQVDisablePatch = TRUE;
- break;
- case VIA_K8M800:
- Swov->ThreeHQVBuffer = TRUE;
- Swov->HQVFetchByteUnit = FALSE;
- Swov->HQVDisablePatch = TRUE;
- break;
- case VIA_PM800:
- Swov->ThreeHQVBuffer = TRUE;
- Swov->HQVFetchByteUnit = FALSE;
- Swov->HQVDisablePatch = FALSE;
- break;
- default:
- xf86DrvMsg(pVia->scrnIndex, X_ERROR, "%s: Unhandled ChipSet.\n",
- __FUNCTION__);
+ if (attribute == xvColorKey) {
+ *value =(INT32) Port->ColorKey;
+ return Success;
+ } else if (attribute == xvAutoPaint) {
+ if (Port->autoPaint)
+ *value = 1;
+ else
+ *value = 0;
+ return Success;
+ } else if (attribute == xvBrightness) {
+ *value = Port->brightness;
+ return Success;
+ } else if (attribute == xvContrast) {
+ *value = Port->contrast;
+ return Success;
+ } else if (attribute == xvSaturation) {
+ *value = Port->saturation;
+ return Success;
+ } else if (attribute == xvHue) {
+ *value = Port->hue;
+ return Success;
+ } else if (attribute == xvOpacity) {
+ *value = Port->Opacity;
+ return Success;
}
-}
-
-/*
- * F U N C T I O N D E C L A R A T I O N
- */
-static void viaStopVideo(ScrnInfoPtr, pointer, Bool);
-static void viaQueryBestSize(ScrnInfoPtr, Bool,
- short, short, short, short, unsigned int *, unsigned int *, pointer);
-static int viaQueryImageAttributes(ScrnInfoPtr,
- int, unsigned short *, unsigned short *, int *, int *);
-static int viaGetPortAttribute(ScrnInfoPtr, Atom ,INT32 *, pointer);
-static int viaSetPortAttribute(ScrnInfoPtr, Atom, INT32, pointer);
-static int viaPutImage(ScrnInfoPtr, short, short, short, short, short, short,
- short, short,int, unsigned char*, short, short, Bool,
- RegionPtr, pointer);
-static int ViaSwovReputImage(ScrnInfoPtr pScrn, short drw_x, short drw_y,
- RegionPtr clipBoxes, pointer data);
-
-static Atom xvBrightness, xvContrast, xvColorKey, xvHue, xvSaturation,
- xvAutoPaint, xvOpacity;
-
-/*
- * S T R U C T S
- */
-/* client libraries expect an encoding */
-static XF86VideoEncodingRec DummyEncoding[1] = {
- {XV_IMAGE, "XV_IMAGE", VIA_MAX_XVIMAGE_X, VIA_MAX_XVIMAGE_Y, {1, 1}},
-};
-
-#define NUM_FORMATS_G 9
-
-static XF86VideoFormatRec FormatsG[NUM_FORMATS_G] =
-{
- { 8, TrueColor }, /* Dithered */
- { 8, PseudoColor }, /* Using .. */
- { 8, StaticColor },
- { 8, GrayScale },
- { 8, StaticGray }, /* .. TexelLUT */
- {16, TrueColor},
- {24, TrueColor},
- {16, DirectColor},
- {24, DirectColor}
-};
-
-#define NUM_ATTRIBUTES_G 7
-static XF86AttributeRec AttributesG[NUM_ATTRIBUTES_G] =
-{
- {XvSettable | XvGettable, 0, 0x00FFFFFF, "XV_COLORKEY"},
- {XvSettable | XvGettable, 0, 10000, "XV_BRIGHTNESS"},
- {XvSettable | XvGettable, 0, 20000, "XV_CONTRAST"},
- {XvSettable | XvGettable, 0, 20000, "XV_SATURATION"},
- {XvSettable | XvGettable, -180, 180, "XV_HUE"},
- {XvSettable | XvGettable, 0, 1, "XV_AUTOPAINT_COLORKEY"},
- {XvSettable | XvGettable, 0, 0x0F, "XV_OPACITY"}
-};
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "%s: Unhandled attribute.\n",
+ __FUNCTION__);
+ *value = 0;
+ return BadMatch;
+}
/*
* BLOODY MESS!
@@ -1543,7 +895,10 @@ static XF86AttributeRec AttributesG[NUM_ATTRIBUTES_G] =
#define VIDEO_BPP 2
-static Bool
+/*
+ *
+ */
+static Bool
ViaSwovBandwidth(ScrnInfoPtr pScrn)
{
VIAPtr pVia = VIAPTR(pScrn);
@@ -1602,7 +957,7 @@ ViaSwovBandwidth(ScrnInfoPtr pScrn)
memEfficiency = (float)SINGLE_3205_133;
break;
}
-
+
width = mode->HDisplay;
height = mode->VDisplay;
refresh = mode->VRefresh;
@@ -1630,108 +985,216 @@ ViaSwovBandwidth(ScrnInfoPtr pScrn)
needBandWidth = (float)(((pScrn->bitsPerPixel >> 3) + VIDEO_BPP)*dClock);
totalBandWidth = (float)(mClock*16.*memEfficiency);
-
+
if (needBandWidth < totalBandWidth)
return TRUE;
}
return FALSE;
}
+/*
+ * Only needs to be altered when the Front buffer size changes.
+ */
static void
-ViaVideoReset(struct ViaSwov *Swov)
+ViaHQVFetch(struct ViaSwov *Swov, struct ViaXvPort *Port)
{
- VIAFUNC(Swov->scrnIndex);
+ CARD32 Fetch = Port->Width;
+ CARD32 Height = Port->Height;
+
+ switch (Port->FourCC) {
+ case FOURCC_YV12:
+ case FOURCC_I420:
+ /* Fetch is ok */
+ break;
+ case FOURCC_YUY2:
+ case FOURCC_RV15:
+ case FOURCC_RV16:
+ Fetch *= 2;
+ break;
+ case FOURCC_RV32:
+ Fetch *= 4;
+ break;
+ default:
+ xf86DrvMsg(Swov->scrnIndex, X_ERROR, "%s: Unhandled FourCC.\n",
+ __FUNCTION__);
+ }
- Swov->Video->Video1Control = 0;
- Swov->Video->Video3Control = 0;
- Swov->Video->Compose = 0x80000000;
- Swov->Video->Compose = 0x40000000;
- Swov->Video->ColorKey = 0x821;
- Swov->Video->ColorKeySecond = 0x00000000;
- Swov->Video->Video3ColorKey = 0x00000000;
- Swov->Video->AlphaControl = 0x001FF000;
-}
+ if (Swov->HQVFetchByteUnit) /* CLE266A */
+ Fetch >>= 3;
-void
-ViaVideoSave(struct ViaSwov *Swov)
-{
- VIAFUNC(Swov->scrnIndex);
+ if ((Port->Deinterlace & VIA_DEINT_BOB) &&
+ !(Port->Deinterlace & VIA_DEINT_INTERLEAVE))
+ Height <<= 1;
- Swov->Video1Control = Swov->Video->Video1Control;
- Swov->Video3Control = Swov->Video->Video3Control;
- Swov->Video->Video1Control = 0;
- Swov->Video->Video3Control = 0;
- Swov->Video->Compose = 0x80000000;
- Swov->Video->Compose = 0x40000000;
+ Swov->HQV->SrcFetch = ((Fetch - 1) << 16) | (Height - 1);
}
-void
-ViaVideoRestore(struct ViaSwov *Swov)
+/*
+ * Only needs to be altered when the Back buffer size changes.
+ */
+static void
+ViaSwovStride(struct ViaSwov *Swov, struct ViaXvPort *Port)
{
- VIAFUNC(Swov->scrnIndex);
-
- Swov->Video->Video1Control = Swov->Video1Control;
- Swov->Video->Video3Control = Swov->Video3Control;
- Swov->Video->Compose = 0x80000000;
- Swov->Video->Compose = 0x40000000;
+ switch (Port->FourCC) {
+ case FOURCC_YV12:
+ case FOURCC_I420:
+ /* planar YUV */
+ Swov->HQV->SrcStride = ((Port->Width >> 1) << 16) | Port->Width;
+ Swov->HQV->DstStride = Port->Width << 1;
+ Swov->Video->Video3Stride = Port->Width << 1;
+ break;
+ case FOURCC_YUY2:
+ case FOURCC_RV15:
+ case FOURCC_RV16:
+ Swov->HQV->SrcStride = Port->Width << 1;
+ Swov->HQV->DstStride = Port->Width << 1;
+ Swov->Video->Video3Stride = Port->Width << 1;
+ break;
+ case FOURCC_RV32:
+ Swov->HQV->SrcStride = Port->Width << 2;
+ Swov->HQV->DstStride = Port->Width << 2;
+ Swov->Video->Video3Stride = Port->Width << 2;
+ break;
+ default:
+ xf86DrvMsg(Swov->scrnIndex, X_ERROR, "%s: Unhandled FourCC.\n",
+ __FUNCTION__);
+ }
}
-void
-ViaVideoExit(ScrnInfoPtr pScrn)
+/*
+ *
+ */
+static Bool
+ViaSwovSurfaceCreate(ScrnInfoPtr pScrn, CARD32 FourCC, CARD16 Width, CARD16 Height)
{
- struct ViaSwov *Swov = VIAPTR(pScrn)->Swov;
+ VIAPtr pVia = VIAPTR(pScrn);
+ struct ViaSwov *Swov = pVia->Swov;
+ struct ViaXvPort *Port = Swov->Port;
+ int FrontSize, BackSize;
- VIAFUNC(Swov->scrnIndex);
+ VIAFUNC(pScrn->scrnIndex);
+ ViaDebug(pScrn->scrnIndex, "%s: FourCC 0x%08X, Width %d, Height %d\n",
+ __FUNCTION__, FourCC, Width, Height);
- if (Swov->Active)
- ViaSwovStop(pScrn);
+ switch (FourCC) {
+ case FOURCC_YV12:
+ case FOURCC_I420:
+ if (FourCC == FOURCC_I420) { /* YUV */
+ Port->CbOffset = Width * Height;
+ Port->CrOffset = Port->CbOffset + (Width >> 1) * (Height >> 1);
+ } else { /* YVU */
+ Port->CrOffset = Width * Height;
+ Port->CbOffset = Port->CrOffset + (Width >> 1) * (Height >> 1);
+ }
- if (Swov->Port->Front[0])
- ViaSwovSurfaceDestroy(pScrn);
+ FrontSize = (Width * Height * 3) >> 1;
+ BackSize = Width * Height * 2;
+ break;
+ case FOURCC_YUY2:
+ case FOURCC_RV15:
+ case FOURCC_RV16:
+ Port->CrOffset = 0;
+ Port->CbOffset = 0;
- Swov->Video->Video1Control = 0;
- Swov->Video->Video3Control = 0;
- Swov->Video->Compose = 0x80000000;
- Swov->Video->Compose = 0x40000000;
- Swov->Video->AlphaControl = 0x001FF000;
+ FrontSize = Width * Height * 2;
+ BackSize = FrontSize;
+ break;
+ case FOURCC_RV32:
+ Port->CrOffset = 0;
+ Port->CbOffset = 0;
- /* Free all adapter info allocated in viaInitVideo. */
- if (Swov->Adaptor) {
- if (Swov->Adaptor->pPortPrivates) {
- if (Swov->Adaptor->pPortPrivates->ptr)
- xfree(Swov->Adaptor->pPortPrivates->ptr);
- xfree(Swov->Adaptor->pPortPrivates);
+ FrontSize = Width * Height * 4;
+ BackSize = FrontSize;
+ break;
+ default:
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "%s: unhandled FourCC: 0x%08X\n",
+ __FUNCTION__, FourCC);
+ return FALSE;
+ }
+
+ Port->FourCC = FourCC;
+ Port->Width = Width;
+ Port->Height = Height;
+
+ /* Front buffer, where the HQV sources its video. */
+ Port->Front[0] = ViaMemAlloc(pScrn, FrontSize, 16);
+ if (!Port->Front[0])
+ return FALSE;
+
+ ViaHQVFetch(Swov, Port);
+
+ /* Back Buffer: HQV destination and Video3 source. */
+ Port->Back[0] = ViaMemAlloc(pScrn, BackSize, 16);
+ Port->Back[1] = ViaMemAlloc(pScrn, BackSize, 16);
+ if (!Port->Back[0] || !Port->Back[1])
+ return FALSE;
+
+ /* This one may fail. */
+ Port->Front[1] = ViaMemAlloc(pScrn, FrontSize, 16);
+ if (!Port->Front[1]) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "%s: Not enough memory available.\n",
+ __FUNCTION__);
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "%s: Using only a single front buffer.\n",
+ __FUNCTION__);
+
+ Swov->HQV->SrcAddressY = Port->Front[0]->Base;
+ if (Port->CrOffset) {
+ Swov->HQV->SrcAddressU = Port->Front[0]->Base + Port->CbOffset;
+ Swov->HQV->SrcAddressV = Port->Front[0]->Base + Port->CrOffset;
}
- xfree(Swov->Adaptor);
}
- if (Swov->Adaptors)
- xfree(Swov->Adaptors);
+ /* This one may fail too. */
+ if (Swov->ThreeHQVBuffer) {
+ Port->Back[2] = ViaMemAlloc(pScrn, BackSize, 16);
+ if (!Port->Back[2]) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "%s: Not enough memory available.\n",
+ __FUNCTION__);
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "%s: Using only 2 back buffers.\n",
+ __FUNCTION__);
+ }
+ }
+
+ Swov->HQV->DstAddress0 = Port->Back[0]->Base;
+ Swov->HQV->DstAddress1 = Port->Back[1]->Base;
+ if (Port->Back[2])
+ Swov->HQV->DstAddress2 = Port->Back[2]->Base;
+
+ ViaSwovStride(Swov, Port);
+
+ return TRUE;
}
-static struct ViaXvPort *
-ViaXvPortInit(ScreenPtr pScreen)
+/*
+ *
+ */
+static void
+ViaSwovSurfaceDestroy(ScrnInfoPtr pScrn)
{
- struct ViaXvPort *Port = xnfcalloc(1, sizeof(struct ViaXvPort));
-
- Port->ColorKey = 0x821;
- Port->autoPaint = TRUE;
- Port->brightness = 5000.;
- Port->saturation = 10000;
- Port->contrast = 10000;
- Port->hue = 0;
- Port->Opacity = 0;
+ struct ViaSwov *Swov = VIAPTR(pScrn)->Swov;
+ struct ViaXvPort *Port = Swov->Port;
-#ifdef X_USE_REGION_NULL
- REGION_NULL(pScreen, &Port->clip);
-#else
- REGION_INIT(pScreen, &Port->clip, NullBox, 1);
-#endif
+ VIAFUNC(pScrn->scrnIndex);
- /* init ViaMem pointers */
+ Port->FourCC = 0;
Port->Width = 0;
Port->Height = 0;
+ if (Port->Front[0])
+ ViaMemFree(pScrn, Port->Front[0]);
+ if (Port->Front[1])
+ ViaMemFree(pScrn, Port->Front[1]);
+ if (Port->Back[0])
+ ViaMemFree(pScrn, Port->Back[0]);
+ if (Port->Back[1])
+ ViaMemFree(pScrn, Port->Back[1]);
+ if (Port->Back[2])
+ ViaMemFree(pScrn, Port->Back[2]);
+ if (Port->Alpha[0])
+ ViaMemFree(pScrn, Port->Alpha[0]);
+ if (Port->Alpha[1])
+ ViaMemFree(pScrn, Port->Alpha[1]);
+
Port->Front[0] = NULL;
Port->Front[1] = NULL;
Port->Back[0] = NULL;
@@ -1739,263 +1202,407 @@ ViaXvPortInit(ScreenPtr pScreen)
Port->Back[2] = NULL;
Port->Alpha[0] = NULL;
Port->Alpha[1] = NULL;
+}
- /* attribute? */
- Port->Deinterlace = VIA_DEINT_INTERLEAVE;
+/*
+ * I've ditched all the FourCC stuff here. It's HQV->Video3 anyway.
+ * When not YV12 (amazingly), the FIFO was set set to
+ * (depth, prethreshold, threshhold) (1,0,0) when Width <= 8
+ */
+static void
+ViaSwovFIFO(VIAPtr pVia, struct ViaSwov *Swov)
+{
+ CARD8 depth, prethreshold, threshold;
- Port->Src_X = 0;
- Port->Src_Y = 0;
- Port->Src_W = 0;
- Port->Src_H = 0;
+ switch (pVia->Chipset) {
+ case VIA_CLE266:
+ if (CLE266_REV_IS_CX(pVia->ChipRev)) {
+ depth = 64;
+ prethreshold = 56;
+ threshold = 56;
+ Swov->Video->Video3Control |= V3_EXPIRE_NUM_F;
+ } else { /* CLE266Ax */
+ depth = 32;
+ prethreshold = 16;
+ threshold = 8;
+ Swov->Video->Video3Control |= V3_EXPIRE_NUM;
+ }
+ break;
+ case VIA_KM400:
+ case VIA_K8M800:
+ depth = 32;
+ prethreshold = 29;
+ threshold = 29;
+ Swov->Video->Video3Control |= V3_EXPIRE_NUM_3205;
+ break;
+ default:
+ depth = 1;
+ prethreshold = 0;
+ threshold = 0;
+ break;
+ }
- Port->Drw_X = 0;
- Port->Drw_Y = 0;
- Port->Drw_W = 0;
- Port->Drw_H = 0;
+ Swov->Video->Video3AlphaFifo &= ~V3_FIFO_MASK;
+ Swov->Video->Video3AlphaFifo |= ((depth - 1) & 0xff) | ((threshold & 0xff) << 8);
- return Port;
+ Swov->Video->Video3AlphaPreFifo &= ~V3_PREFIFO_MASK;
+ Swov->Video->Video3AlphaPreFifo |= (prethreshold & 0x7f);
}
-static XF86VideoAdaptorPtr
-ViaXvAdaptorInit(ScrnInfoPtr pScrn)
+/*
+ *
+ */
+static void
+ViaHQVInit(struct ViaSwov *Swov)
{
- XF86VideoAdaptorPtr Adaptor;
+ struct ViaXvPort *Port = Swov->Port;
- VIAFUNC(pScrn->scrnIndex);
+ Swov->HQV->Control = HQV_SRC_SW;
+ /* not CLE266Ax could need |= HQV_ENABLE | HQV_SW_FLIP */
- Adaptor = xf86XVAllocateVideoAdaptorRec(pScrn);
-
- Adaptor->type = XvInputMask | XvWindowMask | XvImageMask |
- XvVideoMask | XvStillMask;
- Adaptor->flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT;
-
- Adaptor->name = "XV_SWOV";
- Adaptor->nEncodings = 1;
- Adaptor->pEncodings = DummyEncoding;
- Adaptor->nFormats = sizeof(FormatsG) / sizeof(FormatsG[0]);
- Adaptor->pFormats = FormatsG;
-
- Adaptor->nPorts = 1;
- Adaptor->pPortPrivates = (DevUnion *)xnfcalloc(1, sizeof(DevUnion));
- Adaptor->pPortPrivates->ptr = VIAPTR(pScrn)->Swov->Port;
- Adaptor->nAttributes = NUM_ATTRIBUTES_G;
- Adaptor->pAttributes = AttributesG;
+ switch (Port->FourCC) {
+ case FOURCC_YV12:
+ case FOURCC_I420:
+ Swov->HQV->Control |= HQV_YUV420;
+ break;
+ case FOURCC_YUY2:
+ Swov->HQV->Control |= HQV_YUV422;
+ break;
+ case FOURCC_RV15:
+ Swov->HQV->Control |= HQV_RGB15;
+ break;
+ case FOURCC_RV16:
+ Swov->HQV->Control |= HQV_RGB16;
+ break;
+ case FOURCC_RV32:
+ Swov->HQV->Control |= HQV_RGB32;
+ break;
+ default:
+ xf86DrvMsg(Swov->scrnIndex, X_ERROR, "%s: Unhandled FourCC.\n",
+ __FUNCTION__);
+ }
- Adaptor->nImages = NUM_IMAGES_G;
- Adaptor->pImages = ImagesG;
- Adaptor->PutVideo = NULL;
- Adaptor->StopVideo = viaStopVideo;
- Adaptor->QueryBestSize = viaQueryBestSize;
- Adaptor->GetPortAttribute = viaGetPortAttribute;
- Adaptor->SetPortAttribute = viaSetPortAttribute;
- Adaptor->PutImage = viaPutImage;
- Adaptor->ReputImage = ViaSwovReputImage;
- Adaptor->QueryImageAttributes = viaQueryImageAttributes;
-
- return Adaptor;
+ /* why this flip stuff? -- Luc */
+ if (Port->Back[2]) {
+ Swov->HQV->Control &= ~HQV_SW_FLIP;
+ Swov->HQV->Control |= HQV_TRIPLE_BUFF | HQV_FLIP_STATUS;
+ }
+
+ /* For DCT450 test-BOB INTERLEAVE */
+ if ((Port->Deinterlace & VIA_DEINT_BOB)) {
+ Swov->HQV->Control |= HQV_FIELD_2_FRAME | HQV_DEINTERLACE;
+ if ((Port->Deinterlace & VIA_DEINT_INTERLEAVE))
+ Swov->HQV->Control |= HQV_FRAME_2_FIELD;
+ }
+
+ Swov->HQV->Control |= HQV_ENABLE;
}
-void
-ViaVideoInit(ScrnInfoPtr pScrn, ScreenPtr pScreen)
+/*
+ *
+ */
+static void
+ViaVideo3Init(struct ViaSwov *Swov)
{
- VIAPtr pVia = VIAPTR(pScrn);
- struct ViaSwov *Swov;
- XF86VideoAdaptorPtr adaptor[1], *adaptors[1];
- int num_adaptors;
+ struct ViaXvPort *Port = Swov->Port;
- VIAFUNC(pScrn->scrnIndex);
+ Swov->Video->Compose = V_COMMAND_LOAD_VBI | ALWAYS_SELECT_VIDEO;
+ Swov->Video->Video3Control = V3_COLORSPACE_SIGN | V3_YUV422| V3_SWAP_HW_HQV;
- num_adaptors = xf86XVListGenericAdaptors(pScrn, adaptors);
+ switch (Port->FourCC) {
+ case FOURCC_YV12:
+ case FOURCC_I420:
+ case FOURCC_YUY2:
+ Swov->Video->Video3Control |= V3_YUV422;
+ break;
+ case FOURCC_RV15:
+ Swov->Video->Video3Control |= V3_RGB15;
+ break;
+ case FOURCC_RV16:
+ Swov->Video->Video3Control |= V3_RGB16;
+ break;
+ case FOURCC_RV32:
+ Swov->Video->Video3Control |= V3_RGB32;
+ break;
+ default:
+ xf86DrvMsg(Swov->scrnIndex, X_ERROR, "%s: Unhandled FourCC.\n",
+ __FUNCTION__);
+ }
+}
- xvBrightness = MAKE_ATOM("XV_BRIGHTNESS");
- xvContrast = MAKE_ATOM("XV_CONTRAST");
- xvColorKey = MAKE_ATOM("XV_COLORKEY");
- xvHue = MAKE_ATOM("XV_HUE");
- xvSaturation = MAKE_ATOM("XV_SATURATION");
- xvAutoPaint = MAKE_ATOM("XV_AUTOPAINT_COLORKEY");
- xvOpacity = MAKE_ATOM("XV_OPACITY");
+/*
+ *
+ */
+static void
+ViaHQVSwovIdle(struct ViaSwov *Swov)
+{
+ int i;
- ViaSwovInit(pVia);
- Swov = pVia->Swov;
+ for (i = 0; i < 10; i++)
+ if (!(Swov->Video->Compose & V3_COMMAND_FIRE) &&
+ (Swov->HQV->Control & HQV_IDLE))
+ break;
+ else
+ usleep(1);
- Swov->Port = ViaXvPortInit(pScreen);
+ if (i) {
+ ViaDebug(Swov->scrnIndex, "%s: idle/fire wait: %d.\n", __FUNCTION__, i);
+ if (!(Swov->HQV->Control & HQV_IDLE))
+ xf86DrvMsg(Swov->scrnIndex, X_WARNING, "%s: HQV not idle.\n",
+ __FUNCTION__);
+ if ((Swov->Video->Compose & V3_COMMAND_FIRE))
+ xf86DrvMsg(Swov->scrnIndex, X_WARNING, "%s: Video3 still firing.\n",
+ __FUNCTION__);
+ }
- Swov->Adaptor = ViaXvAdaptorInit(pScrn);
- ViaVideoReset(Swov);
+}
- Swov->Adaptors = xalloc((num_adaptors + 1) * sizeof(XF86VideoAdaptorPtr*));
+/*
+ * Minify is done by the HQV entirely.
+ * Zoom is done by V3.
+ *
+ */
+static void
+ViaSwovZoomH(struct ViaSwov *Swov, struct ViaXvPort *Port)
+{
+ unsigned long tmp;
- if (num_adaptors)
- memcpy(Swov->Adaptors, adaptors, num_adaptors * sizeof(XF86VideoAdaptorPtr));
+ Swov->HQV->Minify &= 0xFFFF0000;
+ Swov->HQV->Filter &= 0xFFFF0000;
+ Swov->Video->Video3Zoom &= 0x0000FFFF;
+ Swov->Video->Video3Minify &= 0xF8FFFFFD;
- adaptor[0] = pVia->Swov->Adaptor;
- memcpy(Swov->Adaptors + num_adaptors, adaptor, sizeof(XF86VideoAdaptorPtr));
+ if (Port->Src_W == Port->Drw_W) { /* No zoom */
+ Swov->HQV->Filter |= HQV_H_HIPASS_F1_DEFAULT;
+ } else if (Port->Src_W < Port->Drw_W) { /* Zoom in */
- xf86XVScreenInit(pScreen, Swov->Adaptors, num_adaptors + 1);
- VIASetColorSpace(pVia);
+ tmp = Port->Src_W * 0x800 / Port->Drw_W;
+ Swov->Video->Video3Zoom |= ((tmp & 0x7ff) << 16) | V3_X_ZOOM_ENABLE;
+
+ Swov->Video->Video3Minify |= V3_X_INTERPOLY;
+ Swov->HQV->Filter |= HQV_H_HIPASS_F1_DEFAULT;
+
+ } else { /* Zoom out */
+ tmp = Port->Drw_W * 0x800 * 0x400 / Port->Src_W;
+ tmp = tmp / 0x400 + ((tmp & 0x3ff) ? 1 : 0);
+
+ Swov->HQV->Minify |= (tmp & 0x7ff) | HQV_H_MINIFY_ENABLE;
+
+ if (Port->Src_W > (4 * Port->Drw_W))
+ Swov->HQV->Filter |= HQV_H_TAP8_12221;
+ else
+ Swov->HQV->Filter |= HQV_H_TAP4_121;
+ Swov->HQV->Minify |= HQV_HDEBLOCK_FILTER;
+ }
}
-static void
-viaStopVideo(ScrnInfoPtr pScrn, pointer data, Bool exit)
+/*
+ *
+ */
+static void
+ViaSwovZoomV(struct ViaSwov *Swov, struct ViaXvPort *Port)
{
- struct ViaSwov *Swov = VIAPTR(pScrn)->Swov;
- struct ViaXvPort *Port = (struct ViaXvPort *)data;
+ unsigned long tmp;
+ short Src_H = Port->Src_H;
- VIAFUNC(pScrn->scrnIndex);
+ if ((Port->Deinterlace & VIA_DEINT_BOB) &&
+ !(Port->Deinterlace & VIA_DEINT_INTERLEAVE))
+ Src_H <<= 1;
- if (!Port->Opacity)
- REGION_EMPTY(pScrn->pScreen, &Port->clip);
+ Swov->HQV->Minify &= 0x0000FFFF;
+ Swov->HQV->Filter &= 0x0000FFFF;
+ Swov->Video->Video3Zoom &= 0xFFFF0000;
+ Swov->Video->Video3Minify &= 0xFFF8FFFA;
- /* Hide overlay */
- Swov->Video->Video3Control &= ~V3_ENABLE;
- Swov->Video->Compose |= V3_COMMAND_FIRE;
+ /* Setup Y zoom factor */
+ if (Src_H == Port->Drw_H) { /* No zoom */
+ Swov->HQV->Filter |= HQV_V_TAP4_121;
+ } else if (Src_H < Port->Drw_H) { /* Zoom in */
+ ScrnInfoPtr pScrn = xf86Screens[Swov->scrnIndex];
- if (exit) {
- ViaDebug(pScrn->scrnIndex, "%s: Exiting!\n", __FUNCTION__);
+ tmp = Src_H * 0x0400 / Port->Drw_H;
+ Swov->Video->Video3Zoom |= ((tmp & 0x3ff) | V3_Y_ZOOM_ENABLE);
- ViaSwovStop(pScrn);
- ViaSwovSurfaceDestroy(pScrn);
+ if ((VIAPTR(pScrn)->Chipset == VIA_CLE266) && (pScrn->currentMode->HDisplay > 1024))
+ /* Temporary fix for 2D bandwidth problem. 2002/08/01*/
+ Swov->Video->Video3Minify |= V3_YCBCR_INTERPOLY;
+ else
+ Swov->Video->Video3Minify |= V3_Y_INTERPOLY | V3_YCBCR_INTERPOLY;
- Port->Drw_X = 0;
- Port->Drw_Y = 0;
- Port->Drw_W = 0;
- Port->Drw_H = 0;
- }
+ Swov->HQV->Filter |= HQV_V_TAP4_121;
+ Swov->HQV->Filter &= ~HQV_V_LOWPASS_4TAP;
+ } else { /* Zoom out */
+ tmp = Port->Drw_H * 0x0800 * 0x400 / Src_H;
+ tmp = tmp / 0x400 + ((tmp & 0x3ff) ? 1 : 0);
+ Swov->HQV->Minify |= ((tmp & 0x7ff) << 16) | HQV_V_MINIFY_ENABLE;
+
+ if (Src_H > (4 * Port->Drw_H))
+ Swov->HQV->Filter |= HQV_V_TAP8_12221;
+ else
+ Swov->HQV->Filter |= HQV_V_TAP4_121;
+ Swov->HQV->Minify |= HQV_VDEBLOCK_FILTER;
+ }
}
-static int
-viaSetPortAttribute(ScrnInfoPtr pScrn, Atom attribute, INT32 value, pointer data)
+/*
+ * Returns FALSE when the overlay is not currently visible.
+ */
+static Bool
+ViaSwovVisibleH(ScrnInfoPtr pScrn, struct ViaXvPort *Port)
{
- VIAPtr pVia = VIAPTR(pScrn);
- struct ViaXvPort *Port = (struct ViaXvPort *) data;
+ struct ViaSwov *Swov = VIAPTR(pScrn)->Swov;
+ short limit;
+ long temp;
+ CARD32 Fetch;
+ short Src_X, Src_W, Dst_X, Dst_W;
- if (attribute == xvColorKey) {
- Port->ColorKey = value;
+ /* Horizontal */
+ if (pScrn->currentMode->HDisplay < 2047)
+ limit = pScrn->currentMode->HDisplay;
+ else
+ limit = 2047;
- if (!Port->Opacity) {
- ViaSwovColorKey(pScrn, value);
- REGION_EMPTY(pScrn->pScreen, &Port->clip);
- }
- return Success;
- } else if (attribute == xvAutoPaint) {
- if (value)
- Port->autoPaint = TRUE;
- else
- Port->autoPaint = FALSE;
- return Success;
- } else if (attribute == xvBrightness) {
- Port->brightness = value;
- VIASetColorSpace(pVia);
- return Success;
- } else if (attribute == xvContrast) {
- Port->contrast = value;
- VIASetColorSpace(pVia);
- return Success;
- } else if (attribute == xvSaturation) {
- Port->saturation = value;
- VIASetColorSpace(pVia);
- return Success;
- } else if (attribute == xvHue) {
- Port->hue = value;
- VIASetColorSpace(pVia);
- return Success;
- } else if (attribute == xvOpacity) {
- if ((value < 0) || (value > 15))
- return BadValue;
+ if (((Port->Drw_X + Port->Drw_W) < pScrn->frameX0) ||
+ (Port->Drw_X > (limit + pScrn->frameX0)))
+ return FALSE;
- if (pVia->Swov->Active)
- ViaSwovAlphaSet(pScrn, value);
- else
- Port->Opacity = value;
- return Success;
- }
+ Src_X = Port->Src_X;
+ Dst_W = Port->Drw_W;
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "%s: Unhandled attribute.\n",
- __FUNCTION__);
- return BadMatch;
-}
+ if (Port->Drw_X < pScrn->frameX0) {
+ temp = (pScrn->frameX0 - Port->Drw_X) * Port->Src_W;
+ temp += Port->Drw_W >> 1;
+ Src_X += temp / Port->Drw_W;
-static int
-viaGetPortAttribute(ScrnInfoPtr pScrn, Atom attribute, INT32 *value, pointer data)
-{
- struct ViaXvPort *Port = (struct ViaXvPort *) data;
+ Dst_W -= pScrn->frameX0 - Port->Drw_X;
+ Dst_X = 0;
+ } else
+ Dst_X = Port->Drw_X - pScrn->frameX0;
- if (attribute == xvColorKey) {
- *value =(INT32) Port->ColorKey;
- return Success;
- } else if (attribute == xvAutoPaint) {
- if (Port->autoPaint)
- *value = 1;
+ if ((Dst_X + Dst_W) > limit)
+ Dst_W = limit - Dst_X;
+
+ if (Dst_W != Port->Drw_W) {
+ temp = Dst_W * Port->Src_W;
+ temp += Port->Drw_W >> 1;
+ Src_W = temp / Port->Drw_W;
+ } else
+ Src_W = Port->Src_W;
+
+ /* set up window */
+ Swov->Video->Video3WindowEnd &= 0x0000FFFF;
+ Swov->Video->Video3WindowEnd |= (Dst_X + Dst_W - 1) << 16;
+
+ Swov->Video->Video3WindowStart &= 0x0000FFFF;
+ Swov->Video->Video3WindowStart |= Dst_X << 16;
+
+ /* set up Fetch */
+ if (Port->FourCC == FOURCC_RV32) {
+ if (Dst_W >= Src_W)
+ Fetch = (ALIGN_TO(Src_W << 2, 16) >> 4) + 1;
else
- *value = 0;
- return Success;
- } else if (attribute == xvBrightness) {
- *value = Port->brightness;
- return Success;
- } else if (attribute == xvContrast) {
- *value = Port->contrast;
- return Success;
- } else if (attribute == xvSaturation) {
- *value = Port->saturation;
- return Success;
- } else if (attribute == xvHue) {
- *value = Port->hue;
- return Success;
- } else if (attribute == xvOpacity) {
- *value = Port->Opacity;
- return Success;
+ Fetch = (ALIGN_TO(Dst_W << 2, 16) >> 4) + 1;
+ } else {
+ if (Dst_W >= Src_W)
+ Fetch = (ALIGN_TO(Src_W << 1, 16) >> 4) + 1;
+ else
+ Fetch = (ALIGN_TO(Dst_W << 1, 16) >> 4) + 1;
}
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "%s: Unhandled attribute.\n",
- __FUNCTION__);
- *value = 0;
- return BadMatch;
-}
+ /* Fix planar mode problem. */
+ if (Fetch < 4)
+ Fetch = 4;
-static void
-viaQueryBestSize(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)
-{
- *p_w = drw_w;
- *p_h = drw_h;
-
- if (*p_w > 2048 )
- *p_w = 2048;
+ Swov->Video->Video3AlphaFetch &= ~V3_FETCH_COUNT;
+ Swov->Video->Video3AlphaFetch |= Fetch << 20;
+
+ Swov->Video->Video3SrcWidth = Src_W - 1;
+
+ /* for startAddress offset */
+ Port->Offset_X = Src_X;
+
+ /* for alpha */
+ Port->Win_X = Dst_X;
+ Port->Win_W = Dst_W;
+
+ return TRUE;
}
-/* Newer X versions have this built in, but debian xfree86-4.3.0 doesn't. */
-#ifndef REGION_EQUAL
+/*
+ *
+ */
static Bool
-RegionsEqual(ScreenPtr pScreen, RegionPtr A, RegionPtr B)
+ViaSwovVisibleV(ScrnInfoPtr pScrn, struct ViaXvPort *Port)
{
- int *dataA, *dataB;
- int num;
+ struct ViaSwov *Swov = VIAPTR(pScrn)->Swov;
+ short limit;
+ long temp;
+ short Src_Y, Dst_Y, Dst_H;
- num = REGION_NUM_RECTS(A);
- if(num != REGION_NUM_RECTS(B))
- return FALSE;
+ if (pScrn->currentMode->VDisplay < 2047)
+ limit = pScrn->currentMode->VDisplay;
+ else
+ limit = 2047;
- 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))
+ if (((Port->Drw_Y + Port->Drw_H) < pScrn->frameY0) ||
+ (Port->Drw_Y > (limit + pScrn->frameY0)))
return FALSE;
- dataA = (int*)REGION_RECTS(A);
- dataB = (int*)REGION_RECTS(B);
+ Src_Y = Port->Src_Y;
+ Dst_H = Port->Drw_H;
+
+ if (Port->Drw_Y < pScrn->frameY0) {
+ /* Round down. */
+ temp = (pScrn->frameY0 - Port->Drw_Y) * Port->Src_H;
+ Src_Y += temp / Port->Drw_H;
+
+ Dst_H -= pScrn->frameY0 - Port->Drw_Y;
+ Dst_Y = 0;
+ } else
+ Dst_Y = Port->Drw_Y - pScrn->frameY0;
+
+ if ((Dst_Y + Dst_H) > limit)
+ Dst_H = limit - Dst_Y;
+
+ /* set up window */
+ Swov->Video->Video3WindowEnd &= 0xFFFF0000;
+ Swov->Video->Video3WindowEnd |= Dst_Y + Dst_H - 1;
+
+ Swov->Video->Video3WindowStart &= 0xFFFF0000;
+ Swov->Video->Video3WindowStart |= Dst_Y;
+
+ /* for startAddress offset */
+ Port->Offset_Y = Src_Y;
+
+ /* for alpha */
+ Port->Win_Y = Dst_Y;
+ Port->Win_H = Dst_H;
- while(num--) {
- if((dataA[0] != dataB[0]) || (dataA[1] != dataB[1]))
- return FALSE;
- dataA += 2;
- dataB += 2;
- }
-
return TRUE;
}
-#define REGION_EQUAL(_pScreen, _pReg1, _pReg2) RegionsEqual((_pScreen), (_pReg1), (_pReg2))
-#endif /* !REGION_EQUAL */
+
+/*
+ *
+ */
+static void
+ViaSwovStartAddress(struct ViaSwov *Swov, struct ViaXvPort *Port)
+{
+ unsigned long Offset;
+
+ Offset = Port->Offset_Y * Port->Width + Port->Offset_X;
+
+ if (Port->FourCC == FOURCC_RV32)
+ Offset <<= 2;
+ else
+ Offset <<= 1;
+
+ /* Warning: hardware rounds down to the nearest 16bytes */
+
+ Swov->Video->Video3Address0 = Port->Back[0]->Base + Offset;
+ Swov->Video->Video3Address1 = Port->Back[1]->Base + Offset;
+ if (Port->Back[2])
+ Swov->Video->Video3Address2 = Port->Back[2]->Base + Offset;
+}
/*
*
@@ -2049,33 +1656,113 @@ ViaSwovWindow(ScrnInfoPtr pScrn, short src_x, short src_y, short drw_x,
return FALSE;
}
-
+
+/*
+ * Newer X versions have this built in, but debian xfree86-4.3.0 doesn't.
+ */
+#ifndef REGION_EQUAL
+static Bool
+RegionsEqual(ScreenPtr pScreen, 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;
+ }
+
+ return TRUE;
+}
+#define REGION_EQUAL(_pScreen, _pReg1, _pReg2) RegionsEqual((_pScreen), (_pReg1), (_pReg2))
+#endif /* !REGION_EQUAL */
+
+/*
+ *
+ */
static void
-ViaVideo3Init(struct ViaSwov *Swov)
+ViaSwovCopy(VIAPtr pVia, struct ViaMem *Mem, unsigned char *buf)
{
+#if 0
+ xf86memcpy(pVia->FBBase + Mem->Base, buf, Mem->Size);
+#else
+ {
+ CARD32 *Dst = (CARD32 *) (pVia->FBBase + Mem->Base);
+ CARD32 *End = (CARD32 *) (pVia->FBBase + Mem->Base + Mem->Size);
+ CARD32 *Src = (CARD32 *) buf;
+
+ while (Dst < End) {
+ *Dst = *Src;
+ Dst++;
+ Src++;
+ }
+ }
+#endif
+}
+
+/*
+ *
+ */
+static void
+ViaHQVFlip(VIAPtr pVia, unsigned char* buf)
+{
+ struct ViaSwov *Swov = pVia->Swov;
struct ViaXvPort *Port = Swov->Port;
+ int i;
- Swov->Video->Compose = V_COMMAND_LOAD_VBI | ALWAYS_SELECT_VIDEO;
- Swov->Video->Video3Control = V3_COLORSPACE_SIGN | V3_YUV422| V3_SWAP_HW_HQV;
+ for (i = 0; i < 15; i++)
+ if (!(Swov->HQV->Control & HQV_SW_FLIP))
+ break;
+ else
+ usleep(1);
- switch (Port->FourCC) {
- case FOURCC_YV12:
- case FOURCC_I420:
- case FOURCC_YUY2:
- Swov->Video->Video3Control |= V3_YUV422;
- break;
- case FOURCC_RV15:
- Swov->Video->Video3Control |= V3_RGB15;
- break;
- case FOURCC_RV16:
- Swov->Video->Video3Control |= V3_RGB16;
- break;
- case FOURCC_RV32:
- Swov->Video->Video3Control |= V3_RGB32;
- break;
- default:
- xf86DrvMsg(Swov->scrnIndex, X_ERROR, "%s: Unhandled FourCC.\n",
- __FUNCTION__);
+ if (i) {
+ ViaDebug(Swov->scrnIndex, "%s: flip wait: %d.\n", __FUNCTION__, i);
+ if ((Swov->HQV->Control & HQV_SW_FLIP))
+ xf86DrvMsg(Swov->scrnIndex, X_WARNING, "%s: HQV is still flipping.\n",
+ __FUNCTION__);
+ }
+
+ if (!Port->Front[1]) /* single buffering */
+ ViaSwovCopy(pVia, Port->Front[0], buf);
+ else { /* We only need to set the address */
+ Swov->HQV->SrcAddressY = Port->Front[0]->Base;
+ if (Port->CrOffset) {
+ Swov->HQV->SrcAddressU = Port->Front[0]->Base + Port->CbOffset;
+ Swov->HQV->SrcAddressV = Port->Front[0]->Base + Port->CrOffset;
+ }
+ }
+
+ Swov->HQV->Control |= HQV_SW_FLIP | HQV_FLIP_STATUS;
+
+ /* Before we fire V3 for the first time, wait. */
+ if (!Swov->Active) {
+ for (i = 0; i < 15; i++)
+ if ((Swov->HQV->Control & HQV_FLIP_STATUS))
+ break;
+ else
+ usleep(1);
+ if (i) {
+ ViaDebug(Swov->scrnIndex, "%s: status wait: %d.\n", __FUNCTION__, i);
+ if (!(Swov->HQV->Control & HQV_FLIP_STATUS))
+ xf86DrvMsg(Swov->scrnIndex, X_WARNING, "%s: Unable to initialise"
+ " the HQV. (Status still not set)\n", __FUNCTION__);
+ }
}
}
@@ -2195,6 +1882,75 @@ viaPutImage(ScrnInfoPtr pScrn, short src_x, short src_y, short drw_x,
}
/*
+ * This doesn't fix the case where the overlay window was not
+ * in the visible frame when switching away. That one requires
+ * some DIX poking.
+ */
+static int
+ViaSwovReputImage(ScrnInfoPtr pScrn, short drw_x, short drw_y,
+ RegionPtr clipBoxes, pointer data)
+{
+ struct ViaSwov *Swov = VIAPTR(pScrn)->Swov;
+ struct ViaXvPort *Port = Swov->Port;
+ Bool HVisible = TRUE, VVisible = TRUE;
+
+ if (!Swov->Active) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "%s: Overlay not active.\n",
+ __FUNCTION__);
+ return BadAccess;
+ }
+
+ /* redraw colorkey when needed -- does this ever get hit here? */
+ if (!REGION_EQUAL(pScrn->pScreen, &Port->clip, clipBoxes)) {
+ REGION_COPY(pScrn->pScreen, &Port->clip, clipBoxes);
+ if (Port->autoPaint && !Port->Opacity)
+ xf86XVFillKeyHelper(pScrn->pScreen, Port->ColorKey, clipBoxes);
+ }
+
+ /* FrameAdjust is usually in only a single direction */
+ if ((pScrn->frameX0 != Swov->frameX0) || (drw_x != Port->Drw_X)) {
+ Port->Drw_X = drw_x;
+ HVisible = ViaSwovVisibleH(pScrn, Swov->Port);
+ }
+
+ if ((pScrn->frameY0 != Swov->frameY0) || (drw_y != Port->Drw_Y)) {
+ Port->Drw_Y = drw_y;
+ VVisible = ViaSwovVisibleV(pScrn, Swov->Port);
+ }
+
+ if (HVisible && VVisible) {
+ ViaSwovStartAddress(Swov, Swov->Port);
+ Swov->Video->Video3Control |= V3_ENABLE;
+ } else
+ Swov->Video->Video3Control &= ~V3_ENABLE;
+
+ if (Port->Opacity)
+ ViaSwovAlphaPosition(pScrn);
+
+ Swov->Video->Compose |= V3_COMMAND_FIRE;
+
+ Swov->frameX0 = pScrn->frameX0;
+ Swov->frameY0 = pScrn->frameY0;
+
+ return Success;
+}
+
+/*
+ *
+ */
+static void
+viaQueryBestSize(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)
+{
+ *p_w = drw_w;
+ *p_h = drw_h;
+
+ if (*p_w > 2048 )
+ *p_w = 2048;
+}
+
+/*
*
*/
static int
@@ -2202,15 +1958,15 @@ viaQueryImageAttributes(ScrnInfoPtr pScrn, int FourCC, CARD16 *Width,
CARD16 *Height, int *pitches, int *offsets)
{
int Size;
-
+
if (!Width || !Height)
return 0;
-
+
if (*Width > VIA_MAX_XVIMAGE_X)
*Width = VIA_MAX_XVIMAGE_X;
if (*Height > VIA_MAX_XVIMAGE_Y)
*Height = VIA_MAX_XVIMAGE_Y;
-
+
switch (FourCC) {
case FOURCC_YV12: /* YUV420 */
case FOURCC_I420:
@@ -2266,63 +2022,353 @@ viaQueryImageAttributes(ScrnInfoPtr pScrn, int FourCC, CARD16 *Width,
*Height = 0;
return 0;
}
-
+
return Size;
}
+/*
+ *
+ */
+static void
+ViaVideoReset(struct ViaSwov *Swov)
+{
+ VIAFUNC(Swov->scrnIndex);
+
+ Swov->Video->Video1Control = 0;
+ Swov->Video->Video3Control = 0;
+ Swov->Video->Compose = 0x80000000;
+ Swov->Video->Compose = 0x40000000;
+ Swov->Video->ColorKey = 0x821;
+ Swov->Video->ColorKeySecond = 0x00000000;
+ Swov->Video->Video3ColorKey = 0x00000000;
+ Swov->Video->AlphaControl = 0x001FF000;
+}
+
+/*
+ *
+ */
+void
+ViaVideoSave(struct ViaSwov *Swov)
+{
+ VIAFUNC(Swov->scrnIndex);
+
+ Swov->Video1Control = Swov->Video->Video1Control;
+ Swov->Video3Control = Swov->Video->Video3Control;
+ Swov->Video->Video1Control = 0;
+ Swov->Video->Video3Control = 0;
+ Swov->Video->Compose = 0x80000000;
+ Swov->Video->Compose = 0x40000000;
+}
/*
- * This doesn't fix the case where the overlay window was not
- * in the visible frame when switching away. That one requires
- * some DIX poking.
+ *
*/
-static int
-ViaSwovReputImage(ScrnInfoPtr pScrn, short drw_x, short drw_y,
- RegionPtr clipBoxes, pointer data)
+void
+ViaVideoRestore(struct ViaSwov *Swov)
+{
+ VIAFUNC(Swov->scrnIndex);
+
+ Swov->Video->Video1Control = Swov->Video1Control;
+ Swov->Video->Video3Control = Swov->Video3Control;
+ Swov->Video->Compose = 0x80000000;
+ Swov->Video->Compose = 0x40000000;
+}
+
+/*
+ *
+ */
+static void
+ViaSwovStop(ScrnInfoPtr pScrn)
{
struct ViaSwov *Swov = VIAPTR(pScrn)->Swov;
- struct ViaXvPort *Port = Swov->Port;
- Bool HVisible = TRUE, VVisible = TRUE;
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
- if (!Swov->Active) {
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "%s: Overlay not active.\n",
- __FUNCTION__);
- return BadAccess;
- }
+ VIAFUNC(pScrn->scrnIndex);
- /* redraw colorkey when needed -- does this ever get hit here? */
- if (!REGION_EQUAL(pScrn->pScreen, &Port->clip, clipBoxes)) {
- REGION_COPY(pScrn->pScreen, &Port->clip, clipBoxes);
- if (Port->autoPaint && !Port->Opacity)
- xf86XVFillKeyHelper(pScrn->pScreen, Port->ColorKey, clipBoxes);
- }
+ if (Swov->HQVDisablePatch)
+ ViaSeqMask(hwp, 0x2E, 0x00, 0x10);
- /* FrameAdjust is usually in only a single direction */
- if ((pScrn->frameX0 != Swov->frameX0) || (drw_x != Port->Drw_X)) {
- Port->Drw_X = drw_x;
- HVisible = ViaSwovVisibleH(pScrn, Swov->Port);
- }
+ Swov->Video->Video3AlphaFifo = ALPHA_FIFO_THRESHOLD4 | ALPHA_FIFO_DEPTH8
+ | 0x00002431; /* threshold 24, depth 32 */
- if ((pScrn->frameY0 != Swov->frameY0) || (drw_y != Port->Drw_Y)) {
- Port->Drw_Y = drw_y;
- VVisible = ViaSwovVisibleV(pScrn, Swov->Port);
+ Swov->HQV->Control &= ~HQV_ENABLE;
+
+ if (Swov->HQVDisablePatch)
+ ViaSeqMask(hwp, 0x2E, 0x10, 0x10);
+
+ /* disable alpha too */
+ Swov->Video->AlphaControl = 0x001FF000;
+
+ Swov->Active = FALSE;
+}
+
+/*
+ *
+ */
+void
+ViaVideoExit(ScrnInfoPtr pScrn)
+{
+ struct ViaSwov *Swov = VIAPTR(pScrn)->Swov;
+
+ VIAFUNC(Swov->scrnIndex);
+
+ if (Swov->Active)
+ ViaSwovStop(pScrn);
+
+ if (Swov->Port->Front[0])
+ ViaSwovSurfaceDestroy(pScrn);
+
+ Swov->Video->Video1Control = 0;
+ Swov->Video->Video3Control = 0;
+ Swov->Video->Compose = 0x80000000;
+ Swov->Video->Compose = 0x40000000;
+ Swov->Video->AlphaControl = 0x001FF000;
+
+ /* Free all adapter info allocated in viaInitVideo. */
+ if (Swov->Adaptor) {
+ if (Swov->Adaptor->pPortPrivates) {
+ if (Swov->Adaptor->pPortPrivates->ptr)
+ xfree(Swov->Adaptor->pPortPrivates->ptr);
+ xfree(Swov->Adaptor->pPortPrivates);
+ }
+ xfree(Swov->Adaptor);
}
- if (HVisible && VVisible) {
- ViaSwovStartAddress(Swov, Swov->Port);
- Swov->Video->Video3Control |= V3_ENABLE;
- } else
- Swov->Video->Video3Control &= ~V3_ENABLE;
+ if (Swov->Adaptors)
+ xfree(Swov->Adaptors);
+}
- if (Port->Opacity)
- ViaSwovAlphaPosition(pScrn);
+/*
+ *
+ */
+static void
+viaStopVideo(ScrnInfoPtr pScrn, pointer data, Bool exit)
+{
+ struct ViaSwov *Swov = VIAPTR(pScrn)->Swov;
+ struct ViaXvPort *Port = (struct ViaXvPort *)data;
+
+ VIAFUNC(pScrn->scrnIndex);
+ if (!Port->Opacity)
+ REGION_EMPTY(pScrn->pScreen, &Port->clip);
+
+ /* Hide overlay */
+ Swov->Video->Video3Control &= ~V3_ENABLE;
Swov->Video->Compose |= V3_COMMAND_FIRE;
- Swov->frameX0 = pScrn->frameX0;
- Swov->frameY0 = pScrn->frameY0;
+ if (exit) {
+ ViaDebug(pScrn->scrnIndex, "%s: Exiting!\n", __FUNCTION__);
- return Success;
+ ViaSwovStop(pScrn);
+ ViaSwovSurfaceDestroy(pScrn);
+
+ Port->Drw_X = 0;
+ Port->Drw_Y = 0;
+ Port->Drw_W = 0;
+ Port->Drw_H = 0;
+ }
+}
+
+/*
+ *
+ */
+static void
+ViaSwovInit(VIAPtr pVia)
+{
+ struct ViaSwov *Swov = pVia->Swov;
+
+ VIAFUNC(pVia->scrnIndex);
+
+ Swov->scrnIndex = pVia->scrnIndex;
+
+ Swov->Allowed = FALSE;
+ Swov->Active = FALSE;
+
+ Swov->Adaptor = NULL;
+ Swov->Adaptors = NULL;
+
+ /* Set up memory Map */
+ Swov->Video = (struct ViaVideoRegs *) (pVia->MapBase + 0x200);
+ Swov->HQV = (struct ViaHQVRegs *) (pVia->MapBase + 0x3D0);
+
+#ifdef HAVE_DEBUG
+ if (pVia->PrintSwovRegs)
+ ViaSwovPrintRegs(Swov);
+#endif
+
+ /* make sure that nothing is active -- we might have an unclean state */
+ Swov->Video->Video1Control &= ~0x00000001;
+ Swov->Video->Video3Control &= ~0x00000001;
+ Swov->HQV->Control &= ~0x08000000;
+ Swov->Video->AlphaControl = 0x001FF000;
+
+ /* old HWDiff stuff */
+ switch(pVia->Chipset) {
+ case VIA_CLE266:
+ if (CLE266_REV_IS_AX(pVia->ChipRev)) {
+ Swov->ThreeHQVBuffer = FALSE;
+ Swov->HQVFetchByteUnit = TRUE;
+ Swov->HQVDisablePatch = FALSE;
+ } else {
+ Swov->ThreeHQVBuffer = TRUE;
+ Swov->HQVFetchByteUnit = FALSE;
+ Swov->HQVDisablePatch = TRUE;
+ }
+ break;
+ case VIA_KM400:
+ Swov->ThreeHQVBuffer = TRUE;
+ Swov->HQVFetchByteUnit = FALSE;
+ Swov->HQVDisablePatch = TRUE;
+ break;
+ case VIA_K8M800:
+ Swov->ThreeHQVBuffer = TRUE;
+ Swov->HQVFetchByteUnit = FALSE;
+ Swov->HQVDisablePatch = TRUE;
+ break;
+ case VIA_PM800:
+ Swov->ThreeHQVBuffer = TRUE;
+ Swov->HQVFetchByteUnit = FALSE;
+ Swov->HQVDisablePatch = FALSE;
+ break;
+ default:
+ xf86DrvMsg(pVia->scrnIndex, X_ERROR, "%s: Unhandled ChipSet.\n",
+ __FUNCTION__);
+ }
+}
+
+/*
+ *
+ */
+static struct ViaXvPort *
+ViaXvPortInit(ScreenPtr pScreen)
+{
+ struct ViaXvPort *Port = xnfcalloc(1, sizeof(struct ViaXvPort));
+
+ Port->ColorKey = 0x821;
+ Port->autoPaint = TRUE;
+ Port->brightness = 5000.;
+ Port->saturation = 10000;
+ Port->contrast = 10000;
+ Port->hue = 0;
+ Port->Opacity = 0;
+
+#ifdef X_USE_REGION_NULL
+ REGION_NULL(pScreen, &Port->clip);
+#else
+ REGION_INIT(pScreen, &Port->clip, NullBox, 1);
+#endif
+
+ /* init ViaMem pointers */
+ Port->Width = 0;
+ Port->Height = 0;
+
+ Port->Front[0] = NULL;
+ Port->Front[1] = NULL;
+ Port->Back[0] = NULL;
+ Port->Back[1] = NULL;
+ Port->Back[2] = NULL;
+ Port->Alpha[0] = NULL;
+ Port->Alpha[1] = NULL;
+
+ /* attribute? */
+ Port->Deinterlace = VIA_DEINT_INTERLEAVE;
+
+ Port->Src_X = 0;
+ Port->Src_Y = 0;
+ Port->Src_W = 0;
+ Port->Src_H = 0;
+
+ Port->Drw_X = 0;
+ Port->Drw_Y = 0;
+ Port->Drw_W = 0;
+ Port->Drw_H = 0;
+
+ return Port;
+}
+
+/*
+ *
+ */
+static XF86VideoAdaptorPtr
+ViaXvAdaptorInit(ScrnInfoPtr pScrn)
+{
+ XF86VideoAdaptorPtr Adaptor;
+
+ VIAFUNC(pScrn->scrnIndex);
+
+ Adaptor = xf86XVAllocateVideoAdaptorRec(pScrn);
+
+ Adaptor->type = XvInputMask | XvWindowMask | XvImageMask |
+ XvVideoMask | XvStillMask;
+ Adaptor->flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT;
+
+ Adaptor->name = "XV_SWOV";
+ Adaptor->nEncodings = 1;
+ Adaptor->pEncodings = DummyEncoding;
+ Adaptor->nFormats = sizeof(FormatsG) / sizeof(FormatsG[0]);
+ Adaptor->pFormats = FormatsG;
+
+ Adaptor->nPorts = 1;
+ Adaptor->pPortPrivates = (DevUnion *)xnfcalloc(1, sizeof(DevUnion));
+ Adaptor->pPortPrivates->ptr = VIAPTR(pScrn)->Swov->Port;
+ Adaptor->nAttributes = NUM_ATTRIBUTES_G;
+ Adaptor->pAttributes = AttributesG;
+
+ Adaptor->nImages = NUM_IMAGES_G;
+ Adaptor->pImages = ImagesG;
+ Adaptor->PutVideo = NULL;
+ Adaptor->StopVideo = viaStopVideo;
+ Adaptor->QueryBestSize = viaQueryBestSize;
+ Adaptor->GetPortAttribute = viaGetPortAttribute;
+ Adaptor->SetPortAttribute = viaSetPortAttribute;
+ Adaptor->PutImage = viaPutImage;
+ Adaptor->ReputImage = ViaSwovReputImage;
+ Adaptor->QueryImageAttributes = viaQueryImageAttributes;
+
+ return Adaptor;
+}
+
+/*
+ *
+ */
+void
+ViaVideoInit(ScrnInfoPtr pScrn, ScreenPtr pScreen)
+{
+ VIAPtr pVia = VIAPTR(pScrn);
+ struct ViaSwov *Swov;
+ XF86VideoAdaptorPtr adaptor[1], *adaptors[1];
+ int num_adaptors;
+
+ VIAFUNC(pScrn->scrnIndex);
+
+ num_adaptors = xf86XVListGenericAdaptors(pScrn, adaptors);
+
+ xvBrightness = MAKE_ATOM("XV_BRIGHTNESS");
+ xvContrast = MAKE_ATOM("XV_CONTRAST");
+ xvColorKey = MAKE_ATOM("XV_COLORKEY");
+ xvHue = MAKE_ATOM("XV_HUE");
+ xvSaturation = MAKE_ATOM("XV_SATURATION");
+ xvAutoPaint = MAKE_ATOM("XV_AUTOPAINT_COLORKEY");
+ xvOpacity = MAKE_ATOM("XV_OPACITY");
+
+ ViaSwovInit(pVia);
+ Swov = pVia->Swov;
+
+ Swov->Port = ViaXvPortInit(pScreen);
+
+ Swov->Adaptor = ViaXvAdaptorInit(pScrn);
+ ViaVideoReset(Swov);
+
+ Swov->Adaptors = xalloc((num_adaptors + 1) * sizeof(XF86VideoAdaptorPtr*));
+
+ if (num_adaptors)
+ memcpy(Swov->Adaptors, adaptors, num_adaptors * sizeof(XF86VideoAdaptorPtr));
+
+ adaptor[0] = pVia->Swov->Adaptor;
+ memcpy(Swov->Adaptors + num_adaptors, adaptor, sizeof(XF86VideoAdaptorPtr));
+
+ xf86XVScreenInit(pScreen, Swov->Adaptors, num_adaptors + 1);
+ VIASetColorSpace(pVia);
}
#endif /* !XvExtension */