From af6460ff4f40f0d0145afcd80ae8707d9dd33b6f Mon Sep 17 00:00:00 2001 From: Logan McNaughton Date: Mon, 2 Apr 2018 09:28:38 -0600 Subject: [PATCH] Require GL_NV_shader_noperspective_interpolation for GLES depth clamp emulation --- .../GLSL/glsl_CombinerProgramBuilder.cpp | 25 +++++++++---------- .../glsl_CombinerProgramUniformFactory.cpp | 2 +- .../OpenGLContext/GLSL/glsl_ShaderStorage.h | 2 +- src/Graphics/OpenGLContext/opengl_GLInfo.cpp | 1 + src/Graphics/OpenGLContext/opengl_GLInfo.h | 1 + 5 files changed, 16 insertions(+), 15 deletions(-) diff --git a/src/Graphics/OpenGLContext/GLSL/glsl_CombinerProgramBuilder.cpp b/src/Graphics/OpenGLContext/GLSL/glsl_CombinerProgramBuilder.cpp index a1febe5d..070d39d0 100644 --- a/src/Graphics/OpenGLContext/GLSL/glsl_CombinerProgramBuilder.cpp +++ b/src/Graphics/OpenGLContext/GLSL/glsl_CombinerProgramBuilder.cpp @@ -229,7 +229,8 @@ public: std::stringstream ss; ss << "#version " << Utils::to_string(_glinfo.majorVersion) << Utils::to_string(_glinfo.minorVersion) << "0 es " << std::endl; ss << "# define IN in" << std::endl << "# define OUT out" << std::endl; - ss << "OUT highp float vZCoord;" << std::endl << "uniform lowp int uClampMode;" << std::endl; + if (_glinfo.noPerspective) + ss << "noperspective OUT highp float vZCoord;" << std::endl << "uniform lowp int uClampMode;" << std::endl; m_part = ss.str(); } else { @@ -421,9 +422,9 @@ public: m_part = " gl_ClipDistance[0] = gl_Position.w - gl_Position.z; \n" ; - } else if (config.generalEmulation.enableFragmentDepthWrite != 0 && config.frameBufferEmulation.N64DepthCompare == 0) { + } else if (config.generalEmulation.enableFragmentDepthWrite != 0 && _glinfo.noPerspective) { m_part = - " vZCoord = gl_Position.z; \n" + " vZCoord = gl_Position.z / gl_Position.w; \n" " if (uClampMode > 0) \n" " gl_Position.z = 0.0; \n" ; @@ -863,9 +864,9 @@ public: m_part = "highp float writeDepth();\n"; ; - if (_glinfo.isGLESX) { + if (_glinfo.isGLESX && _glinfo.noPerspective) { m_part = - "IN highp float vZCoord; \n" + "noperspective IN highp float vZCoord; \n" "uniform lowp float uPolygonOffset; \n" "uniform lowp int uClampMode; \n" + m_part @@ -1449,11 +1450,10 @@ public: "highp float writeDepth() \n" "{ \n" ; - if (_glinfo.isGLESX && config.frameBufferEmulation.N64DepthCompare == 0) { + if (_glinfo.isGLESX && _glinfo.noPerspective) { m_part += - " highp float z_value = vZCoord * gl_FragCoord.w; \n" - " if (uClampMode == 1 && (z_value > 1.0)) discard; \n" - " highp float FragDepth = clamp((z_value - uPolygonOffset) * uDepthScale.s + uDepthScale.t, 0.0, 1.0); \n" + " if (uClampMode == 1 && (vZCoord > 1.0)) discard; \n" + " highp float FragDepth = clamp((vZCoord - uPolygonOffset) * uDepthScale.s + uDepthScale.t, 0.0, 1.0); \n" ; } else { m_part += @@ -1469,13 +1469,12 @@ public: "} \n" ; } else { - if (_glinfo.isGLESX && config.frameBufferEmulation.N64DepthCompare == 0) { + if (_glinfo.isGLESX && _glinfo.noPerspective) { m_part = "highp float writeDepth() \n" "{ \n" - " highp float z_value = vZCoord * gl_FragCoord.w; \n" - " if (uClampMode == 1 && (z_value > 1.0)) discard; \n" - " highp float depth = uDepthSource == 0 ? (z_value - uPolygonOffset) : uPrimDepth; \n" + " if (uClampMode == 1 && (vZCoord > 1.0)) discard; \n" + " highp float depth = uDepthSource == 0 ? (vZCoord - uPolygonOffset) : uPrimDepth; \n" " return clamp(depth * uDepthScale.s + uDepthScale.t, 0.0, 1.0); \n" "} \n" ; diff --git a/src/Graphics/OpenGLContext/GLSL/glsl_CombinerProgramUniformFactory.cpp b/src/Graphics/OpenGLContext/GLSL/glsl_CombinerProgramUniformFactory.cpp index 30d835b8..a97b3cc1 100644 --- a/src/Graphics/OpenGLContext/GLSL/glsl_CombinerProgramUniformFactory.cpp +++ b/src/Graphics/OpenGLContext/GLSL/glsl_CombinerProgramUniformFactory.cpp @@ -971,7 +971,7 @@ void CombinerProgramUniformFactory::buildUniforms(GLuint _program, config.frameBufferEmulation.N64DepthCompare != 0) _uniforms.emplace_back(new URenderTarget(_program)); - if (m_glInfo.isGLESX) { + if (m_glInfo.isGLESX && m_glInfo.noPerspective) { _uniforms.emplace_back(new UClampMode(_program)); _uniforms.emplace_back(new UPolygonOffset(_program)); } diff --git a/src/Graphics/OpenGLContext/GLSL/glsl_ShaderStorage.h b/src/Graphics/OpenGLContext/GLSL/glsl_ShaderStorage.h index 1c87cb7d..2d37ae92 100644 --- a/src/Graphics/OpenGLContext/GLSL/glsl_ShaderStorage.h +++ b/src/Graphics/OpenGLContext/GLSL/glsl_ShaderStorage.h @@ -20,7 +20,7 @@ namespace glsl { bool _saveCombinerKeys(const graphics::Combiners & _combiners) const; bool _loadFromCombinerKeys(graphics::Combiners & _combiners); - const u32 m_formatVersion = 0x1CU; + const u32 m_formatVersion = 0x1DU; const u32 m_keysFormatVersion = 0x04; const opengl::GLInfo & m_glinfo; opengl::CachedUseProgram * m_useProgram; diff --git a/src/Graphics/OpenGLContext/opengl_GLInfo.cpp b/src/Graphics/OpenGLContext/opengl_GLInfo.cpp index 8434148e..5fa55251 100644 --- a/src/Graphics/OpenGLContext/opengl_GLInfo.cpp +++ b/src/Graphics/OpenGLContext/opengl_GLInfo.cpp @@ -101,4 +101,5 @@ void GLInfo::init() { } depthTexture = !isGLES2 || Utils::isExtensionSupported(*this, "GL_OES_depth_texture"); + noPerspective = Utils::isExtensionSupported(*this, "GL_NV_shader_noperspective_interpolation"); } diff --git a/src/Graphics/OpenGLContext/opengl_GLInfo.h b/src/Graphics/OpenGLContext/opengl_GLInfo.h index 4a290a67..c6a94163 100644 --- a/src/Graphics/OpenGLContext/opengl_GLInfo.h +++ b/src/Graphics/OpenGLContext/opengl_GLInfo.h @@ -24,6 +24,7 @@ struct GLInfo { bool shaderStorage = false; bool msaa = false; bool depthTexture = false; + bool noPerspective = false; Renderer renderer = Renderer::Other; void init();