From 4866002c9bf6d4438087c4b53c100d7cf1271084 Mon Sep 17 00:00:00 2001 From: Techjar Date: Sat, 5 Jun 2021 06:47:04 -0400 Subject: [PATCH] VideoCommon: Perform OpenGL bounding box inversion in pixel shader Running the min/max operation on the upside down, quad-rounded pixel coordinates before inverting them to the standard upper-left origin produces wrong results. Therefore, we need to do the inversion before rounding to pixel quads. --- Source/Core/VideoBackends/OGL/OGLRender.cpp | 22 ++------------------- Source/Core/VideoCommon/PixelShaderGen.cpp | 14 ++++++------- 2 files changed, 9 insertions(+), 27 deletions(-) diff --git a/Source/Core/VideoBackends/OGL/OGLRender.cpp b/Source/Core/VideoBackends/OGL/OGLRender.cpp index d3435c51d5..bf0650f961 100644 --- a/Source/Core/VideoBackends/OGL/OGLRender.cpp +++ b/Source/Core/VideoBackends/OGL/OGLRender.cpp @@ -856,30 +856,12 @@ void Renderer::SetScissorRect(const MathUtil::Rectangle& rc) u16 Renderer::BBoxReadImpl(int index) { - // swap 2 and 3 for top/bottom - if (index >= 2) - index ^= 1; - - int value = BoundingBox::Get(index); - if (index >= 2) - { - // up/down -- we have to swap up and down - value = EFB_HEIGHT - value; - } - - return static_cast(value); + return static_cast(BoundingBox::Get(index)); } void Renderer::BBoxWriteImpl(int index, u16 value) { - s32 swapped_value = value; - if (index >= 2) - { - index ^= 1; // swap 2 and 3 for top/bottom - swapped_value = EFB_HEIGHT - swapped_value; - } - - BoundingBox::Set(index, swapped_value); + BoundingBox::Set(index, value); } void Renderer::BBoxFlushImpl() diff --git a/Source/Core/VideoCommon/PixelShaderGen.cpp b/Source/Core/VideoCommon/PixelShaderGen.cpp index 80d6c09573..37e856ae42 100644 --- a/Source/Core/VideoCommon/PixelShaderGen.cpp +++ b/Source/Core/VideoCommon/PixelShaderGen.cpp @@ -499,16 +499,15 @@ void UpdateBoundingBox(float2 rawpos) {{ // such that width = right - left + 1. This has been verified on hardware. int2 pos = int2(rawpos * cefbscale); +#ifdef API_OPENGL + // We need to invert the Y coordinate due to OpenGL's lower-left origin + pos.y = {efb_height} - pos.y - 1; +#endif + // The GC/Wii GPU rasterizes in 2x2 pixel groups, so bounding box values will be rounded to the // extents of these groups, rather than the exact pixel. -#ifdef API_OPENGL - // Need to flip the operands for Y on OpenGL because of lower-left origin. - int2 pos_tl = int2(pos.x & ~1, pos.y | 1); - int2 pos_br = int2(pos.x | 1, pos.y & ~1); -#else int2 pos_tl = pos & ~1; int2 pos_br = pos | 1; -#endif #ifdef SUPPORTS_SUBGROUP_REDUCTION if (CAN_USE_SUBGROUP_REDUCTION) {{ @@ -526,7 +525,8 @@ void UpdateBoundingBox(float2 rawpos) {{ #endif }} -)"); +)", + fmt::arg("efb_height", EFB_HEIGHT)); } }