Skip to content
Snippets Groups Projects
Commit 5d55403f authored by Subv's avatar Subv
Browse files

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?
parent 049ce242
No related branches found
No related tags found
No related merge requests found
...@@ -354,10 +354,35 @@ public: ...@@ -354,10 +354,35 @@ public:
f32 scale_x; f32 scale_x;
f32 scale_y; f32 scale_y;
f32 scale_z; f32 scale_z;
u32 translate_x; f32 translate_x;
u32 translate_y; f32 translate_y;
u32 translate_z; f32 translate_z;
INSERT_PADDING_WORDS(2); 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]; } viewport_transform[NumViewports];
struct { struct {
...@@ -371,15 +396,6 @@ public: ...@@ -371,15 +396,6 @@ public:
}; };
float depth_range_near; float depth_range_near;
float depth_range_far; 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]; } viewport[NumViewports];
INSERT_PADDING_WORDS(0x1D); INSERT_PADDING_WORDS(0x1D);
......
...@@ -298,7 +298,7 @@ void RasterizerOpenGL::DrawArrays() { ...@@ -298,7 +298,7 @@ void RasterizerOpenGL::DrawArrays() {
const bool has_stencil = false; const bool has_stencil = false;
const bool using_color_fb = true; const bool using_color_fb = true;
const bool using_depth_fb = false; 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 = const bool write_color_fb =
state.color_mask.red_enabled == GL_TRUE || state.color_mask.green_enabled == GL_TRUE || 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, ...@@ -702,7 +702,7 @@ void RasterizerOpenGL::BindFramebufferSurfaces(const Surface& color_surface,
void RasterizerOpenGL::SyncViewport(const MathUtil::Rectangle<u32>& surfaces_rect, u16 res_scale) { void RasterizerOpenGL::SyncViewport(const MathUtil::Rectangle<u32>& surfaces_rect, u16 res_scale) {
const auto& regs = Core::System().GetInstance().GPU().Maxwell3D().regs; 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.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; state.viewport.y = static_cast<GLint>(surfaces_rect.bottom) + viewport_rect.bottom * res_scale;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment