diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index e2a4220525..17860d4479 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -885,10 +885,18 @@ u32 RasterizerOpenGL::SetupTextures(Maxwell::ShaderStage stage, Shader& shader, void RasterizerOpenGL::SetupAlphaTesting(Shader& shader) { const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs; - glProgramUniform1i(shader->GetProgramHandle(), shader->GetAlphaTestingEnableLocation(), + glProgramUniform1ui(shader->GetProgramHandle(), shader->GetAlphaTestingEnableLocation(), regs.alpha_test_enabled); glProgramUniform1f(shader->GetProgramHandle(), shader->GetAlphaTestingRefLocation(), regs.alpha_test_ref); + + u32 func = static_cast(regs.alpha_test_func); + // Normalize the gl variants of opCompare to be the same as the normal variants + if (func >= 0x200) { + func = func - 0x200 + 1U; + } + + glProgramUniform1ui(shader->GetProgramHandle(), shader->GetAlphaTestingFuncLocation(), func); } void RasterizerOpenGL::SyncViewport() { diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index e890cfe576..cbf501cc72 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp @@ -1280,13 +1280,13 @@ private: header.ps.IsColorComponentOutputEnabled(render_target, 1) || header.ps.IsColorComponentOutputEnabled(render_target, 2) || header.ps.IsColorComponentOutputEnabled(render_target, 3)) { - shader.AddLine(fmt::format("if ({} < alpha_testing_ref) discard;", + shader.AddLine(fmt::format("if (AlphaFunc({}, alpha_testing_ref, alpha_testing_func)) discard;", regs.GetRegisterAsFloat(current_reg))); current_reg += 4; } } --shader.scope; - shader.AddLine("}"); + shader.AddLine('}'); // Write the color outputs using the data in the shader registers, disabled // rendertargets/components are skipped in the register assignment. @@ -3505,6 +3505,38 @@ private: declarations.AddLine("bool " + pred + " = false;"); } declarations.AddNewLine(); + GenerateFunctionDeclarations(); + } + + void GenerateFunctionDeclarations() { + if (stage == Maxwell3D::Regs::ShaderStage::Fragment) { + declarations.AddLine("bool AlphaFunc(in float value, in float ref, in uint func) {"); + declarations.scope++; + declarations.AddLine("switch (func) {"); + declarations.scope++; + declarations.AddLine("case 1:"); + declarations.AddLine("return false;"); + declarations.AddLine("case 2:"); + declarations.AddLine("return value < ref;"); + declarations.AddLine("case 3:"); + declarations.AddLine("return value == ref;"); + declarations.AddLine("case 4:"); + declarations.AddLine("return value <= ref;"); + declarations.AddLine("case 5:"); + declarations.AddLine("return value > ref;"); + declarations.AddLine("case 6:"); + declarations.AddLine("return value != ref;"); + declarations.AddLine("case 7:"); + declarations.AddLine("return value >= ref;"); + declarations.AddLine("case 8:"); + declarations.AddLine("return true;"); + declarations.AddLine("default:"); + declarations.AddLine("return false;"); + declarations.scope--; + declarations.AddLine('}'); + declarations.scope--; + declarations.AddLine('}'); + } } private: