diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index 5087d94063c539e7017b02cecb90d952a2ae6357..ca410287a8dfa078982f634653fe53d527a8b21d 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -663,13 +663,10 @@ void RasterizerOpenGL::DrawArrays() {
     SyncCullMode();
     SyncPrimitiveRestart();
     SyncScissorTest(state);
-    // Alpha Testing is synced on shaders.
     SyncTransformFeedback();
     SyncPointState();
-    CheckAlphaTests();
     SyncPolygonOffset();
-    // TODO(bunnei): Sync framebuffer_scale uniform here
-    // TODO(bunnei): Sync scissorbox uniform(s) here
+    SyncAlphaTest();
 
     // Draw the vertex batch
     const bool is_indexed = accelerate_draw == AccelDraw::Indexed;
@@ -1121,10 +1118,17 @@ void RasterizerOpenGL::SyncPolygonOffset() {
     state.polygon_offset.clamp = regs.polygon_offset_clamp;
 }
 
-void RasterizerOpenGL::CheckAlphaTests() {
+void RasterizerOpenGL::SyncAlphaTest() {
     const auto& regs = system.GPU().Maxwell3D().regs;
     UNIMPLEMENTED_IF_MSG(regs.alpha_test_enabled != 0 && regs.rt_control.count > 1,
                          "Alpha Testing is enabled with more than one rendertarget");
+
+    state.alpha_test.enabled = regs.alpha_test_enabled;
+    if (!state.alpha_test.enabled) {
+        return;
+    }
+    state.alpha_test.func = MaxwellToGL::ComparisonOp(regs.alpha_test_func);
+    state.alpha_test.ref = regs.alpha_test_ref;
 }
 
 } // namespace OpenGL
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h
index f2643f26f8045ce9bb7ed070dd4ea5199676958c..2817f65c966f44851224b0e16420835c567886e3 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer.h
@@ -166,8 +166,8 @@ private:
     /// Syncs the polygon offsets
     void SyncPolygonOffset();
 
-    /// Check asserts for alpha testing.
-    void CheckAlphaTests();
+    /// Syncs the alpha test state to match the guest state
+    void SyncAlphaTest();
 
     /// Check for extension that are not strictly required
     /// but are needed for correct emulation
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
index e9f8d40dbba35f3d0162afee15ba36f33ce35487..ab75bb795e1669e8be4251b1f0dea7630f52333b 100644
--- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
@@ -1447,27 +1447,9 @@ private:
 
         UNIMPLEMENTED_IF_MSG(header.ps.omap.sample_mask != 0, "Sample mask write is unimplemented");
 
-        code.AddLine("if (alpha_test[0] != 0) {{");
-        ++code.scope;
-        // We start on the register containing the alpha value in the first RT.
-        u32 current_reg = 3;
-        for (u32 render_target = 0; render_target < Maxwell::NumRenderTargets; ++render_target) {
-            // TODO(Blinkhawk): verify the behavior of alpha testing on hardware when
-            // multiple render targets are used.
-            if (header.ps.IsColorComponentOutputEnabled(render_target, 0) ||
-                header.ps.IsColorComponentOutputEnabled(render_target, 1) ||
-                header.ps.IsColorComponentOutputEnabled(render_target, 2) ||
-                header.ps.IsColorComponentOutputEnabled(render_target, 3)) {
-                code.AddLine("if (!AlphaFunc({})) discard;", SafeGetRegister(current_reg));
-                current_reg += 4;
-            }
-        }
-        --code.scope;
-        code.AddLine("}}");
-
         // Write the color outputs using the data in the shader registers, disabled
         // rendertargets/components are skipped in the register assignment.
-        current_reg = 0;
+        u32 current_reg = 0;
         for (u32 render_target = 0; render_target < Maxwell::NumRenderTargets; ++render_target) {
             // TODO(Subv): Figure out how dual-source blending is configured in the Switch.
             for (u32 component = 0; component < 4; ++component) {
diff --git a/src/video_core/renderer_opengl/gl_shader_gen.cpp b/src/video_core/renderer_opengl/gl_shader_gen.cpp
index d2bb705a9f7f43820a7b6a4ec0ddd8460667c95c..269dda1222a8a1befe8d3ef662912e8d0af2896d 100644
--- a/src/video_core/renderer_opengl/gl_shader_gen.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_gen.cpp
@@ -28,7 +28,6 @@ layout (location = 0) out vec4 position;
 layout (std140, binding = EMULATION_UBO_BINDING) uniform vs_config {
     vec4 viewport_flip;
     uvec4 config_pack; // instance_id, flip_stage, y_direction, padding
-    uvec4 alpha_test;
 };
 
 )";
@@ -91,7 +90,6 @@ layout (location = 0) out vec4 position;
 layout (std140, binding = EMULATION_UBO_BINDING) uniform gs_config {
     vec4 viewport_flip;
     uvec4 config_pack; // instance_id, flip_stage, y_direction, padding
-    uvec4 alpha_test;
 };
 
 )";
@@ -129,33 +127,8 @@ layout (location = 0) in noperspective vec4 position;
 layout (std140, binding = EMULATION_UBO_BINDING) uniform fs_config {
     vec4 viewport_flip;
     uvec4 config_pack; // instance_id, flip_stage, y_direction, padding
-    uvec4 alpha_test;
 };
 
-bool AlphaFunc(in float value) {
-    float ref = uintBitsToFloat(alpha_test[2]);
-    switch (alpha_test[1]) {
-        case 1:
-            return false;
-        case 2:
-            return value < ref;
-        case 3:
-            return value == ref;
-        case 4:
-            return value <= ref;
-        case 5:
-            return value > ref;
-        case 6:
-            return value != ref;
-        case 7:
-            return value >= ref;
-        case 8:
-            return true;
-        default:
-            return false;
-    }
-}
-
 )";
     const ShaderIR program_ir(setup.program.code, PROGRAM_OFFSET);
     ProgramResult program =
