From 7405b050befce7deed751ff12ab3882bc3126871 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Thu, 25 Apr 2013 07:44:16 -0700 Subject: [PATCH] Revert secondary texture cache. This reverts commits 5d978fc6266d8edffa3592e1b0fa3332453e1aa3, 6a7722283ce6da3cee7533206c2ff5b72af35773, fd34a2e74d7b1c19a12b28d73c9caee9ce47f0b7, 5bdf91ea436986366031a9099de9a48a8dd14728, 223bb6795aab9f1650cf8fd1e38571b869680cf5, and e2a9813d82ff6ab5a62e5fe15b97c1d2821e1c09. --- GPU/GLES/TextureCache.cpp | 116 ++++++++++++-------------------------- GPU/GLES/TextureCache.h | 4 -- 2 files changed, 35 insertions(+), 85 deletions(-) diff --git a/GPU/GLES/TextureCache.cpp b/GPU/GLES/TextureCache.cpp index f57e57994c..37b3849fff 100644 --- a/GPU/GLES/TextureCache.cpp +++ b/GPU/GLES/TextureCache.cpp @@ -26,14 +26,8 @@ #include "GPU/GLES/Framebuffer.h" #include "Core/Config.h" -#include "native/ext/cityhash/city.h" - -#define TEXCACHE_USE_CITYHASH 1 - // If a texture hasn't been seen for this many frames, get rid of it. #define TEXTURE_KILL_AGE 200 -// These are cache misses, kill them quicker. -#define TEXTURE_SECOND_KILL_AGE 30 u32 RoundUpToPowerOf2(u32 v) { @@ -66,20 +60,14 @@ TextureCache::~TextureCache() { void TextureCache::Clear(bool delete_them) { glBindTexture(GL_TEXTURE_2D, 0); if (delete_them) { - lastBoundTexture = -1; for (TexCache::iterator iter = cache.begin(); iter != cache.end(); ++iter) { DEBUG_LOG(G3D, "Deleting texture %i", iter->second.texture); glDeleteTextures(1, &iter->second.texture); } - for (TexCache::iterator iter = secondCache.begin(); iter != secondCache.end(); ++iter) { - DEBUG_LOG(G3D, "Deleting texture %i", iter->second.texture); - glDeleteTextures(1, &iter->second.texture); - } } - if (cache.size() + secondCache.size()) { - INFO_LOG(G3D, "Texture cached cleared from %i textures", (int)(cache.size() + secondCache.size())); + if (cache.size()) { + INFO_LOG(G3D, "Texture cached cleared from %i textures", (int)cache.size()); cache.clear(); - secondCache.clear(); } } @@ -94,14 +82,6 @@ void TextureCache::Decimate() { else ++iter; } - for (TexCache::iterator iter = secondCache.begin(), end = secondCache.end(); iter != end; ) { - if (iter->second.lastFrame + TEXTURE_SECOND_KILL_AGE < gpuStats.numFrames) { - glDeleteTextures(1, &iter->second.texture); - secondCache.erase(iter++); - } - else - ++iter; - } } void TextureCache::Invalidate(u32 addr, int size, bool force) { @@ -674,25 +654,12 @@ static inline u32 MiniHash(const u32 *ptr) { static inline u32 QuickTexHash(u32 addr, int bufw, int w, int h, u32 format) { u32 sizeInRAM = (bitsPerPixel[format < 11 ? format : 0] * bufw * h / 2) / 8; -#if TEXCACHE_USE_CITYHASH - return CityHash32(Memory::GetCharPointer(addr), sizeInRAM); -#else const u32 *checkp = (const u32 *) Memory::GetPointer(addr); u32 check = 0; for (u32 i = 0; i < (sizeInRAM * 2) / 4; ++i) check += *checkp++; return check; -#endif -} - -inline bool TextureCache::TexCacheEntry::Matches(u16 dim2, u32 hash2, u8 format2, int maxLevel2) { - return dim == dim2 && hash == hash2 && format == format2 && maxLevel == maxLevel2; -} -inline bool TextureCache::TexCacheEntry::MatchesClut(bool hasClut, u8 clutformat2, u32 clutaddr2) { - if (!hasClut) - return true; - return clutformat == clutformat2 && clutaddr == clutaddr2 && cluthash == Memory::Read_U32(clutaddr); } void TextureCache::SetTexture() { @@ -760,10 +727,19 @@ void TextureCache::SetTexture() { //Validate the texture here (width, height etc) int dim = gstate.texsize[0] & 0xF0F; - //TODO: Check more texture parameters, compute real texture hash - bool match = entry->Matches(dim, texhash, format, maxLevel) && entry->MatchesClut(hasClut, clutformat, clutaddr); + bool match = true; bool rehash = entry->status == TexCacheEntry::STATUS_UNRELIABLE; - bool doDelete = true; + + //TODO: Check more texture parameters, compute real texture hash + if (dim != entry->dim || + entry->hash != texhash || + entry->format != format || + entry->maxLevel != maxLevel || + (hasClut && + (entry->clutformat != clutformat || + entry->clutaddr != clutaddr || + entry->cluthash != Memory::Read_U32(entry->clutaddr)))) + match = false; if (match) { if (entry->lastFrame != gpuStats.numFrames) { @@ -776,48 +752,26 @@ void TextureCache::SetTexture() { } else { --entry->framesUntilNextFullHash; } + } - // If it's not huge or has been invalidated many times, recheck the whole texture. - if (entry->invalidHint > 180 || (entry->invalidHint > 15 && dim <= 0x909)) { - entry->invalidHint = 0; - rehash = true; - } + // If it's not huge or has been invalidated many times, recheck the whole texture. + if (entry->invalidHint > 180 || (entry->invalidHint > 15 && dim <= 0x909)) { + entry->invalidHint = 0; + rehash = true; + } - if (rehash && entry->status != TexCacheEntry::STATUS_RELIABLE) { - int w = 1 << (gstate.texsize[0] & 0xf); - int h = 1 << ((gstate.texsize[0] >> 8) & 0xf); - int bufw = gstate.texbufwidth[0] & 0x3ff; - u32 check = QuickTexHash(texaddr, bufw, w, h, format); - if (check != entry->fullhash) { - entry->status = TexCacheEntry::STATUS_UNRELIABLE; - entry->numFrames = 0; - - // Don't give up just yet. Let's try the secondary cache. - u64 secondKey = ((u64)texaddr << 32) | (u64)(check ^ clutaddr); - TexCache::iterator secondIter = secondCache.find(secondKey); - if (secondIter != secondCache.end()) - { - TexCacheEntry *secondEntry = &secondIter->second; - if (secondEntry->Matches(dim, texhash, format, maxLevel) && secondEntry->MatchesClut(hasClut, clutformat, clutaddr)) - entry = secondEntry; - else - { - match = false; - gpuStats.numTextureInvalidations++; - } - } - else - { - match = false; - gpuStats.numTextureInvalidations++; - - secondKey = ((u64)entry->addr << 32) | (u64)(entry->fullhash ^ entry->clutaddr); - secondCache[secondKey] = *entry; - doDelete = false; - } - } else if (entry->status == TexCacheEntry::STATUS_UNRELIABLE && entry->numFrames > TexCacheEntry::FRAMES_REGAIN_TRUST) { - entry->status = TexCacheEntry::STATUS_HASHING; - } + if (rehash && entry->status != TexCacheEntry::STATUS_RELIABLE) { + int w = 1 << (gstate.texsize[0] & 0xf); + int h = 1 << ((gstate.texsize[0] >> 8) & 0xf); + int bufw = gstate.texbufwidth[0] & 0x3ff; + u32 check = QuickTexHash(texaddr, bufw, w, h, format); + if (check != entry->fullhash) { + match = false; + gpuStats.numTextureInvalidations++; + entry->status = TexCacheEntry::STATUS_UNRELIABLE; + entry->numFrames = 0; + } else if (entry->status == TexCacheEntry::STATUS_UNRELIABLE && entry->numFrames > TexCacheEntry::FRAMES_REGAIN_TRUST) { + entry->status = TexCacheEntry::STATUS_HASHING; } } @@ -834,10 +788,10 @@ void TextureCache::SetTexture() { return; //Done! } else { INFO_LOG(G3D, "Texture different or overwritten, reloading at %08x", texaddr); + if (entry->texture == lastBoundTexture) + lastBoundTexture = -1; - if (doDelete) { - glDeleteTextures(1, &entry->texture); - } + glDeleteTextures(1, &entry->texture); if (entry->status == TexCacheEntry::STATUS_RELIABLE) { entry->status = TexCacheEntry::STATUS_HASHING; } diff --git a/GPU/GLES/TextureCache.h b/GPU/GLES/TextureCache.h index 5007275ce5..55185140db 100644 --- a/GPU/GLES/TextureCache.h +++ b/GPU/GLES/TextureCache.h @@ -84,9 +84,6 @@ private: u8 minFilt; bool sClamp; bool tClamp; - - bool Matches(u16 dim2, u32 hash2, u8 format2, int maxLevel2); - bool MatchesClut(bool hasClut, u8 clutformat2, u32 clutaddr2); }; void Decimate(); // Run this once per frame to get rid of old textures. @@ -99,7 +96,6 @@ private: typedef std::map TexCache; TexCache cache; - TexCache secondCache; template class SimpleBuf {