summaryrefslogtreecommitdiff
path: root/Source/Core/VideoBackends/Software/Clipper.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/Core/VideoBackends/Software/Clipper.cpp')
-rw-r--r--Source/Core/VideoBackends/Software/Clipper.cpp29
1 files changed, 22 insertions, 7 deletions
diff --git a/Source/Core/VideoBackends/Software/Clipper.cpp b/Source/Core/VideoBackends/Software/Clipper.cpp
index f13ebb90b7..ae6b60f1ee 100644
--- a/Source/Core/VideoBackends/Software/Clipper.cpp
+++ b/Source/Core/VideoBackends/Software/Clipper.cpp
@@ -307,7 +307,7 @@ void ProcessTriangle(OutputVertexData* v0, OutputVertexData* v1, OutputVertexDat
PerspectiveDivide(v0);
PerspectiveDivide(v1);
PerspectiveDivide(v2);
- Rasterizer::UpdateZSlope(v0, v1, v2);
+ Rasterizer::UpdateZSlope(v0, v1, v2, bpmem.scissorOffset.x * 2, bpmem.scissorOffset.y * 2);
INCSTAT(g_stats.this_frame.num_triangles_culled)
return;
}
@@ -320,7 +320,7 @@ void ProcessTriangle(OutputVertexData* v0, OutputVertexData* v1, OutputVertexDat
PerspectiveDivide(v0);
PerspectiveDivide(v2);
PerspectiveDivide(v1);
- Rasterizer::UpdateZSlope(v0, v2, v1);
+ Rasterizer::UpdateZSlope(v0, v2, v1, bpmem.scissorOffset.x * 2, bpmem.scissorOffset.y * 2);
INCSTAT(g_stats.this_frame.num_triangles_culled)
return;
}
@@ -345,7 +345,24 @@ void ProcessTriangle(OutputVertexData* v0, OutputVertexData* v1, OutputVertexDat
Vertices[2] = v2;
}
- ClipTriangle(indices, &numIndices);
+ // TODO: behavior when disable_clipping_detection is set doesn't quite match actual hardware;
+ // there does still seem to be a maximum size after which things are clipped. Also, currently
+ // when clipping is enabled triangles are clipped to exactly the viewport, but on hardware there
+ // is a guardband (and with certain scissor configurations, things can show up in it)
+ // Mario Party 8 in widescreen breaks without this: https://bugs.dolphin-emu.org/issues/12769
+ bool skip_clipping = false;
+ if (xfmem.clipDisable.disable_clipping_detection)
+ {
+ // If any w coordinate is negative, then the perspective divide will flip coordinates, breaking
+ // various assumptions (including backface). So, we still need to do clipping in that case.
+ // This isn't the actual condition hardware uses.
+ if (Vertices[0]->projectedPosition.w >= 0 && Vertices[1]->projectedPosition.w >= 0 &&
+ Vertices[2]->projectedPosition.w >= 0)
+ skip_clipping = true;
+ }
+
+ if (!skip_clipping)
+ ClipTriangle(indices, &numIndices);
for (int i = 0; i + 3 <= numIndices; i += 3)
{
@@ -533,10 +550,8 @@ void PerspectiveDivide(OutputVertexData* vertex)
Vec3& screen = vertex->screenPosition;
float wInverse = 1.0f / projected.w;
- screen.x =
- projected.x * wInverse * xfmem.viewport.wd + xfmem.viewport.xOrig - bpmem.scissorOffset.x * 2;
- screen.y =
- projected.y * wInverse * xfmem.viewport.ht + xfmem.viewport.yOrig - bpmem.scissorOffset.y * 2;
+ screen.x = projected.x * wInverse * xfmem.viewport.wd + xfmem.viewport.xOrig;
+ screen.y = projected.y * wInverse * xfmem.viewport.ht + xfmem.viewport.yOrig;
screen.z = projected.z * wInverse * xfmem.viewport.zRange + xfmem.viewport.farZ;
}
} // namespace Clipper