From 0b9a72a62d38481ff08f742b2318d07f29ff5dff Mon Sep 17 00:00:00 2001 From: EmptyChaos Date: Thu, 24 Mar 2016 02:42:08 +0000 Subject: [PATCH] VideoCommon: Refactor TexMode0 mipmaps disabled test into a helper function --- Source/Core/VideoBackends/D3D/D3DState.cpp | 8 +++++--- Source/Core/VideoBackends/D3D/Render.cpp | 3 ++- Source/Core/VideoBackends/D3D12/D3DState.cpp | 8 +++++--- Source/Core/VideoBackends/D3D12/Render.cpp | 3 ++- Source/Core/VideoBackends/OGL/SamplerCache.cpp | 6 +++--- .../Core/VideoBackends/Software/TextureSampler.cpp | 7 ++++--- Source/Core/VideoCommon/SamplerCommon.h | 12 ++++++++++++ Source/Core/VideoCommon/TextureCacheBase.cpp | 3 ++- 8 files changed, 35 insertions(+), 15 deletions(-) diff --git a/Source/Core/VideoBackends/D3D/D3DState.cpp b/Source/Core/VideoBackends/D3D/D3DState.cpp index ca8778b909..64c6b48740 100644 --- a/Source/Core/VideoBackends/D3D/D3DState.cpp +++ b/Source/Core/VideoBackends/D3D/D3DState.cpp @@ -2,6 +2,8 @@ // Licensed under GPLv2+ // Refer to the license.txt file included. +#include + #include "Common/BitSet.h" #include "Common/CommonTypes.h" #include "Common/MsgHandler.h" @@ -260,7 +262,7 @@ ID3D11SamplerState* StateCache::Get(SamplerState state) unsigned int mip = d3dMipFilters[state.min_filter & 3]; - if (state.max_anisotropy > 1 && !IsBpTexMode0PointFiltering(state)) + if (state.max_anisotropy > 1 && !SamplerCommon::IsBpTexMode0PointFiltering(state)) { sampdc.Filter = D3D11_FILTER_ANISOTROPIC; sampdc.MaxAnisotropy = (u32)state.max_anisotropy; @@ -311,8 +313,8 @@ ID3D11SamplerState* StateCache::Get(SamplerState state) sampdc.AddressU = d3dClamps[state.wrap_s]; sampdc.AddressV = d3dClamps[state.wrap_t]; - sampdc.MaxLOD = (mip == TexMode0::TEXF_NONE) ? 0.0f : (float)state.max_lod / 16.f; - sampdc.MinLOD = (float)state.min_lod / 16.f; + sampdc.MaxLOD = SamplerCommon::AreBpTexMode0MipmapsEnabled(state) ? state.max_lod / 16.f : 0.f; + sampdc.MinLOD = std::min(state.min_lod / 16.f, sampdc.MaxLOD); sampdc.MipLODBias = (s32)state.lod_bias / 32.0f; ID3D11SamplerState* res = nullptr; diff --git a/Source/Core/VideoBackends/D3D/Render.cpp b/Source/Core/VideoBackends/D3D/Render.cpp index 9b73300fb9..dd6fafcdb9 100644 --- a/Source/Core/VideoBackends/D3D/Render.cpp +++ b/Source/Core/VideoBackends/D3D/Render.cpp @@ -36,6 +36,7 @@ #include "VideoCommon/OnScreenDisplay.h" #include "VideoCommon/PixelEngine.h" #include "VideoCommon/PixelShaderManager.h" +#include "VideoCommon/SamplerCommon.h" #include "VideoCommon/VideoConfig.h" namespace DX11 @@ -1201,7 +1202,7 @@ void Renderer::SetSamplerState(int stage, int texindex, bool custom_tex) if (g_ActiveConfig.bForceFiltering) { // Only use mipmaps if the game says they are available. - gx_state.sampler[stage].min_filter = (tm0.min_filter & 3) == TexMode0::TEXF_NONE ? 4 : 6; + gx_state.sampler[stage].min_filter = SamplerCommon::AreBpTexMode0MipmapsEnabled(tm0) ? 6 : 4; gx_state.sampler[stage].mag_filter = 1; // linear mag } else diff --git a/Source/Core/VideoBackends/D3D12/D3DState.cpp b/Source/Core/VideoBackends/D3D12/D3DState.cpp index c752087c91..9da11541cc 100644 --- a/Source/Core/VideoBackends/D3D12/D3DState.cpp +++ b/Source/Core/VideoBackends/D3D12/D3DState.cpp @@ -2,6 +2,8 @@ // Licensed under GPLv2+ // Refer to the license.txt file included. +#include + #include "Common/BitSet.h" #include "Common/CommonTypes.h" #include "Common/FileUtil.h" @@ -186,7 +188,7 @@ D3D12_SAMPLER_DESC StateCache::GetDesc12(SamplerState state) unsigned int mip = d3d_mip_filters[state.min_filter & 3]; sampdc.MaxAnisotropy = 1; - if (g_ActiveConfig.iMaxAnisotropy > 0 && !IsBpTexMode0PointFiltering(state)) + if (g_ActiveConfig.iMaxAnisotropy > 0 && !SamplerCommon::IsBpTexMode0PointFiltering(state)) { sampdc.Filter = D3D12_FILTER_ANISOTROPIC; sampdc.MaxAnisotropy = 1 << g_ActiveConfig.iMaxAnisotropy; @@ -242,8 +244,8 @@ D3D12_SAMPLER_DESC StateCache::GetDesc12(SamplerState state) sampdc.BorderColor[0] = sampdc.BorderColor[1] = sampdc.BorderColor[2] = sampdc.BorderColor[3] = 1.0f; - sampdc.MaxLOD = (mip == TexMode0::TEXF_NONE) ? 0.0f : static_cast(state.max_lod) / 16.f; - sampdc.MinLOD = static_cast(state.min_lod) / 16.f; + sampdc.MaxLOD = SamplerCommon::AreBpTexMode0MipmapsEnabled(state) ? state.max_lod / 16.f : 0.f; + sampdc.MinLOD = std::min(state.min_lod / 16.f, sampdc.MaxLOD); sampdc.MipLODBias = static_cast(state.lod_bias) / 32.0f; return sampdc; diff --git a/Source/Core/VideoBackends/D3D12/Render.cpp b/Source/Core/VideoBackends/D3D12/Render.cpp index 49f882f89c..ac95d198b3 100644 --- a/Source/Core/VideoBackends/D3D12/Render.cpp +++ b/Source/Core/VideoBackends/D3D12/Render.cpp @@ -39,6 +39,7 @@ #include "VideoCommon/OnScreenDisplay.h" #include "VideoCommon/PixelEngine.h" #include "VideoCommon/PixelShaderManager.h" +#include "VideoCommon/SamplerCommon.h" #include "VideoCommon/VertexLoaderManager.h" #include "VideoCommon/VideoConfig.h" @@ -1246,7 +1247,7 @@ void Renderer::SetSamplerState(int stage, int tex_index, bool custom_tex) if (g_ActiveConfig.bForceFiltering) { // Only use mipmaps if the game says they are available. - new_state.min_filter = (tm0.min_filter & 3) == TexMode0::TEXF_NONE ? 4 : 6; + new_state.min_filter = SamplerCommon::AreBpTexMode0MipmapsEnabled(tm0) ? 6 : 4; new_state.mag_filter = 1; // linear mag } else diff --git a/Source/Core/VideoBackends/OGL/SamplerCache.cpp b/Source/Core/VideoBackends/OGL/SamplerCache.cpp index 5f809825d5..d9a2008a50 100644 --- a/Source/Core/VideoBackends/OGL/SamplerCache.cpp +++ b/Source/Core/VideoBackends/OGL/SamplerCache.cpp @@ -60,7 +60,7 @@ void SamplerCache::SetSamplerState(int stage, const TexMode0& tm0, const TexMode // take equivalent forced linear when bForceFiltering if (g_ActiveConfig.bForceFiltering) { - params.tm0.min_filter = (tm0.min_filter & 3) == TexMode0::TEXF_NONE ? 4 : 6; + params.tm0.min_filter = SamplerCommon::AreBpTexMode0MipmapsEnabled(tm0) ? 6 : 4; params.tm0.mag_filter = 1; } @@ -136,7 +136,7 @@ void SamplerCache::SetParameters(GLuint sampler_id, const Params& params) GLint mag_filter = tm0.mag_filter ? GL_LINEAR : GL_NEAREST; if (g_ActiveConfig.iMaxAnisotropy > 0 && g_ogl_config.bSupportsAniso && - !IsBpTexMode0PointFiltering(tm0)) + !SamplerCommon::IsBpTexMode0PointFiltering(tm0)) { // https://www.opengl.org/registry/specs/EXT/texture_filter_anisotropic.txt // For predictable results on all hardware/drivers, only use one of: @@ -145,7 +145,7 @@ void SamplerCache::SetParameters(GLuint sampler_id, const Params& params) // Letting the game set other combinations will have varying arbitrary results; // possibly being interpreted as equal to bilinear/trilinear, implicitly // disabling anisotropy, or changing the anisotropic algorithm employed. - min_filter = (tm0.min_filter & 3) == TexMode0::TEXF_NONE ? GL_LINEAR : GL_LINEAR_MIPMAP_LINEAR; + min_filter = SamplerCommon::AreBpTexMode0MipmapsEnabled(tm0) ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR; mag_filter = GL_LINEAR; glSamplerParameterf(sampler_id, GL_TEXTURE_MAX_ANISOTROPY_EXT, (float)(1 << g_ActiveConfig.iMaxAnisotropy)); } diff --git a/Source/Core/VideoBackends/Software/TextureSampler.cpp b/Source/Core/VideoBackends/Software/TextureSampler.cpp index 6c1001a6c8..b5049cb6a3 100644 --- a/Source/Core/VideoBackends/Software/TextureSampler.cpp +++ b/Source/Core/VideoBackends/Software/TextureSampler.cpp @@ -10,6 +10,7 @@ #include "VideoBackends/Software/TextureSampler.h" #include "VideoCommon/BPMemory.h" +#include "VideoCommon/SamplerCommon.h" #include "VideoCommon/TextureDecoder.h" #define ALLOW_MIPMAP 1 @@ -69,14 +70,14 @@ void Sample(s32 s, s32 t, s32 lod, bool linear, u8 texmap, u8 *sample) s32 lodFract = lod & 0xf; - if (lod > 0 && tm0.min_filter & 3) + if (lod > 0 && SamplerCommon::AreBpTexMode0MipmapsEnabled(tm0)) { // use mipmap baseMip = lod >> 4; - mipLinear = (lodFract && tm0.min_filter & 2); + mipLinear = (lodFract && tm0.min_filter & TexMode0::TEXF_LINEAR); // if using nearest mip filter and lodFract >= 0.5 round up to next mip - baseMip += (lodFract >> 3) & (tm0.min_filter & 1); + baseMip += (lodFract >> 3) & (tm0.min_filter & TexMode0::TEXF_POINT); } if (mipLinear) diff --git a/Source/Core/VideoCommon/SamplerCommon.h b/Source/Core/VideoCommon/SamplerCommon.h index 5e6dd565f1..0605fddd03 100644 --- a/Source/Core/VideoCommon/SamplerCommon.h +++ b/Source/Core/VideoCommon/SamplerCommon.h @@ -4,6 +4,9 @@ #pragma once +namespace SamplerCommon +{ + // Helper for checking if a BPMemory TexMode0 register is set to Point // Filtering modes. This is used to decide whether Anisotropic enhancements // are (mostly) safe in the VideoBackends. @@ -16,3 +19,12 @@ constexpr bool IsBpTexMode0PointFiltering(const T& tm0) { return tm0.min_filter < 4 && !tm0.mag_filter; } + +// Check if the minification filter has mipmap based filtering modes enabled. +template +constexpr bool AreBpTexMode0MipmapsEnabled(const T& tm0) +{ + return (tm0.min_filter & 3) != 0; +} + +} diff --git a/Source/Core/VideoCommon/TextureCacheBase.cpp b/Source/Core/VideoCommon/TextureCacheBase.cpp index ffa2c68ad3..1707be49cb 100644 --- a/Source/Core/VideoCommon/TextureCacheBase.cpp +++ b/Source/Core/VideoCommon/TextureCacheBase.cpp @@ -26,6 +26,7 @@ #include "VideoCommon/FramebufferManagerBase.h" #include "VideoCommon/HiresTextures.h" #include "VideoCommon/RenderBase.h" +#include "VideoCommon/SamplerCommon.h" #include "VideoCommon/Statistics.h" #include "VideoCommon/TextureCacheBase.h" #include "VideoCommon/TextureDecoder.h" @@ -440,7 +441,7 @@ TextureCacheBase::TCacheEntryBase* TextureCacheBase::Load(const u32 stage) const int texformat = tex.texImage0[id].format; const u32 tlutaddr = tex.texTlut[id].tmem_offset << 9; const u32 tlutfmt = tex.texTlut[id].tlut_format; - const bool use_mipmaps = (tex.texMode0[id].min_filter & 3) != 0; + const bool use_mipmaps = SamplerCommon::AreBpTexMode0MipmapsEnabled(tex.texMode0[id]); u32 tex_levels = use_mipmaps ? ((tex.texMode1[id].max_lod + 0xf) / 0x10 + 1) : 1; const bool from_tmem = tex.texImage1[id].image_type != 0;