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