summaryrefslogtreecommitdiff
path: root/Source/Core/VideoCommon/BPFunctions.cpp
diff options
context:
space:
mode:
authorPokechu22 <Pokechu022@gmail.com>2022-01-26 12:09:00 -0800
committerPokechu22 <Pokechu022@gmail.com>2022-04-08 18:30:59 -0700
commit4e9a3147763ce742718092cf0d05ed7d9a6b19ad (patch)
tree0f0447240463efefcaaa6d1db5d6769234c531d0 /Source/Core/VideoCommon/BPFunctions.cpp
parentdbb857b175c6687740b337147ce9f4d0e3fc52aa (diff)
Round viewport coordinates when vertex rounding is enabled
This should fix https://bugs.dolphin-emu.org/issues/9105
Diffstat (limited to 'Source/Core/VideoCommon/BPFunctions.cpp')
-rw-r--r--Source/Core/VideoCommon/BPFunctions.cpp26
1 files changed, 20 insertions, 6 deletions
diff --git a/Source/Core/VideoCommon/BPFunctions.cpp b/Source/Core/VideoCommon/BPFunctions.cpp
index ba2bf6e0d3..fe3867c29c 100644
--- a/Source/Core/VideoCommon/BPFunctions.cpp
+++ b/Source/Core/VideoCommon/BPFunctions.cpp
@@ -4,6 +4,7 @@
#include "VideoCommon/BPFunctions.h"
#include <algorithm>
+#include <cmath>
#include <string_view>
#include "Common/CommonTypes.h"
@@ -74,13 +75,26 @@ void SetScissor()
void SetViewport()
{
- s32 xoff = bpmem.scissorOffset.x * 2;
- s32 yoff = bpmem.scissorOffset.y * 2;
- float x = g_renderer->EFBToScaledXf(xfmem.viewport.xOrig - xfmem.viewport.wd - xoff);
- float y = g_renderer->EFBToScaledYf(xfmem.viewport.yOrig + xfmem.viewport.ht - yoff);
+ const s32 xoff = bpmem.scissorOffset.x * 2;
+ const s32 yoff = bpmem.scissorOffset.y * 2;
+ float raw_x = xfmem.viewport.xOrig - xfmem.viewport.wd - xoff;
+ float raw_y = xfmem.viewport.yOrig + xfmem.viewport.ht - yoff;
+ float raw_width = 2.0f * xfmem.viewport.wd;
+ float raw_height = -2.0f * xfmem.viewport.ht;
+ if (g_ActiveConfig.UseVertexRounding())
+ {
+ // Round the viewport to match full 1x IR pixels as well.
+ // This eliminates a line in the archery mode in Wii Sports Resort at 3x IR and higher.
+ raw_x = std::round(raw_x);
+ raw_y = std::round(raw_y);
+ raw_width = std::round(raw_width);
+ raw_height = std::round(raw_height);
+ }
- float width = g_renderer->EFBToScaledXf(2.0f * xfmem.viewport.wd);
- float height = g_renderer->EFBToScaledYf(-2.0f * xfmem.viewport.ht);
+ float x = g_renderer->EFBToScaledXf(raw_x);
+ float y = g_renderer->EFBToScaledYf(raw_y);
+ float width = g_renderer->EFBToScaledXf(raw_width);
+ float height = g_renderer->EFBToScaledYf(raw_height);
float min_depth = (xfmem.viewport.farZ - xfmem.viewport.zRange) / 16777216.0f;
float max_depth = xfmem.viewport.farZ / 16777216.0f;
if (width < 0.f)