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.
This commit is contained in:
Techjar 2021-06-05 06:47:04 -04:00
parent 638909aec6
commit 4866002c9b
2 changed files with 9 additions and 27 deletions

View File

@ -856,30 +856,12 @@ void Renderer::SetScissorRect(const MathUtil::Rectangle<int>& rc)
u16 Renderer::BBoxReadImpl(int index) u16 Renderer::BBoxReadImpl(int index)
{ {
// swap 2 and 3 for top/bottom return static_cast<u16>(BoundingBox::Get(index));
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<u16>(value);
} }
void Renderer::BBoxWriteImpl(int index, u16 value) void Renderer::BBoxWriteImpl(int index, u16 value)
{ {
s32 swapped_value = value; BoundingBox::Set(index, value);
if (index >= 2)
{
index ^= 1; // swap 2 and 3 for top/bottom
swapped_value = EFB_HEIGHT - swapped_value;
}
BoundingBox::Set(index, swapped_value);
} }
void Renderer::BBoxFlushImpl() void Renderer::BBoxFlushImpl()

View File

@ -499,16 +499,15 @@ void UpdateBoundingBox(float2 rawpos) {{
// such that width = right - left + 1. This has been verified on hardware. // such that width = right - left + 1. This has been verified on hardware.
int2 pos = int2(rawpos * cefbscale); 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 // 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. // 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_tl = pos & ~1;
int2 pos_br = pos | 1; int2 pos_br = pos | 1;
#endif
#ifdef SUPPORTS_SUBGROUP_REDUCTION #ifdef SUPPORTS_SUBGROUP_REDUCTION
if (CAN_USE_SUBGROUP_REDUCTION) {{ if (CAN_USE_SUBGROUP_REDUCTION) {{
@ -526,7 +525,8 @@ void UpdateBoundingBox(float2 rawpos) {{
#endif #endif
}} }}
)"); )",
fmt::arg("efb_height", EFB_HEIGHT));
} }
} }