| 131 | } |
| 132 | |
| 133 | void AccelerationStructure::build(VkQueue queue, VkBuildAccelerationStructureFlagsKHR flags, VkBuildAccelerationStructureModeKHR mode) |
| 134 | { |
| 135 | assert(!geometries.empty()); |
| 136 | |
| 137 | std::vector<VkAccelerationStructureGeometryKHR> acceleration_structure_geometries; |
| 138 | std::vector<VkAccelerationStructureBuildRangeInfoKHR> acceleration_structure_build_range_infos; |
| 139 | std::vector<uint32_t> primitive_counts; |
| 140 | for (auto &geometry : geometries) |
| 141 | { |
| 142 | if (mode == VK_BUILD_ACCELERATION_STRUCTURE_MODE_UPDATE_KHR && !geometry.second.updated) |
| 143 | { |
| 144 | continue; |
| 145 | } |
| 146 | acceleration_structure_geometries.push_back(geometry.second.geometry); |
| 147 | // Infer build range info from geometry |
| 148 | VkAccelerationStructureBuildRangeInfoKHR build_range_info; |
| 149 | build_range_info.primitiveCount = geometry.second.primitive_count; |
| 150 | build_range_info.primitiveOffset = 0; |
| 151 | build_range_info.firstVertex = 0; |
| 152 | build_range_info.transformOffset = geometry.second.transform_offset; |
| 153 | acceleration_structure_build_range_infos.push_back(build_range_info); |
| 154 | primitive_counts.push_back(geometry.second.primitive_count); |
| 155 | geometry.second.updated = false; |
| 156 | } |
| 157 | |
| 158 | VkAccelerationStructureBuildGeometryInfoKHR build_geometry_info{}; |
| 159 | build_geometry_info.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_GEOMETRY_INFO_KHR; |
| 160 | build_geometry_info.type = type; |
| 161 | build_geometry_info.flags = flags; |
| 162 | build_geometry_info.mode = mode; |
| 163 | if (mode == VK_BUILD_ACCELERATION_STRUCTURE_MODE_UPDATE_KHR && handle != VK_NULL_HANDLE) |
| 164 | { |
| 165 | build_geometry_info.srcAccelerationStructure = handle; |
| 166 | build_geometry_info.dstAccelerationStructure = handle; |
| 167 | } |
| 168 | build_geometry_info.geometryCount = static_cast<uint32_t>(acceleration_structure_geometries.size()); |
| 169 | build_geometry_info.pGeometries = acceleration_structure_geometries.data(); |
| 170 | |
| 171 | // Get required build sizes |
| 172 | build_sizes_info.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_SIZES_INFO_KHR; |
| 173 | vkGetAccelerationStructureBuildSizesKHR( |
| 174 | device.get_handle(), |
| 175 | VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR, |
| 176 | &build_geometry_info, |
| 177 | primitive_counts.data(), |
| 178 | &build_sizes_info); |
| 179 | |
| 180 | // Create a buffer for the acceleration structure |
| 181 | if (!buffer || buffer->get_size() != build_sizes_info.accelerationStructureSize) |
| 182 | { |
| 183 | buffer = std::make_unique<vkb::core::BufferC>( |
| 184 | device, |
| 185 | build_sizes_info.accelerationStructureSize, |
| 186 | VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_STORAGE_BIT_KHR | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT, |
| 187 | VMA_MEMORY_USAGE_GPU_ONLY); |
| 188 | |
| 189 | VkAccelerationStructureCreateInfoKHR acceleration_structure_create_info{}; |
| 190 | acceleration_structure_create_info.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_KHR; |
nothing calls this directly
no test coverage detected