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 <[email protected]> --- 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 _______________________________________________ [email protected]: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
