From 00540ea44c7d4738037d96f5ddbb78b2c554fd26 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 15 Jun 2013 23:04:43 -0700 Subject: [PATCH] Hash/convert more when a CLUT base is used. This seems a bit strange, but the games that use these bases seem to read outside the loaded CLUT to a previously loaded CLUT. May cause a performance issue on games that use a base but don't do this. --- GPU/GLES/TextureCache.cpp | 28 +++++++++++++++------------- GPU/GLES/TextureCache.h | 2 +- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/GPU/GLES/TextureCache.cpp b/GPU/GLES/TextureCache.cpp index 180c2530bc..8506ff03de 100644 --- a/GPU/GLES/TextureCache.cpp +++ b/GPU/GLES/TextureCache.cpp @@ -809,27 +809,29 @@ void TextureCache::LoadClut() { u32 clutAddr = GetClutAddr(); clutTotalBytes_ = (gstate.loadclut & 0x3f) * 32; if (Memory::IsValidAddress(clutAddr)) { - Memory::Memcpy((u8 *)clutBufRaw_, clutAddr, clutTotalBytes_); + Memory::Memcpy(clutBufRaw_, clutAddr, clutTotalBytes_); } else { memset(clutBufRaw_, 0xFF, clutTotalBytes_); - clutHash_ = 0; } // Reload the clut next time. - clutLastFormat_ = 0xFF; + clutLastFormat_ = 0xFFFFFFFF; } void TextureCache::UpdateCurrentClut() { - // 0xFF is an invalid format, it means not yet hashed or updated. - if (clutLastFormat_ == 0xFF) { - // QuickClutHash is not quite good enough apparently. - // clutHash_ = QuickClutHash((const u8 *)clutBufRaw_, clutTotalBytes_); - clutHash_ = CityHash32((const char *)clutBufRaw_, clutTotalBytes_); - } + const GEPaletteFormat clutFormat = (GEPaletteFormat)(gstate.clutformat & 3); + const u32 clutBase = (gstate.clutformat & 0x1f0000) >> 12; + const u32 clutBaseBytes = clutBase * (clutFormat == GE_CMODE_32BIT_ABGR8888 ? sizeof(u32) : sizeof(u16)); + // Technically, these extra bytes weren't loaded, but hopefully it was loaded earlier. + // If not, we're going to hash random data, which hopefully doesn't cause a performance issue. + const u32 clutExtendedBytes = clutTotalBytes_ + clutBaseBytes; + + // QuickClutHash is not quite good enough apparently. + // clutHash_ = QuickClutHash((const u8 *)clutBufRaw_, clutExtendedBytes); + clutHash_ = CityHash32((const char *)clutBufRaw_, clutExtendedBytes); - GEPaletteFormat clutFormat = (GEPaletteFormat)(gstate.clutformat & 3); // Avoid a copy when we don't need to convert colors. if (clutFormat != GE_CMODE_32BIT_ABGR8888) { - ConvertColors(clutBufConverted_, clutBufRaw_, getClutDestFormat(clutFormat), clutTotalBytes_ / sizeof(u16)); + ConvertColors(clutBufConverted_, clutBufRaw_, getClutDestFormat(clutFormat), clutExtendedBytes / sizeof(u16)); clutBuf_ = clutBufConverted_; } else { clutBuf_ = clutBufRaw_; @@ -855,7 +857,7 @@ void TextureCache::UpdateCurrentClut() { } } - clutLastFormat_ = clutFormat; + clutLastFormat_ = gstate.clutformat; } template @@ -888,7 +890,7 @@ void TextureCache::SetTexture() { u32 clutformat, cluthash; if (hasClut) { clutformat = gstate.clutformat & 3; - if (clutLastFormat_ != clutformat) { + if (clutLastFormat_ != gstate.clutformat) { // We update here because the clut format can be specified after the load. UpdateCurrentClut(); } diff --git a/GPU/GLES/TextureCache.h b/GPU/GLES/TextureCache.h index 92b76e2cf1..361885f41c 100644 --- a/GPU/GLES/TextureCache.h +++ b/GPU/GLES/TextureCache.h @@ -127,7 +127,7 @@ private: SimpleBuf tmpTexBufRearrange; - u8 clutLastFormat_; + u32 clutLastFormat_; u32 *clutBufRaw_; u32 *clutBufConverted_; u32 *clutBuf_;