diff options
| author | JMC47 <JMC4789@gmail.com> | 2022-04-24 15:00:42 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-04-24 15:00:42 -0400 |
| commit | c0488de4829cb3a7d1d76522cee821ec8ad03f95 (patch) | |
| tree | f780b8a71377afc24ccf79504f53d0c230510198 /Source/Core/VideoBackends/Software/Clipper.cpp | |
| parent | 8e7c84842595f64b63184933cf4f6d7c78bb82e8 (diff) | |
| parent | f3eff70e2fda8ad0894f34336584f331ab989b68 (diff) | |
Merge pull request #10251 from Pokechu22/negative-scissor
Rework scissor handling
Diffstat (limited to 'Source/Core/VideoBackends/Software/Clipper.cpp')
| -rw-r--r-- | Source/Core/VideoBackends/Software/Clipper.cpp | 29 |
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 |
