diff --git a/GPU/Software/RasterizerRectangle.cpp b/GPU/Software/RasterizerRectangle.cpp index 4c2e4ad1a9..f07f66092a 100644 --- a/GPU/Software/RasterizerRectangle.cpp +++ b/GPU/Software/RasterizerRectangle.cpp @@ -116,8 +116,12 @@ void DrawSprite(const VertexData &v0, const VertexData &v1, const BinCoords &ran DrawingCoords scissorTL = TransformUnit::ScreenToDrawing(range.x1, range.y1); DrawingCoords scissorBR = TransformUnit::ScreenToDrawing(range.x2, range.y2); - int z = v1.screenpos.z; - int fog = 255; + const int z = v1.screenpos.z; + constexpr int fog = 255; + + // Since it's flat, we can check depth range early. Matters for earlyZChecks. + if (pixelID.applyDepthRange && (z < pixelID.cached.minz || z > pixelID.cached.maxz)) + return; bool isWhite = v1.color0 == 0xFFFFFFFF; @@ -204,15 +208,31 @@ void DrawSprite(const VertexData &v0, const VertexData &v1, const BinCoords &ran float t = tf_start; const Vec4 c0 = Vec4::FromRGBA(v1.color0); - for (int y = pos0.y; y < pos1.y; y++) { - float s = sf_start; - // Not really that fast but faster than triangle. - for (int x = pos0.x; x < pos1.x; x++) { - Vec4 prim_color = state.nearest(s, t, xoff, yoff, ToVec4IntArg(c0), &texptr, &texbufw, 0, 0, state.samplerID); - state.drawPixel(x, y, z, 255, ToVec4IntArg(prim_color), pixelID); - s += dsf; + if (pixelID.earlyZChecks) { + for (int y = pos0.y; y < pos1.y; y++) { + float s = sf_start; + // Not really that fast but faster than triangle. + for (int x = pos0.x; x < pos1.x; x++) { + if (CheckDepthTestPassed(pixelID.DepthTestFunc(), x, y, pixelID.cached.depthbufStride, z)) { + Vec4 prim_color = state.nearest(s, t, xoff, yoff, ToVec4IntArg(c0), &texptr, &texbufw, 0, 0, state.samplerID); + state.drawPixel(x, y, z, fog, ToVec4IntArg(prim_color), pixelID); + } + + s += dsf; + } + t += dtf; + } + } else { + for (int y = pos0.y; y < pos1.y; y++) { + float s = sf_start; + // Not really that fast but faster than triangle. + for (int x = pos0.x; x < pos1.x; x++) { + Vec4 prim_color = state.nearest(s, t, xoff, yoff, ToVec4IntArg(c0), &texptr, &texbufw, 0, 0, state.samplerID); + state.drawPixel(x, y, z, fog, ToVec4IntArg(prim_color), pixelID); + s += dsf; + } + t += dtf; } - t += dtf; } } } else { @@ -239,6 +259,16 @@ void DrawSprite(const VertexData &v0, const VertexData &v1, const BinCoords &ran pixel++; } } + } else if (pixelID.earlyZChecks) { + const Vec4 prim_color = Vec4::FromRGBA(v1.color0); + for (int y = pos0.y; y < pos1.y; y++) { + for (int x = pos0.x; x < pos1.x; x++) { + if (!CheckDepthTestPassed(pixelID.DepthTestFunc(), x, y, pixelID.cached.depthbufStride, z)) + continue; + + state.drawPixel(x, y, z, fog, ToVec4IntArg(prim_color), pixelID); + } + } } else { const Vec4 prim_color = Vec4::FromRGBA(v1.color0); for (int y = pos0.y; y < pos1.y; y++) {