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 bc1eea90b9)

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/38803>
This commit is contained in:
Natalie Vock 2025-11-17 16:41:19 +01:00 committed by Dylan Baker
parent 142c392389
commit 8e9da72044
3 changed files with 6 additions and 38 deletions

View file

@ -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

View file

@ -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,

View file

@ -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