Skip to content

Commit

Permalink
VideoBackends: Account for pixel quads in bounding box calculation
Browse files Browse the repository at this point in the history
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. To account for this, we'll round the top/left down to even and
the bottom/right up to odd. I have verified that the values resulting
from this change exactly match a real Wii.
  • Loading branch information
Techjar committed May 22, 2021
1 parent 40a4715 commit 7d50689
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 4 deletions.
11 changes: 10 additions & 1 deletion Source/Core/VideoBackends/D3D/D3DRender.cpp
Expand Up @@ -266,7 +266,16 @@ void Renderer::UnbindTexture(const AbstractTexture* texture)

u16 Renderer::BBoxRead(int index)
{
return static_cast<u16>(BBox::Get(index));
u16 value = static_cast<u16>(BBox::Get(index));

// 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.
if (index == 0 || index == 2)
value &= ~1;
else
value |= 1;

return value;
}

void Renderer::BBoxWrite(int index, u16 value)
Expand Down
11 changes: 10 additions & 1 deletion Source/Core/VideoBackends/D3D12/D3D12Renderer.cpp
Expand Up @@ -108,7 +108,16 @@ std::unique_ptr<AbstractPipeline> Renderer::CreatePipeline(const AbstractPipelin

u16 Renderer::BBoxRead(int index)
{
return static_cast<u16>(m_bounding_box->Get(index));
u16 value = static_cast<u16>(m_bounding_box->Get(index));

// 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.
if (index == 0 || index == 2)
value &= ~1;
else
value |= 1;

return value;
}

void Renderer::BBoxWrite(int index, u16 value)
Expand Down
7 changes: 7 additions & 0 deletions Source/Core/VideoBackends/OGL/OGLRender.cpp
Expand Up @@ -867,6 +867,13 @@ u16 Renderer::BBoxRead(int index)
value = EFB_HEIGHT - value;
}

// 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.
if (index == 0 || index == 3)
value &= ~1;
else
value |= 1;

return static_cast<u16>(value);
}

Expand Down
11 changes: 10 additions & 1 deletion Source/Core/VideoBackends/Software/SWRenderer.cpp
Expand Up @@ -128,7 +128,16 @@ u32 SWRenderer::AccessEFB(EFBAccessType type, u32 x, u32 y, u32 InputData)

u16 SWRenderer::BBoxRead(int index)
{
return BoundingBox::GetCoordinate(static_cast<BoundingBox::Coordinate>(index));
u16 value = BoundingBox::GetCoordinate(static_cast<BoundingBox::Coordinate>(index));

// 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.
if (index == 0 || index == 2)
value &= ~1;
else
value |= 1;

return value;
}

void SWRenderer::BBoxWrite(int index, u16 value)
Expand Down
11 changes: 10 additions & 1 deletion Source/Core/VideoBackends/Vulkan/VKRenderer.cpp
Expand Up @@ -133,7 +133,16 @@ void Renderer::SetPipeline(const AbstractPipeline* pipeline)

u16 Renderer::BBoxRead(int index)
{
return static_cast<u16>(m_bounding_box->Get(index));
u16 value = static_cast<u16>(m_bounding_box->Get(index));

// 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.
if (index == 0 || index == 2)
value &= ~1;
else
value |= 1;

return value;
}

void Renderer::BBoxWrite(int index, u16 value)
Expand Down

0 comments on commit 7d50689

Please sign in to comment.