From 06a06bbe09ab1a86103924cadf95ced52bc46e27 Mon Sep 17 00:00:00 2001 From: Natalie Vock Date: Sun, 1 Dec 2024 10:32:39 +0100 Subject: [PATCH] radv: Encode child opaqueness information in box nodes Also, use one reserved field from the header to store the root node's opaqueness flags. This is used to propagate opaqueness info across the BLAS/TLAS boundary. Part-of: --- src/amd/vulkan/bvh/bvh.h | 7 +++++-- src/amd/vulkan/bvh/encode.comp | 11 ++++++++++- src/amd/vulkan/bvh/encode_gfx12.comp | 15 ++++++++++++--- src/amd/vulkan/radv_acceleration_structure.c | 2 ++ 4 files changed, 29 insertions(+), 6 deletions(-) diff --git a/src/amd/vulkan/bvh/bvh.h b/src/amd/vulkan/bvh/bvh.h index 07ad8190b77..7525fbfa060 100644 --- a/src/amd/vulkan/bvh/bvh.h +++ b/src/amd/vulkan/bvh/bvh.h @@ -48,7 +48,8 @@ struct radv_accel_struct_geometry_info { struct radv_accel_struct_header { uint32_t bvh_offset; - uint32_t reserved; + /* Copy of the root node's box flags for quicker access (no indirection through bvh_offset) */ + uint32_t root_flags; vk_aabb aabb; /* GFX12 */ @@ -113,7 +114,9 @@ struct radv_bvh_box16_node { struct radv_bvh_box32_node { uint32_t children[4]; vk_aabb coords[4]; - uint32_t reserved[4]; + /* VK_BVH_BOX_FLAG_* indicating if all/no children are opaque */ + uint32_t flags; + uint32_t reserved[3]; }; #define RADV_BVH_ROOT_NODE radv_bvh_node_box32 diff --git a/src/amd/vulkan/bvh/encode.comp b/src/amd/vulkan/bvh/encode.comp index 5551e202c51..6c0cb53aa4e 100644 --- a/src/amd/vulkan/bvh/encode.comp +++ b/src/amd/vulkan/bvh/encode.comp @@ -108,6 +108,8 @@ main() if (bvh_offset == VK_NULL_BVH_OFFSET) break; + uint32_t flags = 0; + REF(radv_bvh_box32_node) dst_node = REF(radv_bvh_box32_node)(OFFSET(args.output_bvh, bvh_offset)); uint32_t node_id = pack_node_id(bvh_offset, radv_bvh_node_box32); @@ -184,6 +186,7 @@ main() REF(vk_ir_box_node) child_node = REF(vk_ir_box_node)OFFSET(args.intermediate_bvh, offset); DEREF(child_node).bvh_offset = dst_offset; + flags |= (DEREF(child_node).flags & 0x3) << i * 8; } else { uint32_t child_index = offset / ir_leaf_node_size; dst_offset = dst_leaf_offset + child_index * output_leaf_node_size; @@ -192,6 +195,10 @@ main() vk_ir_instance_node src_node = DEREF(REF(vk_ir_instance_node)(OFFSET(args.intermediate_bvh, offset))); radv_encode_instance_gfx10_3(OFFSET(args.output_bvh, dst_offset), src_node); + flags |= (src_node.root_flags & 0x3) << i * 8; + } else { + uint32_t child_flags = fetch_child_flags(args.intermediate_bvh, children[i]); + flags |= (child_flags & 0x3) << i * 8; } } @@ -231,13 +238,15 @@ main() gl_SemanticsAcquireRelease | gl_SemanticsMakeAvailable | gl_SemanticsMakeVisible); DEREF(dst_node).children = children; + DEREF(dst_node).flags = flags; break; } if (is_root_node) { REF(radv_accel_struct_header) header = REF(radv_accel_struct_header)(args.output_bvh - args.output_bvh_offset); - DEREF(header).aabb = src.base.aabb; DEREF(header).bvh_offset = args.output_bvh_offset; + DEREF(header).root_flags = src.flags; + DEREF(header).aabb = src.base.aabb; set_parent(RADV_BVH_ROOT_NODE, RADV_BVH_INVALID_NODE); } diff --git a/src/amd/vulkan/bvh/encode_gfx12.comp b/src/amd/vulkan/bvh/encode_gfx12.comp index 805b662e6fd..06ddc3b895b 100644 --- a/src/amd/vulkan/bvh/encode_gfx12.comp +++ b/src/amd/vulkan/bvh/encode_gfx12.comp @@ -190,8 +190,11 @@ encode_gfx12(uint32_t ir_leaf_node_size, REF(vk_ir_box_node) intermediate_intern uint32_t child_node_size_128b = 1; uint32_t encoded_type = 0; uint32_t cull_mask = 0xff; + uint32_t cull_flags = 0; if (type == vk_ir_node_internal) { encoded_type = 5; + REF(vk_ir_box_node) child_node = REF(vk_ir_box_node)OFFSET(args.intermediate_bvh, offset); + cull_flags = DEREF(child_node).flags & 0x3; } else { /* Write leaf node offset. */ uint32_t leaf_index = offset / ir_leaf_node_size; @@ -205,11 +208,17 @@ encode_gfx12(uint32_t ir_leaf_node_size, REF(vk_ir_box_node) intermediate_intern case VK_GEOMETRY_TYPE_TRIANGLES_KHR: { vk_ir_triangle_node src_node = DEREF(REF(vk_ir_triangle_node)(OFFSET(args.intermediate_bvh, offset))); radv_encode_triangle_gfx12(dst_leaf_addr, src_node); + + bool opaque = (src_node.geometry_id_and_flags & VK_GEOMETRY_OPAQUE) != 0; + cull_flags = opaque ? VK_BVH_BOX_FLAG_ONLY_OPAQUE : VK_BVH_BOX_FLAG_NO_OPAQUE; break; } case VK_GEOMETRY_TYPE_AABBS_KHR: { vk_ir_aabb_node src_node = DEREF(REF(vk_ir_aabb_node)(OFFSET(args.intermediate_bvh, offset))); radv_encode_aabb_gfx12(dst_leaf_addr, src_node); + + bool opaque = (src_node.geometry_id_and_flags & VK_GEOMETRY_OPAQUE) != 0; + cull_flags = opaque ? VK_BVH_BOX_FLAG_ONLY_OPAQUE : VK_BVH_BOX_FLAG_NO_OPAQUE; break; } default: @@ -221,7 +230,7 @@ encode_gfx12(uint32_t ir_leaf_node_size, REF(vk_ir_box_node) intermediate_intern radv_encode_instance_gfx12(dst_leaf_addr, src_node); cull_mask = src_node.custom_instance_and_mask >> 24; - + cull_flags = src_node.root_flags & 0x3; break; } } @@ -229,10 +238,10 @@ encode_gfx12(uint32_t ir_leaf_node_size, REF(vk_ir_box_node) intermediate_intern vk_aabb child_aabb = DEREF(REF(vk_ir_node) OFFSET(args.intermediate_bvh, offset)).aabb; radv_gfx12_box_child box_child; - /* TODO: subtree flags culling */ box_child.dword0 = min(uint32_t(floor((child_aabb.min.x - origin.x) / extent.x * float(0x1000))), 0xfff) | - (min(uint32_t(floor((child_aabb.min.y - origin.y) / extent.y * float(0x1000))), 0xfff) << 12); + (min(uint32_t(floor((child_aabb.min.y - origin.y) / extent.y * float(0x1000))), 0xfff) << 12) | + cull_flags << 24; /* TODO: subtree mask culling */ box_child.dword1 = min(uint32_t(floor((child_aabb.min.z - origin.z) / extent.z * float(0x1000))), 0xfff) | diff --git a/src/amd/vulkan/radv_acceleration_structure.c b/src/amd/vulkan/radv_acceleration_structure.c index 4a76a4a15e2..ec071ac2f50 100644 --- a/src/amd/vulkan/radv_acceleration_structure.c +++ b/src/amd/vulkan/radv_acceleration_structure.c @@ -979,6 +979,8 @@ radv_device_init_accel_struct_build_state(struct radv_device *device) struct vk_acceleration_structure_build_args *build_args = &device->meta_state.accel_struct_build.build_args; build_args->subgroup_size = 64; build_args->bvh_bounds_offset = offsetof(struct radv_accel_struct_header, aabb); + build_args->root_flags_offset = offsetof(struct radv_accel_struct_header, root_flags); + build_args->propagate_cull_flags = pdev->info.gfx_level >= GFX11; build_args->emit_markers = device->sqtt.bo; build_args->radix_sort = device->meta_state.accel_struct_build.radix_sort;