From e1df8fc45f8e46f88cf1211fc58ce00e09d759f3 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 15 Mar 2015 19:25:34 -0700 Subject: [PATCH] Centralize sampling params and test optimizations. --- CMakeLists.txt | 1 + GPU/Common/GPUStateUtils.h | 115 +++++++++++++++++++++++ GPU/Common/TextureCacheCommon.cpp | 54 ++++++++++- GPU/Common/TextureCacheCommon.h | 10 ++ GPU/Directx9/PixelShaderGeneratorDX9.cpp | 97 +------------------ GPU/Directx9/PixelShaderGeneratorDX9.h | 4 - GPU/Directx9/TextureCacheDX9.cpp | 47 --------- GPU/Directx9/TextureCacheDX9.h | 8 -- GPU/GLES/FragmentShaderGenerator.cpp | 98 +------------------ GPU/GLES/FragmentShaderGenerator.h | 4 - GPU/GLES/FragmentTestCache.cpp | 2 +- GPU/GLES/Framebuffer.cpp | 2 +- GPU/GLES/TextureCache.cpp | 47 --------- GPU/GLES/TextureCache.h | 8 -- GPU/GPU.vcxproj | 1 + GPU/GPU.vcxproj.filters | 5 +- Windows/WndMainWindow.cpp | 17 ++-- 17 files changed, 197 insertions(+), 323 deletions(-) create mode 100644 GPU/Common/GPUStateUtils.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 1745edbf38..6de89db419 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1453,6 +1453,7 @@ add_library(GPU OBJECT GPU/Common/FramebufferCommon.h GPU/Common/GPUDebugInterface.cpp GPU/Common/GPUDebugInterface.h + GPU/Common/GPUStateUtils.h GPU/Common/DrawEngineCommon.cpp GPU/Common/DrawEngineCommon.h GPU/Common/SplineCommon.cpp diff --git a/GPU/Common/GPUStateUtils.h b/GPU/Common/GPUStateUtils.h new file mode 100644 index 0000000000..c3f0406e7f --- /dev/null +++ b/GPU/Common/GPUStateUtils.h @@ -0,0 +1,115 @@ +// Copyright (c) 2012- PPSSPP Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0 or later versions. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official git repository and contact information can be found at +// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. + +#include "GPU/ge_constants.h" +#include "GPU/GPUState.h" + +// Dest factors where it's safe to eliminate the alpha test under certain conditions +static const bool safeDestFactors[16] = { + true, // GE_DSTBLEND_SRCCOLOR, + true, // GE_DSTBLEND_INVSRCCOLOR, + false, // GE_DSTBLEND_SRCALPHA, + true, // GE_DSTBLEND_INVSRCALPHA, + true, // GE_DSTBLEND_DSTALPHA, + true, // GE_DSTBLEND_INVDSTALPHA, + false, // GE_DSTBLEND_DOUBLESRCALPHA, + false, // GE_DSTBLEND_DOUBLEINVSRCALPHA, + true, // GE_DSTBLEND_DOUBLEDSTALPHA, + true, // GE_DSTBLEND_DOUBLEINVDSTALPHA, + true, //GE_DSTBLEND_FIXB, +}; + +static inline bool IsAlphaTestTriviallyTrue() { + switch (gstate.getAlphaTestFunction()) { + case GE_COMP_NEVER: + return false; + + case GE_COMP_ALWAYS: + return true; + + case GE_COMP_GEQUAL: + if (gstate_c.vertexFullAlpha && (gstate_c.textureFullAlpha || !gstate.isTextureAlphaUsed())) + return true; // If alpha is full, it doesn't matter what the ref value is. + return gstate.getAlphaTestRef() == 0; + + // Non-zero check. If we have no depth testing (and thus no depth writing), and an alpha func that will result in no change if zero alpha, get rid of the alpha test. + // Speeds up Lumines by a LOT on PowerVR. + case GE_COMP_NOTEQUAL: + if (gstate.getAlphaTestRef() == 255) { + // Likely to be rare. Let's just skip the vertexFullAlpha optimization here instead of adding + // complicated code to discard the draw or whatnot. + return false; + } + // Fallthrough on purpose + + case GE_COMP_GREATER: + { +#if 0 + // Easy way to check the values in the debugger without ruining && early-out + bool doTextureAlpha = gstate.isTextureAlphaUsed(); + bool stencilTest = gstate.isStencilTestEnabled(); + bool depthTest = gstate.isDepthTestEnabled(); + GEComparison depthTestFunc = gstate.getDepthTestFunction(); + int alphaRef = gstate.getAlphaTestRef(); + int blendA = gstate.getBlendFuncA(); + bool blendEnabled = gstate.isAlphaBlendEnabled(); + int blendB = gstate.getBlendFuncA(); +#endif + return (gstate_c.vertexFullAlpha && (gstate_c.textureFullAlpha || !gstate.isTextureAlphaUsed())) || ( + (!gstate.isStencilTestEnabled() && + !gstate.isDepthTestEnabled() && + gstate.getAlphaTestRef() == 0 && + gstate.isAlphaBlendEnabled() && + gstate.getBlendFuncA() == GE_SRCBLEND_SRCALPHA && + safeDestFactors[(int)gstate.getBlendFuncB()])); + } + + case GE_COMP_LEQUAL: + return gstate.getAlphaTestRef() == 255; + + case GE_COMP_EQUAL: + case GE_COMP_LESS: + return false; + + default: + return false; + } +} + +static inline bool IsAlphaTestAgainstZero() { + return gstate.getAlphaTestRef() == 0 && gstate.getAlphaTestMask() == 0xFF; +} + +static inline bool IsColorTestAgainstZero() { + return gstate.getColorTestRef() == 0 && gstate.getColorTestMask() == 0xFFFFFF; +} + +static inline bool IsColorTestTriviallyTrue() { + switch (gstate.getColorTestFunction()) { + case GE_COMP_NEVER: + return false; + + case GE_COMP_ALWAYS: + return true; + + case GE_COMP_EQUAL: + case GE_COMP_NOTEQUAL: + return false; + default: + return false; + } +} diff --git a/GPU/Common/TextureCacheCommon.cpp b/GPU/Common/TextureCacheCommon.cpp index 129ff400c0..2972f00ee1 100644 --- a/GPU/Common/TextureCacheCommon.cpp +++ b/GPU/Common/TextureCacheCommon.cpp @@ -15,11 +15,63 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. - +#include "Core/Config.h" +#include "GPU/Common/GPUStateUtils.h" #include "GPU/Common/TextureCacheCommon.h" +#include "GPU/GPUState.h" + +// Ugly. +extern int g_iNumVideos; TextureCacheCommon::~TextureCacheCommon() {} bool TextureCacheCommon::SetOffsetTexture(u32 offset) { return false; } + +void TextureCacheCommon::GetSamplingParams(int &minFilt, int &magFilt, bool &sClamp, bool &tClamp, float &lodBias, int maxLevel) { + minFilt = gstate.texfilter & 0x7; + magFilt = (gstate.texfilter>>8) & 1; + sClamp = gstate.isTexCoordClampedS(); + tClamp = gstate.isTexCoordClampedT(); + + bool noMip = (gstate.texlevel & 0xFFFFFF) == 0x000001 || (gstate.texlevel & 0xFFFFFF) == 0x100001 ; // Fix texlevel at 0 + + if (maxLevel == 0) { + // Enforce no mip filtering, for safety. + minFilt &= 1; // no mipmaps yet + lodBias = 0.0f; + } else { + // Texture lod bias should be signed. + lodBias = (float)(int)(s8)((gstate.texlevel >> 16) & 0xFF) / 16.0f; + } + + if (g_Config.iTexFiltering == TEX_FILTER_LINEAR_VIDEO && g_iNumVideos > 0 && (gstate.getTextureDimension(0) & 0xF) >= 9) { + magFilt |= 1; + minFilt |= 1; + } + if (g_Config.iTexFiltering == TEX_FILTER_LINEAR && (!gstate.isColorTestEnabled() || IsColorTestTriviallyTrue())) { + // TODO: IsAlphaTestTriviallyTrue() is unsafe here. vertexFullAlpha is not calculated yet. + if (!gstate.isAlphaTestEnabled() || IsAlphaTestTriviallyTrue()) { + magFilt |= 1; + minFilt |= 1; + } + } + bool forceNearest = g_Config.iTexFiltering == TEX_FILTER_NEAREST; + // Force Nearest when color test enabled and rendering resolution greater than 480x272 + if ((gstate.isColorTestEnabled() && !IsColorTestTriviallyTrue()) && g_Config.iInternalResolution != 1 && gstate.isModeThrough()) { + // Some games use 0 as the color test color, which won't be too bad if it bleeds. + // Fuchsia and green, etc. are the problem colors. + if (gstate.getColorTestRef() != 0) { + forceNearest = true; + } + } + if (forceNearest) { + magFilt &= ~1; + minFilt &= ~1; + } + + if (!g_Config.bMipMap || noMip) { + minFilt &= 1; + } +} diff --git a/GPU/Common/TextureCacheCommon.h b/GPU/Common/TextureCacheCommon.h index 33bbe9e6a6..6e58c8b18c 100644 --- a/GPU/Common/TextureCacheCommon.h +++ b/GPU/Common/TextureCacheCommon.h @@ -19,9 +19,19 @@ #include "Common/CommonTypes.h" +enum TextureFiltering { + TEX_FILTER_AUTO = 1, + TEX_FILTER_NEAREST = 2, + TEX_FILTER_LINEAR = 3, + TEX_FILTER_LINEAR_VIDEO = 4, +}; + class TextureCacheCommon { public: virtual ~TextureCacheCommon(); virtual bool SetOffsetTexture(u32 offset); + +protected: + void GetSamplingParams(int &minFilt, int &magFilt, bool &sClamp, bool &tClamp, float &lodBias, int maxLevel); }; \ No newline at end of file diff --git a/GPU/Directx9/PixelShaderGeneratorDX9.cpp b/GPU/Directx9/PixelShaderGeneratorDX9.cpp index d0126ef972..bcd5e873d2 100644 --- a/GPU/Directx9/PixelShaderGeneratorDX9.cpp +++ b/GPU/Directx9/PixelShaderGeneratorDX9.cpp @@ -19,6 +19,7 @@ #include "Core/Reporting.h" #include "Core/Config.h" +#include "GPU/Common/GPUStateUtils.h" #include "GPU/Directx9/helper/global.h" #include "GPU/Directx9/PixelShaderGeneratorDX9.h" #include "GPU/ge_constants.h" @@ -31,86 +32,6 @@ namespace DX9 { -// Dest factors where it's safe to eliminate the alpha test under certain conditions -static const bool safeDestFactors[16] = { - true, // GE_DSTBLEND_SRCCOLOR, - true, // GE_DSTBLEND_INVSRCCOLOR, - false, // GE_DSTBLEND_SRCALPHA, - true, // GE_DSTBLEND_INVSRCALPHA, - true, // GE_DSTBLEND_DSTALPHA, - true, // GE_DSTBLEND_INVDSTALPHA, - false, // GE_DSTBLEND_DOUBLESRCALPHA, - false, // GE_DSTBLEND_DOUBLEINVSRCALPHA, - true, // GE_DSTBLEND_DOUBLEDSTALPHA, - true, // GE_DSTBLEND_DOUBLEINVDSTALPHA, - true, //GE_DSTBLEND_FIXB, -}; - -bool IsAlphaTestTriviallyTrue() { - switch (gstate.getAlphaTestFunction()) { - case GE_COMP_NEVER: - return false; - - case GE_COMP_ALWAYS: - return true; - - case GE_COMP_GEQUAL: - if (gstate_c.vertexFullAlpha && (gstate_c.textureFullAlpha || !gstate.isTextureAlphaUsed())) - return true; // If alpha is full, it doesn't matter what the ref value is. - return gstate.getAlphaTestRef() == 0; - - // Non-zero check. If we have no depth testing (and thus no depth writing), and an alpha func that will result in no change if zero alpha, get rid of the alpha test. - // Speeds up Lumines by a LOT on PowerVR. - case GE_COMP_NOTEQUAL: - if (gstate.getAlphaTestRef() == 255) { - // Likely to be rare. Let's just skip the vertexFullAlpha optimization here instead of adding - // complicated code to discard the draw or whatnot. - return false; - } - // Fallthrough on purpose - - case GE_COMP_GREATER: - { -#if 0 - // Easy way to check the values in the debugger without ruining && early-out - bool doTextureAlpha = gstate.isTextureAlphaUsed(); - bool stencilTest = gstate.isStencilTestEnabled(); - bool depthTest = gstate.isDepthTestEnabled(); - GEComparison depthTestFunc = gstate.getDepthTestFunction(); - int alphaRef = gstate.getAlphaTestRef(); - int blendA = gstate.getBlendFuncA(); - bool blendEnabled = gstate.isAlphaBlendEnabled(); - int blendB = gstate.getBlendFuncA(); -#endif - return (gstate_c.vertexFullAlpha && (gstate_c.textureFullAlpha || !gstate.isTextureAlphaUsed())) || ( - (!gstate.isStencilTestEnabled() && - !gstate.isDepthTestEnabled() && - gstate.getAlphaTestRef() == 0 && - gstate.isAlphaBlendEnabled() && - gstate.getBlendFuncA() == GE_SRCBLEND_SRCALPHA && - safeDestFactors[(int)gstate.getBlendFuncB()])); - } - - case GE_COMP_LEQUAL: - return gstate.getAlphaTestRef() == 255; - - case GE_COMP_EQUAL: - case GE_COMP_LESS: - return false; - - default: - return false; - } -} - -bool IsAlphaTestAgainstZero() { - return gstate.getAlphaTestRef() == 0 && gstate.getAlphaTestMask() == 0xFF; -} - -bool IsColorTestAgainstZero() { - return gstate.getColorTestRef() == 0 && gstate.getColorTestMask() == 0xFFFFFF; -} - const bool nonAlphaSrcFactors[16] = { true, // GE_SRCBLEND_DSTCOLOR, true, // GE_SRCBLEND_INVDSTCOLOR, @@ -221,22 +142,6 @@ StencilValueType ReplaceAlphaWithStencilType() { return STENCIL_VALUE_KEEP; } -bool IsColorTestTriviallyTrue() { - switch (gstate.getColorTestFunction()) { - case GE_COMP_NEVER: - return false; - - case GE_COMP_ALWAYS: - return true; - - case GE_COMP_EQUAL: - case GE_COMP_NOTEQUAL: - return false; - default: - return false; - } -} - ReplaceBlendType ReplaceBlendWithShader(bool allowShaderBlend) { if (!gstate.isAlphaBlendEnabled() || gstate.isModeClear()) { return REPLACE_BLEND_NO; diff --git a/GPU/Directx9/PixelShaderGeneratorDX9.h b/GPU/Directx9/PixelShaderGeneratorDX9.h index 6675ea850a..77888ad026 100644 --- a/GPU/Directx9/PixelShaderGeneratorDX9.h +++ b/GPU/Directx9/PixelShaderGeneratorDX9.h @@ -77,10 +77,6 @@ enum ReplaceBlendType { REPLACE_BLEND_COPY_FBO, }; -bool IsAlphaTestAgainstZero(); -bool IsAlphaTestTriviallyTrue(); -bool IsColorTestAgainstZero(); -bool IsColorTestTriviallyTrue(); StencilValueType ReplaceAlphaWithStencilType(); ReplaceAlphaType ReplaceAlphaWithStencil(ReplaceBlendType replaceBlend); ReplaceBlendType ReplaceBlendWithShader(bool allowShaderBlend); diff --git a/GPU/Directx9/TextureCacheDX9.cpp b/GPU/Directx9/TextureCacheDX9.cpp index 5c74e097a2..004d0fd31c 100644 --- a/GPU/Directx9/TextureCacheDX9.cpp +++ b/GPU/Directx9/TextureCacheDX9.cpp @@ -676,53 +676,6 @@ static const u8 MagFilt[2] = { D3DTEXF_LINEAR }; -void TextureCacheDX9::GetSamplingParams(int &minFilt, int &magFilt, bool &sClamp, bool &tClamp, float &lodBias, int maxLevel) { - minFilt = gstate.texfilter & 0x7; - magFilt = (gstate.texfilter>>8) & 1; - sClamp = gstate.isTexCoordClampedS(); - tClamp = gstate.isTexCoordClampedT(); - - bool noMip = (gstate.texlevel & 0xFFFFFF) == 0x000001 || (gstate.texlevel & 0xFFFFFF) == 0x100001 ; // Fix texlevel at 0 - - if (maxLevel == 0) { - // Enforce no mip filtering, for safety. - minFilt &= 1; // no mipmaps yet - lodBias = 0.0f; - } else { - // Texture lod bias should be signed. - lodBias = (float)(int)(s8)((gstate.texlevel >> 16) & 0xFF) / 16.0f; - } - - if (g_Config.iTexFiltering == LINEARFMV && g_iNumVideos > 0 && (gstate.getTextureDimension(0) & 0xF) >= 9) { - magFilt |= 1; - minFilt |= 1; - } - if (g_Config.iTexFiltering == LINEAR && (!gstate.isColorTestEnabled() || IsColorTestTriviallyTrue())) { - // TODO: IsAlphaTestTriviallyTrue() is unsafe here. vertexFullAlpha is not calculated yet. - if (!gstate.isAlphaTestEnabled() || IsAlphaTestTriviallyTrue()) { - magFilt |= 1; - minFilt |= 1; - } - } - bool forceNearest = g_Config.iTexFiltering == NEAREST; - // Force Nearest when color test enabled and rendering resolution greater than 480x272 - if ((gstate.isColorTestEnabled() && !IsColorTestTriviallyTrue()) && g_Config.iInternalResolution != 1 && gstate.isModeThrough()) { - // Some games use 0 as the color test color, which won't be too bad if it bleeds. - // Fuchsia and green, etc. are the problem colors. - if (gstate.getColorTestRef() != 0) { - forceNearest = true; - } - } - if (forceNearest) { - magFilt &= ~1; - minFilt &= ~1; - } - - if (!g_Config.bMipMap || noMip) { - minFilt &= 1; - } -} - void TextureCacheDX9::UpdateSamplingParams(TexCacheEntry &entry, bool force) { int minFilt; int magFilt; diff --git a/GPU/Directx9/TextureCacheDX9.h b/GPU/Directx9/TextureCacheDX9.h index f24399de6d..fd7340e515 100644 --- a/GPU/Directx9/TextureCacheDX9.h +++ b/GPU/Directx9/TextureCacheDX9.h @@ -35,13 +35,6 @@ class FramebufferManagerDX9; class DepalShaderCacheDX9; class ShaderManagerDX9; -enum TextureFiltering { - AUTO = 1, - NEAREST = 2, - LINEAR = 3, - LINEARFMV = 4, -}; - enum FramebufferNotification { NOTIFY_FB_CREATED, NOTIFY_FB_UPDATED, @@ -168,7 +161,6 @@ private: void DeleteTexture(TexCache::iterator it); void *UnswizzleFromMem(const u8 *texptr, u32 bufw, u32 height, u32 bytesPerPixel); void *ReadIndexedTex(int level, const u8 *texptr, int bytesPerIndex, u32 dstFmt, int bufw); - void GetSamplingParams(int &minFilt, int &magFilt, bool &sClamp, bool &tClamp, float &lodBias, int maxLevel); void UpdateSamplingParams(TexCacheEntry &entry, bool force); void LoadTextureLevel(TexCacheEntry &entry, int level, int maxLevel, bool replaceImages, int scaleFactor, u32 dstFmt); D3DFORMAT GetDestFormat(GETextureFormat format, GEPaletteFormat clutFormat) const; diff --git a/GPU/GLES/FragmentShaderGenerator.cpp b/GPU/GLES/FragmentShaderGenerator.cpp index 858a200ca6..e286241ece 100644 --- a/GPU/GLES/FragmentShaderGenerator.cpp +++ b/GPU/GLES/FragmentShaderGenerator.cpp @@ -30,6 +30,7 @@ #include "gfx_es2/gpu_features.h" #include "Core/Reporting.h" #include "Core/Config.h" +#include "GPU/Common/GPUStateUtils.h" #include "GPU/GLES/FragmentShaderGenerator.h" #include "GPU/GLES/Framebuffer.h" #include "GPU/GLES/ShaderManager.h" @@ -40,86 +41,6 @@ // #define DEBUG_SHADER -// Dest factors where it's safe to eliminate the alpha test under certain conditions -const bool safeDestFactors[16] = { - true, // GE_DSTBLEND_SRCCOLOR, - true, // GE_DSTBLEND_INVSRCCOLOR, - false, // GE_DSTBLEND_SRCALPHA, - true, // GE_DSTBLEND_INVSRCALPHA, - true, // GE_DSTBLEND_DSTALPHA, - true, // GE_DSTBLEND_INVDSTALPHA, - false, // GE_DSTBLEND_DOUBLESRCALPHA, - false, // GE_DSTBLEND_DOUBLEINVSRCALPHA, - true, // GE_DSTBLEND_DOUBLEDSTALPHA, - true, // GE_DSTBLEND_DOUBLEINVDSTALPHA, - true, //GE_DSTBLEND_FIXB, -}; - -bool IsAlphaTestTriviallyTrue() { - switch (gstate.getAlphaTestFunction()) { - case GE_COMP_NEVER: - return false; - - case GE_COMP_ALWAYS: - return true; - - case GE_COMP_GEQUAL: - if (gstate_c.vertexFullAlpha && (gstate_c.textureFullAlpha || !gstate.isTextureAlphaUsed())) - return true; // If alpha is full, it doesn't matter what the ref value is. - return gstate.getAlphaTestRef() == 0; - - // Non-zero check. If we have no depth testing (and thus no depth writing), and an alpha func that will result in no change if zero alpha, get rid of the alpha test. - // Speeds up Lumines by a LOT on PowerVR. - case GE_COMP_NOTEQUAL: - if (gstate.getAlphaTestRef() == 255) { - // Likely to be rare. Let's just skip the vertexFullAlpha optimization here instead of adding - // complicated code to discard the draw or whatnot. - return false; - } - // Fallthrough on purpose - - case GE_COMP_GREATER: - { -#if 0 - // Easy way to check the values in the debugger without ruining && early-out - bool doTextureAlpha = gstate.isTextureAlphaUsed(); - bool stencilTest = gstate.isStencilTestEnabled(); - bool depthTest = gstate.isDepthTestEnabled(); - GEComparison depthTestFunc = gstate.getDepthTestFunction(); - int alphaRef = gstate.getAlphaTestRef(); - int blendA = gstate.getBlendFuncA(); - bool blendEnabled = gstate.isAlphaBlendEnabled(); - int blendB = gstate.getBlendFuncA(); -#endif - return (gstate_c.vertexFullAlpha && (gstate_c.textureFullAlpha || !gstate.isTextureAlphaUsed())) || ( - (!gstate.isStencilTestEnabled() && - !gstate.isDepthTestEnabled() && - gstate.getAlphaTestRef() == 0 && - gstate.isAlphaBlendEnabled() && - gstate.getBlendFuncA() == GE_SRCBLEND_SRCALPHA && - safeDestFactors[(int)gstate.getBlendFuncB()])); - } - - case GE_COMP_LEQUAL: - return gstate.getAlphaTestRef() == 255; - - case GE_COMP_EQUAL: - case GE_COMP_LESS: - return false; - - default: - return false; - } -} - -bool IsAlphaTestAgainstZero() { - return gstate.getAlphaTestRef() == 0 && gstate.getAlphaTestMask() == 0xFF; -} - -bool IsColorTestAgainstZero() { - return gstate.getColorTestRef() == 0 && gstate.getColorTestMask() == 0xFFFFFF; -} - const bool nonAlphaSrcFactors[16] = { true, // GE_SRCBLEND_DSTCOLOR, true, // GE_SRCBLEND_INVDSTCOLOR, @@ -202,6 +123,7 @@ StencilValueType ReplaceAlphaWithStencilType() { case GE_FORMAT_INVALID: switch (gstate.getStencilOpZPass()) { case GE_STENCILOP_REPLACE: + // TODO: Could detect zero here and force ZERO - less uniform updates? return STENCIL_VALUE_UNIFORM; case GE_STENCILOP_ZERO: @@ -225,22 +147,6 @@ StencilValueType ReplaceAlphaWithStencilType() { return STENCIL_VALUE_KEEP; } -bool IsColorTestTriviallyTrue() { - switch (gstate.getColorTestFunction()) { - case GE_COMP_NEVER: - return false; - - case GE_COMP_ALWAYS: - return true; - - case GE_COMP_EQUAL: - case GE_COMP_NOTEQUAL: - return false; - default: - return false; - } -} - ReplaceBlendType ReplaceBlendWithShader(bool allowShaderBlend) { if (!gstate.isAlphaBlendEnabled() || gstate.isModeClear()) { return REPLACE_BLEND_NO; diff --git a/GPU/GLES/FragmentShaderGenerator.h b/GPU/GLES/FragmentShaderGenerator.h index 0ec45caed3..934fa1efd6 100644 --- a/GPU/GLES/FragmentShaderGenerator.h +++ b/GPU/GLES/FragmentShaderGenerator.h @@ -52,10 +52,6 @@ enum ReplaceBlendType { REPLACE_BLEND_COPY_FBO, }; -bool IsAlphaTestAgainstZero(); -bool IsAlphaTestTriviallyTrue(); -bool IsColorTestAgainstZero(); -bool IsColorTestTriviallyTrue(); StencilValueType ReplaceAlphaWithStencilType(); ReplaceAlphaType ReplaceAlphaWithStencil(ReplaceBlendType replaceBlend); ReplaceBlendType ReplaceBlendWithShader(bool allowShaderBlend); diff --git a/GPU/GLES/FragmentTestCache.cpp b/GPU/GLES/FragmentTestCache.cpp index ec4d85f1f7..b6357b02ea 100644 --- a/GPU/GLES/FragmentTestCache.cpp +++ b/GPU/GLES/FragmentTestCache.cpp @@ -16,7 +16,7 @@ // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. #include "Core/Config.h" -#include "GPU/GLES/FragmentShaderGenerator.h" +#include "GPU/Common/GPUStateUtils.h" #include "GPU/GLES/FragmentTestCache.h" #include "GPU/GPUState.h" diff --git a/GPU/GLES/Framebuffer.cpp b/GPU/GLES/Framebuffer.cpp index ac1eaf7592..56c115879d 100644 --- a/GPU/GLES/Framebuffer.cpp +++ b/GPU/GLES/Framebuffer.cpp @@ -389,7 +389,7 @@ void FramebufferManager::DrawPixels(VirtualFramebuffer *vfb, int dstX, int dstY, void FramebufferManager::DrawFramebuffer(const u8 *srcPixels, GEBufferFormat srcPixelFormat, int srcStride, bool applyPostShader) { MakePixelTexture(srcPixels, srcPixelFormat, srcStride, 512, 272); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, g_Config.iTexFiltering == NEAREST ? GL_NEAREST : GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, g_Config.iTexFiltering == TEX_FILTER_NEAREST ? GL_NEAREST : GL_LINEAR); DisableState(); diff --git a/GPU/GLES/TextureCache.cpp b/GPU/GLES/TextureCache.cpp index d796230bc4..372db34d65 100644 --- a/GPU/GLES/TextureCache.cpp +++ b/GPU/GLES/TextureCache.cpp @@ -660,53 +660,6 @@ static const GLuint MagFiltGL[2] = { GL_LINEAR }; -void TextureCache::GetSamplingParams(int &minFilt, int &magFilt, bool &sClamp, bool &tClamp, float &lodBias, int maxLevel) { - minFilt = gstate.texfilter & 0x7; - magFilt = (gstate.texfilter>>8) & 1; - sClamp = gstate.isTexCoordClampedS(); - tClamp = gstate.isTexCoordClampedT(); - - bool noMip = (gstate.texlevel & 0xFFFFFF) == 0x000001 || (gstate.texlevel & 0xFFFFFF) == 0x100001 ; // Fix texlevel at 0 - - if (maxLevel == 0) { - // Enforce no mip filtering, for safety. - minFilt &= 1; // no mipmaps yet - lodBias = 0.0f; - } else { - // Texture lod bias should be signed. - lodBias = (float)(int)(s8)((gstate.texlevel >> 16) & 0xFF) / 16.0f; - } - - if (g_Config.iTexFiltering == LINEARFMV && g_iNumVideos > 0 && (gstate.getTextureDimension(0) & 0xF) >= 9) { - magFilt |= 1; - minFilt |= 1; - } - if (g_Config.iTexFiltering == LINEAR && (!gstate.isColorTestEnabled() || IsColorTestTriviallyTrue())) { - // TODO: IsAlphaTestTriviallyTrue() is unsafe here. vertexFullAlpha is not calculated yet. - if (!gstate.isAlphaTestEnabled() || IsAlphaTestTriviallyTrue()) { - magFilt |= 1; - minFilt |= 1; - } - } - bool forceNearest = g_Config.iTexFiltering == NEAREST; - // Force Nearest when color test enabled and rendering resolution greater than 480x272 - if ((gstate.isColorTestEnabled() && !IsColorTestTriviallyTrue()) && g_Config.iInternalResolution != 1 && gstate.isModeThrough()) { - // Some games use 0 as the color test color, which won't be too bad if it bleeds. - // Fuchsia and green, etc. are the problem colors. - if (gstate.getColorTestRef() != 0) { - forceNearest = true; - } - } - if (forceNearest) { - magFilt &= ~1; - minFilt &= ~1; - } - - if (!g_Config.bMipMap || noMip) { - minFilt &= 1; - } -} - // This should not have to be done per texture! OpenGL is silly yo void TextureCache::UpdateSamplingParams(TexCacheEntry &entry, bool force) { int minFilt; diff --git a/GPU/GLES/TextureCache.h b/GPU/GLES/TextureCache.h index bc9cd034f3..af6be0441f 100644 --- a/GPU/GLES/TextureCache.h +++ b/GPU/GLES/TextureCache.h @@ -33,13 +33,6 @@ class FramebufferManager; class DepalShaderCache; class ShaderManager; -enum TextureFiltering { - AUTO = 1, - NEAREST = 2, - LINEAR = 3, - LINEARFMV = 4, -}; - enum FramebufferNotification { NOTIFY_FB_CREATED, NOTIFY_FB_UPDATED, @@ -180,7 +173,6 @@ private: void DeleteTexture(TexCache::iterator it); void *UnswizzleFromMem(const u8 *texptr, u32 bufw, u32 height, u32 bytesPerPixel); void *ReadIndexedTex(int level, const u8 *texptr, int bytesPerIndex, GLuint dstFmt, int bufw); - void GetSamplingParams(int &minFilt, int &magFilt, bool &sClamp, bool &tClamp, float &lodBias, int maxLevel); void UpdateSamplingParams(TexCacheEntry &entry, bool force); void LoadTextureLevel(TexCacheEntry &entry, int level, bool replaceImages, int scaleFactor, GLenum dstFmt); GLenum GetDestFormat(GETextureFormat format, GEPaletteFormat clutFormat) const; diff --git a/GPU/GPU.vcxproj b/GPU/GPU.vcxproj index 13ef73247c..d60e152b0f 100644 --- a/GPU/GPU.vcxproj +++ b/GPU/GPU.vcxproj @@ -185,6 +185,7 @@ + diff --git a/GPU/GPU.vcxproj.filters b/GPU/GPU.vcxproj.filters index c1f9d54f59..60c9232ff4 100644 --- a/GPU/GPU.vcxproj.filters +++ b/GPU/GPU.vcxproj.filters @@ -192,6 +192,9 @@ GLES + + Common + @@ -372,4 +375,4 @@ GLES - \ No newline at end of file + diff --git a/Windows/WndMainWindow.cpp b/Windows/WndMainWindow.cpp index 521989b758..8fa73d2d5f 100644 --- a/Windows/WndMainWindow.cpp +++ b/Windows/WndMainWindow.cpp @@ -1588,10 +1588,10 @@ namespace MainWindow g_Config.iShowFPSCounter = !g_Config.iShowFPSCounter; break; - case ID_OPTIONS_TEXTUREFILTERING_AUTO: setTexFiltering(AUTO); break; - case ID_OPTIONS_NEARESTFILTERING: setTexFiltering(NEAREST); break; - case ID_OPTIONS_LINEARFILTERING: setTexFiltering(LINEAR); break; - case ID_OPTIONS_LINEARFILTERING_CG: setTexFiltering(LINEARFMV); break; + case ID_OPTIONS_TEXTUREFILTERING_AUTO: setTexFiltering(TEX_FILTER_AUTO); break; + case ID_OPTIONS_NEARESTFILTERING: setTexFiltering(TEX_FILTER_NEAREST); break; + case ID_OPTIONS_LINEARFILTERING: setTexFiltering(TEX_FILTER_LINEAR); break; + case ID_OPTIONS_LINEARFILTERING_CG: setTexFiltering(TEX_FILTER_LINEAR_VIDEO); break; case ID_OPTIONS_BUFLINEARFILTER: setBufFilter(SCALE_LINEAR); break; case ID_OPTIONS_BUFNEARESTFILTER: setBufFilter(SCALE_NEAREST); break; @@ -1918,11 +1918,10 @@ namespace MainWindow ID_OPTIONS_LINEARFILTERING, ID_OPTIONS_LINEARFILTERING_CG, }; - if(g_Config.iTexFiltering < AUTO) - g_Config.iTexFiltering = AUTO; - - else if(g_Config.iTexFiltering > LINEARFMV) - g_Config.iTexFiltering = LINEARFMV; + if (g_Config.iTexFiltering < TEX_FILTER_AUTO) + g_Config.iTexFiltering = TEX_FILTER_AUTO; + else if (g_Config.iTexFiltering > TEX_FILTER_LINEAR_VIDEO) + g_Config.iTexFiltering = TEX_FILTER_LINEAR_VIDEO; for (int i = 0; i < ARRAY_SIZE(texfilteringitems); i++) { CheckMenuItem(menu, texfilteringitems[i], MF_BYCOMMAND | ((i + 1) == g_Config.iTexFiltering ? MF_CHECKED : MF_UNCHECKED));