[prev in list] [next in list] [prev in thread] [next in thread] 

List:       freedesktop-xorg-devel
Subject:    [PATCH] [glint] Fix uploading YV12 data to texture buffer on BE
From:       Mark Kettenis <mark.kettenis () xs4all ! nl>
Date:       2011-02-28 23:32:26
Message-ID: 201102282332.p1SNWQ6d000182 () glazunov ! sibelius ! xs4all ! nl
[Download RAW message or body]

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@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

_______________________________________________
xorg-devel@lists.x.org: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: http://lists.x.org/mailman/listinfo/xorg-devel
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic