diff options
| author | mimimi085181 <mimimi085181@gmail.com> | 2015-09-13 13:30:56 +0200 |
|---|---|---|
| committer | mimimi085181 <mimimi085181@gmail.com> | 2015-09-26 20:19:02 +0200 |
| commit | e24b8c4ab728c50b3c6a1d8b0066bdbf2f9292d7 (patch) | |
| tree | c2637b1abf11161528bfb564e45bc0ef0c46b48f /Source/Core/VideoCommon/TextureCacheBase.cpp | |
| parent | a91810ba3bb583a14a3e278527f2b801ceb29367 (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.cpp | 33 |
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; + } +} |
