From d3e433a38048c5d32c0929446008586e975ccd0e Mon Sep 17 00:00:00 2001
From: ReinUsesLisp <reinuseslisp@airmail.cc>
Date: Thu, 26 Dec 2019 01:50:38 -0300
Subject: [PATCH] gl_state: Remove viewport and depth range tracking

---
 src/video_core/engines/maxwell_3d.h           | 18 +++----
 .../renderer_opengl/gl_rasterizer.cpp         | 24 +++------
 .../renderer_opengl/gl_rasterizer.h           |  2 +-
 src/video_core/renderer_opengl/gl_state.cpp   | 29 ----------
 src/video_core/renderer_opengl/gl_state.h     | 12 -----
 .../renderer_opengl/renderer_opengl.cpp       | 53 ++++++++-----------
 .../renderer_opengl/renderer_opengl.h         |  2 -
 7 files changed, 39 insertions(+), 101 deletions(-)

diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h
index 3a641c1820..2134d6e4f7 100644
--- a/src/video_core/engines/maxwell_3d.h
+++ b/src/video_core/engines/maxwell_3d.h
@@ -574,7 +574,7 @@ public:
             f32 translate_z;
             INSERT_UNION_PADDING_WORDS(2);
 
-            Common::Rectangle<s32> GetRect() const {
+            Common::Rectangle<f32> GetRect() const {
                 return {
                     GetX(),               // left
                     GetY() + GetHeight(), // top
@@ -583,20 +583,20 @@ public:
                 };
             };
 
-            s32 GetX() const {
-                return static_cast<s32>(std::max(0.0f, translate_x - std::fabs(scale_x)));
+            f32 GetX() const {
+                return std::max(0.0f, translate_x - std::fabs(scale_x));
             }
 
-            s32 GetY() const {
-                return static_cast<s32>(std::max(0.0f, translate_y - std::fabs(scale_y)));
+            f32 GetY() const {
+                return std::max(0.0f, translate_y - std::fabs(scale_y));
             }
 
-            s32 GetWidth() const {
-                return static_cast<s32>(translate_x + std::fabs(scale_x)) - GetX();
+            f32 GetWidth() const {
+                return translate_x + std::fabs(scale_x) - GetX();
             }
 
-            s32 GetHeight() const {
-                return static_cast<s32>(translate_y + std::fabs(scale_y)) - GetY();
+            f32 GetHeight() const {
+                return translate_y + std::fabs(scale_y) - GetY();
             }
         };
 
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index 3ccedcf55d..63295761ad 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -360,7 +360,6 @@ void RasterizerOpenGL::ConfigureFramebuffers() {
     texture_cache.GuardRenderTargets(false);
 
     state.draw.draw_framebuffer = framebuffer_cache.GetFramebuffer(key);
-    SyncViewport(state);
 }
 
 void RasterizerOpenGL::ConfigureClearFramebuffer(OpenGLState& current_state, bool using_color_fb,
@@ -405,7 +404,6 @@ void RasterizerOpenGL::Clear() {
     SCOPE_EXIT({ prev_state.Apply(); });
 
     OpenGLState clear_state{OpenGLState::GetCurState()};
-    clear_state.SetDefaultViewports();
     if (regs.clear_buffers.R || regs.clear_buffers.G || regs.clear_buffers.B ||
         regs.clear_buffers.A) {
         use_color = true;
@@ -464,7 +462,6 @@ void RasterizerOpenGL::Clear() {
 
     ConfigureClearFramebuffer(clear_state, use_color, use_depth, use_stencil);
 
-    SyncViewport(clear_state);
     SyncRasterizeEnable(clear_state);
     if (regs.clear_flags.scissor) {
         SyncScissorTest();
@@ -496,6 +493,7 @@ void RasterizerOpenGL::Draw(bool is_indexed, bool is_instanced) {
 
     query_cache.UpdateCounters();
 
+    SyncViewport();
     SyncRasterizeEnable(state);
     SyncColorMask();
     SyncFragmentColorClampState();
@@ -935,22 +933,14 @@ void RasterizerOpenGL::SetupImage(u32 binding, const Tegra::Texture::TICEntry& t
     state.images[binding] = view->GetTexture();
 }
 
-void RasterizerOpenGL::SyncViewport(OpenGLState& current_state) {
+void RasterizerOpenGL::SyncViewport() {
     const auto& regs = system.GPU().Maxwell3D().regs;
-    const bool geometry_shaders_enabled =
-        regs.IsShaderConfigEnabled(static_cast<size_t>(Maxwell::ShaderProgram::Geometry));
-    const std::size_t viewport_count =
-        geometry_shaders_enabled ? Tegra::Engines::Maxwell3D::Regs::NumViewports : 1;
-    for (std::size_t i = 0; i < viewport_count; i++) {
-        auto& viewport = current_state.viewports[i];
+    for (std::size_t i = 0; i < Maxwell::NumViewports; ++i) {
         const auto& src = regs.viewports[i];
-        const Common::Rectangle<s32> viewport_rect{regs.viewport_transform[i].GetRect()};
-        viewport.x = viewport_rect.left;
-        viewport.y = viewport_rect.bottom;
-        viewport.width = viewport_rect.GetWidth();
-        viewport.height = viewport_rect.GetHeight();
-        viewport.depth_range_far = src.depth_range_far;
-        viewport.depth_range_near = src.depth_range_near;
+        const Common::Rectangle<f32> rect{regs.viewport_transform[i].GetRect()};
+        glViewportIndexedf(static_cast<GLuint>(i), rect.left, rect.bottom, rect.GetWidth(),
+                           rect.GetHeight());
+        glDepthRangef(src.depth_range_near, src.depth_range_far);
     }
 
     bool flip_y = false;
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h
index 0450657a79..d1d0aec326 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer.h
@@ -130,7 +130,7 @@ private:
                     const GLShader::ImageEntry& entry);
 
     /// Syncs the viewport and depth range to match the guest state
-    void SyncViewport(OpenGLState& current_state);
+    void SyncViewport();
 
     /// Syncs the depth clamp state
     void SyncDepthClamp();
diff --git a/src/video_core/renderer_opengl/gl_state.cpp b/src/video_core/renderer_opengl/gl_state.cpp
index dcea16fd3d..7c08cc3c21 100644
--- a/src/video_core/renderer_opengl/gl_state.cpp
+++ b/src/video_core/renderer_opengl/gl_state.cpp
@@ -85,10 +85,6 @@ void Enable(GLenum cap, GLuint index, bool& current_value, bool new_value) {
 
 OpenGLState::OpenGLState() = default;
 
-void OpenGLState::SetDefaultViewports() {
-    viewports.fill(Viewport{});
-}
-
 void OpenGLState::ApplyFramebufferState() {
     if (UpdateValue(cur_state.draw.read_framebuffer, draw.read_framebuffer)) {
         glBindFramebuffer(GL_READ_FRAMEBUFFER, draw.read_framebuffer);
@@ -150,30 +146,6 @@ void OpenGLState::ApplyStencilTest() {
     ConfigStencil(GL_BACK, stencil.back, cur_state.stencil.back);
 }
 
-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];
-
-        if (current.x != updated.x || current.y != updated.y || current.width != updated.width ||
-            current.height != updated.height) {
-            current.x = updated.x;
-            current.y = updated.y;
-            current.width = updated.width;
-            current.height = updated.height;
-            glViewportIndexedf(i, static_cast<GLfloat>(updated.x), static_cast<GLfloat>(updated.y),
-                               static_cast<GLfloat>(updated.width),
-                               static_cast<GLfloat>(updated.height));
-        }
-        if (current.depth_range_near != updated.depth_range_near ||
-            current.depth_range_far != updated.depth_range_far) {
-            current.depth_range_near = updated.depth_range_near;
-            current.depth_range_far = updated.depth_range_far;
-            glDepthRangeIndexed(i, updated.depth_range_near, updated.depth_range_far);
-        }
-    }
-}
-
 void OpenGLState::ApplyGlobalBlending() {
     const Blend& updated = blend[0];
     Blend& current = cur_state.blend[0];
@@ -283,7 +255,6 @@ void OpenGLState::Apply() {
     ApplyProgramPipeline();
     ApplyClipDistances();
     ApplyRasterizerDiscard();
-    ApplyViewport();
     ApplyStencilTest();
     ApplyBlending();
     ApplyTextures();
diff --git a/src/video_core/renderer_opengl/gl_state.h b/src/video_core/renderer_opengl/gl_state.h
index 44eb35dd52..b4c957c0df 100644
--- a/src/video_core/renderer_opengl/gl_state.h
+++ b/src/video_core/renderer_opengl/gl_state.h
@@ -56,16 +56,6 @@ public:
         GLuint program_pipeline = 0; // GL_PROGRAM_PIPELINE_BINDING
     } draw;
 
-    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
-    };
-    std::array<Viewport, Tegra::Engines::Maxwell3D::Regs::NumViewports> viewports;
-
     std::array<bool, 8> clip_distance = {}; // GL_CLIP_DISTANCE
 
     struct {
@@ -82,7 +72,6 @@ public:
         return cur_state;
     }
 
-    void SetDefaultViewports();
     /// Apply this state as the current OpenGL state
     void Apply();
 
@@ -92,7 +81,6 @@ public:
     void ApplyClipDistances();
     void ApplyRasterizerDiscard();
     void ApplyStencilTest();
-    void ApplyViewport();
     void ApplyTargetBlending(std::size_t target, bool force);
     void ApplyGlobalBlending();
     void ApplyBlending();
diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp
index 0d5ef9ef66..12e820979d 100644
--- a/src/video_core/renderer_opengl/renderer_opengl.cpp
+++ b/src/video_core/renderer_opengl/renderer_opengl.cpp
@@ -205,8 +205,8 @@ constexpr GLint TexCoordLocation = 1;
 constexpr GLint ModelViewMatrixLocation = 0;
 
 struct ScreenRectVertex {
-    constexpr ScreenRectVertex(GLfloat x, GLfloat y, GLfloat u, GLfloat v)
-        : position{{x, y}}, tex_coord{{u, v}} {}
+    constexpr ScreenRectVertex(u32 x, u32 y, GLfloat u, GLfloat v)
+        : position{{static_cast<GLfloat>(x), static_cast<GLfloat>(y)}}, tex_coord{{u, v}} {}
 
     std::array<GLfloat, 2> position;
     std::array<GLfloat, 2> tex_coord;
@@ -514,8 +514,18 @@ void RendererOpenGL::ConfigureFramebufferTexture(TextureInfo& texture,
     glTextureStorage2D(texture.resource.handle, 1, internal_format, texture.width, texture.height);
 }
 
-void RendererOpenGL::DrawScreenTriangles(const ScreenInfo& screen_info, float x, float y, float w,
-                                         float h) {
+void RendererOpenGL::DrawScreen(const Layout::FramebufferLayout& layout) {
+    if (renderer_settings.set_background_color) {
+        // Update background color before drawing
+        glClearColor(Settings::values.bg_red, Settings::values.bg_green, Settings::values.bg_blue,
+                     0.0f);
+    }
+
+    // Set projection matrix
+    const std::array ortho_matrix =
+        MakeOrthographicMatrix(static_cast<float>(layout.width), static_cast<float>(layout.height));
+    glUniformMatrix3x2fv(ModelViewMatrixLocation, 1, GL_FALSE, ortho_matrix.data());
+
     const auto& texcoords = screen_info.display_texcoords;
     auto left = texcoords.left;
     auto right = texcoords.right;
@@ -547,12 +557,14 @@ void RendererOpenGL::DrawScreenTriangles(const ScreenInfo& screen_info, float x,
                   static_cast<f32>(screen_info.texture.height);
     }
 
+    const auto& screen = layout.screen;
     const std::array vertices = {
-        ScreenRectVertex(x, y, texcoords.top * scale_u, left * scale_v),
-        ScreenRectVertex(x + w, y, texcoords.bottom * scale_u, left * scale_v),
-        ScreenRectVertex(x, y + h, texcoords.top * scale_u, right * scale_v),
-        ScreenRectVertex(x + w, y + h, texcoords.bottom * scale_u, right * scale_v),
+        ScreenRectVertex(screen.left, screen.top, texcoords.top * scale_u, left * scale_v),
+        ScreenRectVertex(screen.right, screen.top, texcoords.bottom * scale_u, left * scale_v),
+        ScreenRectVertex(screen.left, screen.bottom, texcoords.top * scale_u, right * scale_v),
+        ScreenRectVertex(screen.right, screen.bottom, texcoords.bottom * scale_u, right * scale_v),
     };
+    glNamedBufferSubData(vertex_buffer.handle, 0, sizeof(vertices), std::data(vertices));
 
     state.textures[0] = screen_info.display_texture;
     state.Apply();
@@ -572,6 +584,7 @@ void RendererOpenGL::DrawScreenTriangles(const ScreenInfo& screen_info, float x,
     glCullFace(GL_BACK);
     glFrontFace(GL_CW);
     glColorMaski(0, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+    glViewport(0, 0, layout.width, layout.height);
 
     glVertexAttribFormat(PositionLocation, 2, GL_FLOAT, GL_FALSE,
                          offsetof(ScreenRectVertex, position));
@@ -581,7 +594,7 @@ void RendererOpenGL::DrawScreenTriangles(const ScreenInfo& screen_info, float x,
     glVertexAttribBinding(TexCoordLocation, 0);
     glBindVertexBuffer(0, vertex_buffer.handle, 0, sizeof(ScreenRectVertex));
 
-    glNamedBufferSubData(vertex_buffer.handle, 0, sizeof(vertices), std::data(vertices));
+    glClear(GL_COLOR_BUFFER_BIT);
     glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
 
     // Restore default state
@@ -589,28 +602,6 @@ void RendererOpenGL::DrawScreenTriangles(const ScreenInfo& screen_info, float x,
     state.Apply();
 }
 
-void RendererOpenGL::DrawScreen(const Layout::FramebufferLayout& layout) {
-    if (renderer_settings.set_background_color) {
-        // Update background color before drawing
-        glClearColor(Settings::values.bg_red, Settings::values.bg_green, Settings::values.bg_blue,
-                     0.0f);
-    }
-
-    const auto& screen = layout.screen;
-
-    glViewport(0, 0, layout.width, layout.height);
-    glClear(GL_COLOR_BUFFER_BIT);
-
-    // Set projection matrix
-    const std::array ortho_matrix =
-        MakeOrthographicMatrix(static_cast<float>(layout.width), static_cast<float>(layout.height));
-    glUniformMatrix3x2fv(ModelViewMatrixLocation, 1, GL_FALSE, ortho_matrix.data());
-
-    DrawScreenTriangles(screen_info, static_cast<float>(screen.left),
-                        static_cast<float>(screen.top), static_cast<float>(screen.GetWidth()),
-                        static_cast<float>(screen.GetHeight()));
-}
-
 void RendererOpenGL::TryPresent(int timeout_ms) {
     const auto& layout = render_window.GetFramebufferLayout();
     auto frame = frame_mailbox->TryGetPresentFrame(timeout_ms);
diff --git a/src/video_core/renderer_opengl/renderer_opengl.h b/src/video_core/renderer_opengl/renderer_opengl.h
index 978a4d0eb6..42a2141d85 100644
--- a/src/video_core/renderer_opengl/renderer_opengl.h
+++ b/src/video_core/renderer_opengl/renderer_opengl.h
@@ -76,8 +76,6 @@ private:
     /// Draws the emulated screens to the emulator window.
     void DrawScreen(const Layout::FramebufferLayout& layout);
 
-    void DrawScreenTriangles(const ScreenInfo& screen_info, float x, float y, float w, float h);
-
     void RenderScreenshot();
 
     /// Loads framebuffer from emulated memory into the active OpenGL texture.