diff --git a/Source/Core/VideoCommon/TextureCacheBase.cpp b/Source/Core/VideoCommon/TextureCacheBase.cpp index c5330d6b86..80b8b12ea6 100644 --- a/Source/Core/VideoCommon/TextureCacheBase.cpp +++ b/Source/Core/VideoCommon/TextureCacheBase.cpp @@ -910,7 +910,7 @@ void TextureCacheBase::CopyRenderTargetToTexture(u32 dstAddr, unsigned int dstFo case 8: // R8 colmat[0] = colmat[4] = colmat[8] = colmat[12] = 1; cbufid = 15; - dstFormat |= _GX_TF_CTF; + dstFormat = GX_CTF_R8; break; case 2: // RA4 @@ -1047,8 +1047,11 @@ void TextureCacheBase::CopyRenderTargetToTexture(u32 dstAddr, unsigned int dstFo } } - u32 blockH = TexDecoder_GetBlockHeightInTexels(dstFormat); - const u32 blockW = TexDecoder_GetBlockWidthInTexels(dstFormat); + // Get the base (in memory) format of this efb copy. + int baseFormat = TexDecoder_GetEfbCopyBaseFormat(dstFormat); + + u32 blockH = TexDecoder_GetBlockHeightInTexels(baseFormat); + const u32 blockW = TexDecoder_GetBlockWidthInTexels(baseFormat); // Round up source height to multiple of block size u32 actualHeight = ROUND_UP(tex_h, blockH); @@ -1058,7 +1061,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 = dstFormat == GX_TF_RGBA8 ? 64 : 32; + const u32 bytes_per_block = baseFormat == GX_TF_RGBA8 ? 64 : 32; u32 bytes_per_row = num_blocks_x * bytes_per_block; @@ -1131,7 +1134,7 @@ void TextureCacheBase::CopyRenderTargetToTexture(u32 dstAddr, unsigned int dstFo if (entry) { - entry->SetGeneralParameters(dstAddr, 0, dstFormat); + entry->SetGeneralParameters(dstAddr, 0, baseFormat); entry->SetDimensions(tex_w, tex_h, 1); entry->frameCount = FRAMECOUNT_INVALID; diff --git a/Source/Core/VideoCommon/TextureCacheBase.h b/Source/Core/VideoCommon/TextureCacheBase.h index 00db6e46a3..9435447c9b 100644 --- a/Source/Core/VideoCommon/TextureCacheBase.h +++ b/Source/Core/VideoCommon/TextureCacheBase.h @@ -67,6 +67,7 @@ public: void SetGeneralParameters(u32 _addr, u32 _size, u32 _format) { + _dbg_assert_msg_(VIDEO, _format < 0x10, "You shouldn't use dolphin's \"Extra\" texture formats in a texture cache entry"); addr = _addr; size_in_bytes = _size; format = _format; diff --git a/Source/Core/VideoCommon/TextureDecoder.h b/Source/Core/VideoCommon/TextureDecoder.h index 249024fa3a..26d1163880 100644 --- a/Source/Core/VideoCommon/TextureDecoder.h +++ b/Source/Core/VideoCommon/TextureDecoder.h @@ -72,6 +72,7 @@ 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); void TexDecoder_DecodeRGBA8FromTmem(u8* dst, const u8 *src_ar, const u8 *src_gb, int width, int height); diff --git a/Source/Core/VideoCommon/TextureDecoder_Common.cpp b/Source/Core/VideoCommon/TextureDecoder_Common.cpp index 5f8f314a0b..a37abe6e7e 100644 --- a/Source/Core/VideoCommon/TextureDecoder_Common.cpp +++ b/Source/Core/VideoCommon/TextureDecoder_Common.cpp @@ -156,6 +156,58 @@ 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) +{ + 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: + default: + PanicAlert("Unsupported Texture Format (%08x)! (GetEfbCopyBaseFormat)", format); + return format & 0xf; + } +} + + void TexDecoder_SetTexFmtOverlayOptions(bool enable, bool center) { TexFmt_Overlay_Enable = enable;