ash/extensions/khr/
acceleration_structure.rs

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