From 28fece8e9bb2e4c95ba93fba3c63489a9e26fb47 Mon Sep 17 00:00:00 2001
From: ReinUsesLisp <reinuseslisp@airmail.cc>
Date: Tue, 29 Oct 2019 21:12:42 -0300
Subject: [PATCH 1/7] gl_state: Move initializers from constructor to class
 declaration

---
 src/video_core/renderer_opengl/gl_state.cpp |  99 +------------
 src/video_core/renderer_opengl/gl_state.h   | 146 ++++++++++----------
 2 files changed, 75 insertions(+), 170 deletions(-)

diff --git a/src/video_core/renderer_opengl/gl_state.cpp b/src/video_core/renderer_opengl/gl_state.cpp
index bf86b5a0b..88c32bd4f 100644
--- a/src/video_core/renderer_opengl/gl_state.cpp
+++ b/src/video_core/renderer_opengl/gl_state.cpp
@@ -80,104 +80,7 @@ void Enable(GLenum cap, GLuint index, bool& current_value, bool new_value) {
 
 } // namespace
 
-OpenGLState::OpenGLState() {
-    // These all match default OpenGL values
-    framebuffer_srgb.enabled = false;
-
-    multisample_control.alpha_to_coverage = false;
-    multisample_control.alpha_to_one = false;
-
-    cull.enabled = false;
-    cull.mode = GL_BACK;
-    cull.front_face = GL_CCW;
-
-    depth.test_enabled = false;
-    depth.test_func = GL_LESS;
-    depth.write_mask = GL_TRUE;
-
-    primitive_restart.enabled = false;
-    primitive_restart.index = 0;
-
-    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;
-    }
-
-    const auto ResetStencil = [](auto& config) {
-        config.test_func = GL_ALWAYS;
-        config.test_ref = 0;
-        config.test_mask = 0xFFFFFFFF;
-        config.write_mask = 0xFFFFFFFF;
-        config.action_depth_fail = GL_KEEP;
-        config.action_depth_pass = GL_KEEP;
-        config.action_stencil_fail = GL_KEEP;
-    };
-    stencil.test_enabled = false;
-    ResetStencil(stencil.front);
-    ResetStencil(stencil.back);
-
-    for (auto& item : viewports) {
-        item.x = 0;
-        item.y = 0;
-        item.width = 0;
-        item.height = 0;
-        item.depth_range_near = 0.0f;
-        item.depth_range_far = 1.0f;
-        item.scissor.enabled = false;
-        item.scissor.x = 0;
-        item.scissor.y = 0;
-        item.scissor.width = 0;
-        item.scissor.height = 0;
-    }
-
-    for (auto& item : blend) {
-        item.enabled = true;
-        item.rgb_equation = GL_FUNC_ADD;
-        item.a_equation = GL_FUNC_ADD;
-        item.src_rgb_func = GL_ONE;
-        item.dst_rgb_func = GL_ZERO;
-        item.src_a_func = GL_ONE;
-        item.dst_a_func = GL_ZERO;
-    }
-
-    independant_blend.enabled = false;
-
-    blend_color.red = 0.0f;
-    blend_color.green = 0.0f;
-    blend_color.blue = 0.0f;
-    blend_color.alpha = 0.0f;
-
-    logic_op.enabled = false;
-    logic_op.operation = GL_COPY;
-
-    draw.read_framebuffer = 0;
-    draw.draw_framebuffer = 0;
-    draw.vertex_array = 0;
-    draw.shader_program = 0;
-    draw.program_pipeline = 0;
-
-    clip_distance = {};
-
-    point.size = 1;
-
-    fragment_color_clamp.enabled = false;
-
-    depth_clamp.far_plane = false;
-    depth_clamp.near_plane = false;
-
-    polygon_offset.fill_enable = false;
-    polygon_offset.line_enable = false;
-    polygon_offset.point_enable = false;
-    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;
-}
+OpenGLState::OpenGLState() = default;
 
 void OpenGLState::SetDefaultViewports() {
     for (auto& item : viewports) {
diff --git a/src/video_core/renderer_opengl/gl_state.h b/src/video_core/renderer_opengl/gl_state.h
index c358d3b38..27ea98246 100644
--- a/src/video_core/renderer_opengl/gl_state.h
+++ b/src/video_core/renderer_opengl/gl_state.h
@@ -5,6 +5,7 @@
 #pragma once
 
 #include <array>
+#include <type_traits>
 #include <glad/glad.h>
 #include "video_core/engines/maxwell_3d.h"
 
@@ -36,137 +37,137 @@ constexpr TextureUnit ProcTexDiffLUT{9};
 class OpenGLState {
 public:
     struct {
-        bool enabled; // GL_FRAMEBUFFER_SRGB
+        bool enabled = false; // GL_FRAMEBUFFER_SRGB
     } framebuffer_srgb;
 
     struct {
-        bool alpha_to_coverage; // GL_ALPHA_TO_COVERAGE
-        bool alpha_to_one;      // GL_ALPHA_TO_ONE
+        bool alpha_to_coverage = false; // GL_ALPHA_TO_COVERAGE
+        bool alpha_to_one = false;      // GL_ALPHA_TO_ONE
     } multisample_control;
 
     struct {
-        bool enabled; // GL_CLAMP_FRAGMENT_COLOR_ARB
+        bool enabled = false; // GL_CLAMP_FRAGMENT_COLOR_ARB
     } fragment_color_clamp;
 
     struct {
-        bool far_plane;
-        bool near_plane;
+        bool far_plane = false;
+        bool near_plane = false;
     } depth_clamp; // GL_DEPTH_CLAMP
 
     struct {
-        bool enabled;      // GL_CULL_FACE
-        GLenum mode;       // GL_CULL_FACE_MODE
-        GLenum front_face; // GL_FRONT_FACE
+        bool enabled = false;       // GL_CULL_FACE
+        GLenum mode = GL_BACK;      // GL_CULL_FACE_MODE
+        GLenum front_face = GL_CCW; // GL_FRONT_FACE
     } cull;
 
     struct {
-        bool test_enabled;    // GL_DEPTH_TEST
-        GLenum test_func;     // GL_DEPTH_FUNC
-        GLboolean write_mask; // GL_DEPTH_WRITEMASK
+        bool test_enabled = false;      // GL_DEPTH_TEST
+        GLboolean write_mask = GL_TRUE; // GL_DEPTH_WRITEMASK
+        GLenum test_func = GL_LESS;     // GL_DEPTH_FUNC
     } depth;
 
     struct {
-        bool enabled;
-        GLuint index;
+        bool enabled = false;
+        GLuint index = 0;
     } primitive_restart; // GL_PRIMITIVE_RESTART
 
     struct ColorMask {
-        GLboolean red_enabled;
-        GLboolean green_enabled;
-        GLboolean blue_enabled;
-        GLboolean alpha_enabled;
+        GLboolean red_enabled = GL_TRUE;
+        GLboolean green_enabled = GL_TRUE;
+        GLboolean blue_enabled = GL_TRUE;
+        GLboolean alpha_enabled = GL_TRUE;
     };
     std::array<ColorMask, Tegra::Engines::Maxwell3D::Regs::NumRenderTargets>
         color_mask; // GL_COLOR_WRITEMASK
     struct {
-        bool test_enabled; // GL_STENCIL_TEST
+        bool test_enabled = false; // GL_STENCIL_TEST
         struct {
-            GLenum test_func;           // GL_STENCIL_FUNC
-            GLint test_ref;             // GL_STENCIL_REF
-            GLuint test_mask;           // GL_STENCIL_VALUE_MASK
-            GLuint write_mask;          // GL_STENCIL_WRITEMASK
-            GLenum action_stencil_fail; // GL_STENCIL_FAIL
-            GLenum action_depth_fail;   // GL_STENCIL_PASS_DEPTH_FAIL
-            GLenum action_depth_pass;   // GL_STENCIL_PASS_DEPTH_PASS
+            GLenum test_func = GL_ALWAYS;         // GL_STENCIL_FUNC
+            GLint test_ref = 0;                   // GL_STENCIL_REF
+            GLuint test_mask = 0xFFFFFFFF;        // GL_STENCIL_VALUE_MASK
+            GLuint write_mask = 0xFFFFFFFF;       // GL_STENCIL_WRITEMASK
+            GLenum action_stencil_fail = GL_KEEP; // GL_STENCIL_FAIL
+            GLenum action_depth_fail = GL_KEEP;   // GL_STENCIL_PASS_DEPTH_FAIL
+            GLenum action_depth_pass = GL_KEEP;   // GL_STENCIL_PASS_DEPTH_PASS
         } front, back;
     } stencil;
 
     struct Blend {
-        bool enabled;        // GL_BLEND
-        GLenum rgb_equation; // GL_BLEND_EQUATION_RGB
-        GLenum a_equation;   // GL_BLEND_EQUATION_ALPHA
-        GLenum src_rgb_func; // GL_BLEND_SRC_RGB
-        GLenum dst_rgb_func; // GL_BLEND_DST_RGB
-        GLenum src_a_func;   // GL_BLEND_SRC_ALPHA
-        GLenum dst_a_func;   // GL_BLEND_DST_ALPHA
+        bool enabled = true;               // GL_BLEND
+        GLenum rgb_equation = GL_FUNC_ADD; // GL_BLEND_EQUATION_RGB
+        GLenum a_equation = GL_FUNC_ADD;   // GL_BLEND_EQUATION_ALPHA
+        GLenum src_rgb_func = GL_ONE;      // GL_BLEND_SRC_RGB
+        GLenum dst_rgb_func = GL_ZERO;     // GL_BLEND_DST_RGB
+        GLenum src_a_func = GL_ONE;        // GL_BLEND_SRC_ALPHA
+        GLenum dst_a_func = GL_ZERO;       // GL_BLEND_DST_ALPHA
     };
     std::array<Blend, Tegra::Engines::Maxwell3D::Regs::NumRenderTargets> blend;
 
     struct {
-        bool enabled;
+        bool enabled = false;
     } independant_blend;
 
     struct {
-        GLclampf red;
-        GLclampf green;
-        GLclampf blue;
-        GLclampf alpha;
+        GLclampf red = 0.0f;
+        GLclampf green = 0.0f;
+        GLclampf blue = 0.0f;
+        GLclampf alpha = 0.0f;
     } blend_color; // GL_BLEND_COLOR
 
     struct {
-        bool enabled; // GL_LOGIC_OP_MODE
-        GLenum operation;
+        bool enabled = false; // GL_LOGIC_OP_MODE
+        GLenum operation = GL_COPY;
     } logic_op;
 
-    std::array<GLuint, Tegra::Engines::Maxwell3D::Regs::NumTextureSamplers> textures{};
-    std::array<GLuint, Tegra::Engines::Maxwell3D::Regs::NumTextureSamplers> samplers{};
-    std::array<GLuint, Tegra::Engines::Maxwell3D::Regs::NumImages> images{};
+    std::array<GLuint, Tegra::Engines::Maxwell3D::Regs::NumTextureSamplers> textures = {};
+    std::array<GLuint, Tegra::Engines::Maxwell3D::Regs::NumTextureSamplers> samplers = {};
+    std::array<GLuint, Tegra::Engines::Maxwell3D::Regs::NumImages> images = {};
 
     struct {
-        GLuint read_framebuffer; // GL_READ_FRAMEBUFFER_BINDING
-        GLuint draw_framebuffer; // GL_DRAW_FRAMEBUFFER_BINDING
-        GLuint vertex_array;     // GL_VERTEX_ARRAY_BINDING
-        GLuint shader_program;   // GL_CURRENT_PROGRAM
-        GLuint program_pipeline; // GL_PROGRAM_PIPELINE_BINDING
+        GLuint read_framebuffer = 0; // GL_READ_FRAMEBUFFER_BINDING
+        GLuint draw_framebuffer = 0; // GL_DRAW_FRAMEBUFFER_BINDING
+        GLuint vertex_array = 0;     // GL_VERTEX_ARRAY_BINDING
+        GLuint shader_program = 0;   // GL_CURRENT_PROGRAM
+        GLuint program_pipeline = 0; // GL_PROGRAM_PIPELINE_BINDING
     } draw;
 
-    struct viewport {
-        GLint x;
-        GLint y;
-        GLint width;
-        GLint height;
-        GLfloat depth_range_near; // GL_DEPTH_RANGE
-        GLfloat depth_range_far;  // GL_DEPTH_RANGE
+    struct Viewport {
+        GLint x = 0;
+        GLint y = 0;
+        GLint width = 0;
+        GLint height = 0;
+        GLfloat depth_range_near = 0.0f; // GL_DEPTH_RANGE
+        GLfloat depth_range_far = 1.0f;  // GL_DEPTH_RANGE
         struct {
-            bool enabled; // GL_SCISSOR_TEST
-            GLint x;
-            GLint y;
-            GLsizei width;
-            GLsizei height;
+            bool enabled = false; // GL_SCISSOR_TEST
+            GLint x = 0;
+            GLint y = 0;
+            GLsizei width = 0;
+            GLsizei height = 0;
         } scissor;
     };
-    std::array<viewport, Tegra::Engines::Maxwell3D::Regs::NumViewports> viewports;
+    std::array<Viewport, Tegra::Engines::Maxwell3D::Regs::NumViewports> viewports;
 
     struct {
-        float size; // GL_POINT_SIZE
+        float size = 1.0f; // GL_POINT_SIZE
     } point;
 
     struct {
-        bool point_enable;
-        bool line_enable;
-        bool fill_enable;
-        GLfloat units;
-        GLfloat factor;
-        GLfloat clamp;
+        bool point_enable = false;
+        bool line_enable = false;
+        bool fill_enable = false;
+        GLfloat units = 0.0f;
+        GLfloat factor = 0.0f;
+        GLfloat clamp = 0.0f;
     } polygon_offset;
 
     struct {
-        bool enabled; // GL_ALPHA_TEST
-        GLenum func;  // GL_ALPHA_TEST_FUNC
-        GLfloat ref;  // GL_ALPHA_TEST_REF
+        bool enabled = false;    // GL_ALPHA_TEST
+        GLenum func = GL_ALWAYS; // GL_ALPHA_TEST_FUNC
+        GLfloat ref = 0.0f;      // GL_ALPHA_TEST_REF
     } alpha_test;
 
-    std::array<bool, 8> clip_distance; // GL_CLIP_DISTANCE
+    std::array<bool, 8> clip_distance = {}; // GL_CLIP_DISTANCE
 
     OpenGLState();
 
@@ -253,5 +254,6 @@ private:
         bool color_mask;
     } dirty{};
 };
+static_assert(std::is_trivially_copyable_v<OpenGLState>);
 
 } // namespace OpenGL

From a14d202ac27ae255cec635872125106750c81ca4 Mon Sep 17 00:00:00 2001
From: ReinUsesLisp <reinuseslisp@airmail.cc>
Date: Tue, 29 Oct 2019 21:13:21 -0300
Subject: [PATCH 2/7] gl_state: Remove unused Citra TextureUnits

---
 src/video_core/renderer_opengl/gl_state.h | 23 -----------------------
 1 file changed, 23 deletions(-)

diff --git a/src/video_core/renderer_opengl/gl_state.h b/src/video_core/renderer_opengl/gl_state.h
index 27ea98246..805ee9e4a 100644
--- a/src/video_core/renderer_opengl/gl_state.h
+++ b/src/video_core/renderer_opengl/gl_state.h
@@ -11,29 +11,6 @@
 
 namespace OpenGL {
 
-namespace TextureUnits {
-
-struct TextureUnit {
-    GLint id;
-    constexpr GLenum Enum() const {
-        return static_cast<GLenum>(GL_TEXTURE0 + id);
-    }
-};
-
-constexpr TextureUnit MaxwellTexture(int unit) {
-    return TextureUnit{unit};
-}
-
-constexpr TextureUnit LightingLUT{3};
-constexpr TextureUnit FogLUT{4};
-constexpr TextureUnit ProcTexNoiseLUT{5};
-constexpr TextureUnit ProcTexColorMap{6};
-constexpr TextureUnit ProcTexAlphaMap{7};
-constexpr TextureUnit ProcTexLUT{8};
-constexpr TextureUnit ProcTexDiffLUT{9};
-
-} // namespace TextureUnits
-
 class OpenGLState {
 public:
     struct {

From c7698d0bc80b033944804b3133b83a4385c0c899 Mon Sep 17 00:00:00 2001
From: ReinUsesLisp <reinuseslisp@airmail.cc>
Date: Tue, 29 Oct 2019 21:15:11 -0300
Subject: [PATCH 3/7] gl_state: Minor style changes

---
 src/video_core/renderer_opengl/gl_state.cpp | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/src/video_core/renderer_opengl/gl_state.cpp b/src/video_core/renderer_opengl/gl_state.cpp
index 88c32bd4f..cd440e0d8 100644
--- a/src/video_core/renderer_opengl/gl_state.cpp
+++ b/src/video_core/renderer_opengl/gl_state.cpp
@@ -69,16 +69,18 @@ void Enable(GLenum cap, GLuint index, bool enable) {
 }
 
 void Enable(GLenum cap, bool& current_value, bool new_value) {
-    if (UpdateValue(current_value, new_value))
+    if (UpdateValue(current_value, new_value)) {
         Enable(cap, new_value);
+    }
 }
 
 void Enable(GLenum cap, GLuint index, bool& current_value, bool new_value) {
-    if (UpdateValue(current_value, new_value))
+    if (UpdateValue(current_value, new_value)) {
         Enable(cap, index, new_value);
+    }
 }
 
-} // namespace
+} // Anonymous namespace
 
 OpenGLState::OpenGLState() = default;
 

From d3651b0b8218c40452732f7c084cc72ad848ee15 Mon Sep 17 00:00:00 2001
From: ReinUsesLisp <reinuseslisp@airmail.cc>
Date: Tue, 29 Oct 2019 21:16:03 -0300
Subject: [PATCH 4/7] gl_state: Change SetDefaultViewports to use default
 constructor

---
 src/video_core/renderer_opengl/gl_state.cpp | 15 ++-------------
 1 file changed, 2 insertions(+), 13 deletions(-)

diff --git a/src/video_core/renderer_opengl/gl_state.cpp b/src/video_core/renderer_opengl/gl_state.cpp
index cd440e0d8..cfd1481de 100644
--- a/src/video_core/renderer_opengl/gl_state.cpp
+++ b/src/video_core/renderer_opengl/gl_state.cpp
@@ -2,6 +2,7 @@
 // Licensed under GPLv2 or any later version
 // Refer to the license.txt file included.
 
+#include <algorithm>
 #include <iterator>
 #include <glad/glad.h>
 #include "common/assert.h"
@@ -85,19 +86,7 @@ void Enable(GLenum cap, GLuint index, bool& current_value, bool new_value) {
 OpenGLState::OpenGLState() = default;
 
 void OpenGLState::SetDefaultViewports() {
-    for (auto& item : viewports) {
-        item.x = 0;
-        item.y = 0;
-        item.width = 0;
-        item.height = 0;
-        item.depth_range_near = 0.0f;
-        item.depth_range_far = 1.0f;
-        item.scissor.enabled = false;
-        item.scissor.x = 0;
-        item.scissor.y = 0;
-        item.scissor.width = 0;
-        item.scissor.height = 0;
-    }
+    std::fill(std::begin(viewports), std::end(viewports), Viewport{});
 
     depth_clamp.far_plane = false;
     depth_clamp.near_plane = false;

From 3c6557c235a9b5a1f76ac5a07d301fdf3a615e2a Mon Sep 17 00:00:00 2001
From: ReinUsesLisp <reinuseslisp@airmail.cc>
Date: Tue, 29 Oct 2019 21:17:16 -0300
Subject: [PATCH 5/7] gl_state: Remove ApplyDefaultState

OpenGL has defaults values we can trust. Remove these.
---
 src/video_core/renderer_opengl/gl_rasterizer.cpp |  2 --
 src/video_core/renderer_opengl/gl_state.cpp      | 11 -----------
 src/video_core/renderer_opengl/gl_state.h        |  5 +----
 3 files changed, 1 insertion(+), 17 deletions(-)

diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index 43032e9a7..8774e836c 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -68,8 +68,6 @@ RasterizerOpenGL::RasterizerOpenGL(Core::System& system, Core::Frontend::EmuWind
                                    ScreenInfo& info)
     : texture_cache{system, *this, device}, shader_cache{*this, system, emu_window, device},
       system{system}, screen_info{info}, buffer_cache{*this, system, STREAM_BUFFER_SIZE} {
-    OpenGLState::ApplyDefaultState();
-
     shader_program_manager = std::make_unique<GLShader::ProgramManager>();
     state.draw.shader_program = 0;
     state.Apply();
diff --git a/src/video_core/renderer_opengl/gl_state.cpp b/src/video_core/renderer_opengl/gl_state.cpp
index cfd1481de..48c123ffe 100644
--- a/src/video_core/renderer_opengl/gl_state.cpp
+++ b/src/video_core/renderer_opengl/gl_state.cpp
@@ -92,17 +92,6 @@ void OpenGLState::SetDefaultViewports() {
     depth_clamp.near_plane = false;
 }
 
-void OpenGLState::ApplyDefaultState() {
-    glEnable(GL_BLEND);
-    glDisable(GL_FRAMEBUFFER_SRGB);
-    glDisable(GL_CULL_FACE);
-    glDisable(GL_DEPTH_TEST);
-    glDisable(GL_PRIMITIVE_RESTART);
-    glDisable(GL_STENCIL_TEST);
-    glDisable(GL_COLOR_LOGIC_OP);
-    glDisable(GL_SCISSOR_TEST);
-}
-
 void OpenGLState::ApplyFramebufferState() const {
     if (UpdateValue(cur_state.draw.read_framebuffer, draw.read_framebuffer)) {
         glBindFramebuffer(GL_READ_FRAMEBUFFER, draw.read_framebuffer);
diff --git a/src/video_core/renderer_opengl/gl_state.h b/src/video_core/renderer_opengl/gl_state.h
index 805ee9e4a..b95f33613 100644
--- a/src/video_core/renderer_opengl/gl_state.h
+++ b/src/video_core/renderer_opengl/gl_state.h
@@ -70,7 +70,7 @@ public:
     } stencil;
 
     struct Blend {
-        bool enabled = true;               // GL_BLEND
+        bool enabled = false;              // GL_BLEND
         GLenum rgb_equation = GL_FUNC_ADD; // GL_BLEND_EQUATION_RGB
         GLenum a_equation = GL_FUNC_ADD;   // GL_BLEND_EQUATION_ALPHA
         GLenum src_rgb_func = GL_ONE;      // GL_BLEND_SRC_RGB
@@ -183,9 +183,6 @@ public:
     void ApplyPolygonOffset() const;
     void ApplyAlphaTest() const;
 
-    /// Set the initial OpenGL state
-    static void ApplyDefaultState();
-
     /// Resets any references to the given resource
     OpenGLState& UnbindTexture(GLuint handle);
     OpenGLState& ResetSampler(GLuint handle);

From ce20ed8e4eecfcf04a801fe0f539df520a5e5042 Mon Sep 17 00:00:00 2001
From: ReinUsesLisp <reinuseslisp@airmail.cc>
Date: Tue, 29 Oct 2019 21:24:34 -0300
Subject: [PATCH 6/7] gl_state: Move dirty checks to individual apply calls
 instead of Apply

This requires removing constness from some methods, but for consistency
it's removed in all methods.
---
 src/video_core/renderer_opengl/gl_state.cpp | 90 +++++++++++----------
 src/video_core/renderer_opengl/gl_state.h   | 50 ++++++------
 2 files changed, 74 insertions(+), 66 deletions(-)

diff --git a/src/video_core/renderer_opengl/gl_state.cpp b/src/video_core/renderer_opengl/gl_state.cpp
index 48c123ffe..c431a8635 100644
--- a/src/video_core/renderer_opengl/gl_state.cpp
+++ b/src/video_core/renderer_opengl/gl_state.cpp
@@ -92,7 +92,7 @@ void OpenGLState::SetDefaultViewports() {
     depth_clamp.near_plane = false;
 }
 
-void OpenGLState::ApplyFramebufferState() const {
+void OpenGLState::ApplyFramebufferState() {
     if (UpdateValue(cur_state.draw.read_framebuffer, draw.read_framebuffer)) {
         glBindFramebuffer(GL_READ_FRAMEBUFFER, draw.read_framebuffer);
     }
@@ -101,52 +101,52 @@ void OpenGLState::ApplyFramebufferState() const {
     }
 }
 
-void OpenGLState::ApplyVertexArrayState() const {
+void OpenGLState::ApplyVertexArrayState() {
     if (UpdateValue(cur_state.draw.vertex_array, draw.vertex_array)) {
         glBindVertexArray(draw.vertex_array);
     }
 }
 
-void OpenGLState::ApplyShaderProgram() const {
+void OpenGLState::ApplyShaderProgram() {
     if (UpdateValue(cur_state.draw.shader_program, draw.shader_program)) {
         glUseProgram(draw.shader_program);
     }
 }
 
-void OpenGLState::ApplyProgramPipeline() const {
+void OpenGLState::ApplyProgramPipeline() {
     if (UpdateValue(cur_state.draw.program_pipeline, draw.program_pipeline)) {
         glBindProgramPipeline(draw.program_pipeline);
     }
 }
 
-void OpenGLState::ApplyClipDistances() const {
+void OpenGLState::ApplyClipDistances() {
     for (std::size_t i = 0; i < clip_distance.size(); ++i) {
         Enable(GL_CLIP_DISTANCE0 + static_cast<GLenum>(i), cur_state.clip_distance[i],
                clip_distance[i]);
     }
 }
 
-void OpenGLState::ApplyPointSize() const {
+void OpenGLState::ApplyPointSize() {
     if (UpdateValue(cur_state.point.size, point.size)) {
         glPointSize(point.size);
     }
 }
 
-void OpenGLState::ApplyFragmentColorClamp() const {
+void OpenGLState::ApplyFragmentColorClamp() {
     if (UpdateValue(cur_state.fragment_color_clamp.enabled, fragment_color_clamp.enabled)) {
         glClampColor(GL_CLAMP_FRAGMENT_COLOR_ARB,
                      fragment_color_clamp.enabled ? GL_TRUE : GL_FALSE);
     }
 }
 
-void OpenGLState::ApplyMultisample() const {
+void OpenGLState::ApplyMultisample() {
     Enable(GL_SAMPLE_ALPHA_TO_COVERAGE, cur_state.multisample_control.alpha_to_coverage,
            multisample_control.alpha_to_coverage);
     Enable(GL_SAMPLE_ALPHA_TO_ONE, cur_state.multisample_control.alpha_to_one,
            multisample_control.alpha_to_one);
 }
 
-void OpenGLState::ApplyDepthClamp() const {
+void OpenGLState::ApplyDepthClamp() {
     if (depth_clamp.far_plane == cur_state.depth_clamp.far_plane &&
         depth_clamp.near_plane == cur_state.depth_clamp.near_plane) {
         return;
@@ -159,7 +159,7 @@ void OpenGLState::ApplyDepthClamp() const {
     Enable(GL_DEPTH_CLAMP, depth_clamp.far_plane || depth_clamp.near_plane);
 }
 
-void OpenGLState::ApplySRgb() const {
+void OpenGLState::ApplySRgb() {
     if (cur_state.framebuffer_srgb.enabled == framebuffer_srgb.enabled)
         return;
     cur_state.framebuffer_srgb.enabled = framebuffer_srgb.enabled;
@@ -170,7 +170,7 @@ void OpenGLState::ApplySRgb() const {
     }
 }
 
-void OpenGLState::ApplyCulling() const {
+void OpenGLState::ApplyCulling() {
     Enable(GL_CULL_FACE, cur_state.cull.enabled, cull.enabled);
 
     if (UpdateValue(cur_state.cull.mode, cull.mode)) {
@@ -182,7 +182,12 @@ void OpenGLState::ApplyCulling() const {
     }
 }
 
-void OpenGLState::ApplyColorMask() const {
+void OpenGLState::ApplyColorMask() {
+    if (!dirty.color_mask) {
+        return;
+    }
+    dirty.color_mask = false;
+
     for (std::size_t i = 0; i < Maxwell::NumRenderTargets; ++i) {
         const auto& updated = color_mask[i];
         auto& current = cur_state.color_mask[i];
@@ -197,7 +202,7 @@ void OpenGLState::ApplyColorMask() const {
     }
 }
 
-void OpenGLState::ApplyDepth() const {
+void OpenGLState::ApplyDepth() {
     Enable(GL_DEPTH_TEST, cur_state.depth.test_enabled, depth.test_enabled);
 
     if (cur_state.depth.test_func != depth.test_func) {
@@ -211,7 +216,7 @@ void OpenGLState::ApplyDepth() const {
     }
 }
 
-void OpenGLState::ApplyPrimitiveRestart() const {
+void OpenGLState::ApplyPrimitiveRestart() {
     Enable(GL_PRIMITIVE_RESTART, cur_state.primitive_restart.enabled, primitive_restart.enabled);
 
     if (cur_state.primitive_restart.index != primitive_restart.index) {
@@ -220,7 +225,12 @@ void OpenGLState::ApplyPrimitiveRestart() const {
     }
 }
 
-void OpenGLState::ApplyStencilTest() const {
+void OpenGLState::ApplyStencilTest() {
+    if (!dirty.stencil_state) {
+        return;
+    }
+    dirty.stencil_state = false;
+
     Enable(GL_STENCIL_TEST, cur_state.stencil.test_enabled, stencil.test_enabled);
 
     const auto ConfigStencil = [](GLenum face, const auto& config, auto& current) {
@@ -249,7 +259,7 @@ void OpenGLState::ApplyStencilTest() const {
     ConfigStencil(GL_BACK, stencil.back, cur_state.stencil.back);
 }
 
-void OpenGLState::ApplyViewport() const {
+void OpenGLState::ApplyViewport() {
     for (GLuint i = 0; i < static_cast<GLuint>(Maxwell::NumViewports); ++i) {
         const auto& updated = viewports[i];
         auto& current = cur_state.viewports[i];
@@ -286,7 +296,7 @@ void OpenGLState::ApplyViewport() const {
     }
 }
 
-void OpenGLState::ApplyGlobalBlending() const {
+void OpenGLState::ApplyGlobalBlending() {
     const Blend& updated = blend[0];
     Blend& current = cur_state.blend[0];
 
@@ -310,7 +320,7 @@ void OpenGLState::ApplyGlobalBlending() const {
     }
 }
 
-void OpenGLState::ApplyTargetBlending(std::size_t target, bool force) const {
+void OpenGLState::ApplyTargetBlending(std::size_t target, bool force) {
     const Blend& updated = blend[target];
     Blend& current = cur_state.blend[target];
 
@@ -334,7 +344,12 @@ void OpenGLState::ApplyTargetBlending(std::size_t target, bool force) const {
     }
 }
 
-void OpenGLState::ApplyBlending() const {
+void OpenGLState::ApplyBlending() {
+    if (!dirty.blend_state) {
+        return;
+    }
+    dirty.blend_state = false;
+
     if (independant_blend.enabled) {
         const bool force = independant_blend.enabled != cur_state.independant_blend.enabled;
         for (std::size_t target = 0; target < Maxwell::NumRenderTargets; ++target) {
@@ -353,7 +368,7 @@ void OpenGLState::ApplyBlending() const {
     }
 }
 
-void OpenGLState::ApplyLogicOp() const {
+void OpenGLState::ApplyLogicOp() {
     Enable(GL_COLOR_LOGIC_OP, cur_state.logic_op.enabled, logic_op.enabled);
 
     if (UpdateValue(cur_state.logic_op.operation, logic_op.operation)) {
@@ -361,7 +376,12 @@ void OpenGLState::ApplyLogicOp() const {
     }
 }
 
-void OpenGLState::ApplyPolygonOffset() const {
+void OpenGLState::ApplyPolygonOffset() {
+    if (!dirty.polygon_offset) {
+        return;
+    }
+    dirty.polygon_offset = false;
+
     Enable(GL_POLYGON_OFFSET_FILL, cur_state.polygon_offset.fill_enable,
            polygon_offset.fill_enable);
     Enable(GL_POLYGON_OFFSET_LINE, cur_state.polygon_offset.line_enable,
@@ -382,7 +402,7 @@ void OpenGLState::ApplyPolygonOffset() const {
     }
 }
 
-void OpenGLState::ApplyAlphaTest() const {
+void OpenGLState::ApplyAlphaTest() {
     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))) {
@@ -390,19 +410,19 @@ void OpenGLState::ApplyAlphaTest() const {
     }
 }
 
-void OpenGLState::ApplyTextures() const {
+void OpenGLState::ApplyTextures() {
     if (const auto update = UpdateArray(cur_state.textures, textures)) {
         glBindTextures(update->first, update->second, textures.data() + update->first);
     }
 }
 
-void OpenGLState::ApplySamplers() const {
+void OpenGLState::ApplySamplers() {
     if (const auto update = UpdateArray(cur_state.samplers, samplers)) {
         glBindSamplers(update->first, update->second, samplers.data() + update->first);
     }
 }
 
-void OpenGLState::ApplyImages() const {
+void OpenGLState::ApplyImages() {
     if (const auto update = UpdateArray(cur_state.images, images)) {
         glBindImageTextures(update->first, update->second, images.data() + update->first);
     }
@@ -418,32 +438,20 @@ void OpenGLState::Apply() {
     ApplyPointSize();
     ApplyFragmentColorClamp();
     ApplyMultisample();
-    if (dirty.color_mask) {
-        ApplyColorMask();
-        dirty.color_mask = false;
-    }
+    ApplyColorMask();
     ApplyDepthClamp();
     ApplyViewport();
-    if (dirty.stencil_state) {
-        ApplyStencilTest();
-        dirty.stencil_state = false;
-    }
+    ApplyStencilTest();
     ApplySRgb();
     ApplyCulling();
     ApplyDepth();
     ApplyPrimitiveRestart();
-    if (dirty.blend_state) {
-        ApplyBlending();
-        dirty.blend_state = false;
-    }
+    ApplyBlending();
     ApplyLogicOp();
     ApplyTextures();
     ApplySamplers();
     ApplyImages();
-    if (dirty.polygon_offset) {
-        ApplyPolygonOffset();
-        dirty.polygon_offset = false;
-    }
+    ApplyPolygonOffset();
     ApplyAlphaTest();
 }
 
diff --git a/src/video_core/renderer_opengl/gl_state.h b/src/video_core/renderer_opengl/gl_state.h
index b95f33613..cca25206b 100644
--- a/src/video_core/renderer_opengl/gl_state.h
+++ b/src/video_core/renderer_opengl/gl_state.h
@@ -157,31 +157,31 @@ public:
     /// Apply this state as the current OpenGL state
     void Apply();
 
-    void ApplyFramebufferState() const;
-    void ApplyVertexArrayState() const;
-    void ApplyShaderProgram() const;
-    void ApplyProgramPipeline() const;
-    void ApplyClipDistances() const;
-    void ApplyPointSize() const;
-    void ApplyFragmentColorClamp() const;
-    void ApplyMultisample() const;
-    void ApplySRgb() const;
-    void ApplyCulling() const;
-    void ApplyColorMask() const;
-    void ApplyDepth() const;
-    void ApplyPrimitiveRestart() const;
-    void ApplyStencilTest() const;
-    void ApplyViewport() const;
-    void ApplyTargetBlending(std::size_t target, bool force) const;
-    void ApplyGlobalBlending() const;
-    void ApplyBlending() const;
-    void ApplyLogicOp() const;
-    void ApplyTextures() const;
-    void ApplySamplers() const;
-    void ApplyImages() const;
-    void ApplyDepthClamp() const;
-    void ApplyPolygonOffset() const;
-    void ApplyAlphaTest() const;
+    void ApplyFramebufferState();
+    void ApplyVertexArrayState();
+    void ApplyShaderProgram();
+    void ApplyProgramPipeline();
+    void ApplyClipDistances();
+    void ApplyPointSize();
+    void ApplyFragmentColorClamp();
+    void ApplyMultisample();
+    void ApplySRgb();
+    void ApplyCulling();
+    void ApplyColorMask();
+    void ApplyDepth();
+    void ApplyPrimitiveRestart();
+    void ApplyStencilTest();
+    void ApplyViewport();
+    void ApplyTargetBlending(std::size_t target, bool force);
+    void ApplyGlobalBlending();
+    void ApplyBlending();
+    void ApplyLogicOp();
+    void ApplyTextures();
+    void ApplySamplers();
+    void ApplyImages();
+    void ApplyDepthClamp();
+    void ApplyPolygonOffset();
+    void ApplyAlphaTest();
 
     /// Resets any references to the given resource
     OpenGLState& UnbindTexture(GLuint handle);

From 3d0cde6a756a43902e58d8493228d7c18767e884 Mon Sep 17 00:00:00 2001
From: Rodrigo Locatti <reinuseslisp@airmail.cc>
Date: Wed, 30 Oct 2019 01:30:31 +0000
Subject: [PATCH 7/7] gl_state: Use std::array::fill instead of std::fill

Co-Authored-By: Mat M. <mathew1800@gmail.com>
---
 src/video_core/renderer_opengl/gl_state.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/video_core/renderer_opengl/gl_state.cpp b/src/video_core/renderer_opengl/gl_state.cpp
index c431a8635..f25148362 100644
--- a/src/video_core/renderer_opengl/gl_state.cpp
+++ b/src/video_core/renderer_opengl/gl_state.cpp
@@ -86,7 +86,7 @@ void Enable(GLenum cap, GLuint index, bool& current_value, bool new_value) {
 OpenGLState::OpenGLState() = default;
 
 void OpenGLState::SetDefaultViewports() {
-    std::fill(std::begin(viewports), std::end(viewports), Viewport{});
+    viewports.fill(Viewport{});
 
     depth_clamp.far_plane = false;
     depth_clamp.near_plane = false;