summaryrefslogtreecommitdiff
path: root/Source/Core/VideoCommon/TextureCacheBase.cpp
diff options
context:
space:
mode:
authormimimi085181 <mimimi085181@gmail.com>2015-09-13 13:30:56 +0200
committermimimi085181 <mimimi085181@gmail.com>2015-09-26 20:19:02 +0200
commite24b8c4ab728c50b3c6a1d8b0066bdbf2f9292d7 (patch)
treec2637b1abf11161528bfb564e45bc0ef0c46b48f /Source/Core/VideoCommon/TextureCacheBase.cpp
parenta91810ba3bb583a14a3e278527f2b801ceb29367 (diff)
Respect the stride for efb copies when hashing them
Diffstat (limited to 'Source/Core/VideoCommon/TextureCacheBase.cpp')
-rw-r--r--Source/Core/VideoCommon/TextureCacheBase.cpp33
1 files changed, 31 insertions, 2 deletions
diff --git a/Source/Core/VideoCommon/TextureCacheBase.cpp b/Source/Core/VideoCommon/TextureCacheBase.cpp
index e93e6955f4..1d9b564a8f 100644
--- a/Source/Core/VideoCommon/TextureCacheBase.cpp
+++ b/Source/Core/VideoCommon/TextureCacheBase.cpp
@@ -161,7 +161,7 @@ void TextureCache::Cleanup(int _frameCount)
// Only remove EFB copies when they wouldn't be used anymore(changed hash), because EFB copies living on the
// host GPU are unrecoverable. Perform this check only every TEXTURE_KILL_THRESHOLD for performance reasons
if ((_frameCount - iter->second->frameCount) % TEXTURE_KILL_THRESHOLD == 1 &&
- iter->second->hash != GetHash64(Memory::GetPointer(iter->second->addr), iter->second->size_in_bytes, g_ActiveConfig.iSafeTextureCache_ColorSamples))
+ iter->second->hash != iter->second->CalculateHash())
{
iter = FreeTexture(iter);
}
@@ -1050,7 +1050,7 @@ void TextureCache::CopyRenderTargetToTexture(u32 dstAddr, unsigned int dstFormat
entry->FromRenderTarget(dst, dstFormat, dstStride, srcFormat, srcRect, isIntensity, scaleByHalf, cbufid, colmat);
- u64 hash = GetHash64(dst, (int)entry->size_in_bytes, g_ActiveConfig.iSafeTextureCache_ColorSamples);
+ u64 hash = entry->CalculateHash();
entry->SetHashes(hash, hash);
// Invalidate all textures that overlap the range of our efb copy.
@@ -1166,3 +1166,32 @@ void TextureCache::TCacheEntryBase::Zero(u8* ptr)
ptr += memory_stride;
}
}
+
+u64 TextureCache::TCacheEntryBase::CalculateHash() const
+{
+ u8* ptr = Memory::GetPointer(addr);
+ if (memory_stride == CacheLinesPerRow() * 32)
+ {
+ return GetHash64(ptr, size_in_bytes, g_ActiveConfig.iSafeTextureCache_ColorSamples);
+ }
+ else
+ {
+ u32 blocks = NumBlocksY();
+ u64 temp_hash = size_in_bytes;
+
+ u32 samples_per_row = 0;
+ if (g_ActiveConfig.iSafeTextureCache_ColorSamples != 0)
+ {
+ // Hash at least 4 samples per row to avoid hashing in a bad pattern, like just on the left side of the efb copy
+ samples_per_row = std::max(g_ActiveConfig.iSafeTextureCache_ColorSamples / blocks, 4u);
+ }
+
+ for (u32 i = 0; i < blocks; i++)
+ {
+ // Multiply by a prime number to mix the hash up a bit. This prevents identical blocks from canceling each other out
+ temp_hash = (temp_hash * 397) ^ GetHash64(ptr, CacheLinesPerRow() * 32, samples_per_row);
+ ptr += memory_stride;
+ }
+ return temp_hash;
+ }
+}