From 663bd915dc1878c9838e44172a8bd4ea866d863f Mon Sep 17 00:00:00 2001 From: mimimi085181 Date: Sun, 13 Sep 2015 13:30:56 +0200 Subject: [PATCH] Respect the stride for efb copies when hashing them --- Source/Core/VideoCommon/TextureCacheBase.cpp | 24 ++++++++++++++++++-- Source/Core/VideoCommon/TextureCacheBase.h | 2 ++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/Source/Core/VideoCommon/TextureCacheBase.cpp b/Source/Core/VideoCommon/TextureCacheBase.cpp index 8b7b7190aa1a..3b8d1c212eda 100644 --- a/Source/Core/VideoCommon/TextureCacheBase.cpp +++ b/Source/Core/VideoCommon/TextureCacheBase.cpp @@ -159,7 +159,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); } @@ -1029,7 +1029,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. @@ -1134,3 +1134,23 @@ void TextureCache::TCacheEntryBase::Zero(u8* ptr) ptr += memory_stride; } } + +u64 TextureCache::TCacheEntryBase::CalculateHash() +{ + u8* ptr = Memory::GetPointer(addr); + if (memory_stride == CacheLinesPerRow() * 32) + { + return GetHash64(ptr, (int)size_in_bytes, g_ActiveConfig.iSafeTextureCache_ColorSamples); + } + else + { + u64 temp_hash = size_in_bytes; + u32 samples = ((size_in_bytes + NumBlocksY() - 1) / NumBlocksY()) * g_ActiveConfig.iSafeTextureCache_ColorSamples; + for (u32 i = 0; i < NumBlocksY(); i++) + { + temp_hash = (temp_hash * 397) ^ GetHash64(ptr, (int)CacheLinesPerRow() * 32, samples); + ptr += memory_stride; + } + return temp_hash; + } +} diff --git a/Source/Core/VideoCommon/TextureCacheBase.h b/Source/Core/VideoCommon/TextureCacheBase.h index 6ffcbb82dc5e..7fc581b73f7f 100644 --- a/Source/Core/VideoCommon/TextureCacheBase.h +++ b/Source/Core/VideoCommon/TextureCacheBase.h @@ -114,6 +114,8 @@ class TextureCache u32 CacheLinesPerRow() const; void Zero(u8* ptr); + + u64 CalculateHash(); }; virtual ~TextureCache(); // needs virtual for DX11 dtor