diff --git a/GPU/GLES/FragmentShaderGenerator.cpp b/GPU/GLES/FragmentShaderGenerator.cpp index 6ffd9fdb4a..e7f171d079 100644 --- a/GPU/GLES/FragmentShaderGenerator.cpp +++ b/GPU/GLES/FragmentShaderGenerator.cpp @@ -25,6 +25,7 @@ #include +#include "base/logging.h" #include "gfx_es2/gpu_features.h" #include "Core/Reporting.h" #include "Core/Config.h" @@ -511,7 +512,7 @@ void GenerateFragmentShader(char *buffer) { // PowerVR needs highp to do the fog in MHU correctly. // Others don't, and some can't handle highp in the fragment shader. - highpFog = gl_extensions.gpuVendor == GPU_VENDOR_POWERVR; + highpFog = (gl_extensions.bugs & BUG_PVR_SHADER_PRECISION_BAD) ? true : false; highpTexcoord = highpFog; // GL_NV_shader_framebuffer_fetch available on mobile platform and ES 2.0 only but not desktop @@ -671,7 +672,7 @@ void GenerateFragmentShader(char *buffer) { } // PowerVR needs a custom modulo function. For some reason, this has far higher precision than the builtin one. - if (gl_extensions.gpuVendor == GPU_VENDOR_POWERVR && gstate_c.needShaderTexClamp) { + if ((gl_extensions.bugs & BUG_PVR_SHADER_PRECISION_BAD) && gstate_c.needShaderTexClamp) { WRITE(p, "float mymod(float a, float b) { return a - b * floor(a / b); }\n"); } @@ -693,7 +694,8 @@ void GenerateFragmentShader(char *buffer) { if (gstate.isTextureMapEnabled()) { const char *texcoord = "v_texcoord"; // TODO: Not sure the right way to do this for projection. - if (gstate_c.needShaderTexClamp) { + // This path destroys resolution on older PowerVR no matter what I do, so we disable it on SGX 540 and lesser, and live with the consequences. + if (gstate_c.needShaderTexClamp && !(gl_extensions.bugs & BUG_PVR_SHADER_PRECISION_TERRIBLE)) { // We may be clamping inside a larger surface (tex = 64x64, buffer=480x272). // We may also be wrapping in such a surface, or either one in a too-small surface. // Obviously, clamping to a smaller surface won't work. But better to clamp to something. @@ -707,7 +709,7 @@ void GenerateFragmentShader(char *buffer) { vcoord = "1.0 - " + vcoord; } - std::string modulo = gl_extensions.gpuVendor == GPU_VENDOR_POWERVR ? "mymod" : "mod"; + std::string modulo = (gl_extensions.bugs & BUG_PVR_SHADER_PRECISION_BAD) ? "mymod" : "mod"; if (gstate.isTexCoordClampedS()) { ucoord = "clamp(" + ucoord + ", u_texclamp.z, u_texclamp.x - u_texclamp.z)"; diff --git a/GPU/GLES/VertexShaderGenerator.cpp b/GPU/GLES/VertexShaderGenerator.cpp index e8f1d6841f..79cde6914f 100644 --- a/GPU/GLES/VertexShaderGenerator.cpp +++ b/GPU/GLES/VertexShaderGenerator.cpp @@ -178,8 +178,8 @@ void GenerateVertexShader(int prim, u32 vertType, char *buffer, bool useHWTransf // PowerVR needs highp to do the fog in MHU correctly. // Others don't, and some can't handle highp in the fragment shader. - highpFog = gl_extensions.gpuVendor == GPU_VENDOR_POWERVR; - highpTexcoord = gl_extensions.gpuVendor == GPU_VENDOR_POWERVR; + highpFog = (gl_extensions.bugs & BUG_PVR_SHADER_PRECISION_BAD) ? true : false; + highpTexcoord = highpFog; #elif !defined(FORCE_OPENGL_2_0) if (gl_extensions.VersionGEThan(3, 3, 0)) { diff --git a/native b/native index 0f490c8eb5..277788500e 160000 --- a/native +++ b/native @@ -1 +1 @@ -Subproject commit 0f490c8eb5e173fcda91ae3fd6f1a7416b842d1d +Subproject commit 277788500e88b6971cd2fade29860809cd7e58ef