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    #[inline]
24    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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
241    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]
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]
270    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]
287    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]
309    pub const fn name() -> &'static CStr {
310        vk::KhrAccelerationStructureFn::name()
311    }
312
313    #[inline]
314    pub fn fp(&self) -> &vk::KhrAccelerationStructureFn {
315        &self.fp
316    }
317
318    #[inline]
319    pub fn device(&self) -> vk::Device {
320        self.handle
321    }
322}