softgpu: Correctly fix inversions, matching tests.
Inversions are allowed just fine, but if clipping results in coordinates outside range, the triangle should be culled. Fixes more wanted inversions.
This commit is contained in:
parent
b62790fd00
commit
dc962094f8
3 changed files with 19 additions and 23 deletions
|
@ -162,7 +162,7 @@ ClipCoords TransformUnit::ViewToClip(const ViewCoords &coords) {
|
|||
return Vec3ByMatrix44(coords, gstate.projMatrix);
|
||||
}
|
||||
|
||||
template <bool depthClamp, bool writeOutsideFlag>
|
||||
template <bool depthClamp, bool alwaysCheckRange>
|
||||
static ScreenCoords ClipToScreenInternal(Vec3f scaled, const ClipCoords &coords, bool *outside_range_flag) {
|
||||
ScreenCoords ret;
|
||||
|
||||
|
@ -173,7 +173,7 @@ static ScreenCoords ClipToScreenInternal(Vec3f scaled, const ClipCoords &coords,
|
|||
// This matches hardware tests - depth is clamped when this flag is on.
|
||||
if (depthClamp) {
|
||||
// Note: if the depth is clipped (z/w <= -1.0), the outside_range_flag should NOT be set, even for x and y.
|
||||
if (writeOutsideFlag && coords.z > -coords.w && (scaled.x >= SCREEN_BOUND || scaled.y >= SCREEN_BOUND || scaled.x < 0 || scaled.y < 0)) {
|
||||
if ((alwaysCheckRange || coords.z > -coords.w) && (scaled.x >= SCREEN_BOUND || scaled.y >= SCREEN_BOUND || scaled.x < 0 || scaled.y < 0)) {
|
||||
*outside_range_flag = true;
|
||||
}
|
||||
|
||||
|
@ -181,7 +181,7 @@ static ScreenCoords ClipToScreenInternal(Vec3f scaled, const ClipCoords &coords,
|
|||
scaled.z = 0.f;
|
||||
else if (scaled.z > 65535.0f)
|
||||
scaled.z = 65535.0f;
|
||||
} else if (writeOutsideFlag && (scaled.x > SCREEN_BOUND || scaled.y >= SCREEN_BOUND || scaled.x < 0 || scaled.y < 0)) {
|
||||
} else if (scaled.x > SCREEN_BOUND || scaled.y >= SCREEN_BOUND || scaled.x < 0 || scaled.y < 0) {
|
||||
*outside_range_flag = true;
|
||||
}
|
||||
|
||||
|
@ -209,17 +209,13 @@ static inline ScreenCoords ClipToScreenInternal(const ClipCoords &coords, bool *
|
|||
float z = coords.z * zScale / coords.w + zCenter;
|
||||
|
||||
if (gstate.isDepthClampEnabled()) {
|
||||
if (outside_range_flag)
|
||||
return ClipToScreenInternal<true, true>(Vec3f(x, y, z), coords, outside_range_flag);
|
||||
return ClipToScreenInternal<true, false>(Vec3f(x, y, z), coords, outside_range_flag);
|
||||
return ClipToScreenInternal<true, true>(Vec3f(x, y, z), coords, outside_range_flag);
|
||||
}
|
||||
if (outside_range_flag)
|
||||
return ClipToScreenInternal<false, true>(Vec3f(x, y, z), coords, outside_range_flag);
|
||||
return ClipToScreenInternal<false, false>(Vec3f(x, y, z), coords, outside_range_flag);
|
||||
return ClipToScreenInternal<false, true>(Vec3f(x, y, z), coords, outside_range_flag);
|
||||
}
|
||||
|
||||
ScreenCoords TransformUnit::ClipToScreen(const ClipCoords &coords) {
|
||||
return ClipToScreenInternal(coords, nullptr);
|
||||
ScreenCoords TransformUnit::ClipToScreen(const ClipCoords &coords, bool *outsideRangeFlag) {
|
||||
return ClipToScreenInternal(coords, outsideRangeFlag);
|
||||
}
|
||||
|
||||
ScreenCoords TransformUnit::DrawingToScreen(const DrawingCoords &coords, u16 z) {
|
||||
|
@ -317,9 +313,9 @@ void ComputeTransformState(TransformState *state, const VertexReader &vreader) {
|
|||
}
|
||||
|
||||
if (gstate.isDepthClampEnabled())
|
||||
state->roundToScreen = &ClipToScreenInternal<true, true>;
|
||||
state->roundToScreen = &ClipToScreenInternal<true, false>;
|
||||
else
|
||||
state->roundToScreen = &ClipToScreenInternal<false, true>;
|
||||
state->roundToScreen = &ClipToScreenInternal<false, false>;
|
||||
}
|
||||
|
||||
ClipVertexData TransformUnit::ReadVertex(VertexReader &vreader, const TransformState &state) {
|
||||
|
@ -977,7 +973,8 @@ bool TransformUnit::GetCurrentSimpleVertices(int count, std::vector<GPUDebugVert
|
|||
vertices[i].z = vert.pos.z;
|
||||
} else {
|
||||
Vec4f clipPos = Vec3ByMatrix44(vert.pos, worldviewproj);
|
||||
ScreenCoords screenPos = ClipToScreen(clipPos);
|
||||
bool outsideRangeFlag;
|
||||
ScreenCoords screenPos = ClipToScreen(clipPos, &outsideRangeFlag);
|
||||
float z = clipPos.z * zScale / clipPos.w + zCenter;
|
||||
|
||||
if (gstate.vertType & GE_VTYPE_TC_MASK) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue