diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h
index 5cf62fb016..245410c950 100644
--- a/src/video_core/engines/maxwell_3d.h
+++ b/src/video_core/engines/maxwell_3d.h
@@ -354,10 +354,35 @@ public:
                     f32 scale_x;
                     f32 scale_y;
                     f32 scale_z;
-                    u32 translate_x;
-                    u32 translate_y;
-                    u32 translate_z;
+                    f32 translate_x;
+                    f32 translate_y;
+                    f32 translate_z;
                     INSERT_PADDING_WORDS(2);
+
+                    MathUtil::Rectangle<s32> GetRect() const {
+                        return {
+                            GetX(),               // left
+                            GetY() + GetHeight(), // top
+                            GetX() + GetWidth(),  // right
+                            GetY()                // bottom
+                        };
+                    };
+
+                    s32 GetX() const {
+                        return static_cast<s32>(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)));
+                    }
+
+                    s32 GetWidth() const {
+                        return static_cast<s32>(translate_x + std::fabs(scale_x)) - GetX();
+                    }
+
+                    s32 GetHeight() const {
+                        return static_cast<s32>(translate_y + std::fabs(scale_y)) - GetY();
+                    }
                 } viewport_transform[NumViewports];
 
                 struct {
@@ -371,15 +396,6 @@ public:
                     };
                     float depth_range_near;
                     float depth_range_far;
-
-                    MathUtil::Rectangle<s32> GetRect() const {
-                        return {
-                            static_cast<s32>(x),          // left
-                            static_cast<s32>(y + height), // top
-                            static_cast<s32>(x + width),  // right
-                            static_cast<s32>(y)           // bottom
-                        };
-                    };
                 } viewport[NumViewports];
 
                 INSERT_PADDING_WORDS(0x1D);
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index 35c1b18903..0a33868b79 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -298,7 +298,7 @@ void RasterizerOpenGL::DrawArrays() {
     const bool has_stencil = false;
     const bool using_color_fb = true;
     const bool using_depth_fb = false;
-    const MathUtil::Rectangle<s32> viewport_rect{regs.viewport[0].GetRect()};
+    const MathUtil::Rectangle<s32> viewport_rect{regs.viewport_transform[0].GetRect()};
 
     const bool write_color_fb =
         state.color_mask.red_enabled == GL_TRUE || state.color_mask.green_enabled == GL_TRUE ||
@@ -702,7 +702,7 @@ void RasterizerOpenGL::BindFramebufferSurfaces(const Surface& color_surface,
 
 void RasterizerOpenGL::SyncViewport(const MathUtil::Rectangle<u32>& surfaces_rect, u16 res_scale) {
     const auto& regs = Core::System().GetInstance().GPU().Maxwell3D().regs;
-    const MathUtil::Rectangle<s32> viewport_rect{regs.viewport[0].GetRect()};
+    const MathUtil::Rectangle<s32> viewport_rect{regs.viewport_transform[0].GetRect()};
 
     state.viewport.x = static_cast<GLint>(surfaces_rect.left) + viewport_rect.left * res_scale;
     state.viewport.y = static_cast<GLint>(surfaces_rect.bottom) + viewport_rect.bottom * res_scale;