Video: Clearly separate Texture and EFB Copy formats

Improve bookkeeping around formats. Hopefully make code less confusing.

- Rename TlutFormat -> TLUTFormat to follow conventions.
- Use enum classes to prevent using a Texture format where an EFB Copy format
  is expected or vice-versa.
- Use common EFBCopyFormat names regardless of depth and YUV configurations.
This commit is contained in:
N.E.C
2017-07-30 12:45:55 -07:00
parent 9649494f67
commit c3a57bbad5
27 changed files with 1275 additions and 1319 deletions

View File

@ -21,227 +21,176 @@ static bool TexFmt_Overlay_Center = false;
// STATE_TO_SAVE
alignas(16) u8 texMem[TMEM_SIZE];
int TexDecoder_GetTexelSizeInNibbles(int format)
int TexDecoder_GetTexelSizeInNibbles(TextureFormat format)
{
switch (format & 0x3f)
switch (format)
{
case GX_TF_I4:
// 4-bit formats
case TextureFormat::I4:
case TextureFormat::C4:
return 1;
case GX_TF_I8:
// 8-bit formats
case TextureFormat::I8:
case TextureFormat::IA4:
case TextureFormat::C8:
return 2;
case GX_TF_IA4:
return 2;
case GX_TF_IA8:
// 16-bit formats
case TextureFormat::IA8:
case TextureFormat::RGB565:
case TextureFormat::RGB5A3:
case TextureFormat::C14X2:
return 4;
case GX_TF_RGB565:
return 4;
case GX_TF_RGB5A3:
return 4;
case GX_TF_RGBA8:
// 32-bit formats
case TextureFormat::RGBA8:
return 8;
case GX_TF_C4:
// Compressed format
case TextureFormat::CMPR:
return 1;
case GX_TF_C8:
return 2;
case GX_TF_C14X2:
return 4;
case GX_TF_CMPR:
return 1;
case GX_CTF_R4:
return 1;
case GX_CTF_RA4:
return 2;
case GX_CTF_RA8:
return 4;
case GX_CTF_A8:
return 2;
case GX_CTF_R8:
return 2;
case GX_CTF_G8:
return 2;
case GX_CTF_B8:
return 2;
case GX_CTF_RG8:
return 4;
case GX_CTF_GB8:
return 4;
case GX_TF_Z8:
return 2;
case GX_TF_Z16:
return 4;
case GX_TF_Z24X8:
return 8;
case GX_CTF_Z4:
return 1;
case GX_CTF_Z8H:
return 2;
case GX_CTF_Z8M:
return 2;
case GX_CTF_Z8L:
return 2;
case GX_CTF_Z16R:
return 4;
case GX_CTF_Z16L:
return 4;
default:
PanicAlert("Unsupported Texture Format (%08x)! (GetTexelSizeInNibbles)", format);
PanicAlert("Invalid Texture Format (0x%X)! (GetTexelSizeInNibbles)", static_cast<int>(format));
return 1;
}
}
int TexDecoder_GetTextureSizeInBytes(int width, int height, int format)
int TexDecoder_GetTextureSizeInBytes(int width, int height, TextureFormat format)
{
return (width * height * TexDecoder_GetTexelSizeInNibbles(format)) / 2;
}
int TexDecoder_GetBlockWidthInTexels(u32 format)
int TexDecoder_GetBlockWidthInTexels(TextureFormat format)
{
switch (format)
{
case GX_TF_I4:
// 4-bit formats
case TextureFormat::I4:
case TextureFormat::C4:
return 8;
case GX_TF_I8:
// 8-bit formats
case TextureFormat::I8:
case TextureFormat::IA4:
case TextureFormat::C8:
return 8;
case GX_TF_IA4:
return 8;
case GX_TF_IA8:
// 16-bit formats
case TextureFormat::IA8:
case TextureFormat::RGB565:
case TextureFormat::RGB5A3:
case TextureFormat::C14X2:
return 4;
case GX_TF_RGB565:
// 32-bit formats
case TextureFormat::RGBA8:
return 4;
case GX_TF_RGB5A3:
return 4;
case GX_TF_RGBA8:
return 4;
case GX_TF_C4:
// Compressed format
case TextureFormat::CMPR:
return 8;
case GX_TF_C8:
return 8;
case GX_TF_C14X2:
return 4;
case GX_TF_CMPR:
return 8;
case GX_CTF_R4:
return 8;
case GX_CTF_RA4:
return 8;
case GX_CTF_RA8:
return 4;
case GX_CTF_A8:
return 8;
case GX_CTF_R8:
return 8;
case GX_CTF_G8:
return 8;
case GX_CTF_B8:
return 8;
case GX_CTF_RG8:
return 4;
case GX_CTF_GB8:
return 4;
case GX_TF_Z8:
return 8;
case GX_TF_Z16:
return 4;
case GX_TF_Z24X8:
return 4;
case GX_CTF_Z4:
return 8;
case GX_CTF_Z8H:
return 8;
case GX_CTF_Z8M:
return 8;
case GX_CTF_Z8L:
return 8;
case GX_CTF_Z16R:
return 4;
case GX_CTF_Z16L:
return 4;
default:
PanicAlert("Unsupported Texture Format (%08x)! (GetBlockWidthInTexels)", format);
PanicAlert("Invalid Texture Format (0x%X)! (GetBlockWidthInTexels)", static_cast<int>(format));
return 8;
}
}
int TexDecoder_GetBlockHeightInTexels(u32 format)
int TexDecoder_GetBlockHeightInTexels(TextureFormat format)
{
switch (format)
{
case GX_TF_I4:
// 4-bit formats
case TextureFormat::I4:
case TextureFormat::C4:
return 8;
case GX_TF_I8:
// 8-bit formats
case TextureFormat::I8:
case TextureFormat::IA4:
case TextureFormat::C8:
return 4;
case GX_TF_IA4:
// 16-bit formats
case TextureFormat::IA8:
case TextureFormat::RGB565:
case TextureFormat::RGB5A3:
case TextureFormat::C14X2:
return 4;
case GX_TF_IA8:
// 32-bit formats
case TextureFormat::RGBA8:
return 4;
case GX_TF_RGB565:
return 4;
case GX_TF_RGB5A3:
return 4;
case GX_TF_RGBA8:
return 4;
case GX_TF_C4:
// Compressed format
case TextureFormat::CMPR:
return 8;
case GX_TF_C8:
default:
PanicAlert("Invalid Texture Format (0x%X)! (GetBlockHeightInTexels)", static_cast<int>(format));
return 4;
case GX_TF_C14X2:
return 4;
case GX_TF_CMPR:
}
}
int TexDecoder_GetEFBCopyBlockWidthInTexels(EFBCopyFormat format)
{
switch (format)
{
// 4-bit formats
case EFBCopyFormat::R4:
return 8;
case GX_CTF_R4:
// 8-bit formats
case EFBCopyFormat::A8:
case EFBCopyFormat::R8_0x1:
case EFBCopyFormat::R8:
case EFBCopyFormat::G8:
case EFBCopyFormat::B8:
return 8;
case GX_CTF_RA4:
// 16-bit formats
case EFBCopyFormat::RA8:
case EFBCopyFormat::RGB565:
case EFBCopyFormat::RGB5A3:
case EFBCopyFormat::RG8:
case EFBCopyFormat::GB8:
return 4;
case GX_CTF_RA8:
return 4;
case GX_CTF_A8:
return 4;
case GX_CTF_R8:
return 4;
case GX_CTF_G8:
return 4;
case GX_CTF_B8:
return 4;
case GX_CTF_RG8:
return 4;
case GX_CTF_GB8:
return 4;
case GX_TF_Z8:
return 4;
case GX_TF_Z16:
return 4;
case GX_TF_Z24X8:
return 4;
case GX_CTF_Z4:
return 8;
case GX_CTF_Z8H:
return 4;
case GX_CTF_Z8M:
return 4;
case GX_CTF_Z8L:
return 4;
case GX_CTF_Z16R:
return 4;
case GX_CTF_Z16L:
// 32-bit formats
case EFBCopyFormat::RGBA8:
return 4;
default:
PanicAlert("Unsupported Texture Format (%08x)! (GetBlockHeightInTexels)", format);
PanicAlert("Invalid EFB Copy Format (0x%X)! (GetEFBCopyBlockWidthInTexels)",
static_cast<int>(format));
return 8;
}
}
int TexDecoder_GetEFBCopyBlockHeightInTexels(EFBCopyFormat format)
{
switch (format)
{
// 4-bit formats
case EFBCopyFormat::R4:
return 8;
// 8-bit formats
case EFBCopyFormat::A8:
case EFBCopyFormat::R8_0x1:
case EFBCopyFormat::R8:
case EFBCopyFormat::G8:
case EFBCopyFormat::B8:
return 4;
// 16-bit formats
case EFBCopyFormat::RA8:
case EFBCopyFormat::RGB565:
case EFBCopyFormat::RGB5A3:
case EFBCopyFormat::RG8:
case EFBCopyFormat::GB8:
return 4;
// 32-bit formats
case EFBCopyFormat::RGBA8:
return 4;
default:
PanicAlert("Invalid EFB Copy Format (0x%X)! (GetEFBCopyBlockHeightInTexels)",
static_cast<int>(format));
return 4;
}
}
// returns bytes
int TexDecoder_GetPaletteSize(int format)
int TexDecoder_GetPaletteSize(TextureFormat format)
{
switch (format)
{
case GX_TF_C4:
case TextureFormat::C4:
return 16 * 2;
case GX_TF_C8:
case TextureFormat::C8:
return 256 * 2;
case GX_TF_C14X2:
case TextureFormat::C14X2:
return 16384 * 2;
default:
return 0;
@ -251,51 +200,33 @@ int TexDecoder_GetPaletteSize(int format)
// Get the "in memory" texture format of an EFB copy's format.
// With the exception of c4/c8/c14 paletted texture formats (which are handled elsewhere)
// this is the format the game should be using when it is drawing an EFB copy back.
int TexDecoder_GetEfbCopyBaseFormat(int format)
TextureFormat TexDecoder_GetEFBCopyBaseFormat(EFBCopyFormat format)
{
switch (format)
{
case GX_TF_I4:
case GX_CTF_Z4:
case GX_CTF_R4:
return GX_TF_I4;
case GX_TF_I8:
case GX_CTF_A8:
case GX_CTF_R8:
case GX_CTF_G8:
case GX_CTF_B8:
case GX_TF_Z8:
case GX_CTF_Z8H:
case GX_CTF_Z8M:
case GX_CTF_Z8L:
return GX_TF_I8;
case GX_TF_IA4:
case GX_CTF_RA4:
return GX_TF_IA4;
case GX_TF_IA8:
case GX_TF_Z16:
case GX_CTF_RA8:
case GX_CTF_RG8:
case GX_CTF_GB8:
case GX_CTF_Z16R:
case GX_CTF_Z16L:
return GX_TF_IA8;
case GX_TF_RGB565:
return GX_TF_RGB565;
case GX_TF_RGB5A3:
return GX_TF_RGB5A3;
case GX_TF_RGBA8:
case GX_TF_Z24X8:
case GX_CTF_YUVA8:
return GX_TF_RGBA8;
// These formats can't be (directly) generated by EFB copies
case GX_TF_C4:
case GX_TF_C8:
case GX_TF_C14X2:
case GX_TF_CMPR:
case EFBCopyFormat::R4:
return TextureFormat::I4;
case EFBCopyFormat::A8:
case EFBCopyFormat::R8_0x1:
case EFBCopyFormat::R8:
case EFBCopyFormat::G8:
case EFBCopyFormat::B8:
return TextureFormat::I8;
case EFBCopyFormat::RA4:
return TextureFormat::IA4;
case EFBCopyFormat::RA8:
case EFBCopyFormat::RG8:
case EFBCopyFormat::GB8:
return TextureFormat::IA8;
case EFBCopyFormat::RGB565:
return TextureFormat::RGB565;
case EFBCopyFormat::RGB5A3:
return TextureFormat::RGB5A3;
case EFBCopyFormat::RGBA8:
return TextureFormat::RGBA8;
default:
PanicAlert("Unsupported Texture Format (%08x)! (GetEfbCopyBaseFormat)", format);
return format & 0xf;
PanicAlert("Invalid EFB Copy Format (0x%X)! (GetEFBCopyBaseFormat)", static_cast<int>(format));
return static_cast<TextureFormat>(format);
}
}
@ -320,7 +251,7 @@ static const char* texfmt[] = {
"CZ16L", "0x3D", "0x3E", "0x3F",
};
static void TexDecoder_DrawOverlay(u8* dst, int width, int height, int texformat)
static void TexDecoder_DrawOverlay(u8* dst, int width, int height, TextureFormat texformat)
{
int w = std::min(width, 40);
int h = std::min(height, 10);
@ -334,7 +265,7 @@ static void TexDecoder_DrawOverlay(u8* dst, int width, int height, int texformat
yoff = 0;
}
const char* fmt = texfmt[texformat & 15];
const char* fmt = texfmt[static_cast<int>(texformat) & 15];
while (*fmt)
{
int xcnt = 0;
@ -363,8 +294,8 @@ static void TexDecoder_DrawOverlay(u8* dst, int width, int height, int texformat
}
}
void TexDecoder_Decode(u8* dst, const u8* src, int width, int height, int texformat, const u8* tlut,
TlutFormat tlutfmt)
void TexDecoder_Decode(u8* dst, const u8* src, int width, int height, TextureFormat texformat,
const u8* tlut, TLUTFormat tlutfmt)
{
_TexDecoder_DecodeImpl((u32*)dst, src, width, height, texformat, tlut, tlutfmt);
@ -409,23 +340,23 @@ static inline u32 DecodePixel_RGB5A3(u16 val)
return r | (g << 8) | (b << 16) | (a << 24);
}
static inline u32 DecodePixel_Paletted(u16 pixel, TlutFormat tlutfmt)
static inline u32 DecodePixel_Paletted(u16 pixel, TLUTFormat tlutfmt)
{
switch (tlutfmt)
{
case GX_TL_IA8:
case TLUTFormat::IA8:
return DecodePixel_IA8(pixel);
case GX_TL_RGB565:
case TLUTFormat::RGB565:
return DecodePixel_RGB565(Common::swap16(pixel));
case GX_TL_RGB5A3:
case TLUTFormat::RGB5A3:
return DecodePixel_RGB5A3(Common::swap16(pixel));
default:
return 0;
}
}
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)
{
/* General formula for computing texture offset
//
@ -440,7 +371,7 @@ void TexDecoder_DecodeTexel(u8* dst, const u8* src, int s, int t, int imageWidth
switch (texformat)
{
case GX_TF_C4:
case TextureFormat::C4:
{
u16 sBlk = s >> 3;
u16 tBlk = t >> 3;
@ -459,7 +390,7 @@ void TexDecoder_DecodeTexel(u8* dst, const u8* src, int s, int t, int imageWidth
*((u32*)dst) = DecodePixel_Paletted(tlut[val], tlutfmt);
}
break;
case GX_TF_I4:
case TextureFormat::I4:
{
u16 sBlk = s >> 3;
u16 tBlk = t >> 3;
@ -480,7 +411,7 @@ void TexDecoder_DecodeTexel(u8* dst, const u8* src, int s, int t, int imageWidth
dst[3] = val;
}
break;
case GX_TF_I8:
case TextureFormat::I8:
{
u16 sBlk = s >> 3;
u16 tBlk = t >> 2;
@ -497,7 +428,7 @@ void TexDecoder_DecodeTexel(u8* dst, const u8* src, int s, int t, int imageWidth
dst[3] = val;
}
break;
case GX_TF_C8:
case TextureFormat::C8:
{
u16 sBlk = s >> 3;
u16 tBlk = t >> 2;
@ -513,7 +444,7 @@ void TexDecoder_DecodeTexel(u8* dst, const u8* src, int s, int t, int imageWidth
*((u32*)dst) = DecodePixel_Paletted(tlut[val], tlutfmt);
}
break;
case GX_TF_IA4:
case TextureFormat::IA4:
{
u16 sBlk = s >> 3;
u16 tBlk = t >> 2;
@ -532,7 +463,7 @@ void TexDecoder_DecodeTexel(u8* dst, const u8* src, int s, int t, int imageWidth
dst[3] = a;
}
break;
case GX_TF_IA8:
case TextureFormat::IA8:
{
u16 sBlk = s >> 2;
u16 tBlk = t >> 2;
@ -548,7 +479,7 @@ void TexDecoder_DecodeTexel(u8* dst, const u8* src, int s, int t, int imageWidth
*((u32*)dst) = DecodePixel_IA8(*valAddr);
}
break;
case GX_TF_C14X2:
case TextureFormat::C14X2:
{
u16 sBlk = s >> 2;
u16 tBlk = t >> 2;
@ -567,7 +498,7 @@ void TexDecoder_DecodeTexel(u8* dst, const u8* src, int s, int t, int imageWidth
*((u32*)dst) = DecodePixel_Paletted(tlut[val], tlutfmt);
}
break;
case GX_TF_RGB565:
case TextureFormat::RGB565:
{
u16 sBlk = s >> 2;
u16 tBlk = t >> 2;
@ -583,7 +514,7 @@ void TexDecoder_DecodeTexel(u8* dst, const u8* src, int s, int t, int imageWidth
*((u32*)dst) = DecodePixel_RGB565(Common::swap16(*valAddr));
}
break;
case GX_TF_RGB5A3:
case TextureFormat::RGB5A3:
{
u16 sBlk = s >> 2;
u16 tBlk = t >> 2;
@ -599,7 +530,7 @@ void TexDecoder_DecodeTexel(u8* dst, const u8* src, int s, int t, int imageWidth
*((u32*)dst) = DecodePixel_RGB5A3(Common::swap16(*valAddr));
}
break;
case GX_TF_RGBA8:
case TextureFormat::RGBA8:
{
u16 sBlk = s >> 2;
u16 tBlk = t >> 2;
@ -618,7 +549,7 @@ void TexDecoder_DecodeTexel(u8* dst, const u8* src, int s, int t, int imageWidth
dst[2] = valAddr[33];
}
break;
case GX_TF_CMPR:
case TextureFormat::CMPR:
{
u16 sDxt = s >> 2;
u16 tDxt = t >> 2;