diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index ec19369279..133ac6c0f2 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -460,7 +460,6 @@ void RasterizerOpenGL::Clear() {
     // TODO: Signal state tracker about these changes
     state_tracker.NotifyBlend0();
     // TODO(Rodrigo): Find out if these changes affect clearing
-    glClipControl(GL_LOWER_LEFT, GL_ZERO_TO_ONE);
     glDisablei(GL_BLEND, 0);
 
     UNIMPLEMENTED_IF(regs.clear_flags.viewport);
@@ -927,7 +926,23 @@ void RasterizerOpenGL::SyncViewport() {
     auto& flags = gpu.dirty.flags;
     const auto& regs = gpu.regs;
 
-    if (flags[Dirty::Viewports]) {
+    const bool dirty_viewport = flags[Dirty::Viewports];
+    if (dirty_viewport || flags[Dirty::ClipControl]) {
+        flags[Dirty::ClipControl] = false;
+
+        bool flip_y = false;
+        if (regs.viewport_transform[0].scale_y < 0.0) {
+            flip_y = !flip_y;
+        }
+        if (regs.screen_y_control.y_negate != 0) {
+            flip_y = !flip_y;
+        }
+        glClipControl(flip_y ? GL_UPPER_LEFT : GL_LOWER_LEFT,
+                      regs.depth_mode == Maxwell::DepthMode::ZeroToOne ? GL_ZERO_TO_ONE
+                                                                       : GL_NEGATIVE_ONE_TO_ONE);
+    }
+
+    if (dirty_viewport) {
         flags[Dirty::Viewports] = false;
 
         const bool force = flags[Dirty::ViewportTransform];
@@ -948,17 +963,6 @@ void RasterizerOpenGL::SyncViewport() {
                                 static_cast<GLdouble>(src.depth_range_far));
         }
     }
-
-    bool flip_y = false;
-    if (regs.viewport_transform[0].scale_y < 0.0) {
-        flip_y = !flip_y;
-    }
-    if (regs.screen_y_control.y_negate != 0) {
-        flip_y = !flip_y;
-    }
-    glClipControl(flip_y ? GL_UPPER_LEFT : GL_LOWER_LEFT,
-                  regs.depth_mode == Maxwell::DepthMode::ZeroToOne ? GL_ZERO_TO_ONE
-                                                                   : GL_NEGATIVE_ONE_TO_ONE);
 }
 
 void RasterizerOpenGL::SyncDepthClamp() {
diff --git a/src/video_core/renderer_opengl/gl_state_tracker.cpp b/src/video_core/renderer_opengl/gl_state_tracker.cpp
index 8bb827ac57..3d64b1ea4a 100644
--- a/src/video_core/renderer_opengl/gl_state_tracker.cpp
+++ b/src/video_core/renderer_opengl/gl_state_tracker.cpp
@@ -211,6 +211,12 @@ void SetupDirtyPointSize(Tables& tables) {
     tables[0][OFF(point_sprite_enable)] = PointSize;
 }
 
+void SetupDirtyClipControl(Tables& tables) {
+    auto& table = tables[0];
+    table[OFF(screen_y_control)] = ClipControl;
+    table[OFF(depth_mode)] = ClipControl;
+}
+
 void SetupDirtyMisc(Tables& tables) {
     auto& table = tables[0];
 
@@ -248,6 +254,7 @@ void StateTracker::Initialize() {
     SetupDirtyLogicOp(tables);
     SetupDirtyFragmentClampColor(tables);
     SetupDirtyPointSize(tables);
+    SetupDirtyClipControl(tables);
     SetupDirtyMisc(tables);
 
     auto& store = dirty.on_write_stores;
diff --git a/src/video_core/renderer_opengl/gl_state_tracker.h b/src/video_core/renderer_opengl/gl_state_tracker.h
index 90b17a7d6b..5269dadff9 100644
--- a/src/video_core/renderer_opengl/gl_state_tracker.h
+++ b/src/video_core/renderer_opengl/gl_state_tracker.h
@@ -71,6 +71,7 @@ enum : u8 {
     LogicOp,
     FragmentClampColor,
     PointSize,
+    ClipControl,
 
     Last
 };
@@ -167,6 +168,11 @@ public:
         flags[OpenGL::Dirty::LogicOp] = true;
     }
 
+    void NotifyClipControl() {
+        auto& flags = system.GPU().Maxwell3D().dirty.flags;
+        flags[OpenGL::Dirty::ClipControl] = true;
+    }
+
 private:
     Core::System& system;
 };
diff --git a/src/video_core/renderer_opengl/gl_texture_cache.cpp b/src/video_core/renderer_opengl/gl_texture_cache.cpp
index d8a2bf9eb7..4b86018d5f 100644
--- a/src/video_core/renderer_opengl/gl_texture_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_texture_cache.cpp
@@ -532,11 +532,9 @@ void TextureCacheOpenGL::ImageBlit(View& src_view, View& dst_view,
     }
     // TODO(Rodrigo): Find out if rasterizer discard affects blits
     // TODO(Rodrigo): Find out if blending affects blits
-    // TODO(Rodrigo): Find out if clip control affects blits
     glDisable(GL_RASTERIZER_DISCARD);
     glDisablei(GL_SCISSOR_TEST, 0);
     glDisablei(GL_BLEND, 0);
-    glClipControl(GL_LOWER_LEFT, GL_ZERO_TO_ONE);
 
     glBindFramebuffer(GL_READ_FRAMEBUFFER, src_framebuffer.handle);
     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, dst_framebuffer.handle);
diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp
index 7391412c2b..7b4c2b80c7 100644
--- a/src/video_core/renderer_opengl/renderer_opengl.cpp
+++ b/src/video_core/renderer_opengl/renderer_opengl.cpp
@@ -590,6 +590,7 @@ void RendererOpenGL::DrawScreen(const Layout::FramebufferLayout& layout) {
     state_tracker.NotifyRasterizeEnable();
     state_tracker.NotifyFramebufferSRGB();
     state_tracker.NotifyLogicOp();
+    state_tracker.NotifyClipControl();
 
     program_manager.UseVertexShader(vertex_program.handle);
     program_manager.UseGeometryShader(0);