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:
parent
638909aec6
commit
4866002c9b
|
@ -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()
|
||||||
|
|
|
@ -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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue