1 use crate::prelude::*; 2 use crate::vk; 3 use crate::RawPtr; 4 use crate::{Device, Instance}; 5 use std::ffi::CStr; 6 use std::mem; 7 8 #[derive(Clone)] 9 pub struct AccelerationStructure { 10 handle: vk::Device, 11 fp: vk::KhrAccelerationStructureFn, 12 } 13 14 impl AccelerationStructure { new(instance: &Instance, device: &Device) -> Self15 pub fn new(instance: &Instance, device: &Device) -> Self { 16 let handle = device.handle(); 17 let fp = vk::KhrAccelerationStructureFn::load(|name| unsafe { 18 mem::transmute(instance.get_device_proc_addr(handle, name.as_ptr())) 19 }); 20 Self { handle, fp } 21 } 22 23 #[inline] get_properties( instance: &Instance, pdevice: vk::PhysicalDevice, ) -> vk::PhysicalDeviceAccelerationStructurePropertiesKHR24 pub unsafe fn get_properties( 25 instance: &Instance, 26 pdevice: vk::PhysicalDevice, 27 ) -> vk::PhysicalDeviceAccelerationStructurePropertiesKHR { 28 let mut props_rt = vk::PhysicalDeviceAccelerationStructurePropertiesKHR::default(); 29 { 30 let mut props = vk::PhysicalDeviceProperties2::builder().push_next(&mut props_rt); 31 instance.get_physical_device_properties2(pdevice, &mut props); 32 } 33 props_rt 34 } 35 36 /// <https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkCreateAccelerationStructureKHR.html> 37 #[inline] create_acceleration_structure( &self, create_info: &vk::AccelerationStructureCreateInfoKHR, allocation_callbacks: Option<&vk::AllocationCallbacks>, ) -> VkResult<vk::AccelerationStructureKHR>38 pub unsafe fn create_acceleration_structure( 39 &self, 40 create_info: &vk::AccelerationStructureCreateInfoKHR, 41 allocation_callbacks: Option<&vk::AllocationCallbacks>, 42 ) -> VkResult<vk::AccelerationStructureKHR> { 43 let mut accel_struct = mem::zeroed(); 44 (self.fp.create_acceleration_structure_khr)( 45 self.handle, 46 create_info, 47 allocation_callbacks.as_raw_ptr(), 48 &mut accel_struct, 49 ) 50 .result_with_success(accel_struct) 51 } 52 53 /// <https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkDestroyAccelerationStructureKHR.html> 54 #[inline] destroy_acceleration_structure( &self, accel_struct: vk::AccelerationStructureKHR, allocation_callbacks: Option<&vk::AllocationCallbacks>, )55 pub unsafe fn destroy_acceleration_structure( 56 &self, 57 accel_struct: vk::AccelerationStructureKHR, 58 allocation_callbacks: Option<&vk::AllocationCallbacks>, 59 ) { 60 (self.fp.destroy_acceleration_structure_khr)( 61 self.handle, 62 accel_struct, 63 allocation_callbacks.as_raw_ptr(), 64 ); 65 } 66 67 /// <https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkCmdBuildAccelerationStructuresKHR.html> 68 #[inline] cmd_build_acceleration_structures( &self, command_buffer: vk::CommandBuffer, infos: &[vk::AccelerationStructureBuildGeometryInfoKHR], build_range_infos: &[&[vk::AccelerationStructureBuildRangeInfoKHR]], )69 pub unsafe fn cmd_build_acceleration_structures( 70 &self, 71 command_buffer: vk::CommandBuffer, 72 infos: &[vk::AccelerationStructureBuildGeometryInfoKHR], 73 build_range_infos: &[&[vk::AccelerationStructureBuildRangeInfoKHR]], 74 ) { 75 assert_eq!(infos.len(), build_range_infos.len()); 76 77 let build_range_infos = build_range_infos 78 .iter() 79 .zip(infos.iter()) 80 .map(|(range_info, info)| { 81 assert_eq!(range_info.len(), info.geometry_count as usize); 82 range_info.as_ptr() 83 }) 84 .collect::<Vec<_>>(); 85 86 (self.fp.cmd_build_acceleration_structures_khr)( 87 command_buffer, 88 infos.len() as _, 89 infos.as_ptr(), 90 build_range_infos.as_ptr(), 91 ); 92 } 93 94 /// <https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkCmdBuildAccelerationStructuresIndirectKHR.html> 95 #[inline] cmd_build_acceleration_structures_indirect( &self, command_buffer: vk::CommandBuffer, infos: &[vk::AccelerationStructureBuildGeometryInfoKHR], indirect_device_addresses: &[vk::DeviceAddress], indirect_strides: &[u32], max_primitive_counts: &[&[u32]], )96 pub unsafe fn cmd_build_acceleration_structures_indirect( 97 &self, 98 command_buffer: vk::CommandBuffer, 99 infos: &[vk::AccelerationStructureBuildGeometryInfoKHR], 100 indirect_device_addresses: &[vk::DeviceAddress], 101 indirect_strides: &[u32], 102 max_primitive_counts: &[&[u32]], 103 ) { 104 assert_eq!(infos.len(), indirect_device_addresses.len()); 105 assert_eq!(infos.len(), indirect_strides.len()); 106 assert_eq!(infos.len(), max_primitive_counts.len()); 107 108 let max_primitive_counts = max_primitive_counts 109 .iter() 110 .zip(infos.iter()) 111 .map(|(cnt, info)| { 112 assert_eq!(cnt.len(), info.geometry_count as usize); 113 cnt.as_ptr() 114 }) 115 .collect::<Vec<_>>(); 116 117 (self.fp.cmd_build_acceleration_structures_indirect_khr)( 118 command_buffer, 119 infos.len() as _, 120 infos.as_ptr(), 121 indirect_device_addresses.as_ptr(), 122 indirect_strides.as_ptr(), 123 max_primitive_counts.as_ptr(), 124 ); 125 } 126 127 /// <https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkBuildAccelerationStructuresKHR.html> 128 #[inline] build_acceleration_structures( &self, deferred_operation: vk::DeferredOperationKHR, infos: &[vk::AccelerationStructureBuildGeometryInfoKHR], build_range_infos: &[&[vk::AccelerationStructureBuildRangeInfoKHR]], ) -> VkResult<()>129 pub unsafe fn build_acceleration_structures( 130 &self, 131 deferred_operation: vk::DeferredOperationKHR, 132 infos: &[vk::AccelerationStructureBuildGeometryInfoKHR], 133 build_range_infos: &[&[vk::AccelerationStructureBuildRangeInfoKHR]], 134 ) -> VkResult<()> { 135 assert_eq!(infos.len(), build_range_infos.len()); 136 137 let build_range_infos = build_range_infos 138 .iter() 139 .zip(infos.iter()) 140 .map(|(range_info, info)| { 141 assert_eq!(range_info.len(), info.geometry_count as usize); 142 range_info.as_ptr() 143 }) 144 .collect::<Vec<_>>(); 145 146 (self.fp.build_acceleration_structures_khr)( 147 self.handle, 148 deferred_operation, 149 infos.len() as _, 150 infos.as_ptr(), 151 build_range_infos.as_ptr(), 152 ) 153 .result() 154 } 155 156 /// <https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkCopyAccelerationStructureKHR.html> 157 #[inline] copy_acceleration_structure( &self, deferred_operation: vk::DeferredOperationKHR, info: &vk::CopyAccelerationStructureInfoKHR, ) -> VkResult<()>158 pub unsafe fn copy_acceleration_structure( 159 &self, 160 deferred_operation: vk::DeferredOperationKHR, 161 info: &vk::CopyAccelerationStructureInfoKHR, 162 ) -> VkResult<()> { 163 (self.fp.copy_acceleration_structure_khr)(self.handle, deferred_operation, info).result() 164 } 165 166 /// <https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkCopyAccelerationStructureToMemoryKHR.html> 167 #[inline] copy_acceleration_structure_to_memory( &self, deferred_operation: vk::DeferredOperationKHR, info: &vk::CopyAccelerationStructureToMemoryInfoKHR, ) -> VkResult<()>168 pub unsafe fn copy_acceleration_structure_to_memory( 169 &self, 170 deferred_operation: vk::DeferredOperationKHR, 171 info: &vk::CopyAccelerationStructureToMemoryInfoKHR, 172 ) -> VkResult<()> { 173 (self.fp.copy_acceleration_structure_to_memory_khr)(self.handle, deferred_operation, info) 174 .result() 175 } 176 177 /// <https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkCopyMemoryToAccelerationStructureKHR.html> 178 #[inline] copy_memory_to_acceleration_structure( &self, deferred_operation: vk::DeferredOperationKHR, info: &vk::CopyMemoryToAccelerationStructureInfoKHR, ) -> VkResult<()>179 pub unsafe fn copy_memory_to_acceleration_structure( 180 &self, 181 deferred_operation: vk::DeferredOperationKHR, 182 info: &vk::CopyMemoryToAccelerationStructureInfoKHR, 183 ) -> VkResult<()> { 184 (self.fp.copy_memory_to_acceleration_structure_khr)(self.handle, deferred_operation, info) 185 .result() 186 } 187 188 /// <https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkWriteAccelerationStructuresPropertiesKHR.html> 189 #[inline] write_acceleration_structures_properties( &self, acceleration_structures: &[vk::AccelerationStructureKHR], query_type: vk::QueryType, data: &mut [u8], stride: usize, ) -> VkResult<()>190 pub unsafe fn write_acceleration_structures_properties( 191 &self, 192 acceleration_structures: &[vk::AccelerationStructureKHR], 193 query_type: vk::QueryType, 194 data: &mut [u8], 195 stride: usize, 196 ) -> VkResult<()> { 197 (self.fp.write_acceleration_structures_properties_khr)( 198 self.handle, 199 acceleration_structures.len() as _, 200 acceleration_structures.as_ptr(), 201 query_type, 202 data.len(), 203 data.as_mut_ptr().cast(), 204 stride, 205 ) 206 .result() 207 } 208 209 /// <https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkCmdCopyAccelerationStructureKHR.html> 210 #[inline] cmd_copy_acceleration_structure( &self, command_buffer: vk::CommandBuffer, info: &vk::CopyAccelerationStructureInfoKHR, )211 pub unsafe fn cmd_copy_acceleration_structure( 212 &self, 213 command_buffer: vk::CommandBuffer, 214 info: &vk::CopyAccelerationStructureInfoKHR, 215 ) { 216 (self.fp.cmd_copy_acceleration_structure_khr)(command_buffer, info); 217 } 218 219 /// <https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkCmdCopyAccelerationStructureToMemoryKHR.html> 220 #[inline] cmd_copy_acceleration_structure_to_memory( &self, command_buffer: vk::CommandBuffer, info: &vk::CopyAccelerationStructureToMemoryInfoKHR, )221 pub unsafe fn cmd_copy_acceleration_structure_to_memory( 222 &self, 223 command_buffer: vk::CommandBuffer, 224 info: &vk::CopyAccelerationStructureToMemoryInfoKHR, 225 ) { 226 (self.fp.cmd_copy_acceleration_structure_to_memory_khr)(command_buffer, info); 227 } 228 229 /// <https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkCmdCopyMemoryToAccelerationStructureKHR.html> 230 #[inline] cmd_copy_memory_to_acceleration_structure( &self, command_buffer: vk::CommandBuffer, info: &vk::CopyMemoryToAccelerationStructureInfoKHR, )231 pub unsafe fn cmd_copy_memory_to_acceleration_structure( 232 &self, 233 command_buffer: vk::CommandBuffer, 234 info: &vk::CopyMemoryToAccelerationStructureInfoKHR, 235 ) { 236 (self.fp.cmd_copy_memory_to_acceleration_structure_khr)(command_buffer, info); 237 } 238 239 /// <https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkGetAccelerationStructureHandleKHR.html> 240 #[inline] get_acceleration_structure_device_address( &self, info: &vk::AccelerationStructureDeviceAddressInfoKHR, ) -> vk::DeviceAddress241 pub unsafe fn get_acceleration_structure_device_address( 242 &self, 243 info: &vk::AccelerationStructureDeviceAddressInfoKHR, 244 ) -> vk::DeviceAddress { 245 (self.fp.get_acceleration_structure_device_address_khr)(self.handle, info) 246 } 247 248 /// <https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkCmdWriteAccelerationStructuresPropertiesKHR.html> 249 #[inline] cmd_write_acceleration_structures_properties( &self, command_buffer: vk::CommandBuffer, structures: &[vk::AccelerationStructureKHR], query_type: vk::QueryType, query_pool: vk::QueryPool, first_query: u32, )250 pub unsafe fn cmd_write_acceleration_structures_properties( 251 &self, 252 command_buffer: vk::CommandBuffer, 253 structures: &[vk::AccelerationStructureKHR], 254 query_type: vk::QueryType, 255 query_pool: vk::QueryPool, 256 first_query: u32, 257 ) { 258 (self.fp.cmd_write_acceleration_structures_properties_khr)( 259 command_buffer, 260 structures.len() as _, 261 structures.as_ptr(), 262 query_type, 263 query_pool, 264 first_query, 265 ); 266 } 267 268 /// <https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkGetDeviceAccelerationStructureCompatibilityKHR.html> 269 #[inline] get_device_acceleration_structure_compatibility( &self, version: &vk::AccelerationStructureVersionInfoKHR, ) -> vk::AccelerationStructureCompatibilityKHR270 pub unsafe fn get_device_acceleration_structure_compatibility( 271 &self, 272 version: &vk::AccelerationStructureVersionInfoKHR, 273 ) -> vk::AccelerationStructureCompatibilityKHR { 274 let mut compatibility = vk::AccelerationStructureCompatibilityKHR::default(); 275 276 (self.fp.get_device_acceleration_structure_compatibility_khr)( 277 self.handle, 278 version, 279 &mut compatibility, 280 ); 281 282 compatibility 283 } 284 285 /// <https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkGetAccelerationStructureBuildSizesKHR.html> 286 #[inline] get_acceleration_structure_build_sizes( &self, build_type: vk::AccelerationStructureBuildTypeKHR, build_info: &vk::AccelerationStructureBuildGeometryInfoKHR, max_primitive_counts: &[u32], ) -> vk::AccelerationStructureBuildSizesInfoKHR287 pub unsafe fn get_acceleration_structure_build_sizes( 288 &self, 289 build_type: vk::AccelerationStructureBuildTypeKHR, 290 build_info: &vk::AccelerationStructureBuildGeometryInfoKHR, 291 max_primitive_counts: &[u32], 292 ) -> vk::AccelerationStructureBuildSizesInfoKHR { 293 assert_eq!(max_primitive_counts.len(), build_info.geometry_count as _); 294 295 let mut size_info = vk::AccelerationStructureBuildSizesInfoKHR::default(); 296 297 (self.fp.get_acceleration_structure_build_sizes_khr)( 298 self.handle, 299 build_type, 300 build_info, 301 max_primitive_counts.as_ptr(), 302 &mut size_info, 303 ); 304 305 size_info 306 } 307 308 #[inline] name() -> &'static CStr309 pub const fn name() -> &'static CStr { 310 vk::KhrAccelerationStructureFn::name() 311 } 312 313 #[inline] fp(&self) -> &vk::KhrAccelerationStructureFn314 pub fn fp(&self) -> &vk::KhrAccelerationStructureFn { 315 &self.fp 316 } 317 318 #[inline] device(&self) -> vk::Device319 pub fn device(&self) -> vk::Device { 320 self.handle 321 } 322 } 323