diff --git a/GPU/GLES/TextureCache.cpp b/GPU/GLES/TextureCache.cpp index 77fea05f9c..5d55edee44 100644 --- a/GPU/GLES/TextureCache.cpp +++ b/GPU/GLES/TextureCache.cpp @@ -64,10 +64,15 @@ void TextureCache::Clear(bool delete_them) { 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()) { - INFO_LOG(G3D, "Texture cached cleared from %i textures", (int)cache.size()); + if (cache.size() + secondCache.size()) { + INFO_LOG(G3D, "Texture cached cleared from %i textures", (int)(cache.size() + secondCache.size())); cache.clear(); + secondCache.clear(); } } @@ -82,6 +87,14 @@ void TextureCache::Decimate() { else ++iter; } + for (TexCache::iterator iter = secondCache.begin(), end = secondCache.end(); iter != end; ) { + if (iter->second.lastFrame + TEXTURE_KILL_AGE < gpuStats.numFrames) { + glDeleteTextures(1, &iter->second.texture); + secondCache.erase(iter++); + } + else + ++iter; + } } void TextureCache::Invalidate(u32 addr, int size, bool force) { @@ -662,6 +675,15 @@ static inline u32 QuickTexHash(u32 addr, int bufw, int w, int h, u32 format) { return check; } +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() { u32 texaddr = (gstate.texaddr[0] & 0xFFFFF0) | ((gstate.texbufwidth[0]<<8) & 0x0F000000); if (!Memory::IsValidAddress(texaddr)) { @@ -727,19 +749,9 @@ void TextureCache::SetTexture() { //Validate the texture here (width, height etc) int dim = gstate.texsize[0] & 0xF0F; - bool match = true; - bool rehash = entry->status == TexCacheEntry::STATUS_UNRELIABLE; - //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; + bool match = entry->Matches(dim, texhash, format, maxLevel) && entry->MatchesClut(hasClut, clutformat, clutaddr); + bool rehash = entry->status == TexCacheEntry::STATUS_UNRELIABLE; if (match) { if (entry->lastFrame != gpuStats.numFrames) { diff --git a/GPU/GLES/TextureCache.h b/GPU/GLES/TextureCache.h index 55185140db..5007275ce5 100644 --- a/GPU/GLES/TextureCache.h +++ b/GPU/GLES/TextureCache.h @@ -84,6 +84,9 @@ 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. @@ -96,6 +99,7 @@ private: typedef std::map TexCache; TexCache cache; + TexCache secondCache; template class SimpleBuf {