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;