diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h
index 33eb57360505314f6786cfb2a00b37444ad976e7..0509ba3a2755219984f88ad15d0545e2521feeb1 100644
--- a/src/video_core/engines/maxwell_3d.h
+++ b/src/video_core/engines/maxwell_3d.h
@@ -462,6 +462,16 @@ public:
             }
         };
 
+        struct ColorMask {
+            union {
+                u32 raw;
+                BitField<0, 4, u32> R;
+                BitField<4, 4, u32> G;
+                BitField<8, 4, u32> B;
+                BitField<12, 4, u32> A;
+            };
+        };
+
         bool IsShaderConfigEnabled(std::size_t index) const {
             // The VertexB is always enabled.
             if (index == static_cast<std::size_t>(Regs::ShaderProgram::VertexB)) {
@@ -571,7 +581,11 @@ public:
                 u32 stencil_back_mask;
                 u32 stencil_back_func_mask;
 
-                INSERT_PADDING_WORDS(0x13);
+                INSERT_PADDING_WORDS(0xC);
+
+                u32 color_mask_common;
+
+                INSERT_PADDING_WORDS(0x6);
 
                 u32 rt_separate_frag_data;
 
@@ -847,8 +861,9 @@ public:
                     BitField<6, 4, u32> RT;
                     BitField<10, 11, u32> layer;
                 } clear_buffers;
-
-                INSERT_PADDING_WORDS(0x4B);
+                INSERT_PADDING_WORDS(0xB);
+                std::array<ColorMask, NumRenderTargets> color_mask;
+                INSERT_PADDING_WORDS(0x38);
 
                 struct {
                     u32 query_address_high;
@@ -1081,6 +1096,7 @@ ASSERT_REG_POSITION(scissor_test, 0x380);
 ASSERT_REG_POSITION(stencil_back_func_ref, 0x3D5);
 ASSERT_REG_POSITION(stencil_back_mask, 0x3D6);
 ASSERT_REG_POSITION(stencil_back_func_mask, 0x3D7);
+ASSERT_REG_POSITION(color_mask_common, 0x3E4);
 ASSERT_REG_POSITION(rt_separate_frag_data, 0x3EB);
 ASSERT_REG_POSITION(zeta, 0x3F8);
 ASSERT_REG_POSITION(vertex_attrib_format, 0x458);
@@ -1127,6 +1143,7 @@ ASSERT_REG_POSITION(instanced_arrays, 0x620);
 ASSERT_REG_POSITION(cull, 0x646);
 ASSERT_REG_POSITION(logic_op, 0x671);
 ASSERT_REG_POSITION(clear_buffers, 0x674);
+ASSERT_REG_POSITION(color_mask, 0x680);
 ASSERT_REG_POSITION(query, 0x6C0);
 ASSERT_REG_POSITION(vertex_array[0], 0x700);
 ASSERT_REG_POSITION(independent_blend, 0x780);
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index 73770ff6932109446fa16411843200fba1ce9fe9..bb263b6aaee889f96b88b58570fd55e871dc74c0 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -511,10 +511,10 @@ void RasterizerOpenGL::Clear() {
 
     OpenGLState clear_state;
     clear_state.draw.draw_framebuffer = framebuffer.handle;
-    clear_state.color_mask.red_enabled = regs.clear_buffers.R ? GL_TRUE : GL_FALSE;
-    clear_state.color_mask.green_enabled = regs.clear_buffers.G ? GL_TRUE : GL_FALSE;
-    clear_state.color_mask.blue_enabled = regs.clear_buffers.B ? GL_TRUE : GL_FALSE;
-    clear_state.color_mask.alpha_enabled = regs.clear_buffers.A ? GL_TRUE : GL_FALSE;
+    clear_state.color_mask[0].red_enabled = regs.clear_buffers.R ? GL_TRUE : GL_FALSE;
+    clear_state.color_mask[0].green_enabled = regs.clear_buffers.G ? GL_TRUE : GL_FALSE;
+    clear_state.color_mask[0].blue_enabled = regs.clear_buffers.B ? GL_TRUE : GL_FALSE;
+    clear_state.color_mask[0].alpha_enabled = regs.clear_buffers.A ? GL_TRUE : GL_FALSE;
 
     if (regs.clear_buffers.R || regs.clear_buffers.G || regs.clear_buffers.B ||
         regs.clear_buffers.A) {
@@ -573,7 +573,7 @@ void RasterizerOpenGL::DrawArrays() {
     ScopeAcquireGLContext acquire_context{emu_window};
 
     ConfigureFramebuffers();
-
+    SyncColorMask();
     SyncDepthTestState();
     SyncStencilTestState();
     SyncBlendState();
@@ -989,6 +989,18 @@ void RasterizerOpenGL::SyncStencilTestState() {
     state.stencil.back.write_mask = regs.stencil_back_mask;
 }
 
+void RasterizerOpenGL::SyncColorMask() {
+    const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs;
+    for (size_t i = 0; i < Tegra::Engines::Maxwell3D::Regs::NumRenderTargets; i++) {
+        const auto& source = regs.color_mask[regs.color_mask_common ? 0 : i];
+        auto& dest = state.color_mask[i];
+        dest.red_enabled = (source.R == 0) ? GL_FALSE : GL_TRUE;
+        dest.green_enabled = (source.G == 0) ? GL_FALSE : GL_TRUE;
+        dest.blue_enabled = (source.B == 0) ? GL_FALSE : GL_TRUE;
+        dest.alpha_enabled = (source.A == 0) ? GL_FALSE : GL_TRUE;
+    }
+}
+
 void RasterizerOpenGL::SyncBlendState() {
     const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs;
 
@@ -1000,6 +1012,7 @@ void RasterizerOpenGL::SyncBlendState() {
     state.independant_blend.enabled = regs.independent_blend_enable;
     if (!state.independant_blend.enabled) {
         auto& blend = state.blend[0];
+        blend.enabled = regs.blend.enable[0] != 0;
         blend.separate_alpha = regs.blend.separate_alpha;
         blend.rgb_equation = MaxwellToGL::BlendEquation(regs.blend.equation_rgb);
         blend.src_rgb_func = MaxwellToGL::BlendFunc(regs.blend.factor_source_rgb);
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h
index 8ec22df8d72b780e77bf8b3fdf8f193bd48ee479..60e7838036d6747d8954422373c0ffabeab84f58 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer.h
@@ -169,6 +169,9 @@ private:
     /// Syncs the point state to match the guest state
     void SyncPointState();
 
+    /// Syncs Color Mask
+    void SyncColorMask();
+
     /// Check asserts for alpha testing.
     void CheckAlphaTests();
 
diff --git a/src/video_core/renderer_opengl/gl_state.cpp b/src/video_core/renderer_opengl/gl_state.cpp
index 2e1f81e269f6d2b3367820e15008773fd384875d..9517285e560908f0280be39bb62f4c8bee1c604e 100644
--- a/src/video_core/renderer_opengl/gl_state.cpp
+++ b/src/video_core/renderer_opengl/gl_state.cpp
@@ -25,12 +25,12 @@ OpenGLState::OpenGLState() {
 
     primitive_restart.enabled = false;
     primitive_restart.index = 0;
-
-    color_mask.red_enabled = GL_TRUE;
-    color_mask.green_enabled = GL_TRUE;
-    color_mask.blue_enabled = GL_TRUE;
-    color_mask.alpha_enabled = GL_TRUE;
-
+    for (auto& item : color_mask) {
+        item.red_enabled = GL_TRUE;
+        item.green_enabled = GL_TRUE;
+        item.blue_enabled = GL_TRUE;
+        item.alpha_enabled = GL_TRUE;
+    }
     stencil.test_enabled = false;
     auto reset_stencil = [](auto& config) {
         config.test_func = GL_ALWAYS;
@@ -135,6 +135,32 @@ void OpenGLState::ApplyCulling() const {
     }
 }
 
+void OpenGLState::ApplyColorMask() const {
+    if (GLAD_GL_ARB_viewport_array) {
+        for (size_t i = 0; i < Tegra::Engines::Maxwell3D::Regs::NumRenderTargets; i++) {
+            const auto& updated = color_mask[i];
+            const auto& current = cur_state.color_mask[i];
+            if (updated.red_enabled != current.red_enabled ||
+                updated.green_enabled != current.green_enabled ||
+                updated.blue_enabled != current.blue_enabled ||
+                updated.alpha_enabled != current.alpha_enabled) {
+                glColorMaski(static_cast<GLuint>(i), updated.red_enabled, updated.green_enabled,
+                             updated.blue_enabled, updated.alpha_enabled);
+            }
+        }
+    } else {
+        const auto& updated = color_mask[0];
+        const auto& current = cur_state.color_mask[0];
+        if (updated.red_enabled != current.red_enabled ||
+            updated.green_enabled != current.green_enabled ||
+            updated.blue_enabled != current.blue_enabled ||
+            updated.alpha_enabled != current.alpha_enabled) {
+            glColorMask(updated.red_enabled, updated.green_enabled, updated.blue_enabled,
+                        updated.alpha_enabled);
+        }
+    }
+}
+
 void OpenGLState::ApplyDepth() const {
     // Depth test
     const bool depth_test_changed = depth.test_enabled != cur_state.depth.test_enabled;
@@ -444,18 +470,11 @@ void OpenGLState::Apply() const {
             }
         }
     }
-    // Color mask
-    if (color_mask.red_enabled != cur_state.color_mask.red_enabled ||
-        color_mask.green_enabled != cur_state.color_mask.green_enabled ||
-        color_mask.blue_enabled != cur_state.color_mask.blue_enabled ||
-        color_mask.alpha_enabled != cur_state.color_mask.alpha_enabled) {
-        glColorMask(color_mask.red_enabled, color_mask.green_enabled, color_mask.blue_enabled,
-                    color_mask.alpha_enabled);
-    }
     // Point
     if (point.size != cur_state.point.size) {
         glPointSize(point.size);
     }
+    ApplyColorMask();
     ApplyViewport();
     ApplyScissor();
     ApplyStencilTest();
diff --git a/src/video_core/renderer_opengl/gl_state.h b/src/video_core/renderer_opengl/gl_state.h
index a027ca33ce29488e614beaa6b6cfae31bab8d0ae..b8cf1f637c376ae39e6a150d1a188c44ed1e4477 100644
--- a/src/video_core/renderer_opengl/gl_state.h
+++ b/src/video_core/renderer_opengl/gl_state.h
@@ -56,13 +56,14 @@ public:
         GLuint index;
     } primitive_restart; // GL_PRIMITIVE_RESTART
 
-    struct {
+    struct ColorMask {
         GLboolean red_enabled;
         GLboolean green_enabled;
         GLboolean blue_enabled;
         GLboolean alpha_enabled;
-    } color_mask; // GL_COLOR_WRITEMASK
-
+    };
+    std::array<ColorMask, Tegra::Engines::Maxwell3D::Regs::NumRenderTargets>
+        color_mask; // GL_COLOR_WRITEMASK
     struct {
         bool test_enabled; // GL_STENCIL_TEST
         struct {
@@ -198,6 +199,7 @@ private:
     static bool s_rgb_used;
     void ApplySRgb() const;
     void ApplyCulling() const;
+    void ApplyColorMask() const;
     void ApplyDepth() const;
     void ApplyPrimitiveRestart() const;
     void ApplyStencilTest() const;