From 82a7a264096560c6f1e244712bb8e091532a4f1d Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 27 Feb 2021 17:17:21 -0800 Subject: [PATCH] GPU: Look up replaced filtering options. --- GPU/Common/TextureCacheCommon.cpp | 58 +++++++++++++++++++------------ GPU/Common/TextureCacheCommon.h | 2 +- GPU/D3D11/TextureCacheD3D11.cpp | 2 +- GPU/Directx9/TextureCacheDX9.cpp | 2 +- GPU/GLES/TextureCacheGLES.cpp | 2 +- GPU/Vulkan/TextureCacheVulkan.cpp | 2 +- 6 files changed, 40 insertions(+), 28 deletions(-) diff --git a/GPU/Common/TextureCacheCommon.cpp b/GPU/Common/TextureCacheCommon.cpp index 180cbfa527..47dcf6d755 100644 --- a/GPU/Common/TextureCacheCommon.cpp +++ b/GPU/Common/TextureCacheCommon.cpp @@ -147,7 +147,7 @@ static int TexLog2(float delta) { return useful - 127 * 256; } -SamplerCacheKey TextureCacheCommon::GetSamplingParams(int maxLevel, u32 texAddr) { +SamplerCacheKey TextureCacheCommon::GetSamplingParams(int maxLevel, const TexCacheEntry *entry) { SamplerCacheKey key; int minFilt = gstate.texfilter & 0x7; @@ -214,37 +214,49 @@ SamplerCacheKey TextureCacheCommon::GetSamplingParams(int maxLevel, u32 texAddr) } // Video bilinear override - if (!key.magFilt && texAddr != 0 && IsVideo(texAddr)) { + if (!key.magFilt && entry != nullptr && IsVideo(entry->addr)) { // Enforce bilinear filtering on magnification. key.magFilt = 1; } - // Filtering overrides - switch (g_Config.iTexFiltering) { - case TEX_FILTER_AUTO: - // Follow what the game wants. We just do a single heuristic change to avoid bleeding of wacky color test colors - // in higher resolution (used by some games for sprites, and they accidentally have linear filter on). - if (gstate.isModeThrough() && g_Config.iInternalResolution != 1) { - bool uglyColorTest = gstate.isColorTestEnabled() && !IsColorTestTriviallyTrue() && gstate.getColorTestRef() != 0; - if (uglyColorTest) { - // Force to nearest. - key.magFilt = 0; - key.minFilt = 0; + // Filtering overrides from replacements or settings. + TextureFiltering forceFiltering = TEX_FILTER_AUTO; + u64 cachekey = replacer_.Enabled() ? entry->CacheKey() : 0; + if (!replacer_.Enabled() || !replacer_.FindFiltering(cachekey, entry->fullhash, &forceFiltering)) { + switch (g_Config.iTexFiltering) { + case TEX_FILTER_AUTO: + // Follow what the game wants. We just do a single heuristic change to avoid bleeding of wacky color test colors + // in higher resolution (used by some games for sprites, and they accidentally have linear filter on). + if (gstate.isModeThrough() && g_Config.iInternalResolution != 1) { + bool uglyColorTest = gstate.isColorTestEnabled() && !IsColorTestTriviallyTrue() && gstate.getColorTestRef() != 0; + if (uglyColorTest) + forceFiltering = TEX_FILTER_FORCE_NEAREST; } + break; + case TEX_FILTER_FORCE_LINEAR: + // Override to linear filtering if there's no alpha or color testing going on. + if ((!gstate.isColorTestEnabled() || IsColorTestTriviallyTrue()) && + (!gstate.isAlphaTestEnabled() || IsAlphaTestTriviallyTrue())) { + forceFiltering = TEX_FILTER_FORCE_LINEAR; + } + break; + case TEX_FILTER_FORCE_NEAREST: + default: + // Just force to nearest without checks. Safe (but ugly). + forceFiltering = TEX_FILTER_FORCE_NEAREST; + break; } + } + + switch (forceFiltering) { + case TEX_FILTER_AUTO: break; case TEX_FILTER_FORCE_LINEAR: - // Override to linear filtering if there's no alpha or color testing going on. - if ((!gstate.isColorTestEnabled() || IsColorTestTriviallyTrue()) && - (!gstate.isAlphaTestEnabled() || IsAlphaTestTriviallyTrue())) { - key.magFilt = 1; - key.minFilt = 1; - key.mipFilt = 1; - } + key.magFilt = 1; + key.minFilt = 1; + key.mipFilt = 1; break; case TEX_FILTER_FORCE_NEAREST: - default: - // Just force to nearest without checks. Safe (but ugly). key.magFilt = 0; key.minFilt = 0; break; @@ -254,7 +266,7 @@ SamplerCacheKey TextureCacheCommon::GetSamplingParams(int maxLevel, u32 texAddr) } SamplerCacheKey TextureCacheCommon::GetFramebufferSamplingParams(u16 bufferWidth, u16 bufferHeight) { - SamplerCacheKey key = GetSamplingParams(0, 0); + SamplerCacheKey key = GetSamplingParams(0, nullptr); // Kill any mipmapping settings. key.mipEnable = false; diff --git a/GPU/Common/TextureCacheCommon.h b/GPU/Common/TextureCacheCommon.h index 79eac7be9f..9b16ade566 100644 --- a/GPU/Common/TextureCacheCommon.h +++ b/GPU/Common/TextureCacheCommon.h @@ -285,7 +285,7 @@ protected: u32 EstimateTexMemoryUsage(const TexCacheEntry *entry); - SamplerCacheKey GetSamplingParams(int maxLevel, u32 texAddr); + SamplerCacheKey GetSamplingParams(int maxLevel, const TexCacheEntry *entry); SamplerCacheKey GetFramebufferSamplingParams(u16 bufferWidth, u16 bufferHeight); void UpdateMaxSeenV(TexCacheEntry *entry, bool throughMode); diff --git a/GPU/D3D11/TextureCacheD3D11.cpp b/GPU/D3D11/TextureCacheD3D11.cpp index c96b56e61a..24f20071a5 100644 --- a/GPU/D3D11/TextureCacheD3D11.cpp +++ b/GPU/D3D11/TextureCacheD3D11.cpp @@ -225,7 +225,7 @@ void TextureCacheD3D11::BindTexture(TexCacheEntry *entry) { lastBoundTexture = textureView; } int maxLevel = (entry->status & TexCacheEntry::STATUS_BAD_MIPS) ? 0 : entry->maxLevel; - SamplerCacheKey samplerKey = GetSamplingParams(maxLevel, entry->addr); + SamplerCacheKey samplerKey = GetSamplingParams(maxLevel, entry); ID3D11SamplerState *state = samplerCache_.GetOrCreateSampler(device_, samplerKey); context_->PSSetSamplers(0, 1, &state); } diff --git a/GPU/Directx9/TextureCacheDX9.cpp b/GPU/Directx9/TextureCacheDX9.cpp index 8b8032121a..0b1d536ed7 100644 --- a/GPU/Directx9/TextureCacheDX9.cpp +++ b/GPU/Directx9/TextureCacheDX9.cpp @@ -196,7 +196,7 @@ void TextureCacheDX9::BindTexture(TexCacheEntry *entry) { lastBoundTexture = texture; } int maxLevel = (entry->status & TexCacheEntry::STATUS_BAD_MIPS) ? 0 : entry->maxLevel; - SamplerCacheKey samplerKey = GetSamplingParams(maxLevel, entry->addr); + SamplerCacheKey samplerKey = GetSamplingParams(maxLevel, entry); ApplySamplingParams(samplerKey); } diff --git a/GPU/GLES/TextureCacheGLES.cpp b/GPU/GLES/TextureCacheGLES.cpp index 20a96ff4bc..e15b900aca 100644 --- a/GPU/GLES/TextureCacheGLES.cpp +++ b/GPU/GLES/TextureCacheGLES.cpp @@ -228,7 +228,7 @@ void TextureCacheGLES::BindTexture(TexCacheEntry *entry) { lastBoundTexture = entry->textureName; } int maxLevel = (entry->status & TexCacheEntry::STATUS_BAD_MIPS) ? 0 : entry->maxLevel; - SamplerCacheKey samplerKey = GetSamplingParams(maxLevel, entry->addr); + SamplerCacheKey samplerKey = GetSamplingParams(maxLevel, entry); ApplySamplingParams(samplerKey); gstate_c.SetUseShaderDepal(false); } diff --git a/GPU/Vulkan/TextureCacheVulkan.cpp b/GPU/Vulkan/TextureCacheVulkan.cpp index 64a76d2303..31ea90b565 100644 --- a/GPU/Vulkan/TextureCacheVulkan.cpp +++ b/GPU/Vulkan/TextureCacheVulkan.cpp @@ -519,7 +519,7 @@ void TextureCacheVulkan::BindTexture(TexCacheEntry *entry) { entry->vkTex->Touch(); imageView_ = entry->vkTex->GetImageView(); int maxLevel = (entry->status & TexCacheEntry::STATUS_BAD_MIPS) ? 0 : entry->maxLevel; - SamplerCacheKey samplerKey = GetSamplingParams(maxLevel, entry->addr); + SamplerCacheKey samplerKey = GetSamplingParams(maxLevel, entry); curSampler_ = samplerCache_.GetOrCreateSampler(samplerKey); drawEngine_->SetDepalTexture(VK_NULL_HANDLE); gstate_c.SetUseShaderDepal(false);