summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authorStenzek <stenzek@gmail.com>2019-03-24 13:10:01 +1000
committerStenzek <stenzek@gmail.com>2019-04-21 12:41:15 +1000
commitdbaba0062a057836b31455d7abe3fea6a20b99d8 (patch)
tree58501b837d02d08a1275e53b1580d72828eadaa4 /Source/Core
parent4b1adab7856cb2dd28418a1d748a0e8cebf94a2f (diff)
TextureDecoder: Move XFB decoding to Common
This was previously missing for generic (which is used on ARM).
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/VideoCommon/TextureDecoder.h1
-rw-r--r--Source/Core/VideoCommon/TextureDecoder_Common.cpp38
-rw-r--r--Source/Core/VideoCommon/TextureDecoder_Generic.cpp3
-rw-r--r--Source/Core/VideoCommon/TextureDecoder_x64.cpp33
4 files changed, 44 insertions, 31 deletions
diff --git a/Source/Core/VideoCommon/TextureDecoder.h b/Source/Core/VideoCommon/TextureDecoder.h
index 2a270eacd1..a1313afab1 100644
--- a/Source/Core/VideoCommon/TextureDecoder.h
+++ b/Source/Core/VideoCommon/TextureDecoder.h
@@ -116,6 +116,7 @@ void TexDecoder_DecodeTexel(u8* dst, const u8* src, int s, int t, int imageWidth
TextureFormat texformat, const u8* tlut, TLUTFormat tlutfmt);
void TexDecoder_DecodeTexelRGBA8FromTmem(u8* dst, const u8* src_ar, const u8* src_gb, int s, int t,
int imageWidth);
+void TexDecoder_DecodeXFB(u8* dst, const u8* src, u32 width, u32 height, u32 stride);
void TexDecoder_SetTexFmtOverlayOptions(bool enable, bool center);
diff --git a/Source/Core/VideoCommon/TextureDecoder_Common.cpp b/Source/Core/VideoCommon/TextureDecoder_Common.cpp
index 2e84e3d282..5fbe34a098 100644
--- a/Source/Core/VideoCommon/TextureDecoder_Common.cpp
+++ b/Source/Core/VideoCommon/TextureDecoder_Common.cpp
@@ -751,3 +751,41 @@ void TexDecoder_DecodeRGBA8FromTmem(u8* dst, const u8* src_ar, const u8* src_gb,
}
}
}
+
+void TexDecoder_DecodeXFB(u8* dst, const u8* src, u32 width, u32 height, u32 stride)
+{
+ const u8* src_ptr = src;
+ u8* dst_ptr = dst;
+
+ for (u32 y = 0; y < height; y++)
+ {
+ const u8* row_ptr = src_ptr;
+ for (u32 x = 0; x < width; x += 2)
+ {
+ // We do this one color sample (aka 2 RGB pixels) at a time
+ int Y1 = int(*(row_ptr++)) - 16;
+ int U = int(*(row_ptr++)) - 128;
+ int Y2 = int(*(row_ptr++)) - 16;
+ int V = int(*(row_ptr++)) - 128;
+
+ // We do the inverse BT.601 conversion for YCbCr to RGB
+ // http://www.equasys.de/colorconversion.html#YCbCr-RGBColorFormatConversion
+ u8 R1 = static_cast<u8>(MathUtil::Clamp(int(1.164f * Y1 + 1.596f * V), 0, 255));
+ u8 G1 = static_cast<u8>(MathUtil::Clamp(int(1.164f * Y1 - 0.392f * U - 0.813f * V), 0, 255));
+ u8 B1 = static_cast<u8>(MathUtil::Clamp(int(1.164f * Y1 + 2.017f * U), 0, 255));
+
+ u8 R2 = static_cast<u8>(MathUtil::Clamp(int(1.164f * Y2 + 1.596f * V), 0, 255));
+ u8 G2 = static_cast<u8>(MathUtil::Clamp(int(1.164f * Y2 - 0.392f * U - 0.813f * V), 0, 255));
+ u8 B2 = static_cast<u8>(MathUtil::Clamp(int(1.164f * Y2 + 2.017f * U), 0, 255));
+
+ u32 rgba = 0xff000000 | B1 << 16 | G1 << 8 | R1;
+ std::memcpy(dst_ptr, &rgba, sizeof(rgba));
+ dst_ptr += sizeof(rgba);
+ rgba = 0xff000000 | B2 << 16 | G2 << 8 | R2;
+ std::memcpy(dst_ptr, &rgba, sizeof(rgba));
+ dst_ptr += sizeof(rgba);
+ }
+
+ src_ptr += stride;
+ }
+}
diff --git a/Source/Core/VideoCommon/TextureDecoder_Generic.cpp b/Source/Core/VideoCommon/TextureDecoder_Generic.cpp
index ec74c21db4..4a2b516e7c 100644
--- a/Source/Core/VideoCommon/TextureDecoder_Generic.cpp
+++ b/Source/Core/VideoCommon/TextureDecoder_Generic.cpp
@@ -346,5 +346,8 @@ void _TexDecoder_DecodeImpl(u32* dst, const u8* src, int width, int height, Text
}
break;
}
+ case TextureFormat::XFB:
+ TexDecoder_DecodeXFB(reinterpret_cast<u8*>(dst), src, width, height, width * 2);
+ break;
}
}
diff --git a/Source/Core/VideoCommon/TextureDecoder_x64.cpp b/Source/Core/VideoCommon/TextureDecoder_x64.cpp
index 8a55bb5a53..7d41dbee53 100644
--- a/Source/Core/VideoCommon/TextureDecoder_x64.cpp
+++ b/Source/Core/VideoCommon/TextureDecoder_x64.cpp
@@ -1488,37 +1488,8 @@ void _TexDecoder_DecodeImpl(u32* dst, const u8* src, int width, int height, Text
break;
case TextureFormat::XFB:
- {
- for (int y = 0; y < height; y += 1)
- {
- for (int x = 0; x < width; x += 2)
- {
- size_t offset = static_cast<size_t>((y * width + x) * 2);
-
- // We do this one color sample (aka 2 RGB pixles) at a time
- int Y1 = int(src[offset]) - 16;
- int U = int(src[offset + 1]) - 128;
- int Y2 = int(src[offset + 2]) - 16;
- int V = int(src[offset + 3]) - 128;
-
- // We do the inverse BT.601 conversion for YCbCr to RGB
- // http://www.equasys.de/colorconversion.html#YCbCr-RGBColorFormatConversion
- u8 R1 = static_cast<u8>(MathUtil::Clamp(int(1.164f * Y1 + 1.596f * V), 0, 255));
- u8 G1 =
- static_cast<u8>(MathUtil::Clamp(int(1.164f * Y1 - 0.392f * U - 0.813f * V), 0, 255));
- u8 B1 = static_cast<u8>(MathUtil::Clamp(int(1.164f * Y1 + 2.017f * U), 0, 255));
-
- u8 R2 = static_cast<u8>(MathUtil::Clamp(int(1.164f * Y2 + 1.596f * V), 0, 255));
- u8 G2 =
- static_cast<u8>(MathUtil::Clamp(int(1.164f * Y2 - 0.392f * U - 0.813f * V), 0, 255));
- u8 B2 = static_cast<u8>(MathUtil::Clamp(int(1.164f * Y2 + 2.017f * U), 0, 255));
-
- dst[y * width + x] = 0xff000000 | B1 << 16 | G1 << 8 | R1;
- dst[y * width + x + 1] = 0xff000000 | B2 << 16 | G2 << 8 | R2;
- }
- }
- }
- break;
+ TexDecoder_DecodeXFB(reinterpret_cast<u8*>(dst), src, width, height, width * 2);
+ break;
default:
PanicAlert("Invalid Texture Format (0x%X)! (_TexDecoder_DecodeImpl)",