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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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}