From 5d55403f94233f7645a426897d350cc557aaaa9d Mon Sep 17 00:00:00 2001 From: Subv Date: Mon, 4 Jun 2018 16:36:54 -0500 Subject: GPU: Calculate the correct viewport dimensions based on the scale and translate registers. This is how nouveau calculates the viewport width and height. For some reason some games set 0xFFFF in the VIEWPORT_HORIZ and VIEWPORT_VERT registers, maybe those are a misnomer and actually refer to something else? --- src/video_core/engines/maxwell_3d.h | 40 +++++++++++++++++------- src/video_core/renderer_opengl/gl_rasterizer.cpp | 4 +-- 2 files changed, 30 insertions(+), 14 deletions(-) diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h index 5cf62fb01..245410c95 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 GetRect() const { + return { + GetX(), // left + GetY() + GetHeight(), // top + GetX() + GetWidth(), // right + GetY() // bottom + }; + }; + + s32 GetX() const { + return static_cast(std::max(0.0f, translate_x - std::fabs(scale_x))); + } + + s32 GetY() const { + return static_cast(std::max(0.0f, translate_y - std::fabs(scale_y))); + } + + s32 GetWidth() const { + return static_cast(translate_x + std::fabs(scale_x)) - GetX(); + } + + s32 GetHeight() const { + return static_cast(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 GetRect() const { - return { - static_cast(x), // left - static_cast(y + height), // top - static_cast(x + width), // right - static_cast(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 35c1b1890..0a33868b7 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 viewport_rect{regs.viewport[0].GetRect()}; + const MathUtil::Rectangle 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& surfaces_rect, u16 res_scale) { const auto& regs = Core::System().GetInstance().GPU().Maxwell3D().regs; - const MathUtil::Rectangle viewport_rect{regs.viewport[0].GetRect()}; + const MathUtil::Rectangle viewport_rect{regs.viewport_transform[0].GetRect()}; state.viewport.x = static_cast(surfaces_rect.left) + viewport_rect.left * res_scale; state.viewport.y = static_cast(surfaces_rect.bottom) + viewport_rect.bottom * res_scale; -- cgit v1.2.3