From 341fe04f4bc86f13215f659c00662e79108a9b48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sat, 30 Dec 2023 14:06:24 +0100 Subject: [PATCH] Apply nearest filter for pixel-mapped draws --- GPU/Common/TextureCacheCommon.cpp | 3 +++ GPU/D3D11/DrawEngineD3D11.cpp | 5 ++++- GPU/Directx9/DrawEngineDX9.cpp | 5 ++++- GPU/GLES/DrawEngineGLES.cpp | 5 ++++- GPU/GPUState.h | 3 +++ GPU/Vulkan/DrawEngineVulkan.cpp | 2 ++ GPU/Vulkan/TextureCacheVulkan.cpp | 1 + 7 files changed, 21 insertions(+), 3 deletions(-) diff --git a/GPU/Common/TextureCacheCommon.cpp b/GPU/Common/TextureCacheCommon.cpp index 1d10254f1d80..25f00c832a0b 100644 --- a/GPU/Common/TextureCacheCommon.cpp +++ b/GPU/Common/TextureCacheCommon.cpp @@ -284,6 +284,9 @@ SamplerCacheKey TextureCacheCommon::GetSamplingParams(int maxLevel, const TexCac break; } } + if (gstate_c.pixelMapped) { + forceFiltering = TEX_FILTER_FORCE_NEAREST; + } switch (forceFiltering) { case TEX_FILTER_AUTO: diff --git a/GPU/D3D11/DrawEngineD3D11.cpp b/GPU/D3D11/DrawEngineD3D11.cpp index ac7dece6cf17..0e8099db4a62 100644 --- a/GPU/D3D11/DrawEngineD3D11.cpp +++ b/GPU/D3D11/DrawEngineD3D11.cpp @@ -408,8 +408,11 @@ void DrawEngineD3D11::DoFlush() { if (result.action == SW_CLEAR && everUsedEqualDepth_ && gstate.isClearModeDepthMask() && result.depth > 0.0f && result.depth < 1.0f) result.action = SW_NOT_READY; - if (textureNeedsApply) + if (textureNeedsApply) { + gstate_c.pixelMapped = result.pixelMapped; textureCache_->ApplyTexture(); + gstate_c.pixelMapped = false; + } // Need to ApplyDrawState after ApplyTexture because depal can launch a render pass and that wrecks the state. ApplyDrawState(prim); diff --git a/GPU/Directx9/DrawEngineDX9.cpp b/GPU/Directx9/DrawEngineDX9.cpp index 20f98dfc5963..810fb0419690 100644 --- a/GPU/Directx9/DrawEngineDX9.cpp +++ b/GPU/Directx9/DrawEngineDX9.cpp @@ -365,8 +365,11 @@ void DrawEngineDX9::DoFlush() { if (result.action == SW_CLEAR && everUsedEqualDepth_ && gstate.isClearModeDepthMask() && result.depth > 0.0f && result.depth < 1.0f) result.action = SW_NOT_READY; - if (textureNeedsApply) + if (textureNeedsApply) { + gstate_c.pixelMapped = result.pixelMapped; textureCache_->ApplyTexture(); + gstate_c.pixelMapped = false; + } ApplyDrawState(prim); diff --git a/GPU/GLES/DrawEngineGLES.cpp b/GPU/GLES/DrawEngineGLES.cpp index 0e44b8b667c0..6f4400b5384e 100644 --- a/GPU/GLES/DrawEngineGLES.cpp +++ b/GPU/GLES/DrawEngineGLES.cpp @@ -393,8 +393,11 @@ void DrawEngineGLES::DoFlush() { if (result.action == SW_CLEAR && everUsedEqualDepth_ && gstate.isClearModeDepthMask() && result.depth > 0.0f && result.depth < 1.0f) result.action = SW_NOT_READY; - if (textureNeedsApply) + if (textureNeedsApply) { + gstate_c.pixelMapped = result.pixelMapped; textureCache_->ApplyTexture(); + gstate_c.pixelMapped = false; + } // Need to ApplyDrawState after ApplyTexture because depal can launch a render pass and that wrecks the state. ApplyDrawState(prim); diff --git a/GPU/GPUState.h b/GPU/GPUState.h index e8d77494a572..d7fbf09ddafd 100644 --- a/GPU/GPUState.h +++ b/GPU/GPUState.h @@ -689,6 +689,9 @@ struct GPUStateCache { // We detect this case and go into a special drawing mode. bool blueToAlpha; + // U/V is 1:1 to pixels. Can influence texture sampling. + bool pixelMapped; + // TODO: These should be accessed from the current VFB object directly. u32 curRTWidth; u32 curRTHeight; diff --git a/GPU/Vulkan/DrawEngineVulkan.cpp b/GPU/Vulkan/DrawEngineVulkan.cpp index daf4b25a3a95..c4b823b99b18 100644 --- a/GPU/Vulkan/DrawEngineVulkan.cpp +++ b/GPU/Vulkan/DrawEngineVulkan.cpp @@ -440,7 +440,9 @@ void DrawEngineVulkan::DoFlush() { // to use a "pre-clear" render pass, for high efficiency on tilers. if (result.action == SW_DRAW_PRIMITIVES) { if (textureNeedsApply) { + gstate_c.pixelMapped = result.pixelMapped; textureCache_->ApplyTexture(); + gstate_c.pixelMapped = false; textureCache_->GetVulkanHandles(imageView, sampler); if (imageView == VK_NULL_HANDLE) imageView = (VkImageView)draw_->GetNativeObject(gstate_c.textureIsArray ? Draw::NativeObject::NULL_IMAGEVIEW_ARRAY : Draw::NativeObject::NULL_IMAGEVIEW); diff --git a/GPU/Vulkan/TextureCacheVulkan.cpp b/GPU/Vulkan/TextureCacheVulkan.cpp index f6550eb3f016..6f4b0b08423c 100644 --- a/GPU/Vulkan/TextureCacheVulkan.cpp +++ b/GPU/Vulkan/TextureCacheVulkan.cpp @@ -136,6 +136,7 @@ VkSampler SamplerCache::GetOrCreateSampler(const SamplerCacheKey &key) { samp.magFilter = key.magFilt ? VK_FILTER_LINEAR : VK_FILTER_NEAREST; samp.minFilter = key.minFilt ? VK_FILTER_LINEAR : VK_FILTER_NEAREST; samp.mipmapMode = key.mipFilt ? VK_SAMPLER_MIPMAP_MODE_LINEAR : VK_SAMPLER_MIPMAP_MODE_NEAREST; + if (key.aniso) { // Docs say the min of this value and the supported max are used. samp.maxAnisotropy = 1 << g_Config.iAnisotropyLevel;