diff --git a/src/video_core/renderer_opengl/gl_shader_manager.cpp b/src/video_core/renderer_opengl/gl_shader_manager.cpp
index 05ab01dcbc0f26dee8163466c1eac8f24187e3ac..b05f90f20d4b65429d2e2a88331e7b2949f98d88 100644
--- a/src/video_core/renderer_opengl/gl_shader_manager.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_manager.cpp
@@ -48,17 +48,6 @@ void MaxwellUniformData::SetFromRegs(const Maxwell3D& maxwell, std::size_t shade
     viewport_flip[0] = regs.viewport_transform[0].scale_x < 0.0 ? -1.0f : 1.0f;
     viewport_flip[1] = regs.viewport_transform[0].scale_y < 0.0 ? -1.0f : 1.0f;
 
-    auto func{static_cast<u32>(regs.alpha_test_func)};
-    // Normalize the gl variants of opCompare to be the same as the normal variants
-    const u32 op_gl_variant_base = static_cast<u32>(Maxwell3D::Regs::ComparisonOp::Never);
-    if (func >= op_gl_variant_base) {
-        func = func - op_gl_variant_base + 1U;
-    }
-
-    alpha_test.enabled = regs.alpha_test_enabled;
-    alpha_test.func = func;
-    alpha_test.ref = regs.alpha_test_ref;
-
     instance_id = state.current_instance;
 
     // Assign in which stage the position has to be flipped
diff --git a/src/video_core/renderer_opengl/gl_shader_manager.h b/src/video_core/renderer_opengl/gl_shader_manager.h
index cec18a83216088722d0f74cf10c6e098975ca406..6961e702a240644a5dc72ec45a8a51eb48e48d0f 100644
--- a/src/video_core/renderer_opengl/gl_shader_manager.h
+++ b/src/video_core/renderer_opengl/gl_shader_manager.h
@@ -27,14 +27,8 @@ struct MaxwellUniformData {
         GLuint flip_stage;
         GLfloat y_direction;
     };
-    struct alignas(16) {
-        GLuint enabled;
-        GLuint func;
-        GLfloat ref;
-        GLuint padding;
-    } alpha_test;
 };
-static_assert(sizeof(MaxwellUniformData) == 48, "MaxwellUniformData structure size is incorrect");
+static_assert(sizeof(MaxwellUniformData) == 32, "MaxwellUniformData structure size is incorrect");
 static_assert(sizeof(MaxwellUniformData) < 16384,
               "MaxwellUniformData structure must be less than 16kb as per the OpenGL spec");
 
diff --git a/src/video_core/renderer_opengl/gl_state.cpp b/src/video_core/renderer_opengl/gl_state.cpp
index 7425fbe5dddf568362b049eb7a62ddc261f911e0..d86e137ac1b3968884ca65ca2d853011e8c3e18b 100644
--- a/src/video_core/renderer_opengl/gl_state.cpp
+++ b/src/video_core/renderer_opengl/gl_state.cpp
@@ -156,6 +156,10 @@ OpenGLState::OpenGLState() {
     polygon_offset.factor = 0.0f;
     polygon_offset.units = 0.0f;
     polygon_offset.clamp = 0.0f;
+
+    alpha_test.enabled = false;
+    alpha_test.func = GL_ALWAYS;
+    alpha_test.ref = 0.0f;
 }
 
 void OpenGLState::ApplyDefaultState() {
@@ -461,6 +465,14 @@ void OpenGLState::ApplyPolygonOffset() const {
     }
 }
 
+void OpenGLState::ApplyAlphaTest() const {
+    Enable(GL_ALPHA_TEST, cur_state.alpha_test.enabled, alpha_test.enabled);
+    if (UpdateTie(std::tie(cur_state.alpha_test.func, cur_state.alpha_test.ref),
+                  std::tie(alpha_test.func, alpha_test.ref))) {
+        glAlphaFunc(alpha_test.func, alpha_test.ref);
+    }
+}
+
 void OpenGLState::ApplyTextures() const {
     bool has_delta{};
     std::size_t first{};
@@ -533,6 +545,7 @@ void OpenGLState::Apply() const {
     ApplyTextures();
     ApplySamplers();
     ApplyPolygonOffset();
+    ApplyAlphaTest();
 }
 
 void OpenGLState::EmulateViewportWithScissor() {
diff --git a/src/video_core/renderer_opengl/gl_state.h b/src/video_core/renderer_opengl/gl_state.h
index 41418a7b846e0636f5d59af01664de5f8d31dc0d..b0140495df7c1fb111b40ac24dfd75e79bb6b058 100644
--- a/src/video_core/renderer_opengl/gl_state.h
+++ b/src/video_core/renderer_opengl/gl_state.h
@@ -172,6 +172,12 @@ public:
         GLfloat clamp;
     } polygon_offset;
 
+    struct {
+        bool enabled; // GL_ALPHA_TEST
+        GLenum func;  // GL_ALPHA_TEST_FUNC
+        GLfloat ref;  // GL_ALPHA_TEST_REF
+    } alpha_test;
+
     std::array<bool, 8> clip_distance; // GL_CLIP_DISTANCE
 
     OpenGLState();
@@ -215,6 +221,7 @@ public:
     void ApplySamplers() const;
     void ApplyDepthClamp() const;
     void ApplyPolygonOffset() const;
+    void ApplyAlphaTest() const;
 
     /// Set the initial OpenGL state
     static void ApplyDefaultState();