From 8e9da720448127b73f07ae0898b0cb7cfdadc7ca Mon Sep 17 00:00:00 2001 From: Natalie Vock Date: Mon, 17 Nov 2025 16:41:19 +0100 Subject: [PATCH] radv/rt: Keep updated nodes always active In updateable AS, we keep all nodes active even if they're degenerate/NaN, because too many games ignore API rules about not making inactive nodes active (and some vendor tips outright advise this behavior). We also need to match this by keeping everything active in the update side. The ALWAYS_ACTIVE macro has been long removed and replaced by VK_BVH_BUILD_FLAG, too. Since updating only happens to updateable AS, don't even check for the flag, just implement the always-active handling. Cc: mesa-stable (cherry picked from commit bc1eea90b961c8a3bb4dcf8124e850ef777c35a3) Part-of: --- .pick_status.json | 2 +- src/amd/vulkan/bvh/update.comp | 10 +++------- src/amd/vulkan/bvh/update.h | 32 ++------------------------------ 3 files changed, 6 insertions(+), 38 deletions(-) diff --git a/.pick_status.json b/.pick_status.json index 39af840b371..da3f238b1cb 100644 --- a/.pick_status.json +++ b/.pick_status.json @@ -2354,7 +2354,7 @@ "description": "radv/rt: Keep updated nodes always active", "nominated": true, "nomination_type": 1, - "resolution": 0, + "resolution": 1, "main_sha": null, "because_sha": null, "notes": null diff --git a/src/amd/vulkan/bvh/update.comp b/src/amd/vulkan/bvh/update.comp index e8b0123ebf3..84c3c9ab96c 100644 --- a/src/amd/vulkan/bvh/update.comp +++ b/src/amd/vulkan/bvh/update.comp @@ -42,18 +42,14 @@ void main() { VOID_REF dst_ptr = OFFSET(dst_bvh, dst_offset); uint32_t src_offset = gl_GlobalInvocationID.x * args.geom_data.stride; - vk_aabb bounds; - bool is_active; + vk_aabb bounds = vk_aabb(vec3(0.0f), vec3(0.0f)); if (args.geom_data.geometry_type == VK_GEOMETRY_TYPE_TRIANGLES_KHR) { - is_active = radv_build_triangle(bounds, dst_ptr, args.geom_data, gl_GlobalInvocationID.x, false); + radv_build_triangle(bounds, dst_ptr, args.geom_data, gl_GlobalInvocationID.x, false); } else { VOID_REF src_ptr = OFFSET(args.geom_data.data, src_offset); - is_active = radv_build_aabb(bounds, src_ptr, dst_ptr, args.geom_data.geometry_id, gl_GlobalInvocationID.x, false); + radv_build_aabb(bounds, src_ptr, dst_ptr, args.geom_data.geometry_id, gl_GlobalInvocationID.x, false); } - if (!is_active) - return; - DEREF(INDEX(vk_aabb, args.leaf_bounds, leaf_node_id)) = bounds; memoryBarrier(gl_ScopeDevice, gl_StorageSemanticsBuffer, diff --git a/src/amd/vulkan/bvh/update.h b/src/amd/vulkan/bvh/update.h index 8012f022961..9a9aa0def66 100644 --- a/src/amd/vulkan/bvh/update.h +++ b/src/amd/vulkan/bvh/update.h @@ -10,26 +10,14 @@ #include "encode.h" -bool +void radv_build_triangle(inout vk_aabb bounds, VOID_REF dst_ptr, vk_bvh_geometry_data geom_data, uint32_t global_id, bool gfx12) { - bool is_valid = true; triangle_indices indices = load_indices(geom_data.indices, geom_data.index_format, global_id); triangle_vertices vertices = load_vertices(geom_data.data, indices, geom_data.vertex_format, geom_data.stride); - /* An inactive triangle is one for which the first (X) component of any vertex is NaN. If any - * other vertex component is NaN, and the first is not, the behavior is undefined. If the vertex - * format does not have a NaN representation, then all triangles are considered active. - */ - if (isnan(vertices.vertex[0].x) || isnan(vertices.vertex[1].x) || isnan(vertices.vertex[2].x)) -#if ALWAYS_ACTIVE - is_valid = false; -#else - return false; -#endif - if (geom_data.transform != NULL) { mat4 transform = mat4(1.0); @@ -61,16 +49,12 @@ radv_build_triangle(inout vk_aabb bounds, VOID_REF dst_ptr, vk_bvh_geometry_data radv_encode_triangle_gfx12(dst_ptr, node); else radv_encode_triangle_gfx10_3(dst_ptr, node); - - return is_valid; } -bool +void radv_build_aabb(inout vk_aabb bounds, VOID_REF src_ptr, VOID_REF dst_ptr, uint32_t geometry_id, uint32_t global_id, bool gfx12) { - bool is_valid = true; - for (uint32_t vec = 0; vec < 2; vec++) for (uint32_t comp = 0; comp < 3; comp++) { float coord = DEREF(INDEX(float, src_ptr, comp + vec * 3)); @@ -81,16 +65,6 @@ radv_build_aabb(inout vk_aabb bounds, VOID_REF src_ptr, VOID_REF dst_ptr, uint32 bounds.max[comp] = coord; } - /* An inactive AABB is one for which the minimum X coordinate is NaN. If any other component is - * NaN, and the first is not, the behavior is undefined. - */ - if (isnan(bounds.min.x)) -#if ALWAYS_ACTIVE - is_valid = false; -#else - return false; -#endif - vk_ir_aabb_node node; node.base.aabb = bounds; node.primitive_id = global_id; @@ -100,8 +74,6 @@ radv_build_aabb(inout vk_aabb bounds, VOID_REF src_ptr, VOID_REF dst_ptr, uint32 radv_encode_aabb_gfx12(dst_ptr, node); else radv_encode_aabb_gfx10_3(dst_ptr, node); - - return is_valid; } #endif