| 826 | } |
| 827 | |
| 828 | void BuildGeometryInfoKHR::SetupBuild(bool is_on_device_build, bool use_ppGeometries /*= true*/) { |
| 829 | if (update_dst_as_size_before_build_ && !dst_as_->IsNull() && !dst_as_->IsBuilt()) { |
| 830 | UpdateDstAccelStructSize(); |
| 831 | } |
| 832 | |
| 833 | // Build source and destination acceleration structures |
| 834 | if (!src_as_->IsNull() && !src_as_->IsBuilt()) { |
| 835 | src_as_->Create(); |
| 836 | } |
| 837 | vk_info_.srcAccelerationStructure = src_as_->handle(); |
| 838 | if (!dst_as_->IsNull() && !dst_as_->IsBuilt()) { |
| 839 | dst_as_->Create(); |
| 840 | } |
| 841 | vk_info_.dstAccelerationStructure = dst_as_->handle(); |
| 842 | |
| 843 | if (build_scratch_) { |
| 844 | const VkAccelerationStructureBuildSizesInfoKHR size_info = GetSizeInfo(use_ppGeometries); |
| 845 | const VkDeviceSize scratch_size = vk_info_.mode == VK_BUILD_ACCELERATION_STRUCTURE_MODE_UPDATE_KHR |
| 846 | ? size_info.updateScratchSize |
| 847 | : size_info.buildScratchSize; |
| 848 | if (is_on_device_build) { |
| 849 | // Allocate device local scratch buffer |
| 850 | |
| 851 | // Get minAccelerationStructureScratchOffsetAlignment |
| 852 | VkPhysicalDeviceAccelerationStructurePropertiesKHR as_props = vku::InitStructHelper(); |
| 853 | VkPhysicalDeviceProperties2 phys_dev_props = vku::InitStructHelper(&as_props); |
| 854 | vk::GetPhysicalDeviceProperties2(device_->Physical(), &phys_dev_props); |
| 855 | |
| 856 | assert(device_scratch_); // So far null pointers are not supported |
| 857 | if (!device_scratch_->initialized()) { |
| 858 | VkMemoryAllocateFlagsInfo alloc_flags = vku::InitStructHelper(); |
| 859 | alloc_flags.flags = VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT; |
| 860 | |
| 861 | if (scratch_size > 0) { |
| 862 | device_scratch_->Init(*device_, scratch_size + as_props.minAccelerationStructureScratchOffsetAlignment, |
| 863 | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | |
| 864 | device_scratch_additional_flags_, |
| 865 | VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &alloc_flags); |
| 866 | } |
| 867 | } |
| 868 | if (device_scratch_->CreateInfo().size != 0 && |
| 869 | device_scratch_->CreateInfo().usage & VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT) { |
| 870 | const VkDeviceAddress scratch_address = device_scratch_->Address(); |
| 871 | const auto aligned_scratch_address = |
| 872 | Align<VkDeviceAddress>(scratch_address, as_props.minAccelerationStructureScratchOffsetAlignment); |
| 873 | assert(aligned_scratch_address >= scratch_address); |
| 874 | assert(aligned_scratch_address < (scratch_address + as_props.minAccelerationStructureScratchOffsetAlignment)); |
| 875 | vk_info_.scratchData.deviceAddress = aligned_scratch_address + device_scratch_offset_; |
| 876 | assert(vk_info_.scratchData.deviceAddress < |
| 877 | (scratch_address + |
| 878 | device_scratch_->CreateInfo().size)); // Note: This assert may prove overly conservative in the future |
| 879 | } else { |
| 880 | vk_info_.scratchData.deviceAddress = 0; |
| 881 | } |
| 882 | } else { |
| 883 | // Allocate on host scratch buffer |
| 884 | host_scratch_ = nullptr; |
| 885 | if (scratch_size > 0) { |
no test coverage detected