From c1a7680d9327196dbb233867fb27aabe2ef7c3f7 Mon Sep 17 00:00:00 2001 From: Natalie Vock Date: Sun, 5 Apr 2026 11:53:23 +0200 Subject: [PATCH] radv/rt: Don't enable midpoint sorting Midpoint sorting is incompatible with how our traversal works. Specifically, we change tMax when a hit is committed so we can skip over BVH nodes that are guaranteed not to produce a closer hit. However, changing tMax also changes the intersection interval of box nodes with the ray, and thus, the midpoints of that interval. Stackless traversal relies on getting nodes back in the exact same order as before, and if that requirement is not met, traversal may incorrectly skip over nodes. The likely benefit of midpoint sorting does not make up for the loss of ability to skip over BVH nodes exceeding tMax, so simply disable midpoint sorting. This fixes geometry being visible behind other geometry when it shouldn't be in various applications, including Half-Life 2 RTX. Cc: mesa-stable Part-of: --- src/amd/vulkan/nir/radv_nir_rt_common.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/amd/vulkan/nir/radv_nir_rt_common.c b/src/amd/vulkan/nir/radv_nir_rt_common.c index 24937e834dd..34db65df277 100644 --- a/src/amd/vulkan/nir/radv_nir_rt_common.c +++ b/src/amd/vulkan/nir/radv_nir_rt_common.c @@ -560,15 +560,12 @@ create_bvh_descriptor(nir_builder *b, const struct radv_physical_device *pdev, s /* Enable pointer flags on GFX11+ */ dword3 |= BITFIELD_BIT(119 - 96); - /* Instead of the default box sorting (closest point), use largest for terminate_on_first_hit rays and midpoint - * for closest hit; this makes it more likely that the ray traversal will visit fewer nodes. */ + /* Instead of the default box sorting (closest point), use largest for terminate_on_first_hit rays; + * this makes it more likely that the ray traversal will visit fewer nodes. */ const uint32_t box_sort_largest = 1; - const uint32_t box_sort_midpoint = 2; - /* Only use largest/midpoint sorting when all invocations have the same ray flags, otherwise + /* Only use largest sorting when all invocations have the same ray flags, otherwise * fall back to the default closest point. */ - dword1 = nir_bcsel(b, nir_vote_any(b, 1, ray_flags->terminate_on_first_hit), dword1, - nir_imm_int(b, (box_sort_midpoint << 21) | sort_triangles_first | box_sort_enable)); dword1 = nir_bcsel(b, nir_vote_all(b, 1, ray_flags->terminate_on_first_hit), nir_imm_int(b, (box_sort_largest << 21) | sort_triangles_first | box_sort_enable), dword1); }