diff --git a/GPU/Common/TextureCacheCommon.cpp b/GPU/Common/TextureCacheCommon.cpp index 23b39d2ca8..7b5b67a708 100644 --- a/GPU/Common/TextureCacheCommon.cpp +++ b/GPU/Common/TextureCacheCommon.cpp @@ -212,11 +212,9 @@ SamplerCacheKey TextureCacheCommon::GetSamplingParams(int maxLevel, u32 texAddr) } // Video bilinear override - if (!key.magFilt && texAddr != 0) { - if (videos_.find(texAddr & 0x3FFFFFFF) != videos_.end()) { - // Enforce bilinear filtering on magnification. - key.magFilt = 1; - } + if (!key.magFilt && texAddr != 0 && IsVideo(texAddr)) { + // Enforce bilinear filtering on magnification. + key.magFilt = 1; } // Filtering overrides @@ -427,6 +425,7 @@ TexCacheEntry *TextureCacheCommon::SetTexture() { if (texhash != entry->hash) { match = false; + reason = "minihash"; } else if (entry->GetHashStatus() == TexCacheEntry::STATUS_RELIABLE) { rehash = false; } @@ -690,17 +689,28 @@ void TextureCacheCommon::Decimate(bool forcePressure) { } void TextureCacheCommon::DecimateVideos() { - if (!videos_.empty()) { - for (auto iter = videos_.begin(); iter != videos_.end(); ) { - if (iter->second + VIDEO_DECIMATE_AGE < gpuStats.numFlips) { - videos_.erase(iter++); - } else { - ++iter; - } + for (auto iter = videos_.begin(); iter != videos_.end(); ) { + if (iter->flips + VIDEO_DECIMATE_AGE < gpuStats.numFlips) { + iter = videos_.erase(iter++); + } else { + ++iter; } } } +bool TextureCacheCommon::IsVideo(u32 texaddr) { + texaddr &= 0x3FFFFFFF; + for (auto info : videos_) { + if (texaddr < info.addr) { + continue; + } + if (texaddr < info.addr + info.size) { + return true; + } + } + return false; +} + void TextureCacheCommon::HandleTextureChange(TexCacheEntry *const entry, const char *reason, bool initialMatch, bool doDelete) { cacheSizeEstimate_ -= EstimateTexMemoryUsage(entry); entry->numInvalidated++; @@ -1076,7 +1086,7 @@ void TextureCacheCommon::NotifyConfigChanged() { void TextureCacheCommon::NotifyVideoUpload(u32 addr, int size, int width, GEBufferFormat fmt) { addr &= 0x3FFFFFFF; - videos_[addr] = gpuStats.numFlips; + videos_.push_back({ addr, (u32)size, gpuStats.numFlips }); } void TextureCacheCommon::LoadClut(u32 clutAddr, u32 loadBytes) { @@ -1620,8 +1630,7 @@ void TextureCacheCommon::ApplyTexture() { if (nextNeedsRebuild_) { // Regardless of hash fails or otherwise, if this is a video, mark it frequently changing. // This prevents temporary scaling perf hits on the first second of video. - bool isVideo = videos_.find(entry->addr & 0x3FFFFFFF) != videos_.end(); - if (isVideo) { + if (IsVideo(entry->addr)) { entry->status |= TexCacheEntry::STATUS_CHANGE_FREQUENT; } diff --git a/GPU/Common/TextureCacheCommon.h b/GPU/Common/TextureCacheCommon.h index e4be66c568..809921d790 100644 --- a/GPU/Common/TextureCacheCommon.h +++ b/GPU/Common/TextureCacheCommon.h @@ -302,6 +302,7 @@ protected: void SetTextureFramebuffer(const AttachCandidate &candidate); void DecimateVideos(); + bool IsVideo(u32 texaddr); inline u32 QuickTexHash(TextureReplacer &replacer, u32 addr, int bufw, int w, int h, GETextureFormat format, TexCacheEntry *entry) const { if (replacer.Enabled()) { @@ -345,7 +346,12 @@ protected: TexCache secondCache_; u32 secondCacheSizeEstimate_ = 0; - std::map videos_; + struct VideoInfo { + u32 addr; + u32 size; + int flips; + }; + std::vector videos_; SimpleBuf tmpTexBuf32_; SimpleBuf tmpTexBufRearrange_; diff --git a/GPU/D3D11/TextureCacheD3D11.cpp b/GPU/D3D11/TextureCacheD3D11.cpp index ab9d708409..c96b56e61a 100644 --- a/GPU/D3D11/TextureCacheD3D11.cpp +++ b/GPU/D3D11/TextureCacheD3D11.cpp @@ -741,7 +741,7 @@ void TextureCacheD3D11::LoadTextureLevel(TexCacheEntry &entry, ReplacedTexture & replacedInfo.cachekey = entry.CacheKey(); replacedInfo.hash = entry.fullhash; replacedInfo.addr = entry.addr; - replacedInfo.isVideo = videos_.find(entry.addr & 0x3FFFFFFF) != videos_.end(); + replacedInfo.isVideo = IsVideo(entry.addr); replacedInfo.isFinal = (entry.status & TexCacheEntry::STATUS_TO_SCALE) == 0; replacedInfo.scaleFactor = scaleFactor; replacedInfo.fmt = FromD3D11Format(dstFmt); diff --git a/GPU/Directx9/TextureCacheDX9.cpp b/GPU/Directx9/TextureCacheDX9.cpp index 77188c196b..8b8032121a 100644 --- a/GPU/Directx9/TextureCacheDX9.cpp +++ b/GPU/Directx9/TextureCacheDX9.cpp @@ -667,7 +667,7 @@ void TextureCacheDX9::LoadTextureLevel(TexCacheEntry &entry, ReplacedTexture &re replacedInfo.cachekey = entry.CacheKey(); replacedInfo.hash = entry.fullhash; replacedInfo.addr = entry.addr; - replacedInfo.isVideo = videos_.find(entry.addr & 0x3FFFFFFF) != videos_.end(); + replacedInfo.isVideo = IsVideo(entry.addr); replacedInfo.isFinal = (entry.status & TexCacheEntry::STATUS_TO_SCALE) == 0; replacedInfo.scaleFactor = scaleFactor; replacedInfo.fmt = FromD3D9Format(dstFmt); diff --git a/GPU/GLES/TextureCacheGLES.cpp b/GPU/GLES/TextureCacheGLES.cpp index 8c752ed2df..20a96ff4bc 100644 --- a/GPU/GLES/TextureCacheGLES.cpp +++ b/GPU/GLES/TextureCacheGLES.cpp @@ -696,7 +696,7 @@ void TextureCacheGLES::LoadTextureLevel(TexCacheEntry &entry, ReplacedTexture &r replacedInfo.cachekey = entry.CacheKey(); replacedInfo.hash = entry.fullhash; replacedInfo.addr = entry.addr; - replacedInfo.isVideo = videos_.find(entry.addr & 0x3FFFFFFF) != videos_.end(); + replacedInfo.isVideo = IsVideo(entry.addr); replacedInfo.isFinal = (entry.status & TexCacheEntry::STATUS_TO_SCALE) == 0; replacedInfo.scaleFactor = scaleFactor; replacedInfo.fmt = FromDataFormat(dstFmt); diff --git a/GPU/Vulkan/TextureCacheVulkan.cpp b/GPU/Vulkan/TextureCacheVulkan.cpp index 7dd3caef7b..4b1c322251 100644 --- a/GPU/Vulkan/TextureCacheVulkan.cpp +++ b/GPU/Vulkan/TextureCacheVulkan.cpp @@ -899,7 +899,7 @@ void TextureCacheVulkan::BuildTexture(TexCacheEntry *const entry) { replacedInfo.cachekey = cachekey; replacedInfo.hash = entry->fullhash; replacedInfo.addr = entry->addr; - replacedInfo.isVideo = videos_.find(entry->addr & 0x3FFFFFFF) != videos_.end(); + replacedInfo.isVideo = IsVideo(entry->addr); replacedInfo.isFinal = (entry->status & TexCacheEntry::STATUS_TO_SCALE) == 0; replacedInfo.scaleFactor = scaleFactor; replacedInfo.fmt = FromVulkanFormat(actualFmt);