diff options
Diffstat (limited to 'Source/Core/VideoCommon/TextureDecoder.h')
| -rw-r--r-- | Source/Core/VideoCommon/TextureDecoder.h | 155 |
1 files changed, 81 insertions, 74 deletions
diff --git a/Source/Core/VideoCommon/TextureDecoder.h b/Source/Core/VideoCommon/TextureDecoder.h index b424dd324f..1a33fbfcf8 100644 --- a/Source/Core/VideoCommon/TextureDecoder.h +++ b/Source/Core/VideoCommon/TextureDecoder.h @@ -14,94 +14,101 @@ enum }; alignas(16) extern u8 texMem[TMEM_SIZE]; -enum TextureFormat +enum class TextureFormat { - // These are the texture formats that can be read by the texture mapper. - GX_TF_I4 = 0x0, - GX_TF_I8 = 0x1, - GX_TF_IA4 = 0x2, - GX_TF_IA8 = 0x3, - GX_TF_RGB565 = 0x4, - GX_TF_RGB5A3 = 0x5, - GX_TF_RGBA8 = 0x6, - GX_TF_C4 = 0x8, - GX_TF_C8 = 0x9, - GX_TF_C14X2 = 0xA, - GX_TF_CMPR = 0xE, - - _GX_TF_ZTF = 0x10, // flag for Z texture formats (used internally by dolphin) - - // Depth texture formats (which directly map to the equivalent colour format above.) - GX_TF_Z8 = 0x1 | _GX_TF_ZTF, - GX_TF_Z16 = 0x3 | _GX_TF_ZTF, - GX_TF_Z24X8 = 0x6 | _GX_TF_ZTF, - - _GX_TF_CTF = 0x20, // flag for copy-texture-format only (used internally by dolphin) - - // These are extra formats that can be used when copying from efb, - // they use one of texel formats from above, but pack diffrent data into them. - GX_CTF_R4 = 0x0 | _GX_TF_CTF, - GX_CTF_RA4 = 0x2 | _GX_TF_CTF, - GX_CTF_RA8 = 0x3 | _GX_TF_CTF, - GX_CTF_YUVA8 = 0x6 | _GX_TF_CTF, // YUV 4:4:4 - Dolphin doesn't implement this format as no - // commercial games use it - GX_CTF_A8 = 0x7 | _GX_TF_CTF, - GX_CTF_R8 = 0x8 | _GX_TF_CTF, - GX_CTF_G8 = 0x9 | _GX_TF_CTF, - GX_CTF_B8 = 0xA | _GX_TF_CTF, - GX_CTF_RG8 = 0xB | _GX_TF_CTF, - GX_CTF_GB8 = 0xC | _GX_TF_CTF, - - // extra depth texture formats that can be used for efb copies. - GX_CTF_Z4 = 0x0 | _GX_TF_ZTF | _GX_TF_CTF, - GX_CTF_Z8H = 0x8 | _GX_TF_ZTF | _GX_TF_CTF, // This produces an identical result to to GX_TF_Z8 - GX_CTF_Z8M = 0x9 | _GX_TF_ZTF | _GX_TF_CTF, - GX_CTF_Z8L = 0xA | _GX_TF_ZTF | _GX_TF_CTF, - GX_CTF_Z16R = 0xB | _GX_TF_ZTF | _GX_TF_CTF, // Reversed version of GX_TF_Z16 - GX_CTF_Z16L = 0xC | _GX_TF_ZTF | _GX_TF_CTF, + // These values represent texture format in GX registers. + I4 = 0x0, + I8 = 0x1, + IA4 = 0x2, + IA8 = 0x3, + RGB565 = 0x4, + RGB5A3 = 0x5, + RGBA8 = 0x6, + C4 = 0x8, + C8 = 0x9, + C14X2 = 0xA, + CMPR = 0xE, }; -enum TlutFormat +static inline bool IsColorIndexed(TextureFormat format) { - GX_TL_IA8 = 0x0, - GX_TL_RGB565 = 0x1, - GX_TL_RGB5A3 = 0x2, + return format == TextureFormat::C4 || format == TextureFormat::C8 || + format == TextureFormat::C14X2; +} + +// The EFB Copy pipeline looks like: +// +// 1. Read EFB -> 2. Select color/depth -> 3. Downscale (optional) +// -> 4. YUV conversion (optional) -> 5. Encode Tiles -> 6. Write RAM +// +// The "Encode Tiles" stage receives RGBA8 texels from previous stages and encodes them to various +// formats. EFBCopyFormat is the tile encoder mode. Note that the tile encoder does not care about +// color vs. depth or intensity formats - it only sees RGBA8 texels. +enum class EFBCopyFormat +{ + // These values represent EFB copy format in GX registers. + // Most (but not all) of these values correspond to values of TextureFormat. + R4 = 0x0, // R4, I4, Z4 + + // FIXME: Does 0x1 (Z8) have identical results to 0x8 (Z8H)? + // Is either or both of 0x1 and 0x8 used in games? + R8_0x1 = 0x1, // R8, I8, Z8H (?) + + RA4 = 0x2, // RA4, IA4 + + // FIXME: Earlier versions of this file named the value 0x3 "GX_TF_Z16", which does not reflect + // the results one would expect when copying from the depth buffer with this format. + // For reference: When copying from the depth buffer, R should receive the top 8 bits of + // the Z value, and A should be either 0xFF or 0 (please investigate). + // Please test original hardware and make sure dolphin-emu implements this format + // correctly. + RA8 = 0x3, // RA8, IA8, (FIXME: Z16 too?) + + RGB565 = 0x4, + RGB5A3 = 0x5, + RGBA8 = 0x6, // RGBA8, Z24 + A8 = 0x7, + R8 = 0x8, // R8, I8, Z8H + G8 = 0x9, // G8, Z8M + B8 = 0xA, // B8, Z8L + RG8 = 0xB, // RG8, Z16R (Note: G and R are reversed) + GB8 = 0xC, // GB8, Z16L }; -struct EFBCopyFormat +enum class TLUTFormat { - EFBCopyFormat(u32 efb_format_, TextureFormat copy_format_) - : efb_format(efb_format_), copy_format(copy_format_) - { - } - - bool operator<(const EFBCopyFormat& rhs) const - { - return std::tie(efb_format, copy_format) < std::tie(rhs.efb_format, rhs.copy_format); - } - - u32 efb_format; - TextureFormat copy_format; + // These values represent TLUT format in GX registers. + IA8 = 0x0, + RGB565 = 0x1, + RGB5A3 = 0x2, }; -int TexDecoder_GetTexelSizeInNibbles(int format); -int TexDecoder_GetTextureSizeInBytes(int width, int height, int format); -int TexDecoder_GetBlockWidthInTexels(u32 format); -int TexDecoder_GetBlockHeightInTexels(u32 format); -int TexDecoder_GetPaletteSize(int fmt); -int TexDecoder_GetEfbCopyBaseFormat(int format); - -void TexDecoder_Decode(u8* dst, const u8* src, int width, int height, int texformat, const u8* tlut, - TlutFormat tlutfmt); +static inline bool IsValidTLUTFormat(TLUTFormat tlutfmt) +{ + return tlutfmt == TLUTFormat::IA8 || tlutfmt == TLUTFormat::RGB565 || + tlutfmt == TLUTFormat::RGB5A3; +} + +int TexDecoder_GetTexelSizeInNibbles(TextureFormat format); +int TexDecoder_GetTextureSizeInBytes(int width, int height, TextureFormat format); +int TexDecoder_GetBlockWidthInTexels(TextureFormat format); +int TexDecoder_GetBlockHeightInTexels(TextureFormat format); +int TexDecoder_GetEFBCopyBlockWidthInTexels(EFBCopyFormat format); +int TexDecoder_GetEFBCopyBlockHeightInTexels(EFBCopyFormat format); +int TexDecoder_GetPaletteSize(TextureFormat fmt); +TextureFormat TexDecoder_GetEFBCopyBaseFormat(EFBCopyFormat format); + +void TexDecoder_Decode(u8* dst, const u8* src, int width, int height, TextureFormat texformat, + const u8* tlut, TLUTFormat tlutfmt); void TexDecoder_DecodeRGBA8FromTmem(u8* dst, const u8* src_ar, const u8* src_gb, int width, int height); -void TexDecoder_DecodeTexel(u8* dst, const u8* src, int s, int t, int imageWidth, int texformat, - const u8* tlut, TlutFormat tlutfmt); +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_SetTexFmtOverlayOptions(bool enable, bool center); /* Internal method, implemented by TextureDecoder_Generic and TextureDecoder_x64. */ -void _TexDecoder_DecodeImpl(u32* dst, const u8* src, int width, int height, int texformat, - const u8* tlut, TlutFormat tlutfmt); +void _TexDecoder_DecodeImpl(u32* dst, const u8* src, int width, int height, TextureFormat texformat, + const u8* tlut, TLUTFormat tlutfmt); |
