From 45577507f3f7bf3d3b4415472fc2dbc3d2a0c628 Mon Sep 17 00:00:00 2001 From: Tony Wasserka Date: Sat, 27 Jul 2013 14:30:31 +0200 Subject: [PATCH] softgpu: Disable clipping if it's not requested by the game. Also fix some clipping-related bugs. --- GPU/Software/Clipper.cpp | 10 +++++++++- GPU/Software/TransformUnit.cpp | 7 ++++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/GPU/Software/Clipper.cpp b/GPU/Software/Clipper.cpp index 36b3a823c4..8c242fb288 100644 --- a/GPU/Software/Clipper.cpp +++ b/GPU/Software/Clipper.cpp @@ -233,7 +233,11 @@ void ProcessTriangle(VertexData& v0, VertexData& v1, VertexData& v2) mask |= CalcClipMask(v1.clippos); mask |= CalcClipMask(v2.clippos); - if (mask) { + if (mask && (gstate.clipEnable & 0x1)) { + // discard if any vertex is outside the near clipping plane + if (mask & CLIP_NEG_Z_BIT) + return; + for(int i = 0; i < 3; i += 3) { int vlist[2][2*6+1]; int *inlist = vlist[0], *outlist = vlist[1]; @@ -266,6 +270,10 @@ void ProcessTriangle(VertexData& v0, VertexData& v1, VertexData& v2) indices[numIndices++] = inlist[j]; } } + } else if (CalcClipMask(v0.clippos) & CalcClipMask(v1.clippos) & CalcClipMask(v2.clippos)) { + // If clipping is disabled, only discard the current primitive + // if all three vertices lie outside one of the clipping planes + return; } for(int i = 0; i+3 <= numIndices; i+=3) diff --git a/GPU/Software/TransformUnit.cpp b/GPU/Software/TransformUnit.cpp index 4bd9b4928e..8794e249cd 100644 --- a/GPU/Software/TransformUnit.cpp +++ b/GPU/Software/TransformUnit.cpp @@ -59,7 +59,12 @@ static inline ScreenCoords ClipToScreenInternal(const ClipCoords& coords, bool s float rety = coords.y * vpy1 / coords.w + vpy2; float retz = coords.z * vpz1 / coords.w + vpz2; - if (set_flag && (retx > 4095.9375f || rety > 4096.9375f || retz > 65535.f || retx < 0 || rety < 0 || retz < 0)) + if (gstate.clipEnable & 0x1) { + if (retz < 0.f) retz = 0.f; + if (retz > 65535.f) retz = 65535.f; + } + + if (set_flag && (retx > 4095.9375f || rety > 4096.9375f || retx < 0 || rety < 0 || retz < 0 || retz > 65535.f)) outside_range_flag = true; // 16 = 0xFFFF / 4095.9375