Module: Mesa Branch: main Commit: 7bd265bc863b7a6bf1e002dd5e28279dec558949 URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=7bd265bc863b7a6bf1e002dd5e28279dec558949
Author: Konstantin Seurer <[email protected]> Date: Sat Feb 25 16:32:15 2023 +0100 radv: Move header and geometry info init into separate functions Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/21532> --- src/amd/vulkan/radv_acceleration_structure.c | 170 +++++++++++++++------------ 1 file changed, 95 insertions(+), 75 deletions(-) diff --git a/src/amd/vulkan/radv_acceleration_structure.c b/src/amd/vulkan/radv_acceleration_structure.c index ee8a8bef36d..147610c4df7 100644 --- a/src/amd/vulkan/radv_acceleration_structure.c +++ b/src/amd/vulkan/radv_acceleration_structure.c @@ -989,6 +989,99 @@ encode_nodes(VkCommandBuffer commandBuffer, uint32_t infoCount, /* This is the final access to the leaf nodes, no need to flush */ } +static void +init_header(VkCommandBuffer commandBuffer, uint32_t infoCount, + const VkAccelerationStructureBuildGeometryInfoKHR *pInfos, struct bvh_state *bvh_states) +{ + RADV_FROM_HANDLE(radv_cmd_buffer, cmd_buffer, commandBuffer); + 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); + 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, + }; + + 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; + + header.instance_offset = + bvh_states[i].accel_struct.bvh_offset + sizeof(struct radv_bvh_box32_node); + 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); + header.copy_dispatch_size[1] = 1; + header.copy_dispatch_size[2] = 1; + + header.serialization_size = + header.compacted_size + align(sizeof(struct radv_accel_struct_serialization_header) + + sizeof(uint64_t) * header.instance_count, + 128); + + header.size = header.serialization_size - + sizeof(struct radv_accel_struct_serialization_header) - + sizeof(uint64_t) * header.instance_count; + + header.build_flags = pInfos[i].flags; + header.geometry_count = pInfos[i].geometryCount; + + radv_update_buffer_cp(cmd_buffer, vk_acceleration_structure_get_va(accel_struct) + base, + (const char *)&header + base, sizeof(header) - base); + } +} + +static void +init_geometry_infos(VkCommandBuffer commandBuffer, uint32_t infoCount, + const VkAccelerationStructureBuildGeometryInfoKHR *pInfos, + struct bvh_state *bvh_states, + const VkAccelerationStructureBuildRangeInfoKHR *const *ppBuildRangeInfos) +{ + for (uint32_t i = 0; i < infoCount; ++i) { + RADV_FROM_HANDLE(vk_acceleration_structure, accel_struct, pInfos[i].dstAccelerationStructure); + + uint64_t geometry_infos_size = + pInfos[i].geometryCount * sizeof(struct radv_accel_struct_geometry_info); + + struct radv_accel_struct_geometry_info *geometry_infos = malloc(geometry_infos_size); + if (!geometry_infos) + continue; + + for (uint32_t j = 0; j < pInfos[i].geometryCount; ++j) { + const VkAccelerationStructureGeometryKHR *geometry = + pInfos[i].pGeometries ? pInfos[i].pGeometries + j : pInfos[i].ppGeometries[j]; + geometry_infos[j].type = geometry->geometryType; + geometry_infos[j].flags = geometry->flags; + geometry_infos[j].primitive_count = ppBuildRangeInfos[i][j].primitiveCount; + } + + radv_CmdUpdateBuffer(commandBuffer, accel_struct->buffer, + accel_struct->offset + bvh_states[i].accel_struct.geometry_info_offset, + geometry_infos_size, geometry_infos); + + free(geometry_infos); + } +} + VKAPI_ATTR void VKAPI_CALL radv_CmdBuildAccelerationStructuresKHR( VkCommandBuffer commandBuffer, uint32_t infoCount, @@ -1062,83 +1155,10 @@ radv_CmdBuildAccelerationStructuresKHR( 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); - 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, - }; - - 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 = instance_count; - header.compacted_size = bvh_states[i].accel_struct.size; - - header.copy_dispatch_size[0] = DIV_ROUND_UP(header.compacted_size, 16 * 64); - header.copy_dispatch_size[1] = 1; - header.copy_dispatch_size[2] = 1; - - header.serialization_size = - header.compacted_size + align(sizeof(struct radv_accel_struct_serialization_header) + - sizeof(uint64_t) * header.instance_count, - 128); - - header.size = header.serialization_size - - sizeof(struct radv_accel_struct_serialization_header) - - sizeof(uint64_t) * header.instance_count; - - header.build_flags = pInfos[i].flags; - header.geometry_count = pInfos[i].geometryCount; + init_header(commandBuffer, infoCount, pInfos, bvh_states); - struct radv_accel_struct_geometry_info *geometry_infos = malloc(geometry_infos_size); - if (!geometry_infos) - goto fail; - - for (uint32_t j = 0; j < pInfos[i].geometryCount; ++j) { - const VkAccelerationStructureGeometryKHR *geometry = - pInfos[i].pGeometries ? pInfos[i].pGeometries + j : pInfos[i].ppGeometries[j]; - geometry_infos[j].type = geometry->geometryType; - geometry_infos[j].flags = geometry->flags; - geometry_infos[j].primitive_count = ppBuildRangeInfos[i][j].primitiveCount; - } - - radv_update_buffer_cp(cmd_buffer, vk_acceleration_structure_get_va(accel_struct) + base, - (const char *)&header + base, sizeof(header) - base); - - radv_CmdUpdateBuffer(commandBuffer, accel_struct->buffer, - accel_struct->offset + bvh_states[i].accel_struct.geometry_info_offset, - geometry_infos_size, geometry_infos); - - free(geometry_infos); - } + init_geometry_infos(commandBuffer, infoCount, pInfos, bvh_states, ppBuildRangeInfos); -fail: free(bvh_states); radv_meta_restore(&saved_state, cmd_buffer); }
