[PATCH] [glint] Fix uploading YV12 data to texture buffer on BE machines

Mark Kettenis mark.kettenis at xs4all.nl
Mon Feb 28 15:32:26 PST 2011


On BE machines various hardware byteswapping options are used for the
framebuffer aperture.  Which option gets used depends on the depth of the
framebuffer.  Uploading YV12 data to the texture buffer is done through the
same aperture, but is always done in 32-bit wide units.  Therefore the code
that does the uploading needs to take into account the byteswapping done by
the hardware.  For 32bpp modes we can use the same code as on LE machines,
but 16bpp and 8bpp modes need their own versions.

Signed-off-by: Mark Kettenis <kettenis at openbsd.org>
---
 src/pm2_video.c |   52 +++++++++++++++++++++++++++++++++++++++++-----------
 1 files changed, 41 insertions(+), 11 deletions(-)

diff --git a/src/pm2_video.c b/src/pm2_video.c
index 0c47d16..4ce827c 100644
--- a/src/pm2_video.c
+++ b/src/pm2_video.c
@@ -1696,7 +1696,7 @@ Permedia2GetStill(ScrnInfoPtr pScrn,
 }
 
 static void
-CopyYV12LE(CARD8 *Y, CARD32 *dst, int width, int height, int pitch)
+CopyYV12(CARD8 *Y, CARD32 *dst, int width, int height, int pitch)
 {
     int Y_size = width * height;
     CARD8 *V = Y + Y_size;
@@ -1721,7 +1721,30 @@ CopyYV12LE(CARD8 *Y, CARD32 *dst, int width, int height, int pitch)
 #if X_BYTE_ORDER == X_BIG_ENDIAN
 
 static void
-CopyYV12BE(CARD8 *Y, CARD32 *dst, int width, int height, int pitch)
+CopyYV12_16(CARD8 *Y, CARD32 *dst, int width, int height, int pitch)
+{
+    int Y_size = width * height;
+    CARD8 *V = Y + Y_size;
+    CARD8 *U = V + (Y_size >> 2);
+    int pad = (pitch >> 2) - (width >> 1);
+    int x;
+
+    width >>= 1;
+
+    for (height >>= 1; height > 0; height--) {
+	for (x = 0; x < width; Y += 2, x++)
+	    *dst++ = Y[1] + (V[x] << 8) + (Y[0] << 16) + (U[x] << 24);
+	dst += pad;
+	for (x = 0; x < width; Y += 2, x++)
+	    *dst++ = Y[1] + (V[x] << 8) + (Y[0] << 16) + (U[x] << 24);
+	dst += pad;
+	U += width;
+	V += width;
+    }
+}
+
+static void
+CopyYV12_8(CARD8 *Y, CARD32 *dst, int width, int height, int pitch)
 {
     int Y_size = width * height;
     CARD8 *V = Y + Y_size;
@@ -1743,7 +1766,7 @@ CopyYV12BE(CARD8 *Y, CARD32 *dst, int width, int height, int pitch)
     }
 }
 
-#endif /* X_BYTE_ORDER == X_BIG_ENDIAN */
+#endif
 
 static void
 CopyFlat(CARD8 *src, CARD8 *dst, int width, int height, int pitch)
@@ -1841,17 +1864,24 @@ Permedia2PutImage(ScrnInfoPtr pScrn,
 
     switch (id) {
     case LE4CC('Y','V','1','2'):
-#if X_BYTE_ORDER == X_LITTLE_ENDIAN
-	CopyYV12LE(buf, (CARD32 *)((CARD8 *) pGlint->FbBase + pPPriv->BufferBase[0]),
-	    width, height, pPPriv->BufferStride);
-#else
-	if (pGlint->FBDev)
-	    CopyYV12LE(buf, (CARD32 *)((CARD8 *) pGlint->FbBase + pPPriv->BufferBase[0]),
+	switch(pGlint->HwBpp) {
+#if X_BYTE_ORDER == X_BIG_ENDIAN
+	case 8:
+	case 24:
+	    CopyYV12_8(buf, (CARD32 *)((CARD8 *) pGlint->FbBase + pPPriv->BufferBase[0]),
 		width, height, pPPriv->BufferStride);
-	else
-	    CopyYV12BE(buf, (CARD32 *)((CARD8 *) pGlint->FbBase + pPPriv->BufferBase[0]),
+	    break;
+	case 15:
+	case 16:
+	    CopyYV12_16(buf, (CARD32 *)((CARD8 *) pGlint->FbBase + pPPriv->BufferBase[0]),
 		width, height, pPPriv->BufferStride);
+	    break;
 #endif
+	default:
+	    CopyYV12(buf, (CARD32 *)((CARD8 *) pGlint->FbBase + pPPriv->BufferBase[0]),
+		width, height, pPPriv->BufferStride);
+	    break;
+	}
 	PutYUV(pPPriv, pPPriv->BufferBase[0], FORMAT_YUYV, 1, 0);
 	break;
 
-- 
1.7.3.2



More information about the xorg-devel mailing list