From eea697b1792ab84f4c24f6e1ab5a5286988ade7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Ondra=C4=8Dka?= Date: Mon, 2 Mar 2026 20:29:14 +0100 Subject: [PATCH] r300: disable clip-discard watermark for triangles MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit 0d4aa5f55ff introduced the watermark to optimize the guardband state changes and always computed new_distance as MAX2(distance, watermark). That is correct for point/line paths where distance > 0, but it keeps a non-zero discard distance alive when the next draw sets distance = 0 (triangles). This leaks wide point/line clip-discard state into later triangle draws and can clip away large parts of geometry (as observed in Sauerbraten). Only apply the watermark when distance > 0 and reset it to zero otherwise so triangle draws disable clip-discard as intended. Fixes: 0d4aa5f55ff ("r300: pop-free clipping") Reviewed-by: Marek Olšák Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/14959 (cherry picked from commit ce33f82f8359c48bed9057b38372210c844f5692) Part-of: --- .pick_status.json | 2 +- src/gallium/drivers/r300/r300_state.c | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.pick_status.json b/.pick_status.json index 1b7fa266b6f..f70b604e95f 100644 --- a/.pick_status.json +++ b/.pick_status.json @@ -1274,7 +1274,7 @@ "description": "r300: disable clip-discard watermark for triangles", "nominated": true, "nomination_type": 2, - "resolution": 0, + "resolution": 1, "main_sha": null, "because_sha": "0d4aa5f55ff80df5b357f10bd56864c97ef1f4ba", "notes": null diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c index 901b88b66a9..36c3ea5ee75 100644 --- a/src/gallium/drivers/r300/r300_state.c +++ b/src/gallium/drivers/r300/r300_state.c @@ -147,7 +147,8 @@ void r300_set_clip_discard_distance(struct r300_context *r300, float distance) r300->min_clip_discard_distance_watermark = MIN2(distance, 6.0f); } - float new_distance = MAX2(distance, r300->min_clip_discard_distance_watermark); + float new_distance = distance > 0.0f ? + MAX2(distance, r300->min_clip_discard_distance_watermark) : 0.0f; if (r300->current_clip_discard_distance != new_distance) { r300->current_clip_discard_distance = new_distance;