diff options
| author | N.E.C <beholdnec@gmail.com> | 2017-07-30 12:45:55 -0700 |
|---|---|---|
| committer | N.E.C <beholdnec@gmail.com> | 2017-08-03 18:35:29 -0700 |
| commit | c3a57bbad53567af4546a68f0e9dbcd913bd9a75 (patch) | |
| tree | 4ff1176b00c8df323df8610ff2076545e15c60de /Source/Core/VideoCommon | |
| parent | 9649494f67b86b91c9086f4a9e356fb832c4a9b7 (diff) | |
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.
Diffstat (limited to 'Source/Core/VideoCommon')
| -rw-r--r-- | Source/Core/VideoCommon/BPMemory.h | 7 | ||||
| -rw-r--r-- | Source/Core/VideoCommon/HiresTextures.cpp | 5 | ||||
| -rw-r--r-- | Source/Core/VideoCommon/HiresTextures.h | 6 | ||||
| -rw-r--r-- | Source/Core/VideoCommon/TextureCacheBase.cpp | 168 | ||||
| -rw-r--r-- | Source/Core/VideoCommon/TextureCacheBase.h | 68 | ||||
| -rw-r--r-- | Source/Core/VideoCommon/TextureConversionShader.cpp | 390 | ||||
| -rw-r--r-- | Source/Core/VideoCommon/TextureConversionShader.h | 11 | ||||
| -rw-r--r-- | Source/Core/VideoCommon/TextureDecoder.h | 155 | ||||
| -rw-r--r-- | Source/Core/VideoCommon/TextureDecoder_Common.cpp | 393 | ||||
| -rw-r--r-- | Source/Core/VideoCommon/TextureDecoder_Generic.cpp | 40 | ||||
| -rw-r--r-- | Source/Core/VideoCommon/TextureDecoder_x64.cpp | 111 |
11 files changed, 649 insertions, 705 deletions
diff --git a/Source/Core/VideoCommon/BPMemory.h b/Source/Core/VideoCommon/BPMemory.h index ceb1fd3899..e2730c1472 100644 --- a/Source/Core/VideoCommon/BPMemory.h +++ b/Source/Core/VideoCommon/BPMemory.h @@ -9,6 +9,8 @@ #include "Common/BitField.h" #include "Common/CommonTypes.h" +enum class EFBCopyFormat; + #pragma pack(4) enum @@ -958,7 +960,10 @@ union UPE_Copy BitField<16, 1, u32> auto_conv; // if 0 automatic color conversion by texture format and pixel type - u32 tp_realFormat() const { return target_pixel_format / 2 + (target_pixel_format & 1) * 8; } + EFBCopyFormat tp_realFormat() const + { + return static_cast<EFBCopyFormat>(target_pixel_format / 2 + (target_pixel_format & 1) * 8); + } }; union BPU_PreloadTileInfo diff --git a/Source/Core/VideoCommon/HiresTextures.cpp b/Source/Core/VideoCommon/HiresTextures.cpp index 36b170ef10..60b7630512 100644 --- a/Source/Core/VideoCommon/HiresTextures.cpp +++ b/Source/Core/VideoCommon/HiresTextures.cpp @@ -215,7 +215,7 @@ void HiresTexture::Prefetch() } std::string HiresTexture::GenBaseName(const u8* texture, size_t texture_size, const u8* tlut, - size_t tlut_size, u32 width, u32 height, int format, + size_t tlut_size, u32 width, u32 height, TextureFormat format, bool has_mipmaps, bool dump) { std::string name = ""; @@ -385,7 +385,8 @@ u32 HiresTexture::CalculateMipCount(u32 width, u32 height) std::shared_ptr<HiresTexture> HiresTexture::Search(const u8* texture, size_t texture_size, const u8* tlut, size_t tlut_size, u32 width, - u32 height, int format, bool has_mipmaps) + u32 height, TextureFormat format, + bool has_mipmaps) { std::string base_filename = GenBaseName(texture, texture_size, tlut, tlut_size, width, height, format, has_mipmaps); diff --git a/Source/Core/VideoCommon/HiresTextures.h b/Source/Core/VideoCommon/HiresTextures.h index 3e7625c993..a88e984acd 100644 --- a/Source/Core/VideoCommon/HiresTextures.h +++ b/Source/Core/VideoCommon/HiresTextures.h @@ -11,6 +11,8 @@ #include "Common/CommonTypes.h" #include "VideoCommon/TextureConfig.h" +enum class TextureFormat; + class HiresTexture { public: @@ -22,10 +24,10 @@ public: static std::shared_ptr<HiresTexture> Search(const u8* texture, size_t texture_size, const u8* tlut, size_t tlut_size, u32 width, - u32 height, int format, bool has_mipmaps); + u32 height, TextureFormat format, bool has_mipmaps); static std::string GenBaseName(const u8* texture, size_t texture_size, const u8* tlut, - size_t tlut_size, u32 width, u32 height, int format, + size_t tlut_size, u32 width, u32 height, TextureFormat format, bool has_mipmaps, bool dump = false); static u32 CalculateMipCount(u32 width, u32 height); 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); diff --git a/Source/Core/VideoCommon/TextureCacheBase.h b/Source/Core/VideoCommon/TextureCacheBase.h index 56bf6fb849..00ca728157 100644 --- a/Source/Core/VideoCommon/TextureCacheBase.h +++ b/Source/Core/VideoCommon/TextureCacheBase.h @@ -21,6 +21,47 @@ struct VideoConfig; +struct TextureAndTLUTFormat +{ + TextureAndTLUTFormat(TextureFormat texfmt_ = TextureFormat::I4, + TLUTFormat tlutfmt_ = TLUTFormat::IA8) + : texfmt(texfmt_), tlutfmt(tlutfmt_) + { + } + + bool operator==(const TextureAndTLUTFormat& other) const + { + if (IsColorIndexed(texfmt)) + return texfmt == other.texfmt && tlutfmt == other.tlutfmt; + + return texfmt == other.texfmt; + } + + bool operator!=(const TextureAndTLUTFormat& other) const { return !operator==(other); } + TextureFormat texfmt; + TLUTFormat tlutfmt; +}; + +struct EFBCopyParams +{ + EFBCopyParams(PEControl::PixelFormat efb_format_, EFBCopyFormat copy_format_, bool depth_, + bool yuv_) + : efb_format(efb_format_), copy_format(copy_format_), depth(depth_), yuv(yuv_) + { + } + + bool operator<(const EFBCopyParams& rhs) const + { + return std::tie(efb_format, copy_format, depth, yuv) < + std::tie(rhs.efb_format, rhs.copy_format, rhs.depth, rhs.yuv); + } + + PEControl::PixelFormat efb_format; + EFBCopyFormat copy_format; + bool depth; + bool yuv; +}; + class TextureCacheBase { private: @@ -34,8 +75,8 @@ public: u32 addr; u32 size_in_bytes; u64 base_hash; - u64 hash; // for paletted textures, hash = base_hash ^ palette_hash - u32 format; // bits 0-3 will contain the in-memory format. + u64 hash; // for paletted textures, hash = base_hash ^ palette_hash + TextureAndTLUTFormat format; u32 memory_stride; bool is_efb_copy; bool is_custom_tex; @@ -62,7 +103,7 @@ public: ~TCacheEntry(); - void SetGeneralParameters(u32 _addr, u32 _size, u32 _format) + void SetGeneralParameters(u32 _addr, u32 _size, TextureAndTLUTFormat _format) { addr = _addr; size_in_bytes = _size; @@ -119,9 +160,9 @@ public: void Invalidate(); - virtual void CopyEFB(u8* dst, const EFBCopyFormat& format, u32 native_width, u32 bytes_per_row, - u32 num_blocks_y, u32 memory_stride, bool is_depth_copy, - const EFBRectangle& src_rect, bool scale_by_half) = 0; + virtual void CopyEFB(u8* dst, const EFBCopyParams& params, u32 native_width, u32 bytes_per_row, + u32 num_blocks_y, u32 memory_stride, const EFBRectangle& src_rect, + bool scale_by_half) = 0; virtual bool CompileShaders() = 0; virtual void DeleteShaders() = 0; @@ -130,15 +171,15 @@ public: static void InvalidateAllBindPoints() { valid_bind_points.reset(); } static bool IsValidBindPoint(u32 i) { return valid_bind_points.test(i); } void BindTextures(); - void CopyRenderTargetToTexture(u32 dstAddr, unsigned int dstFormat, u32 dstStride, + void CopyRenderTargetToTexture(u32 dstAddr, EFBCopyFormat dstFormat, u32 dstStride, bool is_depth_copy, const EFBRectangle& srcRect, bool isIntensity, bool scaleByHalf); - virtual void ConvertTexture(TCacheEntry* entry, TCacheEntry* unconverted, void* palette, - TlutFormat format) = 0; + virtual void ConvertTexture(TCacheEntry* entry, TCacheEntry* unconverted, const void* palette, + TLUTFormat format) = 0; // Returns true if the texture data and palette formats are supported by the GPU decoder. - virtual bool SupportsGPUTextureDecode(TextureFormat format, TlutFormat palette_format) + virtual bool SupportsGPUTextureDecode(TextureFormat format, TLUTFormat palette_format) { return false; } @@ -150,7 +191,7 @@ public: virtual void DecodeTextureOnGPU(TCacheEntry* entry, u32 dst_level, const u8* data, size_t data_size, TextureFormat format, u32 width, u32 height, u32 aligned_width, u32 aligned_height, u32 row_stride, - const u8* palette, TlutFormat palette_format) + const u8* palette, TLUTFormat palette_format) { } @@ -177,10 +218,11 @@ private: void SetBackupConfig(const VideoConfig& config); - TCacheEntry* ApplyPaletteToEntry(TCacheEntry* entry, u8* palette, u32 tlutfmt); + TCacheEntry* ApplyPaletteToEntry(TCacheEntry* entry, u8* palette, TLUTFormat tlutfmt); void ScaleTextureCacheEntryTo(TCacheEntry* entry, u32 new_width, u32 new_height); - TCacheEntry* DoPartialTextureUpdates(TCacheEntry* entry_to_update, u8* palette, u32 tlutfmt); + TCacheEntry* DoPartialTextureUpdates(TCacheEntry* entry_to_update, u8* palette, + TLUTFormat tlutfmt); void DumpTexture(TCacheEntry* entry, std::string basename, unsigned int level); void CheckTempSize(size_t required_size); diff --git a/Source/Core/VideoCommon/TextureConversionShader.cpp b/Source/Core/VideoCommon/TextureConversionShader.cpp index e6da729059..ab1b284b78 100644 --- a/Source/Core/VideoCommon/TextureConversionShader.cpp +++ b/Source/Core/VideoCommon/TextureConversionShader.cpp @@ -13,6 +13,7 @@ #include "Common/MathUtil.h" #include "Common/MsgHandler.h" #include "VideoCommon/RenderBase.h" +#include "VideoCommon/TextureCacheBase.h" #include "VideoCommon/TextureConversionShader.h" #include "VideoCommon/VideoCommon.h" @@ -23,64 +24,40 @@ static bool IntensityConstantAdded = false; namespace TextureConversionShader { -u16 GetEncodedSampleCount(u32 format) +u16 GetEncodedSampleCount(EFBCopyFormat format) { switch (format) { - case GX_TF_I4: + case EFBCopyFormat::R4: return 8; - case GX_TF_I8: + case EFBCopyFormat::RA4: return 4; - case GX_TF_IA4: - return 4; - case GX_TF_IA8: - return 2; - case GX_TF_RGB565: - return 2; - case GX_TF_RGB5A3: - return 2; - case GX_TF_RGBA8: - return 1; - case GX_CTF_R4: - return 8; - case GX_CTF_RA4: - return 4; - case GX_CTF_RA8: - return 2; - 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: + case EFBCopyFormat::RA8: return 2; - case GX_CTF_GB8: + case EFBCopyFormat::RGB565: return 2; - case GX_TF_Z8: - return 4; - case GX_TF_Z16: + case EFBCopyFormat::RGB5A3: return 2; - case GX_TF_Z24X8: + case EFBCopyFormat::RGBA8: return 1; - case GX_CTF_Z4: - return 8; - case GX_CTF_Z8M: + case EFBCopyFormat::A8: + case EFBCopyFormat::R8_0x1: + case EFBCopyFormat::R8: + case EFBCopyFormat::G8: + case EFBCopyFormat::B8: return 4; - case GX_CTF_Z8L: - return 4; - case GX_CTF_Z16L: + case EFBCopyFormat::RG8: + case EFBCopyFormat::GB8: return 2; default: + PanicAlert("Invalid EFB Copy Format (0x%X)! (GetEncodedSampleCount)", static_cast<int>(format)); return 1; } } // block dimensions : widthStride, heightStride // texture dims : width, height, x offset, y offset -static void WriteSwizzler(char*& p, u32 format, APIType ApiType) +static void WriteSwizzler(char*& p, EFBCopyFormat format, APIType ApiType) { // left, top, of source rectangle within source texture // width of the destination rectangle, scale_factor (1 or 2) @@ -108,8 +85,8 @@ static void WriteSwizzler(char*& p, u32 format, APIType ApiType) WRITE(p, " return float4(val) / float4(31.0, 63.0, 31.0, 1.0);\n"); WRITE(p, "}\n"); - int blkW = TexDecoder_GetBlockWidthInTexels(format); - int blkH = TexDecoder_GetBlockHeightInTexels(format); + int blkW = TexDecoder_GetEFBCopyBlockWidthInTexels(format); + int blkH = TexDecoder_GetEFBCopyBlockHeightInTexels(format); int samples = GetEncodedSampleCount(format); if (ApiType == APIType::OpenGL) @@ -180,13 +157,13 @@ static void WriteSwizzler(char*& p, u32 format, APIType ApiType) } static void WriteSampleColor(char*& p, const char* colorComp, const char* dest, int xoffset, - APIType ApiType, const EFBCopyFormat& format, bool depth) + APIType ApiType, const EFBCopyParams& params) { WRITE(p, " %s = ", dest); - if (!depth) + if (!params.depth) { - switch (format.efb_format) + switch (params.efb_format) { case PEControl::RGB8_Z24: WRITE(p, "RGBA8ToRGB8("); @@ -246,21 +223,21 @@ static void WriteEncoderEnd(char*& p) IntensityConstantAdded = false; } -static void WriteI8Encoder(char*& p, APIType ApiType, const EFBCopyFormat& format) +static void WriteI8Encoder(char*& p, APIType ApiType, const EFBCopyParams& params) { - WriteSwizzler(p, GX_TF_I8, ApiType); + WriteSwizzler(p, EFBCopyFormat::R8, ApiType); WRITE(p, " float3 texSample;\n"); - WriteSampleColor(p, "rgb", "texSample", 0, ApiType, format, false); + WriteSampleColor(p, "rgb", "texSample", 0, ApiType, params); WriteColorToIntensity(p, "texSample", "ocol0.b"); - WriteSampleColor(p, "rgb", "texSample", 1, ApiType, format, false); + WriteSampleColor(p, "rgb", "texSample", 1, ApiType, params); WriteColorToIntensity(p, "texSample", "ocol0.g"); - WriteSampleColor(p, "rgb", "texSample", 2, ApiType, format, false); + WriteSampleColor(p, "rgb", "texSample", 2, ApiType, params); WriteColorToIntensity(p, "texSample", "ocol0.r"); - WriteSampleColor(p, "rgb", "texSample", 3, ApiType, format, false); + WriteSampleColor(p, "rgb", "texSample", 3, ApiType, params); WriteColorToIntensity(p, "texSample", "ocol0.a"); WRITE(p, " ocol0.rgba += IntensityConst.aaaa;\n"); // see WriteColorToIntensity @@ -268,35 +245,35 @@ static void WriteI8Encoder(char*& p, APIType ApiType, const EFBCopyFormat& forma WriteEncoderEnd(p); } -static void WriteI4Encoder(char*& p, APIType ApiType, const EFBCopyFormat& format) +static void WriteI4Encoder(char*& p, APIType ApiType, const EFBCopyParams& params) { - WriteSwizzler(p, GX_TF_I4, ApiType); + WriteSwizzler(p, EFBCopyFormat::R4, ApiType); WRITE(p, " float3 texSample;\n"); WRITE(p, " float4 color0;\n"); WRITE(p, " float4 color1;\n"); - WriteSampleColor(p, "rgb", "texSample", 0, ApiType, format, false); + WriteSampleColor(p, "rgb", "texSample", 0, ApiType, params); WriteColorToIntensity(p, "texSample", "color0.b"); - WriteSampleColor(p, "rgb", "texSample", 1, ApiType, format, false); + WriteSampleColor(p, "rgb", "texSample", 1, ApiType, params); WriteColorToIntensity(p, "texSample", "color1.b"); - WriteSampleColor(p, "rgb", "texSample", 2, ApiType, format, false); + WriteSampleColor(p, "rgb", "texSample", 2, ApiType, params); WriteColorToIntensity(p, "texSample", "color0.g"); - WriteSampleColor(p, "rgb", "texSample", 3, ApiType, format, false); + WriteSampleColor(p, "rgb", "texSample", 3, ApiType, params); WriteColorToIntensity(p, "texSample", "color1.g"); - WriteSampleColor(p, "rgb", "texSample", 4, ApiType, format, false); + WriteSampleColor(p, "rgb", "texSample", 4, ApiType, params); WriteColorToIntensity(p, "texSample", "color0.r"); - WriteSampleColor(p, "rgb", "texSample", 5, ApiType, format, false); + WriteSampleColor(p, "rgb", "texSample", 5, ApiType, params); WriteColorToIntensity(p, "texSample", "color1.r"); - WriteSampleColor(p, "rgb", "texSample", 6, ApiType, format, false); + WriteSampleColor(p, "rgb", "texSample", 6, ApiType, params); WriteColorToIntensity(p, "texSample", "color0.a"); - WriteSampleColor(p, "rgb", "texSample", 7, ApiType, format, false); + WriteSampleColor(p, "rgb", "texSample", 7, ApiType, params); WriteColorToIntensity(p, "texSample", "color1.a"); WRITE(p, " color0.rgba += IntensityConst.aaaa;\n"); @@ -309,16 +286,16 @@ static void WriteI4Encoder(char*& p, APIType ApiType, const EFBCopyFormat& forma WriteEncoderEnd(p); } -static void WriteIA8Encoder(char*& p, APIType ApiType, const EFBCopyFormat& format) +static void WriteIA8Encoder(char*& p, APIType ApiType, const EFBCopyParams& params) { - WriteSwizzler(p, GX_TF_IA8, ApiType); + WriteSwizzler(p, EFBCopyFormat::RA8, ApiType); WRITE(p, " float4 texSample;\n"); - WriteSampleColor(p, "rgba", "texSample", 0, ApiType, format, false); + WriteSampleColor(p, "rgba", "texSample", 0, ApiType, params); WRITE(p, " ocol0.b = texSample.a;\n"); WriteColorToIntensity(p, "texSample", "ocol0.g"); - WriteSampleColor(p, "rgba", "texSample", 1, ApiType, format, false); + WriteSampleColor(p, "rgba", "texSample", 1, ApiType, params); WRITE(p, " ocol0.r = texSample.a;\n"); WriteColorToIntensity(p, "texSample", "ocol0.a"); @@ -327,26 +304,26 @@ static void WriteIA8Encoder(char*& p, APIType ApiType, const EFBCopyFormat& form WriteEncoderEnd(p); } -static void WriteIA4Encoder(char*& p, APIType ApiType, const EFBCopyFormat& format) +static void WriteIA4Encoder(char*& p, APIType ApiType, const EFBCopyParams& params) { - WriteSwizzler(p, GX_TF_IA4, ApiType); + WriteSwizzler(p, EFBCopyFormat::RA4, ApiType); WRITE(p, " float4 texSample;\n"); WRITE(p, " float4 color0;\n"); WRITE(p, " float4 color1;\n"); - WriteSampleColor(p, "rgba", "texSample", 0, ApiType, format, false); + WriteSampleColor(p, "rgba", "texSample", 0, ApiType, params); WRITE(p, " color0.b = texSample.a;\n"); WriteColorToIntensity(p, "texSample", "color1.b"); - WriteSampleColor(p, "rgba", "texSample", 1, ApiType, format, false); + WriteSampleColor(p, "rgba", "texSample", 1, ApiType, params); WRITE(p, " color0.g = texSample.a;\n"); WriteColorToIntensity(p, "texSample", "color1.g"); - WriteSampleColor(p, "rgba", "texSample", 2, ApiType, format, false); + WriteSampleColor(p, "rgba", "texSample", 2, ApiType, params); WRITE(p, " color0.r = texSample.a;\n"); WriteColorToIntensity(p, "texSample", "color1.r"); - WriteSampleColor(p, "rgba", "texSample", 3, ApiType, format, false); + WriteSampleColor(p, "rgba", "texSample", 3, ApiType, params); WRITE(p, " color0.a = texSample.a;\n"); WriteColorToIntensity(p, "texSample", "color1.a"); @@ -359,14 +336,14 @@ static void WriteIA4Encoder(char*& p, APIType ApiType, const EFBCopyFormat& form WriteEncoderEnd(p); } -static void WriteRGB565Encoder(char*& p, APIType ApiType, const EFBCopyFormat& format) +static void WriteRGB565Encoder(char*& p, APIType ApiType, const EFBCopyParams& params) { - WriteSwizzler(p, GX_TF_RGB565, ApiType); + WriteSwizzler(p, EFBCopyFormat::RGB565, ApiType); WRITE(p, " float3 texSample0;\n"); WRITE(p, " float3 texSample1;\n"); - WriteSampleColor(p, "rgb", "texSample0", 0, ApiType, format, false); - WriteSampleColor(p, "rgb", "texSample1", 1, ApiType, format, false); + WriteSampleColor(p, "rgb", "texSample0", 0, ApiType, params); + WriteSampleColor(p, "rgb", "texSample1", 1, ApiType, params); WRITE(p, " float2 texRs = float2(texSample0.r, texSample1.r);\n"); WRITE(p, " float2 texGs = float2(texSample0.g, texSample1.g);\n"); WRITE(p, " float2 texBs = float2(texSample0.b, texSample1.b);\n"); @@ -384,16 +361,16 @@ static void WriteRGB565Encoder(char*& p, APIType ApiType, const EFBCopyFormat& f WriteEncoderEnd(p); } -static void WriteRGB5A3Encoder(char*& p, APIType ApiType, const EFBCopyFormat& format) +static void WriteRGB5A3Encoder(char*& p, APIType ApiType, const EFBCopyParams& params) { - WriteSwizzler(p, GX_TF_RGB5A3, ApiType); + WriteSwizzler(p, EFBCopyFormat::RGB5A3, ApiType); WRITE(p, " float4 texSample;\n"); WRITE(p, " float color0;\n"); WRITE(p, " float gUpper;\n"); WRITE(p, " float gLower;\n"); - WriteSampleColor(p, "rgba", "texSample", 0, ApiType, format, false); + WriteSampleColor(p, "rgba", "texSample", 0, ApiType, params); // 0.8784 = 224 / 255 which is the maximum alpha value that can be represented in 3 bits WRITE(p, "if(texSample.a > 0.878f) {\n"); @@ -419,7 +396,7 @@ static void WriteRGB5A3Encoder(char*& p, APIType ApiType, const EFBCopyFormat& f WRITE(p, "}\n"); - WriteSampleColor(p, "rgba", "texSample", 1, ApiType, format, false); + WriteSampleColor(p, "rgba", "texSample", 1, ApiType, params); WRITE(p, "if(texSample.a > 0.878f) {\n"); @@ -448,21 +425,21 @@ static void WriteRGB5A3Encoder(char*& p, APIType ApiType, const EFBCopyFormat& f WriteEncoderEnd(p); } -static void WriteRGBA8Encoder(char*& p, APIType ApiType, const EFBCopyFormat& format) +static void WriteRGBA8Encoder(char*& p, APIType ApiType, const EFBCopyParams& params) { - WriteSwizzler(p, GX_TF_RGBA8, ApiType); + WriteSwizzler(p, EFBCopyFormat::RGBA8, ApiType); WRITE(p, " float4 texSample;\n"); WRITE(p, " float4 color0;\n"); WRITE(p, " float4 color1;\n"); - WriteSampleColor(p, "rgba", "texSample", 0, ApiType, format, false); + WriteSampleColor(p, "rgba", "texSample", 0, ApiType, params); WRITE(p, " color0.b = texSample.a;\n"); WRITE(p, " color0.g = texSample.r;\n"); WRITE(p, " color1.b = texSample.g;\n"); WRITE(p, " color1.g = texSample.b;\n"); - WriteSampleColor(p, "rgba", "texSample", 1, ApiType, format, false); + WriteSampleColor(p, "rgba", "texSample", 1, ApiType, params); WRITE(p, " color0.r = texSample.a;\n"); WRITE(p, " color0.a = texSample.r;\n"); WRITE(p, " color1.r = texSample.g;\n"); @@ -473,21 +450,20 @@ static void WriteRGBA8Encoder(char*& p, APIType ApiType, const EFBCopyFormat& fo WriteEncoderEnd(p); } -static void WriteC4Encoder(char*& p, const char* comp, APIType ApiType, const EFBCopyFormat& format, - bool depth) +static void WriteC4Encoder(char*& p, const char* comp, APIType ApiType, const EFBCopyParams& params) { - WriteSwizzler(p, GX_CTF_R4, ApiType); + WriteSwizzler(p, EFBCopyFormat::R4, ApiType); WRITE(p, " float4 color0;\n"); WRITE(p, " float4 color1;\n"); - WriteSampleColor(p, comp, "color0.b", 0, ApiType, format, depth); - WriteSampleColor(p, comp, "color1.b", 1, ApiType, format, depth); - WriteSampleColor(p, comp, "color0.g", 2, ApiType, format, depth); - WriteSampleColor(p, comp, "color1.g", 3, ApiType, format, depth); - WriteSampleColor(p, comp, "color0.r", 4, ApiType, format, depth); - WriteSampleColor(p, comp, "color1.r", 5, ApiType, format, depth); - WriteSampleColor(p, comp, "color0.a", 6, ApiType, format, depth); - WriteSampleColor(p, comp, "color1.a", 7, ApiType, format, depth); + WriteSampleColor(p, comp, "color0.b", 0, ApiType, params); + WriteSampleColor(p, comp, "color1.b", 1, ApiType, params); + WriteSampleColor(p, comp, "color0.g", 2, ApiType, params); + WriteSampleColor(p, comp, "color1.g", 3, ApiType, params); + WriteSampleColor(p, comp, "color0.r", 4, ApiType, params); + WriteSampleColor(p, comp, "color1.r", 5, ApiType, params); + WriteSampleColor(p, comp, "color0.a", 6, ApiType, params); + WriteSampleColor(p, comp, "color1.a", 7, ApiType, params); WriteToBitDepth(p, 4, "color0", "color0"); WriteToBitDepth(p, 4, "color1", "color1"); @@ -496,40 +472,39 @@ static void WriteC4Encoder(char*& p, const char* comp, APIType ApiType, const EF WriteEncoderEnd(p); } -static void WriteC8Encoder(char*& p, const char* comp, APIType ApiType, const EFBCopyFormat& format, - bool depth) +static void WriteC8Encoder(char*& p, const char* comp, APIType ApiType, const EFBCopyParams& params) { - WriteSwizzler(p, GX_CTF_R8, ApiType); + WriteSwizzler(p, EFBCopyFormat::R8, ApiType); - WriteSampleColor(p, comp, "ocol0.b", 0, ApiType, format, depth); - WriteSampleColor(p, comp, "ocol0.g", 1, ApiType, format, depth); - WriteSampleColor(p, comp, "ocol0.r", 2, ApiType, format, depth); - WriteSampleColor(p, comp, "ocol0.a", 3, ApiType, format, depth); + WriteSampleColor(p, comp, "ocol0.b", 0, ApiType, params); + WriteSampleColor(p, comp, "ocol0.g", 1, ApiType, params); + WriteSampleColor(p, comp, "ocol0.r", 2, ApiType, params); + WriteSampleColor(p, comp, "ocol0.a", 3, ApiType, params); WriteEncoderEnd(p); } static void WriteCC4Encoder(char*& p, const char* comp, APIType ApiType, - const EFBCopyFormat& format) + const EFBCopyParams& params) { - WriteSwizzler(p, GX_CTF_RA4, ApiType); + WriteSwizzler(p, EFBCopyFormat::RA4, ApiType); WRITE(p, " float2 texSample;\n"); WRITE(p, " float4 color0;\n"); WRITE(p, " float4 color1;\n"); - WriteSampleColor(p, comp, "texSample", 0, ApiType, format, false); + WriteSampleColor(p, comp, "texSample", 0, ApiType, params); WRITE(p, " color0.b = texSample.x;\n"); WRITE(p, " color1.b = texSample.y;\n"); - WriteSampleColor(p, comp, "texSample", 1, ApiType, format, false); + WriteSampleColor(p, comp, "texSample", 1, ApiType, params); WRITE(p, " color0.g = texSample.x;\n"); WRITE(p, " color1.g = texSample.y;\n"); - WriteSampleColor(p, comp, "texSample", 2, ApiType, format, false); + WriteSampleColor(p, comp, "texSample", 2, ApiType, params); WRITE(p, " color0.r = texSample.x;\n"); WRITE(p, " color1.r = texSample.y;\n"); - WriteSampleColor(p, comp, "texSample", 3, ApiType, format, false); + WriteSampleColor(p, comp, "texSample", 3, ApiType, params); WRITE(p, " color0.a = texSample.x;\n"); WRITE(p, " color1.a = texSample.y;\n"); @@ -541,48 +516,48 @@ static void WriteCC4Encoder(char*& p, const char* comp, APIType ApiType, } static void WriteCC8Encoder(char*& p, const char* comp, APIType ApiType, - const EFBCopyFormat& format) + const EFBCopyParams& params) { - WriteSwizzler(p, GX_CTF_RA8, ApiType); + WriteSwizzler(p, EFBCopyFormat::RA8, ApiType); - WriteSampleColor(p, comp, "ocol0.bg", 0, ApiType, format, false); - WriteSampleColor(p, comp, "ocol0.ra", 1, ApiType, format, false); + WriteSampleColor(p, comp, "ocol0.bg", 0, ApiType, params); + WriteSampleColor(p, comp, "ocol0.ra", 1, ApiType, params); WriteEncoderEnd(p); } static void WriteZ8Encoder(char*& p, const char* multiplier, APIType ApiType, - const EFBCopyFormat& format) + const EFBCopyParams& params) { - WriteSwizzler(p, GX_CTF_Z8M, ApiType); + WriteSwizzler(p, EFBCopyFormat::G8, ApiType); WRITE(p, " float depth;\n"); - WriteSampleColor(p, "r", "depth", 0, ApiType, format, true); + WriteSampleColor(p, "r", "depth", 0, ApiType, params); WRITE(p, "ocol0.b = frac(depth * %s);\n", multiplier); - WriteSampleColor(p, "r", "depth", 1, ApiType, format, true); + WriteSampleColor(p, "r", "depth", 1, ApiType, params); WRITE(p, "ocol0.g = frac(depth * %s);\n", multiplier); - WriteSampleColor(p, "r", "depth", 2, ApiType, format, true); + WriteSampleColor(p, "r", "depth", 2, ApiType, params); WRITE(p, "ocol0.r = frac(depth * %s);\n", multiplier); - WriteSampleColor(p, "r", "depth", 3, ApiType, format, true); + WriteSampleColor(p, "r", "depth", 3, ApiType, params); WRITE(p, "ocol0.a = frac(depth * %s);\n", multiplier); WriteEncoderEnd(p); } -static void WriteZ16Encoder(char*& p, APIType ApiType, const EFBCopyFormat& format) +static void WriteZ16Encoder(char*& p, APIType ApiType, const EFBCopyParams& params) { - WriteSwizzler(p, GX_TF_Z16, ApiType); + WriteSwizzler(p, EFBCopyFormat::RA8, ApiType); WRITE(p, " float depth;\n"); WRITE(p, " float3 expanded;\n"); // byte order is reversed - WriteSampleColor(p, "r", "depth", 0, ApiType, format, true); + WriteSampleColor(p, "r", "depth", 0, ApiType, params); WRITE(p, " depth *= 16777216.0;\n"); WRITE(p, " expanded.r = floor(depth / (256.0 * 256.0));\n"); @@ -592,7 +567,7 @@ static void WriteZ16Encoder(char*& p, APIType ApiType, const EFBCopyFormat& form WRITE(p, " ocol0.b = expanded.g / 255.0;\n"); WRITE(p, " ocol0.g = expanded.r / 255.0;\n"); - WriteSampleColor(p, "r", "depth", 1, ApiType, format, true); + WriteSampleColor(p, "r", "depth", 1, ApiType, params); WRITE(p, " depth *= 16777216.0;\n"); WRITE(p, " expanded.r = floor(depth / (256.0 * 256.0));\n"); @@ -605,16 +580,16 @@ static void WriteZ16Encoder(char*& p, APIType ApiType, const EFBCopyFormat& form WriteEncoderEnd(p); } -static void WriteZ16LEncoder(char*& p, APIType ApiType, const EFBCopyFormat& format) +static void WriteZ16LEncoder(char*& p, APIType ApiType, const EFBCopyParams& params) { - WriteSwizzler(p, GX_CTF_Z16L, ApiType); + WriteSwizzler(p, EFBCopyFormat::GB8, ApiType); WRITE(p, " float depth;\n"); WRITE(p, " float3 expanded;\n"); // byte order is reversed - WriteSampleColor(p, "r", "depth", 0, ApiType, format, true); + WriteSampleColor(p, "r", "depth", 0, ApiType, params); WRITE(p, " depth *= 16777216.0;\n"); WRITE(p, " expanded.r = floor(depth / (256.0 * 256.0));\n"); @@ -626,7 +601,7 @@ static void WriteZ16LEncoder(char*& p, APIType ApiType, const EFBCopyFormat& for WRITE(p, " ocol0.b = expanded.b / 255.0;\n"); WRITE(p, " ocol0.g = expanded.g / 255.0;\n"); - WriteSampleColor(p, "r", "depth", 1, ApiType, format, true); + WriteSampleColor(p, "r", "depth", 1, ApiType, params); WRITE(p, " depth *= 16777216.0;\n"); WRITE(p, " expanded.r = floor(depth / (256.0 * 256.0));\n"); @@ -641,17 +616,17 @@ static void WriteZ16LEncoder(char*& p, APIType ApiType, const EFBCopyFormat& for WriteEncoderEnd(p); } -static void WriteZ24Encoder(char*& p, APIType ApiType, const EFBCopyFormat& format) +static void WriteZ24Encoder(char*& p, APIType ApiType, const EFBCopyParams& params) { - WriteSwizzler(p, GX_TF_Z24X8, ApiType); + WriteSwizzler(p, EFBCopyFormat::RGBA8, ApiType); WRITE(p, " float depth0;\n"); WRITE(p, " float depth1;\n"); WRITE(p, " float3 expanded0;\n"); WRITE(p, " float3 expanded1;\n"); - WriteSampleColor(p, "r", "depth0", 0, ApiType, format, true); - WriteSampleColor(p, "r", "depth1", 1, ApiType, format, true); + WriteSampleColor(p, "r", "depth0", 0, ApiType, params); + WriteSampleColor(p, "r", "depth1", 1, ApiType, params); for (int i = 0; i < 2; i++) { @@ -681,87 +656,81 @@ static void WriteZ24Encoder(char*& p, APIType ApiType, const EFBCopyFormat& form WriteEncoderEnd(p); } -const char* GenerateEncodingShader(const EFBCopyFormat& format, APIType api_type) +const char* GenerateEncodingShader(const EFBCopyParams& params, APIType api_type) { text[sizeof(text) - 1] = 0x7C; // canary char* p = text; - switch (format.copy_format) + switch (params.copy_format) { - case GX_TF_I4: - WriteI4Encoder(p, api_type, format); - break; - case GX_TF_I8: - WriteI8Encoder(p, api_type, format); - break; - case GX_TF_IA4: - WriteIA4Encoder(p, api_type, format); - break; - case GX_TF_IA8: - WriteIA8Encoder(p, api_type, format); - break; - case GX_TF_RGB565: - WriteRGB565Encoder(p, api_type, format); - break; - case GX_TF_RGB5A3: - WriteRGB5A3Encoder(p, api_type, format); - break; - case GX_TF_RGBA8: - WriteRGBA8Encoder(p, api_type, format); - break; - case GX_CTF_R4: - WriteC4Encoder(p, "r", api_type, format, false); - break; - case GX_CTF_RA4: - WriteCC4Encoder(p, "ar", api_type, format); - break; - case GX_CTF_RA8: - WriteCC8Encoder(p, "ar", api_type, format); - break; - case GX_CTF_A8: - WriteC8Encoder(p, "a", api_type, format, false); - break; - case GX_CTF_R8: - WriteC8Encoder(p, "r", api_type, format, false); + case EFBCopyFormat::R4: + if (params.yuv) + WriteI4Encoder(p, api_type, params); + else + WriteC4Encoder(p, "r", api_type, params); break; - case GX_CTF_G8: - WriteC8Encoder(p, "g", api_type, format, false); + case EFBCopyFormat::RA4: + if (params.yuv) + WriteIA4Encoder(p, api_type, params); + else + WriteCC4Encoder(p, "ar", api_type, params); break; - case GX_CTF_B8: - WriteC8Encoder(p, "b", api_type, format, false); + case EFBCopyFormat::RA8: + if (params.yuv) + WriteIA8Encoder(p, api_type, params); + else + WriteCC8Encoder(p, "ar", api_type, params); break; - case GX_CTF_RG8: - WriteCC8Encoder(p, "rg", api_type, format); + case EFBCopyFormat::RGB565: + WriteRGB565Encoder(p, api_type, params); break; - case GX_CTF_GB8: - WriteCC8Encoder(p, "gb", api_type, format); + case EFBCopyFormat::RGB5A3: + WriteRGB5A3Encoder(p, api_type, params); break; - case GX_CTF_Z8H: - case GX_TF_Z8: - WriteC8Encoder(p, "r", api_type, format, true); + case EFBCopyFormat::RGBA8: + if (params.depth) + WriteZ24Encoder(p, api_type, params); + else + WriteRGBA8Encoder(p, api_type, params); break; - case GX_CTF_Z16R: - case GX_TF_Z16: - WriteZ16Encoder(p, api_type, format); + case EFBCopyFormat::A8: + WriteC8Encoder(p, "a", api_type, params); break; - case GX_TF_Z24X8: - WriteZ24Encoder(p, api_type, format); + case EFBCopyFormat::R8_0x1: + case EFBCopyFormat::R8: + if (params.yuv) + WriteI8Encoder(p, api_type, params); + else + WriteC8Encoder(p, "r", api_type, params); break; - case GX_CTF_Z4: - WriteC4Encoder(p, "r", api_type, format, true); + case EFBCopyFormat::G8: + if (params.depth) + WriteZ8Encoder(p, "256.0", api_type, params); // Z8M + else + WriteC8Encoder(p, "g", api_type, params); break; - case GX_CTF_Z8M: - WriteZ8Encoder(p, "256.0", api_type, format); + case EFBCopyFormat::B8: + if (params.depth) + WriteZ8Encoder(p, "65536.0", api_type, params); // Z8L + else + WriteC8Encoder(p, "b", api_type, params); break; - case GX_CTF_Z8L: - WriteZ8Encoder(p, "65536.0", api_type, format); + case EFBCopyFormat::RG8: + if (params.depth) + WriteZ16Encoder(p, api_type, params); // Z16H + else + WriteCC8Encoder(p, "rg", api_type, params); break; - case GX_CTF_Z16L: - WriteZ16LEncoder(p, api_type, format); + case EFBCopyFormat::GB8: + if (params.depth) + WriteZ16LEncoder(p, api_type, params); // Z16L + else + WriteCC8Encoder(p, "gb", api_type, params); break; default: - PanicAlert("Unknown texture copy format: 0x%x\n", static_cast<u32>(format.copy_format)); + PanicAlert("Invalid EFB Copy Format (0x%X)! (GenerateEncodingShader)", + static_cast<int>(params.copy_format)); break; } @@ -895,7 +864,7 @@ vec4 GetPaletteColorNormalized(uint index) )"; static const std::map<TextureFormat, DecodingShaderInfo> s_decoding_shader_info{ - {GX_TF_I4, + {TextureFormat::I4, {BUFFER_FORMAT_R8_UINT, 0, 8, 8, false, R"( layout(local_size_x = 8, local_size_y = 8) in; @@ -930,7 +899,7 @@ static const std::map<TextureFormat, DecodingShaderInfo> s_decoding_shader_info{ } )"}}, - {GX_TF_IA4, + {TextureFormat::IA4, {BUFFER_FORMAT_R8_UINT, 0, 8, 8, false, R"( layout(local_size_x = 8, local_size_y = 8) in; @@ -950,7 +919,7 @@ static const std::map<TextureFormat, DecodingShaderInfo> s_decoding_shader_info{ imageStore(output_image, ivec3(ivec2(coords), 0), norm_color); } )"}}, - {GX_TF_I8, + {TextureFormat::I8, {BUFFER_FORMAT_R8_UINT, 0, 8, 8, false, R"( layout(local_size_x = 8, local_size_y = 8) in; @@ -968,7 +937,7 @@ static const std::map<TextureFormat, DecodingShaderInfo> s_decoding_shader_info{ imageStore(output_image, ivec3(ivec2(coords), 0), norm_color); } )"}}, - {GX_TF_IA8, + {TextureFormat::IA8, {BUFFER_FORMAT_R16_UINT, 0, 8, 8, false, R"( layout(local_size_x = 8, local_size_y = 8) in; @@ -987,7 +956,7 @@ static const std::map<TextureFormat, DecodingShaderInfo> s_decoding_shader_info{ imageStore(output_image, ivec3(ivec2(coords), 0), norm_color); } )"}}, - {GX_TF_RGB565, + {TextureFormat::RGB565, {BUFFER_FORMAT_R16_UINT, 0, 8, 8, false, R"( layout(local_size_x = 8, local_size_y = 8) in; @@ -1011,7 +980,7 @@ static const std::map<TextureFormat, DecodingShaderInfo> s_decoding_shader_info{ } )"}}, - {GX_TF_RGB5A3, + {TextureFormat::RGB5A3, {BUFFER_FORMAT_R16_UINT, 0, 8, 8, false, R"( layout(local_size_x = 8, local_size_y = 8) in; @@ -1045,7 +1014,7 @@ static const std::map<TextureFormat, DecodingShaderInfo> s_decoding_shader_info{ } )"}}, - {GX_TF_RGBA8, + {TextureFormat::RGBA8, {BUFFER_FORMAT_R16_UINT, 0, 8, 8, false, R"( layout(local_size_x = 8, local_size_y = 8) in; @@ -1081,7 +1050,7 @@ static const std::map<TextureFormat, DecodingShaderInfo> s_decoding_shader_info{ imageStore(output_image, ivec3(ivec2(coords), 0), norm_color); } )"}}, - {GX_TF_CMPR, + {TextureFormat::CMPR, {BUFFER_FORMAT_R32G32_UINT, 0, 64, 1, true, R"( // In the compute version of this decoder, we flatten the blocks to a one-dimension array. @@ -1199,8 +1168,9 @@ static const std::map<TextureFormat, DecodingShaderInfo> s_decoding_shader_info{ imageStore(output_image, ivec3(ivec2(uvec2(global_x, global_y)), 0), norm_color); } )"}}, - {GX_TF_C4, - {BUFFER_FORMAT_R8_UINT, static_cast<u32>(TexDecoder_GetPaletteSize(GX_TF_C4)), 8, 8, false, + {TextureFormat::C4, + {BUFFER_FORMAT_R8_UINT, static_cast<u32>(TexDecoder_GetPaletteSize(TextureFormat::C4)), 8, 8, + false, R"( layout(local_size_x = 8, local_size_y = 8) in; @@ -1227,8 +1197,9 @@ static const std::map<TextureFormat, DecodingShaderInfo> s_decoding_shader_info{ } )"}}, - {GX_TF_C8, - {BUFFER_FORMAT_R8_UINT, static_cast<u32>(TexDecoder_GetPaletteSize(GX_TF_C8)), 8, 8, false, + {TextureFormat::C8, + {BUFFER_FORMAT_R8_UINT, static_cast<u32>(TexDecoder_GetPaletteSize(TextureFormat::C8)), 8, 8, + false, R"( layout(local_size_x = 8, local_size_y = 8) in; @@ -1243,8 +1214,9 @@ static const std::map<TextureFormat, DecodingShaderInfo> s_decoding_shader_info{ imageStore(output_image, ivec3(ivec2(coords), 0), norm_color); } )"}}, - {GX_TF_C14X2, - {BUFFER_FORMAT_R16_UINT, static_cast<u32>(TexDecoder_GetPaletteSize(GX_TF_C14X2)), 8, 8, false, + {TextureFormat::C14X2, + {BUFFER_FORMAT_R16_UINT, static_cast<u32>(TexDecoder_GetPaletteSize(TextureFormat::C14X2)), 8, + 8, false, R"( layout(local_size_x = 8, local_size_y = 8) in; @@ -1287,7 +1259,7 @@ std::pair<u32, u32> GetDispatchCount(const DecodingShaderInfo* info, u32 width, (height + (info->group_size_y - 1)) / info->group_size_y}; } -std::string GenerateDecodingShader(TextureFormat format, TlutFormat palette_format, +std::string GenerateDecodingShader(TextureFormat format, TLUTFormat palette_format, APIType api_type) { const DecodingShaderInfo* info = GetDecodingShaderInfo(format); @@ -1297,13 +1269,13 @@ std::string GenerateDecodingShader(TextureFormat format, TlutFormat palette_form std::stringstream ss; switch (palette_format) { - case GX_TL_IA8: + case TLUTFormat::IA8: ss << "#define PALETTE_FORMAT_IA8 1\n"; break; - case GX_TL_RGB565: + case TLUTFormat::RGB565: ss << "#define PALETTE_FORMAT_RGB565 1\n"; break; - case GX_TL_RGB5A3: + case TLUTFormat::RGB5A3: ss << "#define PALETTE_FORMAT_RGB5A3 1\n"; break; } diff --git a/Source/Core/VideoCommon/TextureConversionShader.h b/Source/Core/VideoCommon/TextureConversionShader.h index abcd765245..9b1feb8b45 100644 --- a/Source/Core/VideoCommon/TextureConversionShader.h +++ b/Source/Core/VideoCommon/TextureConversionShader.h @@ -8,15 +8,18 @@ #include <utility> #include "Common/CommonTypes.h" -#include "VideoCommon/TextureDecoder.h" enum class APIType; +enum class TextureFormat; +enum class EFBCopyFormat; +enum class TLUTFormat; +struct EFBCopyParams; namespace TextureConversionShader { -u16 GetEncodedSampleCount(u32 format); +u16 GetEncodedSampleCount(EFBCopyFormat format); -const char* GenerateEncodingShader(const EFBCopyFormat& format, APIType ApiType); +const char* GenerateEncodingShader(const EFBCopyParams& params, APIType ApiType); // View format of the input data to the texture decoding shader. enum BufferFormat @@ -51,7 +54,7 @@ u32 GetBytesPerBufferElement(BufferFormat buffer_format); std::pair<u32, u32> GetDispatchCount(const DecodingShaderInfo* info, u32 width, u32 height); // Returns the GLSL string containing the texture decoding shader for the specified format. -std::string GenerateDecodingShader(TextureFormat format, TlutFormat palette_format, +std::string GenerateDecodingShader(TextureFormat format, TLUTFormat palette_format, APIType api_type); } // namespace TextureConversionShader 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); diff --git a/Source/Core/VideoCommon/TextureDecoder_Common.cpp b/Source/Core/VideoCommon/TextureDecoder_Common.cpp index cad1a918e3..308a5c7415 100644 --- a/Source/Core/VideoCommon/TextureDecoder_Common.cpp +++ b/Source/Core/VideoCommon/TextureDecoder_Common.cpp @@ -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: - return 2; - case GX_TF_IA4: + // 8-bit formats + case TextureFormat::I8: + case TextureFormat::IA4: + case TextureFormat::C8: return 2; - case GX_TF_IA8: - return 4; - case GX_TF_RGB565: - return 4; - case GX_TF_RGB5A3: - return 4; - case GX_TF_RGBA8: + // 16-bit formats + case TextureFormat::IA8: + case TextureFormat::RGB565: + case TextureFormat::RGB5A3: + case TextureFormat::C14X2: + return 4; + // 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: - return 4; - case GX_TF_RGB565: - return 4; - case GX_TF_RGB5A3: + // 16-bit formats + case TextureFormat::IA8: + case TextureFormat::RGB565: + case TextureFormat::RGB5A3: + case TextureFormat::C14X2: return 4; - case GX_TF_RGBA8: + // 32-bit formats + case TextureFormat::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: + default: + PanicAlert("Invalid Texture Format (0x%X)! (GetBlockWidthInTexels)", static_cast<int>(format)); return 8; - case GX_CTF_B8: + } +} + +int TexDecoder_GetBlockHeightInTexels(TextureFormat format) +{ + switch (format) + { + // 4-bit formats + case TextureFormat::I4: + case TextureFormat::C4: return 8; - case GX_CTF_RG8: - return 4; - case GX_CTF_GB8: - return 4; - case GX_TF_Z8: + // 8-bit formats + case TextureFormat::I8: + case TextureFormat::IA4: + case TextureFormat::C8: + return 4; + // 16-bit formats + case TextureFormat::IA8: + case TextureFormat::RGB565: + case TextureFormat::RGB5A3: + case TextureFormat::C14X2: + return 4; + // 32-bit formats + case TextureFormat::RGBA8: + return 4; + // Compressed format + case TextureFormat::CMPR: return 8; - case GX_TF_Z16: - return 4; - case GX_TF_Z24X8: + default: + PanicAlert("Invalid Texture Format (0x%X)! (GetBlockHeightInTexels)", static_cast<int>(format)); return 4; - case GX_CTF_Z4: - return 8; - case GX_CTF_Z8H: - return 8; - case GX_CTF_Z8M: + } +} + +int TexDecoder_GetEFBCopyBlockWidthInTexels(EFBCopyFormat format) +{ + switch (format) + { + // 4-bit formats + case EFBCopyFormat::R4: return 8; - case GX_CTF_Z8L: + // 8-bit formats + case EFBCopyFormat::A8: + case EFBCopyFormat::R8_0x1: + case EFBCopyFormat::R8: + case EFBCopyFormat::G8: + case EFBCopyFormat::B8: return 8; - case GX_CTF_Z16R: + // 16-bit formats + case EFBCopyFormat::RA8: + case EFBCopyFormat::RGB565: + case EFBCopyFormat::RGB5A3: + case EFBCopyFormat::RG8: + case EFBCopyFormat::GB8: return 4; - case GX_CTF_Z16L: + // 32-bit formats + case EFBCopyFormat::RGBA8: return 4; default: - PanicAlert("Unsupported Texture Format (%08x)! (GetBlockWidthInTexels)", format); + PanicAlert("Invalid EFB Copy Format (0x%X)! (GetEFBCopyBlockWidthInTexels)", + static_cast<int>(format)); return 8; } } -int TexDecoder_GetBlockHeightInTexels(u32 format) +int TexDecoder_GetEFBCopyBlockHeightInTexels(EFBCopyFormat format) { switch (format) { - case GX_TF_I4: - return 8; - case GX_TF_I8: - return 4; - case GX_TF_IA4: - return 4; - case GX_TF_IA8: - return 4; - case GX_TF_RGB565: - return 4; - case GX_TF_RGB5A3: - return 4; - case GX_TF_RGBA8: - return 4; - case GX_TF_C4: - return 8; - case GX_TF_C8: - return 4; - case GX_TF_C14X2: - return 4; - case GX_TF_CMPR: - return 8; - case GX_CTF_R4: + // 4-bit formats + case EFBCopyFormat::R4: return 8; - case GX_CTF_RA4: - 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: + // 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("Unsupported Texture Format (%08x)! (GetBlockHeightInTexels)", format); + 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; diff --git a/Source/Core/VideoCommon/TextureDecoder_Generic.cpp b/Source/Core/VideoCommon/TextureDecoder_Generic.cpp index cf89cf2632..ec74c21db4 100644 --- a/Source/Core/VideoCommon/TextureDecoder_Generic.cpp +++ b/Source/Core/VideoCommon/TextureDecoder_Generic.cpp @@ -57,22 +57,22 @@ 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; } } -static inline void DecodeBytes_C4(u32* dst, const u8* src, const u8* tlut_, TlutFormat tlutfmt) +static inline void DecodeBytes_C4(u32* dst, const u8* src, const u8* tlut_, TLUTFormat tlutfmt) { const u16* tlut = (u16*)tlut_; for (int x = 0; x < 4; x++) @@ -83,7 +83,7 @@ static inline void DecodeBytes_C4(u32* dst, const u8* src, const u8* tlut_, Tlut } } -static inline void DecodeBytes_C8(u32* dst, const u8* src, const u8* tlut_, TlutFormat tlutfmt) +static inline void DecodeBytes_C8(u32* dst, const u8* src, const u8* tlut_, TLUTFormat tlutfmt) { const u16* tlut = (u16*)tlut_; for (int x = 0; x < 8; x++) @@ -93,7 +93,7 @@ static inline void DecodeBytes_C8(u32* dst, const u8* src, const u8* tlut_, Tlut } } -static inline void DecodeBytes_C14X2(u32* dst, const u16* src, const u8* tlut_, TlutFormat tlutfmt) +static inline void DecodeBytes_C14X2(u32* dst, const u16* src, const u8* tlut_, TLUTFormat tlutfmt) { const u16* tlut = (u16*)tlut_; for (int x = 0; x < 4; x++) @@ -195,21 +195,21 @@ static void DecodeDXTBlock(u32* dst, const DXTBlock* src, int pitch) // TODO: complete SSE2 optimization of less often used texture formats. // TODO: refactor algorithms using _mm_loadl_epi64 unaligned loads to prefer 128-bit aligned loads. -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) { const int Wsteps4 = (width + 3) / 4; const int Wsteps8 = (width + 7) / 8; switch (texformat) { - case GX_TF_C4: + case TextureFormat::C4: for (int y = 0; y < height; y += 8) for (int x = 0, yStep = (y / 8) * Wsteps8; x < width; x += 8, yStep++) for (int iy = 0, xStep = 8 * yStep; iy < 8; iy++, xStep++) DecodeBytes_C4(dst + (y + iy) * width + x, src + 4 * xStep, tlut, tlutfmt); break; - case GX_TF_I4: + case TextureFormat::I4: { // Reference C implementation: for (int y = 0; y < height; y += 8) @@ -225,7 +225,7 @@ void _TexDecoder_DecodeImpl(u32* dst, const u8* src, int width, int height, int } } break; - case GX_TF_I8: // speed critical + case TextureFormat::I8: // speed critical { // Reference C implementation for (int y = 0; y < height; y += 4) @@ -255,13 +255,13 @@ void _TexDecoder_DecodeImpl(u32* dst, const u8* src, int width, int height, int } } break; - case GX_TF_C8: + case TextureFormat::C8: for (int y = 0; y < height; y += 4) for (int x = 0, yStep = (y / 4) * Wsteps8; x < width; x += 8, yStep++) for (int iy = 0, xStep = 4 * yStep; iy < 4; iy++, xStep++) DecodeBytes_C8((u32*)dst + (y + iy) * width + x, src + 8 * xStep, tlut, tlutfmt); break; - case GX_TF_IA4: + case TextureFormat::IA4: { for (int y = 0; y < height; y += 4) for (int x = 0, yStep = (y / 4) * Wsteps8; x < width; x += 8, yStep++) @@ -269,7 +269,7 @@ void _TexDecoder_DecodeImpl(u32* dst, const u8* src, int width, int height, int DecodeBytes_IA4(dst + (y + iy) * width + x, src + 8 * xStep); } break; - case GX_TF_IA8: + case TextureFormat::IA8: { // Reference C implementation: for (int y = 0; y < height; y += 4) @@ -285,13 +285,13 @@ void _TexDecoder_DecodeImpl(u32* dst, const u8* src, int width, int height, int } } break; - case GX_TF_C14X2: + case TextureFormat::C14X2: for (int y = 0; y < height; y += 4) for (int x = 0, yStep = (y / 4) * Wsteps4; x < width; x += 4, yStep++) for (int iy = 0, xStep = 4 * yStep; iy < 4; iy++, xStep++) DecodeBytes_C14X2(dst + (y + iy) * width + x, (u16*)(src + 8 * xStep), tlut, tlutfmt); break; - case GX_TF_RGB565: + case TextureFormat::RGB565: { // Reference C implementation. for (int y = 0; y < height; y += 4) @@ -305,7 +305,7 @@ void _TexDecoder_DecodeImpl(u32* dst, const u8* src, int width, int height, int } } break; - case GX_TF_RGB5A3: + case TextureFormat::RGB5A3: { // Reference C implementation: for (int y = 0; y < height; y += 4) @@ -314,7 +314,7 @@ void _TexDecoder_DecodeImpl(u32* dst, const u8* src, int width, int height, int DecodeBytes_RGB5A3(dst + (y + iy) * width + x, (u16*)src); } break; - case GX_TF_RGBA8: // speed critical + case TextureFormat::RGBA8: // speed critical { // Reference C implementation. for (int y = 0; y < height; y += 4) @@ -327,7 +327,7 @@ void _TexDecoder_DecodeImpl(u32* dst, const u8* src, int width, int height, int } } break; - case GX_TF_CMPR: // speed critical + case TextureFormat::CMPR: // speed critical // The metroid games use this format almost exclusively. { for (int y = 0; y < height; y += 8) diff --git a/Source/Core/VideoCommon/TextureDecoder_x64.cpp b/Source/Core/VideoCommon/TextureDecoder_x64.cpp index 338ef7ca04..135fc60629 100644 --- a/Source/Core/VideoCommon/TextureDecoder_x64.cpp +++ b/Source/Core/VideoCommon/TextureDecoder_x64.cpp @@ -212,12 +212,13 @@ static void DecodeDXTBlock(u32* dst, const DXTBlock* src, int pitch) // free to make the assumption that addresses are multiples of 16 in the aligned case. // TODO: complete SSE2 optimization of less often used texture formats. // TODO: refactor algorithms using _mm_loadl_epi64 unaligned loads to prefer 128-bit aligned loads. -static void TexDecoder_DecodeImpl_C4(u32* dst, const u8* src, int width, int height, int texformat, - const u8* tlut, TlutFormat tlutfmt, int Wsteps4, int Wsteps8) +static void TexDecoder_DecodeImpl_C4(u32* dst, const u8* src, int width, int height, + TextureFormat texformat, const u8* tlut, TLUTFormat tlutfmt, + int Wsteps4, int Wsteps8) { switch (tlutfmt) { - case GX_TL_RGB5A3: + case TLUTFormat::RGB5A3: { for (int y = 0; y < height; y += 8) for (int x = 0, yStep = (y / 8) * Wsteps8; x < width; x += 8, yStep++) @@ -226,7 +227,7 @@ static void TexDecoder_DecodeImpl_C4(u32* dst, const u8* src, int width, int hei } break; - case GX_TL_IA8: + case TLUTFormat::IA8: { for (int y = 0; y < height; y += 8) for (int x = 0, yStep = (y / 8) * Wsteps8; x < width; x += 8, yStep++) @@ -235,7 +236,7 @@ static void TexDecoder_DecodeImpl_C4(u32* dst, const u8* src, int width, int hei } break; - case GX_TL_RGB565: + case TLUTFormat::RGB565: { for (int y = 0; y < height; y += 8) for (int x = 0, yStep = (y / 8) * Wsteps8; x < width; x += 8, yStep++) @@ -251,8 +252,8 @@ static void TexDecoder_DecodeImpl_C4(u32* dst, const u8* src, int width, int hei FUNCTION_TARGET_SSSE3 static void TexDecoder_DecodeImpl_I4_SSSE3(u32* dst, const u8* src, int width, int height, - int texformat, const u8* tlut, TlutFormat tlutfmt, - int Wsteps4, int Wsteps8) + TextureFormat texformat, const u8* tlut, + TLUTFormat tlutfmt, int Wsteps4, int Wsteps8) { const __m128i kMask_x0f = _mm_set1_epi32(0x0f0f0f0fL); const __m128i kMask_xf0 = _mm_set1_epi32(0xf0f0f0f0L); @@ -298,8 +299,9 @@ static void TexDecoder_DecodeImpl_I4_SSSE3(u32* dst, const u8* src, int width, i } } -static void TexDecoder_DecodeImpl_I4(u32* dst, const u8* src, int width, int height, int texformat, - const u8* tlut, TlutFormat tlutfmt, int Wsteps4, int Wsteps8) +static void TexDecoder_DecodeImpl_I4(u32* dst, const u8* src, int width, int height, + TextureFormat texformat, const u8* tlut, TLUTFormat tlutfmt, + int Wsteps4, int Wsteps8) { const __m128i kMask_x0f = _mm_set1_epi32(0x0f0f0f0fL); const __m128i kMask_xf0 = _mm_set1_epi32(0xf0f0f0f0L); @@ -390,8 +392,8 @@ static void TexDecoder_DecodeImpl_I4(u32* dst, const u8* src, int width, int hei FUNCTION_TARGET_SSSE3 static void TexDecoder_DecodeImpl_I8_SSSE3(u32* dst, const u8* src, int width, int height, - int texformat, const u8* tlut, TlutFormat tlutfmt, - int Wsteps4, int Wsteps8) + TextureFormat texformat, const u8* tlut, + TLUTFormat tlutfmt, int Wsteps4, int Wsteps8) { // xsacha optimized with SSSE3 intrinsics // Produces a ~10% speed improvement over SSE2 implementation @@ -419,8 +421,9 @@ static void TexDecoder_DecodeImpl_I8_SSSE3(u32* dst, const u8* src, int width, i } } -static void TexDecoder_DecodeImpl_I8(u32* dst, const u8* src, int width, int height, int texformat, - const u8* tlut, TlutFormat tlutfmt, int Wsteps4, int Wsteps8) +static void TexDecoder_DecodeImpl_I8(u32* dst, const u8* src, int width, int height, + TextureFormat texformat, const u8* tlut, TLUTFormat tlutfmt, + int Wsteps4, int Wsteps8) { // JSD optimized with SSE2 intrinsics. // Produces an ~86% speed improvement over reference C implementation. @@ -518,12 +521,13 @@ static void TexDecoder_DecodeImpl_I8(u32* dst, const u8* src, int width, int hei } } -static void TexDecoder_DecodeImpl_C8(u32* dst, const u8* src, int width, int height, int texformat, - const u8* tlut, TlutFormat tlutfmt, int Wsteps4, int Wsteps8) +static void TexDecoder_DecodeImpl_C8(u32* dst, const u8* src, int width, int height, + TextureFormat texformat, const u8* tlut, TLUTFormat tlutfmt, + int Wsteps4, int Wsteps8) { switch (tlutfmt) { - case GX_TL_RGB5A3: + case TLUTFormat::RGB5A3: { for (int y = 0; y < height; y += 4) for (int x = 0, yStep = (y / 4) * Wsteps8; x < width; x += 8, yStep++) @@ -532,7 +536,7 @@ static void TexDecoder_DecodeImpl_C8(u32* dst, const u8* src, int width, int hei } break; - case GX_TL_IA8: + case TLUTFormat::IA8: { for (int y = 0; y < height; y += 4) for (int x = 0, yStep = (y / 4) * Wsteps8; x < width; x += 8, yStep++) @@ -541,7 +545,7 @@ static void TexDecoder_DecodeImpl_C8(u32* dst, const u8* src, int width, int hei } break; - case GX_TL_RGB565: + case TLUTFormat::RGB565: { for (int y = 0; y < height; y += 4) for (int x = 0, yStep = (y / 4) * Wsteps8; x < width; x += 8, yStep++) @@ -555,8 +559,9 @@ static void TexDecoder_DecodeImpl_C8(u32* dst, const u8* src, int width, int hei } } -static void TexDecoder_DecodeImpl_IA4(u32* dst, const u8* src, int width, int height, int texformat, - const u8* tlut, TlutFormat tlutfmt, int Wsteps4, int Wsteps8) +static void TexDecoder_DecodeImpl_IA4(u32* dst, const u8* src, int width, int height, + TextureFormat texformat, const u8* tlut, TLUTFormat tlutfmt, + int Wsteps4, int Wsteps8) { for (int y = 0; y < height; y += 4) { @@ -572,8 +577,8 @@ static void TexDecoder_DecodeImpl_IA4(u32* dst, const u8* src, int width, int he FUNCTION_TARGET_SSSE3 static void TexDecoder_DecodeImpl_IA8_SSSE3(u32* dst, const u8* src, int width, int height, - int texformat, const u8* tlut, TlutFormat tlutfmt, - int Wsteps4, int Wsteps8) + TextureFormat texformat, const u8* tlut, + TLUTFormat tlutfmt, int Wsteps4, int Wsteps8) { // xsacha optimized with SSSE3 intrinsics. // Produces an ~50% speed improvement over SSE2 implementation. @@ -595,8 +600,9 @@ static void TexDecoder_DecodeImpl_IA8_SSSE3(u32* dst, const u8* src, int width, } } -static void TexDecoder_DecodeImpl_IA8(u32* dst, const u8* src, int width, int height, int texformat, - const u8* tlut, TlutFormat tlutfmt, int Wsteps4, int Wsteps8) +static void TexDecoder_DecodeImpl_IA8(u32* dst, const u8* src, int width, int height, + TextureFormat texformat, const u8* tlut, TLUTFormat tlutfmt, + int Wsteps4, int Wsteps8) { // JSD optimized with SSE2 intrinsics. // Produces an ~80% speed improvement over reference C implementation. @@ -656,12 +662,12 @@ static void TexDecoder_DecodeImpl_IA8(u32* dst, const u8* src, int width, int he } static void TexDecoder_DecodeImpl_C14X2(u32* dst, const u8* src, int width, int height, - int texformat, const u8* tlut, TlutFormat tlutfmt, + TextureFormat texformat, const u8* tlut, TLUTFormat tlutfmt, int Wsteps4, int Wsteps8) { switch (tlutfmt) { - case GX_TL_RGB5A3: + case TLUTFormat::RGB5A3: { for (int y = 0; y < height; y += 4) for (int x = 0, yStep = (y / 4) * Wsteps4; x < width; x += 4, yStep++) @@ -670,7 +676,7 @@ static void TexDecoder_DecodeImpl_C14X2(u32* dst, const u8* src, int width, int } break; - case GX_TL_IA8: + case TLUTFormat::IA8: { for (int y = 0; y < height; y += 4) for (int x = 0, yStep = (y / 4) * Wsteps4; x < width; x += 4, yStep++) @@ -679,7 +685,7 @@ static void TexDecoder_DecodeImpl_C14X2(u32* dst, const u8* src, int width, int } break; - case GX_TL_RGB565: + case TLUTFormat::RGB565: { for (int y = 0; y < height; y += 4) for (int x = 0, yStep = (y / 4) * Wsteps4; x < width; x += 4, yStep++) @@ -694,8 +700,8 @@ static void TexDecoder_DecodeImpl_C14X2(u32* dst, const u8* src, int width, int } static void TexDecoder_DecodeImpl_RGB565(u32* dst, const u8* src, int width, int height, - int texformat, const u8* tlut, TlutFormat tlutfmt, - int Wsteps4, int Wsteps8) + TextureFormat texformat, const u8* tlut, + TLUTFormat tlutfmt, int Wsteps4, int Wsteps8) { // JSD optimized with SSE2 intrinsics. // Produces an ~78% speed improvement over reference C implementation. @@ -766,8 +772,8 @@ static void TexDecoder_DecodeImpl_RGB565(u32* dst, const u8* src, int width, int FUNCTION_TARGET_SSSE3 static void TexDecoder_DecodeImpl_RGB5A3_SSSE3(u32* dst, const u8* src, int width, int height, - int texformat, const u8* tlut, TlutFormat tlutfmt, - int Wsteps4, int Wsteps8) + TextureFormat texformat, const u8* tlut, + TLUTFormat tlutfmt, int Wsteps4, int Wsteps8) { const __m128i kMask_x1f = _mm_set1_epi32(0x0000001fL); const __m128i kMask_x0f = _mm_set1_epi32(0x0000000fL); @@ -872,8 +878,8 @@ static void TexDecoder_DecodeImpl_RGB5A3_SSSE3(u32* dst, const u8* src, int widt } static void TexDecoder_DecodeImpl_RGB5A3(u32* dst, const u8* src, int width, int height, - int texformat, const u8* tlut, TlutFormat tlutfmt, - int Wsteps4, int Wsteps8) + TextureFormat texformat, const u8* tlut, + TLUTFormat tlutfmt, int Wsteps4, int Wsteps8) { const __m128i kMask_x1f = _mm_set1_epi32(0x0000001fL); const __m128i kMask_x0f = _mm_set1_epi32(0x0000000fL); @@ -993,8 +999,8 @@ static void TexDecoder_DecodeImpl_RGB5A3(u32* dst, const u8* src, int width, int FUNCTION_TARGET_SSSE3 static void TexDecoder_DecodeImpl_RGBA8_SSSE3(u32* dst, const u8* src, int width, int height, - int texformat, const u8* tlut, TlutFormat tlutfmt, - int Wsteps4, int Wsteps8) + TextureFormat texformat, const u8* tlut, + TLUTFormat tlutfmt, int Wsteps4, int Wsteps8) { // xsacha optimized with SSSE3 instrinsics // Produces a ~30% speed improvement over SSE2 implementation @@ -1027,7 +1033,7 @@ static void TexDecoder_DecodeImpl_RGBA8_SSSE3(u32* dst, const u8* src, int width } static void TexDecoder_DecodeImpl_RGBA8(u32* dst, const u8* src, int width, int height, - int texformat, const u8* tlut, TlutFormat tlutfmt, + TextureFormat texformat, const u8* tlut, TLUTFormat tlutfmt, int Wsteps4, int Wsteps8) { // JSD optimized with SSE2 intrinsics @@ -1148,7 +1154,7 @@ static void TexDecoder_DecodeImpl_RGBA8(u32* dst, const u8* src, int width, int } static void TexDecoder_DecodeImpl_CMPR(u32* dst, const u8* src, int width, int height, - int texformat, const u8* tlut, TlutFormat tlutfmt, + TextureFormat texformat, const u8* tlut, TLUTFormat tlutfmt, int Wsteps4, int Wsteps8) { // The metroid games use this format almost exclusively. @@ -1403,19 +1409,19 @@ static void TexDecoder_DecodeImpl_CMPR(u32* dst, const u8* src, int width, int h } } -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) { int Wsteps4 = (width + 3) / 4; int Wsteps8 = (width + 7) / 8; switch (texformat) { - case GX_TF_C4: + case TextureFormat::C4: TexDecoder_DecodeImpl_C4(dst, src, width, height, texformat, tlut, tlutfmt, Wsteps4, Wsteps8); break; - case GX_TF_I4: + case TextureFormat::I4: if (cpu_info.bSSSE3) TexDecoder_DecodeImpl_I4_SSSE3(dst, src, width, height, texformat, tlut, tlutfmt, Wsteps4, Wsteps8); @@ -1423,7 +1429,7 @@ void _TexDecoder_DecodeImpl(u32* dst, const u8* src, int width, int height, int TexDecoder_DecodeImpl_I4(dst, src, width, height, texformat, tlut, tlutfmt, Wsteps4, Wsteps8); break; - case GX_TF_I8: + case TextureFormat::I8: if (cpu_info.bSSSE3) TexDecoder_DecodeImpl_I8_SSSE3(dst, src, width, height, texformat, tlut, tlutfmt, Wsteps4, Wsteps8); @@ -1431,15 +1437,15 @@ void _TexDecoder_DecodeImpl(u32* dst, const u8* src, int width, int height, int TexDecoder_DecodeImpl_I8(dst, src, width, height, texformat, tlut, tlutfmt, Wsteps4, Wsteps8); break; - case GX_TF_C8: + case TextureFormat::C8: TexDecoder_DecodeImpl_C8(dst, src, width, height, texformat, tlut, tlutfmt, Wsteps4, Wsteps8); break; - case GX_TF_IA4: + case TextureFormat::IA4: TexDecoder_DecodeImpl_IA4(dst, src, width, height, texformat, tlut, tlutfmt, Wsteps4, Wsteps8); break; - case GX_TF_IA8: + case TextureFormat::IA8: if (cpu_info.bSSSE3) TexDecoder_DecodeImpl_IA8_SSSE3(dst, src, width, height, texformat, tlut, tlutfmt, Wsteps4, Wsteps8); @@ -1448,17 +1454,17 @@ void _TexDecoder_DecodeImpl(u32* dst, const u8* src, int width, int height, int Wsteps8); break; - case GX_TF_C14X2: + case TextureFormat::C14X2: TexDecoder_DecodeImpl_C14X2(dst, src, width, height, texformat, tlut, tlutfmt, Wsteps4, Wsteps8); break; - case GX_TF_RGB565: + case TextureFormat::RGB565: TexDecoder_DecodeImpl_RGB565(dst, src, width, height, texformat, tlut, tlutfmt, Wsteps4, Wsteps8); break; - case GX_TF_RGB5A3: + case TextureFormat::RGB5A3: if (cpu_info.bSSSE3) TexDecoder_DecodeImpl_RGB5A3_SSSE3(dst, src, width, height, texformat, tlut, tlutfmt, Wsteps4, Wsteps8); @@ -1467,7 +1473,7 @@ void _TexDecoder_DecodeImpl(u32* dst, const u8* src, int width, int height, int Wsteps8); break; - case GX_TF_RGBA8: + case TextureFormat::RGBA8: if (cpu_info.bSSSE3) TexDecoder_DecodeImpl_RGBA8_SSSE3(dst, src, width, height, texformat, tlut, tlutfmt, Wsteps4, Wsteps8); @@ -1476,12 +1482,13 @@ void _TexDecoder_DecodeImpl(u32* dst, const u8* src, int width, int height, int Wsteps8); break; - case GX_TF_CMPR: + case TextureFormat::CMPR: TexDecoder_DecodeImpl_CMPR(dst, src, width, height, texformat, tlut, tlutfmt, Wsteps4, Wsteps8); break; default: - PanicAlert("Unhandled texture format %d", texformat); + PanicAlert("Invalid Texture Format (0x%X)! (_TexDecoder_DecodeImpl)", + static_cast<int>(texformat)); break; } } |
