From 573d326bc2995c1e59922ed797547b8a527c502b Mon Sep 17 00:00:00 2001 From: Konstantin Seurer Date: Mon, 2 Feb 2026 16:49:28 +0100 Subject: [PATCH] radv/bvh: Prefer selecting quads as the first pair of a HW node Is a single triangle is selected, it can be the case that the next iteration can't merge any pair with the triangle. In that case, the HW node with a single triangle will not have the highest hw_node_index, triggering an assert. Fixes: c18a7d0 ("radv: Emit compressed primitive nodes on GFX12") Reviewed-by: Natalie Vock (cherry picked from commit db38d1a98c6c19176ec01d127782e7a6b840ead6) Part-of: --- .pick_status.json | 2 +- .../vulkan/bvh/encode_triangles_gfx12.comp | 20 ++++++++++++++++--- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/.pick_status.json b/.pick_status.json index bc337723ac7..7d4eae1cb6f 100644 --- a/.pick_status.json +++ b/.pick_status.json @@ -1104,7 +1104,7 @@ "description": "radv/bvh: Prefer selecting quads as the first pair of a HW node", "nominated": true, "nomination_type": 2, - "resolution": 0, + "resolution": 1, "main_sha": null, "because_sha": "c18a7d0e2b639659f97c29d54268e3d800ac5d5f", "notes": null diff --git a/src/amd/vulkan/bvh/encode_triangles_gfx12.comp b/src/amd/vulkan/bvh/encode_triangles_gfx12.comp index 6dee0c281bd..7b47f477210 100644 --- a/src/amd/vulkan/bvh/encode_triangles_gfx12.comp +++ b/src/amd/vulkan/bvh/encode_triangles_gfx12.comp @@ -328,9 +328,23 @@ main() vertex_used[i] = false; } } else { - uint32_t chosen_invocation = - findMSB(radv_ballot(cluster, !assigned && required_bit_size == min_required_bit_size)); - if (cluster.invocation_index != chosen_invocation && !assigned) { + uint32_t candidate_mask = radv_ballot(cluster, !assigned && required_bit_size == min_required_bit_size); + + /* Always choose a quad as the first node to make sure that a potential single triangle node will have the + * highest hw_node_index. + */ + if (assigned_mask == 0) { + uint32_t quad_mask = radv_ballot(cluster, !assigned && pair_index_node_index1 != RADV_BVH_INVALID_NODE); + if (quad_mask != 0) { + uint32_t combined_mask = candidate_mask & quad_mask; + if (combined_mask != 0) + candidate_mask = combined_mask; + else + candidate_mask = quad_mask; + } + } + + if (cluster.invocation_index != findMSB(candidate_mask) && !assigned) { vertex_indices = UNASSIGNED_VERTEX_INDICES; for (uint32_t i = 0; i < 6; i++) vertex_used[i] = false;