summaryrefslogtreecommitdiff
path: root/Source/Core/VideoCommon/TextureCacheBase.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/Core/VideoCommon/TextureCacheBase.cpp')
-rw-r--r--Source/Core/VideoCommon/TextureCacheBase.cpp168
1 files changed, 71 insertions, 97 deletions
diff --git a/Source/Core/VideoCommon/TextureCacheBase.cpp b/Source/Core/VideoCommon/TextureCacheBase.cpp
index 5fb73cf175..cd9b9dd19f 100644
--- a/Source/Core/VideoCommon/TextureCacheBase.cpp
+++ b/Source/Core/VideoCommon/TextureCacheBase.cpp
@@ -226,8 +226,8 @@ void TextureCacheBase::SetBackupConfig(const VideoConfig& config)
backup_config.gpu_texture_decoding = config.bEnableGPUTextureDecoding;
}
-TextureCacheBase::TCacheEntry* TextureCacheBase::ApplyPaletteToEntry(TCacheEntry* entry,
- u8* palette, u32 tlutfmt)
+TextureCacheBase::TCacheEntry*
+TextureCacheBase::ApplyPaletteToEntry(TCacheEntry* entry, u8* palette, TLUTFormat tlutfmt)
{
TextureConfig new_config = entry->texture->GetConfig();
new_config.levels = 1;
@@ -243,7 +243,7 @@ TextureCacheBase::TCacheEntry* TextureCacheBase::ApplyPaletteToEntry(TCacheEntry
decoded_entry->frameCount = FRAMECOUNT_INVALID;
decoded_entry->is_efb_copy = false;
- ConvertTexture(decoded_entry, entry, palette, static_cast<TlutFormat>(tlutfmt));
+ ConvertTexture(decoded_entry, entry, palette, tlutfmt);
textures_by_address.emplace(entry->addr, decoded_entry);
return decoded_entry;
@@ -290,7 +290,8 @@ void TextureCacheBase::ScaleTextureCacheEntryTo(TextureCacheBase::TCacheEntry* e
}
TextureCacheBase::TCacheEntry*
-TextureCacheBase::DoPartialTextureUpdates(TCacheEntry* entry_to_update, u8* palette, u32 tlutfmt)
+TextureCacheBase::DoPartialTextureUpdates(TCacheEntry* entry_to_update, u8* palette,
+ TLUTFormat tlutfmt)
{
// If the flag may_have_overlapping_textures is cleared, there are no overlapping EFB copies,
// which aren't applied already. It is set for new textures, and for the affected range
@@ -299,19 +300,17 @@ TextureCacheBase::DoPartialTextureUpdates(TCacheEntry* entry_to_update, u8* pale
return entry_to_update;
entry_to_update->may_have_overlapping_textures = false;
- const bool isPaletteTexture =
- (entry_to_update->format == GX_TF_C4 || entry_to_update->format == GX_TF_C8 ||
- entry_to_update->format == GX_TF_C14X2 || entry_to_update->format >= 0x10000);
+ const bool isPaletteTexture = IsColorIndexed(entry_to_update->format.texfmt);
// EFB copies are excluded from these updates, until there's an example where a game would
// benefit from updating. This would require more work to be done.
if (entry_to_update->IsEfbCopy())
return entry_to_update;
- u32 block_width = TexDecoder_GetBlockWidthInTexels(entry_to_update->format & 0xf);
- u32 block_height = TexDecoder_GetBlockHeightInTexels(entry_to_update->format & 0xf);
+ u32 block_width = TexDecoder_GetBlockWidthInTexels(entry_to_update->format.texfmt);
+ u32 block_height = TexDecoder_GetBlockHeightInTexels(entry_to_update->format.texfmt);
u32 block_size = block_width * block_height *
- TexDecoder_GetTexelSizeInNibbles(entry_to_update->format & 0xf) / 2;
+ TexDecoder_GetTexelSizeInNibbles(entry_to_update->format.texfmt) / 2;
u32 numBlocksX = (entry_to_update->native_width + block_width - 1) / block_width;
@@ -490,9 +489,9 @@ TextureCacheBase::TCacheEntry* TextureCacheBase::Load(const u32 stage)
const u32 address = (tex.texImage3[id].image_base /* & 0x1FFFFF*/) << 5;
u32 width = tex.texImage0[id].width + 1;
u32 height = tex.texImage0[id].height + 1;
- const int texformat = tex.texImage0[id].format;
+ const TextureFormat texformat = static_cast<TextureFormat>(tex.texImage0[id].format);
const u32 tlutaddr = tex.texTlut[id].tmem_offset << 9;
- const u32 tlutfmt = tex.texTlut[id].tlut_format;
+ const TLUTFormat tlutfmt = static_cast<TLUTFormat>(tex.texTlut[id].tlut_format);
const bool use_mipmaps = SamplerCommon::AreBpTexMode0MipmapsEnabled(tex.texMode0[id]);
u32 tex_levels = use_mipmaps ? ((tex.texMode1[id].max_lod + 0xf) / 0x10 + 1) : 1;
const bool from_tmem = tex.texImage1[id].image_type != 0;
@@ -511,18 +510,14 @@ TextureCacheBase::TCacheEntry* TextureCacheBase::Load(const u32 stage)
u64 base_hash = TEXHASH_INVALID;
u64 full_hash = TEXHASH_INVALID;
- u32 full_format = texformat;
+ TextureAndTLUTFormat full_format(texformat, tlutfmt);
- const bool isPaletteTexture =
- (texformat == GX_TF_C4 || texformat == GX_TF_C8 || texformat == GX_TF_C14X2);
+ const bool isPaletteTexture = IsColorIndexed(texformat);
// Reject invalid tlut format.
- if (isPaletteTexture && tlutfmt > GX_TL_RGB5A3)
+ if (isPaletteTexture && !IsValidTLUTFormat(tlutfmt))
return nullptr;
- if (isPaletteTexture)
- full_format = texformat | (tlutfmt << 16);
-
const u32 texture_size =
TexDecoder_GetTextureSizeInBytes(expandedWidth, expandedHeight, texformat);
u32 bytes_per_block = (bsw * bsh * TexDecoder_GetTexelSizeInNibbles(texformat)) / 2;
@@ -766,11 +761,9 @@ TextureCacheBase::TCacheEntry* TextureCacheBase::Load(const u32 stage)
// banks, and if we're doing an copy we may as well just do the whole thing on the CPU, since
// there's no conversion between formats. In the future this could be extended with a separate
// shader, however.
- bool decode_on_gpu =
- !hires_tex && g_ActiveConfig.UseGPUTextureDecoding() &&
- g_texture_cache->SupportsGPUTextureDecode(static_cast<TextureFormat>(texformat),
- static_cast<TlutFormat>(tlutfmt)) &&
- !(from_tmem && texformat == GX_TF_RGBA8);
+ bool decode_on_gpu = !hires_tex && g_ActiveConfig.UseGPUTextureDecoding() &&
+ g_texture_cache->SupportsGPUTextureDecode(texformat, tlutfmt) &&
+ !(from_tmem && texformat == TextureFormat::RGBA8);
// create the entry/texture
TextureConfig config;
@@ -796,18 +789,16 @@ TextureCacheBase::TCacheEntry* TextureCacheBase::Load(const u32 stage)
if (!hires_tex && decode_on_gpu)
{
u32 row_stride = bytes_per_block * (expandedWidth / bsw);
- g_texture_cache->DecodeTextureOnGPU(
- entry, 0, src_data, texture_size, static_cast<TextureFormat>(texformat), width, height,
- expandedWidth, expandedHeight, row_stride, tlut, static_cast<TlutFormat>(tlutfmt));
+ g_texture_cache->DecodeTextureOnGPU(entry, 0, src_data, texture_size, texformat, width, height,
+ expandedWidth, expandedHeight, row_stride, tlut, tlutfmt);
}
else if (!hires_tex)
{
size_t decoded_texture_size = expandedWidth * sizeof(u32) * expandedHeight;
CheckTempSize(decoded_texture_size);
- if (!(texformat == GX_TF_RGBA8 && from_tmem))
+ if (!(texformat == TextureFormat::RGBA8 && from_tmem))
{
- TexDecoder_Decode(temp, src_data, expandedWidth, expandedHeight, texformat, tlut,
- (TlutFormat)tlutfmt);
+ TexDecoder_Decode(temp, src_data, expandedWidth, expandedHeight, texformat, tlut, tlutfmt);
}
else
{
@@ -878,17 +869,16 @@ TextureCacheBase::TCacheEntry* TextureCacheBase::Load(const u32 stage)
if (decode_on_gpu)
{
u32 row_stride = bytes_per_block * (expanded_mip_width / bsw);
- g_texture_cache->DecodeTextureOnGPU(entry, level, mip_src_data, mip_size,
- static_cast<TextureFormat>(texformat), mip_width,
- mip_height, expanded_mip_width, expanded_mip_height,
- row_stride, tlut, static_cast<TlutFormat>(tlutfmt));
+ g_texture_cache->DecodeTextureOnGPU(entry, level, mip_src_data, mip_size, texformat,
+ mip_width, mip_height, expanded_mip_width,
+ expanded_mip_height, row_stride, tlut, tlutfmt);
}
else
{
// No need to call CheckTempSize here, as mips will always be smaller than the base level.
size_t decoded_mip_size = expanded_mip_width * sizeof(u32) * expanded_mip_height;
TexDecoder_Decode(temp, mip_src_data, expanded_mip_width, expanded_mip_height, texformat,
- tlut, (TlutFormat)tlutfmt);
+ tlut, tlutfmt);
entry->texture->Load(level, mip_width, mip_height, expanded_mip_width, temp,
decoded_mip_size);
}
@@ -908,9 +898,10 @@ TextureCacheBase::TCacheEntry* TextureCacheBase::Load(const u32 stage)
return ReturnEntry(stage, entry);
}
-void TextureCacheBase::CopyRenderTargetToTexture(u32 dstAddr, unsigned int dstFormat, u32 dstStride,
- bool is_depth_copy, const EFBRectangle& srcRect,
- bool isIntensity, bool scaleByHalf)
+void TextureCacheBase::CopyRenderTargetToTexture(u32 dstAddr, EFBCopyFormat dstFormat,
+ u32 dstStride, bool is_depth_copy,
+ const EFBRectangle& srcRect, bool isIntensity,
+ bool scaleByHalf)
{
// Emulation methods:
//
@@ -980,81 +971,73 @@ void TextureCacheBase::CopyRenderTargetToTexture(u32 dstAddr, unsigned int dstFo
ColorMask[0] = ColorMask[1] = ColorMask[2] = ColorMask[3] = 255.0f;
ColorMask[4] = ColorMask[5] = ColorMask[6] = ColorMask[7] = 1.0f / 255.0f;
unsigned int cbufid = UINT_MAX;
- u32 srcFormat = bpmem.zcontrol.pixel_format;
+ PEControl::PixelFormat srcFormat = bpmem.zcontrol.pixel_format;
bool efbHasAlpha = srcFormat == PEControl::RGBA6_Z24;
if (is_depth_copy)
{
switch (dstFormat)
{
- case 0: // Z4
+ case EFBCopyFormat::R4: // Z4
colmat[3] = colmat[7] = colmat[11] = colmat[15] = 1.0f;
cbufid = 0;
- dstFormat |= _GX_TF_CTF;
break;
- case 8: // Z8H
- dstFormat |= _GX_TF_CTF;
- case 1: // Z8
+ case EFBCopyFormat::R8_0x1: // Z8
+ case EFBCopyFormat::R8: // Z8H
colmat[0] = colmat[4] = colmat[8] = colmat[12] = 1.0f;
cbufid = 1;
break;
- case 3: // Z16
+ case EFBCopyFormat::RA8: // Z16
colmat[1] = colmat[5] = colmat[9] = colmat[12] = 1.0f;
cbufid = 2;
break;
- case 11: // Z16 (reverse order)
+ case EFBCopyFormat::RG8: // Z16 (reverse order)
colmat[0] = colmat[4] = colmat[8] = colmat[13] = 1.0f;
cbufid = 3;
- dstFormat |= _GX_TF_CTF;
break;
- case 6: // Z24X8
+ case EFBCopyFormat::RGBA8: // Z24X8
colmat[0] = colmat[5] = colmat[10] = 1.0f;
cbufid = 4;
break;
- case 9: // Z8M
+ case EFBCopyFormat::G8: // Z8M
colmat[1] = colmat[5] = colmat[9] = colmat[13] = 1.0f;
cbufid = 5;
- dstFormat |= _GX_TF_CTF;
break;
- case 10: // Z8L
+ case EFBCopyFormat::B8: // Z8L
colmat[2] = colmat[6] = colmat[10] = colmat[14] = 1.0f;
cbufid = 6;
- dstFormat |= _GX_TF_CTF;
break;
- case 12: // Z16L - copy lower 16 depth bits
+ case EFBCopyFormat::GB8: // Z16L - copy lower 16 depth bits
// expected to be used as an IA8 texture (upper 8 bits stored as intensity, lower 8 bits
// stored as alpha)
// Used e.g. in Zelda: Skyward Sword
colmat[1] = colmat[5] = colmat[9] = colmat[14] = 1.0f;
cbufid = 7;
- dstFormat |= _GX_TF_CTF;
break;
default:
- ERROR_LOG(VIDEO, "Unknown copy zbuf format: 0x%x", dstFormat);
+ ERROR_LOG(VIDEO, "Unknown copy zbuf format: 0x%X", static_cast<int>(dstFormat));
colmat[2] = colmat[5] = colmat[8] = 1.0f;
cbufid = 8;
break;
}
-
- dstFormat |= _GX_TF_ZTF;
}
else if (isIntensity)
{
fConstAdd[0] = fConstAdd[1] = fConstAdd[2] = 16.0f / 255.0f;
switch (dstFormat)
{
- case 0: // I4
- case 1: // I8
- case 2: // IA4
- case 3: // IA8
- case 8: // I8
+ case EFBCopyFormat::R4: // I4
+ case EFBCopyFormat::R8_0x1: // I8
+ case EFBCopyFormat::R8: // IA4
+ case EFBCopyFormat::RA4: // IA8
+ case EFBCopyFormat::RA8: // I8
// TODO - verify these coefficients
colmat[0] = 0.257f;
colmat[1] = 0.504f;
@@ -1066,13 +1049,14 @@ void TextureCacheBase::CopyRenderTargetToTexture(u32 dstAddr, unsigned int dstFo
colmat[9] = 0.504f;
colmat[10] = 0.098f;
- if (dstFormat < 2 || dstFormat == 8)
+ if (dstFormat == EFBCopyFormat::R4 || dstFormat == EFBCopyFormat::R8_0x1 ||
+ dstFormat == EFBCopyFormat::R8)
{
colmat[12] = 0.257f;
colmat[13] = 0.504f;
colmat[14] = 0.098f;
fConstAdd[3] = 16.0f / 255.0f;
- if (dstFormat == 0)
+ if (dstFormat == EFBCopyFormat::R4)
{
ColorMask[0] = ColorMask[1] = ColorMask[2] = 255.0f / 16.0f;
ColorMask[4] = ColorMask[5] = ColorMask[6] = 1.0f / 15.0f;
@@ -1086,7 +1070,7 @@ void TextureCacheBase::CopyRenderTargetToTexture(u32 dstAddr, unsigned int dstFo
else // alpha
{
colmat[15] = 1;
- if (dstFormat == 2)
+ if (dstFormat == EFBCopyFormat::RA4)
{
ColorMask[0] = ColorMask[1] = ColorMask[2] = ColorMask[3] = 255.0f / 16.0f;
ColorMask[4] = ColorMask[5] = ColorMask[6] = ColorMask[7] = 1.0f / 15.0f;
@@ -1100,7 +1084,7 @@ void TextureCacheBase::CopyRenderTargetToTexture(u32 dstAddr, unsigned int dstFo
break;
default:
- ERROR_LOG(VIDEO, "Unknown copy intensity format: 0x%x", dstFormat);
+ ERROR_LOG(VIDEO, "Unknown copy intensity format: 0x%X", static_cast<int>(dstFormat));
colmat[0] = colmat[5] = colmat[10] = colmat[15] = 1.0f;
cbufid = 13;
break;
@@ -1110,21 +1094,19 @@ void TextureCacheBase::CopyRenderTargetToTexture(u32 dstAddr, unsigned int dstFo
{
switch (dstFormat)
{
- case 0: // R4
+ case EFBCopyFormat::R4: // R4
colmat[0] = colmat[4] = colmat[8] = colmat[12] = 1;
ColorMask[0] = 255.0f / 16.0f;
ColorMask[4] = 1.0f / 15.0f;
cbufid = 14;
- dstFormat |= _GX_TF_CTF;
break;
- case 1: // R8
- case 8: // R8
+ case EFBCopyFormat::R8_0x1: // R8
+ case EFBCopyFormat::R8: // R8
colmat[0] = colmat[4] = colmat[8] = colmat[12] = 1;
cbufid = 15;
- dstFormat = GX_CTF_R8;
break;
- case 2: // RA4
+ case EFBCopyFormat::RA4: // RA4
colmat[0] = colmat[4] = colmat[8] = colmat[15] = 1.0f;
ColorMask[0] = ColorMask[3] = 255.0f / 16.0f;
ColorMask[4] = ColorMask[7] = 1.0f / 15.0f;
@@ -1136,9 +1118,8 @@ void TextureCacheBase::CopyRenderTargetToTexture(u32 dstAddr, unsigned int dstFo
fConstAdd[3] = 1.0f;
cbufid = 17;
}
- dstFormat |= _GX_TF_CTF;
break;
- case 3: // RA8
+ case EFBCopyFormat::RA8: // RA8
colmat[0] = colmat[4] = colmat[8] = colmat[15] = 1.0f;
cbufid = 18;
@@ -1148,10 +1129,9 @@ void TextureCacheBase::CopyRenderTargetToTexture(u32 dstAddr, unsigned int dstFo
fConstAdd[3] = 1.0f;
cbufid = 19;
}
- dstFormat |= _GX_TF_CTF;
break;
- case 7: // A8
+ case EFBCopyFormat::A8: // A8
colmat[3] = colmat[7] = colmat[11] = colmat[15] = 1.0f;
cbufid = 20;
@@ -1164,33 +1144,28 @@ void TextureCacheBase::CopyRenderTargetToTexture(u32 dstAddr, unsigned int dstFo
fConstAdd[3] = 1.0f;
cbufid = 21;
}
- dstFormat |= _GX_TF_CTF;
break;
- case 9: // G8
+ case EFBCopyFormat::G8: // G8
colmat[1] = colmat[5] = colmat[9] = colmat[13] = 1.0f;
cbufid = 22;
- dstFormat |= _GX_TF_CTF;
break;
- case 10: // B8
+ case EFBCopyFormat::B8: // B8
colmat[2] = colmat[6] = colmat[10] = colmat[14] = 1.0f;
cbufid = 23;
- dstFormat |= _GX_TF_CTF;
break;
- case 11: // RG8
+ case EFBCopyFormat::RG8: // RG8
colmat[0] = colmat[4] = colmat[8] = colmat[13] = 1.0f;
cbufid = 24;
- dstFormat |= _GX_TF_CTF;
break;
- case 12: // GB8
+ case EFBCopyFormat::GB8: // GB8
colmat[1] = colmat[5] = colmat[9] = colmat[14] = 1.0f;
cbufid = 25;
- dstFormat |= _GX_TF_CTF;
break;
- case 4: // RGB565
+ case EFBCopyFormat::RGB565: // RGB565
colmat[0] = colmat[5] = colmat[10] = 1.0f;
ColorMask[0] = ColorMask[2] = 255.0f / 8.0f;
ColorMask[4] = ColorMask[6] = 1.0f / 31.0f;
@@ -1200,7 +1175,7 @@ void TextureCacheBase::CopyRenderTargetToTexture(u32 dstAddr, unsigned int dstFo
cbufid = 26;
break;
- case 5: // RGB5A3
+ case EFBCopyFormat::RGB5A3: // RGB5A3
colmat[0] = colmat[5] = colmat[10] = colmat[15] = 1.0f;
ColorMask[0] = ColorMask[1] = ColorMask[2] = 255.0f / 8.0f;
ColorMask[4] = ColorMask[5] = ColorMask[6] = 1.0f / 31.0f;
@@ -1215,7 +1190,7 @@ void TextureCacheBase::CopyRenderTargetToTexture(u32 dstAddr, unsigned int dstFo
cbufid = 28;
}
break;
- case 6: // RGBA8
+ case EFBCopyFormat::RGBA8: // RGBA8
colmat[0] = colmat[5] = colmat[10] = colmat[15] = 1.0f;
cbufid = 29;
@@ -1228,7 +1203,7 @@ void TextureCacheBase::CopyRenderTargetToTexture(u32 dstAddr, unsigned int dstFo
break;
default:
- ERROR_LOG(VIDEO, "Unknown copy color format: 0x%x", dstFormat);
+ ERROR_LOG(VIDEO, "Unknown copy color format: 0x%X", static_cast<int>(dstFormat));
colmat[0] = colmat[5] = colmat[10] = colmat[15] = 1.0f;
cbufid = 31;
break;
@@ -1267,7 +1242,7 @@ void TextureCacheBase::CopyRenderTargetToTexture(u32 dstAddr, unsigned int dstFo
}
// Get the base (in memory) format of this efb copy.
- int baseFormat = TexDecoder_GetEfbCopyBaseFormat(dstFormat);
+ TextureFormat baseFormat = TexDecoder_GetEFBCopyBaseFormat(dstFormat);
u32 blockH = TexDecoder_GetBlockHeightInTexels(baseFormat);
const u32 blockW = TexDecoder_GetBlockWidthInTexels(baseFormat);
@@ -1280,7 +1255,7 @@ void TextureCacheBase::CopyRenderTargetToTexture(u32 dstAddr, unsigned int dstFo
const u32 num_blocks_x = actualWidth / blockW;
// RGBA takes two cache lines per block; all others take one
- const u32 bytes_per_block = baseFormat == GX_TF_RGBA8 ? 64 : 32;
+ const u32 bytes_per_block = baseFormat == TextureFormat::RGBA8 ? 64 : 32;
const u32 bytes_per_row = num_blocks_x * bytes_per_block;
const u32 covered_range = num_blocks_y * dstStride;
@@ -1290,9 +1265,8 @@ void TextureCacheBase::CopyRenderTargetToTexture(u32 dstAddr, unsigned int dstFo
if (copy_to_ram)
{
- EFBCopyFormat format(srcFormat, static_cast<TextureFormat>(dstFormat));
- CopyEFB(dst, format, tex_w, bytes_per_row, num_blocks_y, dstStride, is_depth_copy, srcRect,
- scaleByHalf);
+ EFBCopyParams format(srcFormat, dstFormat, is_depth_copy, isIntensity);
+ CopyEFB(dst, format, tex_w, bytes_per_row, num_blocks_y, dstStride, srcRect, scaleByHalf);
}
else
{
@@ -1510,7 +1484,7 @@ TextureCacheBase::InvalidateTexture(TexAddrCache::iterator iter)
u32 TextureCacheBase::TCacheEntry::BytesPerRow() const
{
- const u32 blockW = TexDecoder_GetBlockWidthInTexels(format);
+ const u32 blockW = TexDecoder_GetBlockWidthInTexels(format.texfmt);
// Round up source height to multiple of block size
const u32 actualWidth = Common::AlignUp(native_width, blockW);
@@ -1518,14 +1492,14 @@ u32 TextureCacheBase::TCacheEntry::BytesPerRow() const
const u32 numBlocksX = actualWidth / blockW;
// RGBA takes two cache lines per block; all others take one
- const u32 bytes_per_block = format == GX_TF_RGBA8 ? 64 : 32;
+ const u32 bytes_per_block = format == TextureFormat::RGBA8 ? 64 : 32;
return numBlocksX * bytes_per_block;
}
u32 TextureCacheBase::TCacheEntry::NumBlocksY() const
{
- u32 blockH = TexDecoder_GetBlockHeightInTexels(format);
+ u32 blockH = TexDecoder_GetBlockHeightInTexels(format.texfmt);
// Round up source height to multiple of block size
u32 actualHeight = Common::AlignUp(native_height, blockH);