Merge pull request #3036 from mimimi085181/hash-respecting-stride

Respect the stride for efb copies when hashing them
This commit is contained in:
Scott Mansell 2015-09-28 05:23:55 +13:00
commit af327aec79
2 changed files with 33 additions and 2 deletions

View File

@ -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 // 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 // host GPU are unrecoverable. Perform this check only every TEXTURE_KILL_THRESHOLD for performance reasons
if ((_frameCount - iter->second->frameCount) % TEXTURE_KILL_THRESHOLD == 1 && 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); 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); 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); entry->SetHashes(hash, hash);
// Invalidate all textures that overlap the range of our efb copy. // Invalidate all textures that overlap the range of our efb copy.
@ -1166,3 +1166,32 @@ void TextureCache::TCacheEntryBase::Zero(u8* ptr)
ptr += memory_stride; 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;
}
}

View File

@ -114,6 +114,8 @@ public:
u32 CacheLinesPerRow() const; u32 CacheLinesPerRow() const;
void Zero(u8* ptr); void Zero(u8* ptr);
u64 CalculateHash() const;
}; };
virtual ~TextureCache(); // needs virtual for DX11 dtor virtual ~TextureCache(); // needs virtual for DX11 dtor