Module: Mesa Branch: main Commit: e2fa9ba9c657193202fb2b77cb9f9db1c9ba6362 URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=e2fa9ba9c657193202fb2b77cb9f9db1c9ba6362
Author: Konstantin Seurer <[email protected]> Date: Fri Jan 20 21:52:06 2023 +0100 radv: Use indirect header filling for compact builds Sets the accel struct size fields to the correct values which should allow for more compaction. Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/20818> --- src/amd/vulkan/radv_acceleration_structure.c | 48 +++++++++++++++++++++++++--- src/amd/vulkan/radv_private.h | 2 ++ 2 files changed, 46 insertions(+), 4 deletions(-) diff --git a/src/amd/vulkan/radv_acceleration_structure.c b/src/amd/vulkan/radv_acceleration_structure.c index 604746a2036..ee8a8bef36d 100644 --- a/src/amd/vulkan/radv_acceleration_structure.c +++ b/src/amd/vulkan/radv_acceleration_structure.c @@ -71,6 +71,10 @@ static const uint32_t encode_compact_spv[] = { #include "bvh/encode_compact.spv.h" }; +static const uint32_t header_spv[] = { +#include "bvh/header.spv.h" +}; + #define KEY_ID_PAIR_SIZE 8 enum internal_build_type { @@ -307,6 +311,8 @@ radv_device_finish_accel_struct_build_state(struct radv_device *device) &state->alloc); radv_DestroyPipeline(radv_device_to_handle(device), state->accel_struct_build.encode_compact_pipeline, &state->alloc); + radv_DestroyPipeline(radv_device_to_handle(device), state->accel_struct_build.header_pipeline, + &state->alloc); radv_DestroyPipeline(radv_device_to_handle(device), state->accel_struct_build.morton_pipeline, &state->alloc); radv_DestroyPipelineLayout(radv_device_to_handle(device), @@ -321,6 +327,8 @@ radv_device_finish_accel_struct_build_state(struct radv_device *device) state->accel_struct_build.leaf_p_layout, &state->alloc); radv_DestroyPipelineLayout(radv_device_to_handle(device), state->accel_struct_build.encode_p_layout, &state->alloc); + radv_DestroyPipelineLayout(radv_device_to_handle(device), + state->accel_struct_build.header_p_layout, &state->alloc); radv_DestroyPipelineLayout(radv_device_to_handle(device), state->accel_struct_build.morton_p_layout, &state->alloc); @@ -581,6 +589,13 @@ radv_device_init_accel_struct_build_state(struct radv_device *device) if (result != VK_SUCCESS) goto exit; + result = + create_build_pipeline_spv(device, header_spv, sizeof(header_spv), sizeof(struct header_args), + &device->meta_state.accel_struct_build.header_pipeline, + &device->meta_state.accel_struct_build.header_p_layout); + if (result != VK_SUCCESS) + goto exit; + result = create_build_pipeline_spv(device, morton_spv, sizeof(morton_spv), sizeof(struct morton_args), &device->meta_state.accel_struct_build.morton_pipeline, @@ -1045,19 +1060,44 @@ radv_CmdBuildAccelerationStructuresKHR( encode_nodes(commandBuffer, infoCount, pInfos, bvh_states, false); encode_nodes(commandBuffer, infoCount, pInfos, bvh_states, true); + cmd_buffer->state.flush_bits |= flush_bits; + + radv_CmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, + cmd_buffer->device->meta_state.accel_struct_build.header_pipeline); + for (uint32_t i = 0; i < infoCount; ++i) { RADV_FROM_HANDLE(vk_acceleration_structure, accel_struct, pInfos[i].dstAccelerationStructure); - const size_t base = offsetof(struct radv_accel_struct_header, compacted_size); - struct radv_accel_struct_header header; + size_t base = offsetof(struct radv_accel_struct_header, compacted_size); + + uint64_t instance_count = pInfos[i].type == VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR + ? bvh_states[i].leaf_node_count + : 0; + + if (bvh_states[i].config.compact) { + base = offsetof(struct radv_accel_struct_header, geometry_count); + + struct header_args args = { + .src = pInfos[i].scratchData.deviceAddress + bvh_states[i].scratch.header_offset, + .dst = vk_acceleration_structure_get_va(accel_struct), + .bvh_offset = bvh_states[i].accel_struct.bvh_offset, + .instance_count = instance_count, + }; - bool is_tlas = pInfos[i].type == VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR; + radv_CmdPushConstants(commandBuffer, + cmd_buffer->device->meta_state.accel_struct_build.header_p_layout, + VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(args), &args); + + radv_unaligned_dispatch(cmd_buffer, 1, 1, 1); + } + + struct radv_accel_struct_header header; uint64_t geometry_infos_size = pInfos[i].geometryCount * sizeof(struct radv_accel_struct_geometry_info); header.instance_offset = bvh_states[i].accel_struct.bvh_offset + sizeof(struct radv_bvh_box32_node); - header.instance_count = is_tlas ? bvh_states[i].leaf_node_count : 0; + header.instance_count = instance_count; header.compacted_size = bvh_states[i].accel_struct.size; header.copy_dispatch_size[0] = DIV_ROUND_UP(header.compacted_size, 16 * 64); diff --git a/src/amd/vulkan/radv_private.h b/src/amd/vulkan/radv_private.h index d4a6aed3fd6..99d398d9317 100644 --- a/src/amd/vulkan/radv_private.h +++ b/src/amd/vulkan/radv_private.h @@ -699,6 +699,8 @@ struct radv_meta_state { VkPipelineLayout encode_p_layout; VkPipeline encode_pipeline; VkPipeline encode_compact_pipeline; + VkPipelineLayout header_p_layout; + VkPipeline header_pipeline; VkPipelineLayout copy_p_layout; VkPipeline copy_pipeline;
