summaryrefslogtreecommitdiff
path: root/Source/Core/VideoBackends/Software/Rasterizer.cpp
diff options
context:
space:
mode:
authorPokechu22 <Pokechu022@gmail.com>2021-11-29 17:51:02 -0800
committerPokechu22 <Pokechu022@gmail.com>2022-04-08 20:05:32 -0700
commit59f299d5d6cabddacf8e7d80f6f53987e4767c22 (patch)
tree18201f3884d4995e19e351d18104eceeae234040 /Source/Core/VideoBackends/Software/Rasterizer.cpp
parent164e0f742d544f369f7a45e20815f22056a7d866 (diff)
Software: Fix zfreeze with CullMode::All
Diffstat (limited to 'Source/Core/VideoBackends/Software/Rasterizer.cpp')
-rw-r--r--Source/Core/VideoBackends/Software/Rasterizer.cpp27
1 files changed, 17 insertions, 10 deletions
diff --git a/Source/Core/VideoBackends/Software/Rasterizer.cpp b/Source/Core/VideoBackends/Software/Rasterizer.cpp
index b3d0dd3fdb..726692138c 100644
--- a/Source/Core/VideoBackends/Software/Rasterizer.cpp
+++ b/Source/Core/VideoBackends/Software/Rasterizer.cpp
@@ -301,11 +301,27 @@ static void BuildBlock(s32 blockX, s32 blockY)
}
}
+void UpdateZSlope(const OutputVertexData* v0, const OutputVertexData* v1,
+ const OutputVertexData* v2)
+{
+ if (!bpmem.genMode.zfreeze)
+ {
+ const s32 X1 = iround(16.0f * v0->screenPosition[0]) - 9;
+ const s32 Y1 = iround(16.0f * v0->screenPosition[1]) - 9;
+ const SlopeContext ctx(v0, v1, v2, (X1 + 0xF) >> 4, (Y1 + 0xF) >> 4);
+ ZSlope = Slope(v0->screenPosition.z, v1->screenPosition.z, v2->screenPosition.z, ctx);
+ }
+}
+
void DrawTriangleFrontFace(const OutputVertexData* v0, const OutputVertexData* v1,
const OutputVertexData* v2)
{
INCSTAT(g_stats.this_frame.num_triangles_drawn);
+ // The zslope should be updated now, even if the triangle is rejected by the scissor test, as
+ // zfreeze depends on it
+ UpdateZSlope(v0, v1, v2);
+
// adapted from http://devmaster.net/posts/6145/advanced-rasterization
// 28.4 fixed-pou32 coordinates. rounded to nearest and adjusted to match hardware output
@@ -370,22 +386,13 @@ void DrawTriangleFrontFace(const OutputVertexData* v0, const OutputVertexData* v
if (minx >= maxx || miny >= maxy)
return;
- // Set up slopes
+ // Set up the remaining slopes
const SlopeContext ctx(v0, v1, v2, (X1 + 0xF) >> 4, (Y1 + 0xF) >> 4);
float w[3] = {1.0f / v0->projectedPosition.w, 1.0f / v1->projectedPosition.w,
1.0f / v2->projectedPosition.w};
WSlope = Slope(w[0], w[1], w[2], ctx);
- // TODO: The zfreeze emulation is not quite correct, yet!
- // Many things might prevent us from reaching this line (culling, clipping, scissoring).
- // However, the zslope is always guaranteed to be calculated unless all vertices are trivially
- // rejected during clipping!
- // We're currently sloppy at this since we abort early if any of the culling/clipping/scissoring
- // tests fail.
- if (!bpmem.genMode.zfreeze)
- ZSlope = Slope(v0->screenPosition.z, v1->screenPosition.z, v2->screenPosition.z, ctx);
-
for (unsigned int i = 0; i < bpmem.genMode.numcolchans; i++)
{
for (int comp = 0; comp < 4; comp++)