summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuc Verhaegen <libv@skynet.be>2005-10-04 05:03:40 +0000
committerLuc Verhaegen <libv@skynet.be>2005-10-04 05:03:40 +0000
commita65a7ef1b7d2674e249486b166a71577070fc80b (patch)
tree636858e5010fbb39ef643396df8151bd8d71a7a6
parent4b1eb56e8b1ed4518bc7f295a569e7c3c34a869d (diff)
[devel-swov_fourcc_rgb]
- Add RV15, RV16 and RV32. - Check alignment for all fourccs. - Move ImageRec definitions to the start of via_video.c.
-rw-r--r--src/via_video.c333
1 files changed, 263 insertions, 70 deletions
diff --git a/src/via_video.c b/src/via_video.c
index a5037d9..3fb8369 100644
--- a/src/via_video.c
+++ b/src/via_video.c
@@ -59,9 +59,118 @@ void viaInitVideo(ScreenPtr pScreen) {}
#define ALIGN_TO(f, alignment) (((f) + ((alignment)-1)) & ~((alignment)-1))
-/* some HW dependant Pitch alignment */
-#define VIA_PITCH_ALIGN_YUV420 32
-#define VIA_PITCH_ALIGN_YUV422 32
+/*
+ * I'm unable to set the ordering of packed YUV, so only YUY2 is possible.
+ * A conversion routine could be implemented, but it is more efficient
+ * to let the client ignore/convert it. -- Luc.
+ */
+
+/*
+ * VIA seems to have it's RGB components reversed. RGBA tends to mean that
+ * A is the high byte and R the low. Sadly, VIA is not alone in this, and
+ * there is no consensus between devices here either.
+ *
+ * This severely reduces the chances of any inclusion in fourcc.h. But in
+ * case this does happen, ignore it and define our own. -- Luc.
+ */
+
+/*
+ * RGB 555
+ */
+#ifndef FOURCC_RV15
+#define FOURCC_RV15 0x35315652
+#endif
+
+#ifdef XVIMAGE_RV15
+#undef XVIMAGE_RV15
+#endif
+
+#define XVIMAGE_RV15 \
+ { \
+ FOURCC_RV15, \
+ XvRGB, \
+ LSBFirst, \
+ {'R','V','1','5'}, \
+ 16, \
+ XvPacked, \
+ 1, \
+ 15, \
+ 0x7C00, 0x03E0, 0x001F, \
+ 0, 0, 0, \
+ 0, 0, 0, \
+ 0, 0, 0, \
+ {'R','V','B' }, \
+ XvTopToBottom \
+ }
+
+/*
+ * RGB 565
+ */
+#ifndef FOURCC_RV16
+#define FOURCC_RV16 0x36315652
+#endif
+
+#ifdef XVIMAGE_RV16
+#undef XVIMAGE_RV16
+#endif
+
+#define XVIMAGE_RV16 \
+ { \
+ FOURCC_RV16, \
+ XvRGB, \
+ LSBFirst, \
+ {'R','V','1','6' }, \
+ 16, \
+ XvPacked, \
+ 1, \
+ 16, \
+ 0xF800, 0x07E0, 0x001F, \
+ 0, 0, 0, \
+ 0, 0, 0, \
+ 0, 0, 0, \
+ {'R','V','B' }, \
+ XvTopToBottom \
+ }
+
+/*
+ * RGB 888
+ */
+#ifndef FOURCC_RV32
+#define FOURCC_RV32 0x32335652
+#endif
+
+#ifdef XVIMAGE_RV32
+#undef XVIMAGE_RV32
+#endif
+
+#define XVIMAGE_RV32 \
+ { \
+ FOURCC_RV32, \
+ XvRGB, \
+ LSBFirst, \
+ { 'R', 'V' ,'3', '2' }, \
+ 32, \
+ XvPacked, \
+ 1, \
+ 24, \
+ 0xFF0000, 0x00FF00, 0x0000FF, \
+ 0, 0, 0, \
+ 0, 0, 0, \
+ 0, 0, 0, \
+ { 'R', 'V', 'B' }, \
+ XvTopToBottom \
+ }
+
+#define NUM_IMAGES_G 6
+static XF86ImageRec ImagesG[NUM_IMAGES_G] =
+{
+ XVIMAGE_YUY2,
+ XVIMAGE_YV12,
+ XVIMAGE_I420,
+ XVIMAGE_RV15,
+ XVIMAGE_RV16,
+ XVIMAGE_RV32
+};
#ifdef HAVE_DEBUG
/*
@@ -160,7 +269,7 @@ ViaSwovPrintRegs(struct ViaSwov *Swov)
*/
/*
- * Only needs to be altered when HQV front buffer size changes.
+ * Only needs to be altered when the Front buffer size changes.
*/
static void
ViaHQVFetch(struct ViaSwov *Swov, struct ViaXvPort *Port)
@@ -168,9 +277,24 @@ ViaHQVFetch(struct ViaSwov *Swov, struct ViaXvPort *Port)
CARD32 Fetch = Port->Width;
CARD32 Height = Port->Height;
- if (Port->FourCC == FOURCC_YUY2)
- Fetch <<= 1;
-
+ 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;
@@ -182,18 +306,35 @@ ViaHQVFetch(struct ViaSwov *Swov, struct ViaXvPort *Port)
}
/*
- * Only needs to be altered when the second buffer size changes.
+ * Only needs to be altered when the Back buffer size changes.
*/
static void
ViaSwovStride(struct ViaSwov *Swov, struct ViaXvPort *Port)
{
- if ((Port->FourCC == FOURCC_YV12) || (Port->FourCC == FOURCC_I420))
+ switch (Port->FourCC) {
+ case FOURCC_YV12:
+ case FOURCC_I420:
+ /* planar YUV */
Swov->HQV->SrcStride = ((Port->Width >> 1) << 16) | Port->Width;
- else if (Port->FourCC == FOURCC_YUY2)
+ 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;
+ 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__);
+ }
}
/*
@@ -205,19 +346,15 @@ ViaSwovSurfaceCreate(ScrnInfoPtr pScrn, CARD32 FourCC, CARD16 Width, CARD16 Heig
VIAPtr pVia = VIAPTR(pScrn);
struct ViaSwov *Swov = pVia->Swov;
struct ViaXvPort *Port = Swov->Port;
- int size;
+ int FrontSize, BackSize;
VIAFUNC(pScrn->scrnIndex);
ViaDebug(pScrn->scrnIndex, "%s: FourCC 0x%08X, Width %d, Height %d\n",
__FUNCTION__, FourCC, Width, Height);
- if ((FourCC == FOURCC_YV12) || (FourCC == FOURCC_I420)) {
- if (Width != ALIGN_TO(Width, VIA_PITCH_ALIGN_YUV420)) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "%s: wrong Xv image width for"
- " YUV420.\n", __FUNCTION__);
- return FALSE;
- }
-
+ 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);
@@ -226,19 +363,26 @@ ViaSwovSurfaceCreate(ScrnInfoPtr pScrn, CARD32 FourCC, CARD16 Width, CARD16 Heig
Port->CbOffset = Port->CrOffset + (Width >> 1) * (Height >> 1);
}
- size = (Width * Height * 3) >> 1;
- } else if (FourCC == FOURCC_YUY2) {
- if (Width != ALIGN_TO(Width, VIA_PITCH_ALIGN_YUV422)) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "%s: wrong Xv image width for"
- " YUV422.\n", __FUNCTION__);
- return FALSE;
- }
+ 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;
- size = Width * Height * 2;
- } else {
+ FrontSize = Width * Height * 4;
+ BackSize = FrontSize;
+ break;
+ default:
xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "%s: unhandled FourCC: 0x%08X\n",
__FUNCTION__, FourCC);
return FALSE;
@@ -249,22 +393,20 @@ ViaSwovSurfaceCreate(ScrnInfoPtr pScrn, CARD32 FourCC, CARD16 Width, CARD16 Heig
Port->Height = Height;
/* Front buffer, where the HQV sources its video. */
- Port->Front[0] = ViaMemAlloc(pScrn, size, 16);
+ Port->Front[0] = ViaMemAlloc(pScrn, FrontSize, 16);
if (!Port->Front[0])
return FALSE;
ViaHQVFetch(Swov, Port);
/* Back Buffer: HQV destination and Video3 source. */
- size = 2 * Width * Height;
-
- Port->Back[0] = ViaMemAlloc(pScrn, size, 16);
- Port->Back[1] = ViaMemAlloc(pScrn, size, 16);
+ 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, Port->Front[0]->Size, 16);
+ Port->Front[1] = ViaMemAlloc(pScrn, FrontSize, 16);
if (!Port->Front[1]) {
xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "%s: Not enough memory available.\n",
__FUNCTION__);
@@ -280,7 +422,7 @@ ViaSwovSurfaceCreate(ScrnInfoPtr pScrn, CARD32 FourCC, CARD16 Width, CARD16 Heig
/* This one may fail too. */
if (Swov->ThreeHQVBuffer) {
- Port->Back[2] = ViaMemAlloc(pScrn, Port->Back[0]->Size, 16);
+ Port->Back[2] = ViaMemAlloc(pScrn, BackSize, 16);
if (!Port->Back[2]) {
xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "%s: Not enough memory available.\n",
__FUNCTION__);
@@ -586,11 +728,28 @@ ViaHQVInit(struct ViaSwov *Swov)
Swov->HQV->Control = HQV_SRC_SW;
/* not CLE266Ax could need |= HQV_ENABLE | HQV_SW_FLIP */
-
- if ((Port->FourCC == FOURCC_YV12) || (Port->FourCC == FOURCC_I420))
+
+ switch (Port->FourCC) {
+ case FOURCC_YV12:
+ case FOURCC_I420:
Swov->HQV->Control |= HQV_YUV420;
- else
+ 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]) {
@@ -772,10 +931,17 @@ ViaSwovVisibleH(ScrnInfoPtr pScrn, struct ViaXvPort *Port)
Swov->Video->Video3WindowStart |= Dst_X << 16;
/* set up Fetch */
- if (Dst_W >= Src_W)
- Fetch = (ALIGN_TO(Src_W << 1, 16) >> 4) + 1;
- else
- Fetch = (ALIGN_TO(Dst_W << 1, 16) >> 4) + 1;
+ 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)
@@ -850,7 +1016,7 @@ ViaSwovVisibleV(ScrnInfoPtr pScrn, struct ViaXvPort *Port)
}
/*
- * Video3 always takes in YUV422 from the HQV.
+ *
*/
static void
ViaSwovStartAddress(struct ViaSwov *Swov, struct ViaXvPort *Port)
@@ -858,8 +1024,13 @@ ViaSwovStartAddress(struct ViaSwov *Swov, struct ViaXvPort *Port)
unsigned long Offset;
Offset = Port->Offset_Y * Port->Width + Port->Offset_X;
- Offset <<= 1;
- Offset &= ~0x03;
+
+ 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;
@@ -1359,19 +1530,6 @@ static XF86AttributeRec AttributesG[NUM_ATTRIBUTES_G] =
};
/*
- * I'm unable to set the ordering of packed YUV, so only YUY2 is possible.
- * A conversion routine could be implemented, but it is more efficient
- * to let the client ignore/convert it. -- Luc.
- */
-#define NUM_IMAGES_G 3
-static XF86ImageRec ImagesG[NUM_IMAGES_G] =
-{
- XVIMAGE_YUY2,
- XVIMAGE_YV12,
- XVIMAGE_I420
-};
-
-/*
* BLOODY MESS!
*
* The whole bandwidth mess, both for primary and secondary, and for Xv and
@@ -1892,6 +2050,34 @@ ViaSwovWindow(ScrnInfoPtr pScrn, short src_x, short src_y, short drw_x,
return FALSE;
}
+static void
+ViaVideo3Init(struct ViaSwov *Swov)
+{
+ struct ViaXvPort *Port = Swov->Port;
+
+ Swov->Video->Compose = V_COMMAND_LOAD_VBI | ALWAYS_SELECT_VIDEO;
+ Swov->Video->Video3Control = V3_COLORSPACE_SIGN | V3_YUV422| V3_SWAP_HW_HQV;
+
+ 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__);
+ }
+}
/*
* We should clean up on exit - some things in here depend on
@@ -1930,10 +2116,9 @@ viaPutImage(ScrnInfoPtr pScrn, short src_x, short src_y, short drw_x,
ViaSwovCopy(pVia, Port->Front[0], buf);
ViaHQVInit(Swov);
+ ViaVideo3Init(Swov);
Video3Touched = TRUE;
- Swov->Video->Compose = V_COMMAND_LOAD_VBI | ALWAYS_SELECT_VIDEO;
- Swov->Video->Video3Control = V3_COLORSPACE_SIGN | V3_YUV422 | V3_SWAP_HW_HQV;
#ifdef UNUSED
ViaSwovChromaKey(Swov, 0, 0);
@@ -2029,12 +2214,9 @@ viaQueryImageAttributes(ScrnInfoPtr pScrn, int FourCC, CARD16 *Width,
switch (FourCC) {
case FOURCC_YV12: /* YUV420 */
case FOURCC_I420:
- *Width = ALIGN_TO(*Width, 2);
+ *Width = ALIGN_TO(*Width, 32);
*Height = ALIGN_TO(*Height, 2);
- /* impose HW limitations */
- *Width = ALIGN_TO(*Width, VIA_PITCH_ALIGN_YUV420);
-
Size = 3 * (*Width) * (*Height);
Size /= 2;
@@ -2052,10 +2234,9 @@ viaQueryImageAttributes(ScrnInfoPtr pScrn, int FourCC, CARD16 *Width,
break;
case FOURCC_YUY2: /* YUV422 */
- *Width = ALIGN_TO(*Width, 2);
-
- /* impose HW limitations */
- *Width = ALIGN_TO(*Width, VIA_PITCH_ALIGN_YUV422);
+ case FOURCC_RV15: /* RGB555 */
+ case FOURCC_RV16: /* RGB565 */
+ *Width = ALIGN_TO(*Width, 8);
Size = (*Width << 1) * (*Height);
@@ -2066,6 +2247,18 @@ viaQueryImageAttributes(ScrnInfoPtr pScrn, int FourCC, CARD16 *Width,
offsets[0] = 0;
break;
+ case FOURCC_RV32: /* RGB888 */
+ *Width = ALIGN_TO(*Width, 4);
+
+ Size = (*Width << 2) * (*Height);
+
+ if (pitches)
+ pitches[0] = *Width << 2;
+
+ if (offsets)
+ offsets[0] = 0;
+
+ break;
default:
xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "%s: Unhandled FourCC: 0x%08X.\n",
__FUNCTION__, FourCC);