vk_graph/cmd/cmd_ref.rs
1use {
2 crate::{
3 AnyAccelerationStructureNode, AnyResource, Execution, Node,
4 driver::{
5 accel_struct::{
6 AccelerationStructureGeometry, AccelerationStructureGeometryInfo,
7 DeviceOrHostAddress,
8 },
9 device::Device,
10 },
11 },
12 ash::vk,
13 log::trace,
14 std::{cell::RefCell, ops::Deref},
15};
16
17/// Recording interface for general Vulkan commands.
18///
19/// This structure provides a strongly-typed set of methods which allow acceleration structures to
20/// be built and updated.
21///
22/// # Examples
23///
24/// Basic usage:
25///
26/// ```no_run
27/// # use ash::vk;
28/// # use vk_graph::Graph;
29/// # fn main() {
30/// # let mut my_graph = Graph::default();
31/// my_graph.begin_cmd()
32/// .record_cmd(move |cmd| {
33/// // Use provided command buffer functions or native calls
34/// assert_ne!(cmd.handle, vk::CommandBuffer::null());
35/// });
36/// # }
37/// ```
38#[derive(Clone, Copy)]
39pub struct CommandRef<'a> {
40 cmd: &'a crate::driver::cmd_buf::CommandBuffer,
41
42 #[cfg(feature = "checked")]
43 exec: &'a Execution,
44
45 #[cfg(feature = "checked")]
46 graph_id: crate::GraphId,
47
48 node_map: Option<&'a [usize]>,
49 resources: &'a [AnyResource],
50}
51
52impl<'a> CommandRef<'a> {
53 pub(crate) fn new(
54 cmd: &'a crate::driver::cmd_buf::CommandBuffer,
55 resources: &'a [AnyResource],
56 exec: &'a Execution,
57 #[cfg(feature = "checked")] graph_id: crate::GraphId,
58 ) -> Self {
59 Self {
60 cmd,
61 node_map: exec.node_map.as_deref(),
62 resources,
63
64 #[cfg(feature = "checked")]
65 exec,
66
67 #[cfg(feature = "checked")]
68 graph_id: exec.stream_graph_id.unwrap_or(graph_id),
69 }
70 }
71
72 /// Build acceleration structures.
73 ///
74 /// There is no ordering or synchronization implied between any of the individual acceleration
75 /// structure builds.
76 ///
77 /// Requires a scratch buffer which was created with the following requirements:
78 ///
79 /// - Flags must include [`vk::BufferUsageFlags::SHADER_DEVICE_ADDRESS`]
80 /// - Size must be equal to or greater than the `build_size` value returned by
81 /// `AccelerationStructure::size_of`, aligned to `min_accel_struct_scratch_offset_alignment`
82 /// of `PhysicalDevice::vk_khr_acceleration_structure`.
83 ///
84 /// # Examples
85 ///
86 /// Basic usage:
87 ///
88 /// ```no_run
89 /// # use ash::vk;
90 /// # use vk_graph::cmd::BuildAccelerationStructureInfo;
91 /// # use vk_sync::AccessType;
92 /// # use vk_graph::driver::DriverError;
93 /// # use vk_graph::driver::device::{Device, DeviceInfo};
94 /// # use vk_graph::driver::accel_struct::{
95 /// # AccelerationStructure,
96 /// # AccelerationStructureGeometry,
97 /// # AccelerationStructureGeometryData,
98 /// # AccelerationStructureGeometryInfo,
99 /// # AccelerationStructureInfo,
100 /// # DeviceOrHostAddress,
101 /// # };
102 /// # use vk_graph::driver::buffer::{Buffer, BufferInfo};
103 /// # use vk_graph::Graph;
104 /// # use vk_graph::driver::shader::Shader;
105 /// # fn main() -> Result<(), DriverError> {
106 /// # let device = Device::create(DeviceInfo::default())?;
107 /// # let mut my_graph = Graph::default();
108 /// # let info = AccelerationStructureInfo::blas(1);
109 /// # let blas_accel_struct = AccelerationStructure::create(&device, info)?;
110 /// # let blas_node = my_graph.bind_resource(blas_accel_struct);
111 /// # let scratch_buf_info =
112 /// # BufferInfo::device_mem(8, vk::BufferUsageFlags::SHADER_DEVICE_ADDRESS);
113 /// # let scratch_buf = Buffer::create(&device, scratch_buf_info)?;
114 /// # let scratch_buf = my_graph.bind_resource(scratch_buf);
115 /// # let buf_info = BufferInfo::device_mem(8, vk::BufferUsageFlags::INDEX_BUFFER);
116 /// # let my_idx_buf = Buffer::create(&device, buf_info)?;
117 /// # let buf_info = BufferInfo::device_mem(8, vk::BufferUsageFlags::VERTEX_BUFFER);
118 /// # let my_vtx_buf = Buffer::create(&device, buf_info)?;
119 /// # let index_buf = my_graph.bind_resource(my_idx_buf);
120 /// # let vertex_buf = my_graph.bind_resource(my_vtx_buf);
121 /// my_graph.begin_cmd()
122 /// .resource_access(index_buf, AccessType::IndexBuffer)
123 /// .resource_access(vertex_buf, AccessType::VertexBuffer)
124 /// .resource_access(scratch_buf, AccessType::AccelerationStructureBufferWrite)
125 /// .resource_access(blas_node, AccessType::AccelerationStructureBuildWrite)
126 /// .record_cmd(move |cmd| {
127 /// let scratch_addr = cmd.resource(scratch_buf).device_address();
128 /// let geom = AccelerationStructureGeometry {
129 /// max_primitive_count: 64,
130 /// flags: vk::GeometryFlagsKHR::OPAQUE,
131 /// geometry: AccelerationStructureGeometryData::Triangles {
132 /// index_addr: DeviceOrHostAddress::DeviceAddress(
133 /// cmd.resource(index_buf).device_address()
134 /// ),
135 /// index_type: vk::IndexType::UINT32,
136 /// max_vertex: 42,
137 /// transform_addr: None,
138 /// vertex_addr: DeviceOrHostAddress::DeviceAddress(
139 /// cmd.resource(vertex_buf).device_address(),
140 /// ),
141 /// vertex_format: vk::Format::R32G32B32_SFLOAT,
142 /// vertex_stride: 12,
143 /// },
144 /// };
145 /// let build_range = vk::AccelerationStructureBuildRangeInfoKHR {
146 /// first_vertex: 0,
147 /// primitive_count: 1,
148 /// primitive_offset: 0,
149 /// transform_offset: 0,
150 /// };
151 /// let info = AccelerationStructureGeometryInfo::blas([(geom, build_range)]);
152 ///
153 /// cmd.build_accel_struct(&[
154 /// BuildAccelerationStructureInfo::new(blas_node, scratch_addr, info)
155 /// ]);
156 /// });
157 /// # Ok(()) }
158 /// ```
159 ///
160 /// See also:
161 ///
162 /// - [`examples/ray_omni.rs`](/examples/ray_omni.rs)
163 /// - [`examples/ray_tracing.rs`](/examples/ray_tracing.rs)
164 /// - [`examples/rt_triangle.rs`](/examples/rt_triangle.rs)
165 pub fn build_accel_struct(&self, infos: &[BuildAccelerationStructureInfo]) -> &Self {
166 #[derive(Default)]
167 struct Tls {
168 geometries: Vec<vk::AccelerationStructureGeometryKHR<'static>>,
169 ranges: Vec<vk::AccelerationStructureBuildRangeInfoKHR>,
170 }
171
172 thread_local! {
173 static TLS: RefCell<Tls> = Default::default();
174 }
175
176 TLS.with_borrow_mut(|tls| {
177 tls.geometries.clear();
178 tls.geometries.extend(infos.iter().flat_map(|info| {
179 info.build_data.geometries.iter().map(|(geometry, _)| {
180 <&AccelerationStructureGeometry as Into<
181 vk::AccelerationStructureGeometryKHR,
182 >>::into(geometry)
183 })
184 }));
185
186 tls.ranges.clear();
187 tls.ranges.extend(
188 infos
189 .iter()
190 .flat_map(|info| info.build_data.geometries.iter().map(|(_, range)| *range)),
191 );
192
193 let vk_ranges = {
194 let mut start = 0;
195 let mut vk_ranges = Vec::with_capacity(infos.len());
196 for info in infos {
197 let end = start + info.build_data.geometries.len();
198 vk_ranges.push(&tls.ranges[start..end]);
199 start = end;
200 }
201
202 vk_ranges
203 };
204
205 let vk_infos = {
206 let mut start = 0;
207 let mut vk_infos = Vec::with_capacity(infos.len());
208 for info in infos {
209 let end = start + info.build_data.geometries.len();
210 vk_infos.push(
211 vk::AccelerationStructureBuildGeometryInfoKHR::default()
212 .ty(info.build_data.acceleration_structure_type)
213 .flags(info.build_data.flags)
214 .mode(vk::BuildAccelerationStructureModeKHR::BUILD)
215 .dst_acceleration_structure(self.resource(info.accel_struct).handle)
216 .geometries(&tls.geometries[start..end])
217 .scratch_data(info.scratch_addr.into()),
218 );
219 start = end;
220 }
221
222 vk_infos
223 };
224
225 let khr_acceleration_structure =
226 Device::expect_vk_khr_acceleration_structure(&self.cmd.device);
227
228 unsafe {
229 khr_acceleration_structure.cmd_build_acceleration_structures(
230 self.cmd.handle,
231 &vk_infos,
232 &vk_ranges,
233 );
234 }
235 });
236
237 self
238 }
239
240 /// Builds acceleration structures with some parameters provided on the device.
241 ///
242 /// There is no ordering or synchronization implied between any of the individual acceleration
243 /// structure builds.
244 ///
245 /// Each [`BuildAccelerationStructureIndirectInfo::range_base`] is a buffer device address which
246 /// points to an array of [`vk::AccelerationStructureBuildRangeInfoKHR`] structures defining
247 /// dynamic offsets to the addresses where geometry data is stored.
248 pub fn build_accel_struct_indirect(
249 &self,
250 infos: &[BuildAccelerationStructureIndirectInfo],
251 ) -> &Self {
252 #[derive(Default)]
253 struct Tls {
254 geometries: Vec<vk::AccelerationStructureGeometryKHR<'static>>,
255 max_primitive_counts: Vec<u32>,
256 range_bases: Vec<vk::DeviceAddress>,
257 range_strides: Vec<u32>,
258 }
259
260 thread_local! {
261 static TLS: RefCell<Tls> = Default::default();
262 }
263
264 TLS.with_borrow_mut(|tls| {
265 tls.geometries.clear();
266 tls.geometries.extend(infos.iter().flat_map(|info| {
267 info.build_data.geometries.iter().map(
268 <&AccelerationStructureGeometry as Into<
269 vk::AccelerationStructureGeometryKHR,
270 >>::into,
271 )
272 }));
273
274 tls.max_primitive_counts.clear();
275 tls.max_primitive_counts
276 .extend(infos.iter().flat_map(|info| {
277 info.build_data
278 .geometries
279 .iter()
280 .map(|geometry| geometry.max_primitive_count)
281 }));
282
283 tls.range_bases.clear();
284 tls.range_strides.clear();
285 let (vk_infos, vk_max_primitive_counts) = {
286 let mut start = 0;
287 let mut vk_infos = Vec::with_capacity(infos.len());
288 let mut vk_max_primitive_counts = Vec::with_capacity(infos.len());
289 for info in infos {
290 let end = start + info.build_data.geometries.len();
291 vk_infos.push(
292 vk::AccelerationStructureBuildGeometryInfoKHR::default()
293 .ty(info.build_data.acceleration_structure_type)
294 .flags(info.build_data.flags)
295 .mode(vk::BuildAccelerationStructureModeKHR::BUILD)
296 .dst_acceleration_structure(self.resource(info.accel_struct).handle)
297 .geometries(&tls.geometries[start..end])
298 .scratch_data(info.scratch_data.into()),
299 );
300 vk_max_primitive_counts.push(&tls.max_primitive_counts[start..end]);
301 start = end;
302
303 tls.range_bases.push(info.range_base);
304 tls.range_strides.push(info.range_stride);
305 }
306
307 (vk_infos, vk_max_primitive_counts)
308 };
309
310 let khr_acceleration_structure =
311 Device::expect_vk_khr_acceleration_structure(&self.cmd.device);
312
313 unsafe {
314 khr_acceleration_structure.cmd_build_acceleration_structures_indirect(
315 self.cmd.handle,
316 &vk_infos,
317 &tls.range_bases,
318 &tls.range_strides,
319 &vk_max_primitive_counts,
320 );
321 }
322 });
323
324 self
325 }
326
327 pub(crate) fn clone_resource_at(&self, node_idx: usize) -> AnyResource {
328 self.resources[node_idx].clone()
329 }
330
331 pub(crate) fn cmd_push_constants(
332 &self,
333 layout: vk::PipelineLayout,
334 push_consts: &[vk::PushConstantRange],
335 offset: u32,
336 data: &[u8],
337 ) {
338 for push_const in push_consts {
339 let push_const_end = push_const.offset + push_const.size;
340 let data_end = offset + data.len() as u32;
341 let end = data_end.min(push_const_end);
342 let start = offset.max(push_const.offset);
343
344 if end > start {
345 trace!(
346 " push constants {:?} {}..{}",
347 push_const.stage_flags, start, end
348 );
349
350 unsafe {
351 self.device.cmd_push_constants(
352 self.handle,
353 layout,
354 push_const.stage_flags,
355 start,
356 &data[(start - offset) as usize..(end - offset) as usize],
357 );
358 }
359 }
360 }
361 }
362
363 /// Update acceleration structures.
364 ///
365 /// There is no ordering or synchronization implied between any of the individual acceleration
366 /// structure updates.
367 ///
368 /// Requires a scratch buffer which was created with the following requirements:
369 ///
370 /// - Flags must include [`vk::BufferUsageFlags::SHADER_DEVICE_ADDRESS`]
371 /// - Size must be equal to or greater than the `update_size` value returned by
372 /// `AccelerationStructure::size_of`, aligned to `min_accel_struct_scratch_offset_alignment`
373 /// of `PhysicalDevice::vk_khr_acceleration_structure`.
374 pub fn update_accel_struct(&self, infos: &[UpdateAccelerationStructureInfo]) -> &Self {
375 #[derive(Default)]
376 struct Tls {
377 geometries: Vec<vk::AccelerationStructureGeometryKHR<'static>>,
378 ranges: Vec<vk::AccelerationStructureBuildRangeInfoKHR>,
379 }
380
381 thread_local! {
382 static TLS: RefCell<Tls> = Default::default();
383 }
384
385 TLS.with_borrow_mut(|tls| {
386 tls.geometries.clear();
387 tls.geometries.extend(infos.iter().flat_map(|info| {
388 info.update_data.geometries.iter().map(|(geometry, _)| {
389 <&AccelerationStructureGeometry as Into<
390 vk::AccelerationStructureGeometryKHR,
391 >>::into(geometry)
392 })
393 }));
394
395 tls.ranges.clear();
396 tls.ranges.extend(
397 infos
398 .iter()
399 .flat_map(|info| info.update_data.geometries.iter().map(|(_, range)| *range)),
400 );
401
402 let vk_ranges = {
403 let mut start = 0;
404 let mut vk_ranges = Vec::with_capacity(infos.len());
405 for info in infos {
406 let end = start + info.update_data.geometries.len();
407 vk_ranges.push(&tls.ranges[start..end]);
408 start = end;
409 }
410
411 vk_ranges
412 };
413
414 let vk_infos = {
415 let mut start = 0;
416 let mut vk_infos = Vec::with_capacity(infos.len());
417 for info in infos {
418 let end = start + info.update_data.geometries.len();
419 vk_infos.push(
420 vk::AccelerationStructureBuildGeometryInfoKHR::default()
421 .ty(info.update_data.acceleration_structure_type)
422 .flags(info.update_data.flags)
423 .mode(vk::BuildAccelerationStructureModeKHR::UPDATE)
424 .dst_acceleration_structure(self.resource(info.dst_accel_struct).handle)
425 .src_acceleration_structure(self.resource(info.src_accel_struct).handle)
426 .geometries(&tls.geometries[start..end])
427 .scratch_data(info.scratch_addr.into()),
428 );
429 start = end;
430 }
431
432 vk_infos
433 };
434
435 let khr_acceleration_structure =
436 Device::expect_vk_khr_acceleration_structure(&self.cmd.device);
437
438 unsafe {
439 khr_acceleration_structure.cmd_build_acceleration_structures(
440 self.cmd.handle,
441 &vk_infos,
442 &vk_ranges,
443 );
444 }
445 });
446
447 self
448 }
449
450 /// Updates acceleration structures with some parameters provided on the device.
451 ///
452 /// There is no ordering or synchronization implied between any of the individual acceleration
453 /// structure updates.
454 ///
455 /// Each [`UpdateAccelerationStructureIndirectInfo::range_base`] is a buffer device address
456 /// which points to an array of [`vk::AccelerationStructureBuildRangeInfoKHR`] structures
457 /// defining dynamic offsets to the addresses where geometry data is stored.
458 pub fn update_accel_struct_indirect(
459 &self,
460 infos: &[UpdateAccelerationStructureIndirectInfo],
461 ) -> &Self {
462 #[derive(Default)]
463 struct Tls {
464 geometries: Vec<vk::AccelerationStructureGeometryKHR<'static>>,
465 max_primitive_counts: Vec<u32>,
466 range_bases: Vec<vk::DeviceAddress>,
467 range_strides: Vec<u32>,
468 }
469
470 thread_local! {
471 static TLS: RefCell<Tls> = Default::default();
472 }
473
474 TLS.with_borrow_mut(|tls| {
475 tls.geometries.clear();
476 tls.geometries.extend(infos.iter().flat_map(|info| {
477 info.update_data.geometries.iter().map(
478 <&AccelerationStructureGeometry as Into<
479 vk::AccelerationStructureGeometryKHR,
480 >>::into,
481 )
482 }));
483
484 tls.max_primitive_counts.clear();
485 tls.max_primitive_counts
486 .extend(infos.iter().flat_map(|info| {
487 info.update_data
488 .geometries
489 .iter()
490 .map(|geometry| geometry.max_primitive_count)
491 }));
492
493 tls.range_bases.clear();
494 tls.range_strides.clear();
495 let (vk_infos, vk_max_primitive_counts) = {
496 let mut start = 0;
497 let mut vk_infos = Vec::with_capacity(infos.len());
498 let mut vk_max_primitive_counts = Vec::with_capacity(infos.len());
499 for info in infos {
500 let end = start + info.update_data.geometries.len();
501 vk_infos.push(
502 vk::AccelerationStructureBuildGeometryInfoKHR::default()
503 .ty(info.update_data.acceleration_structure_type)
504 .flags(info.update_data.flags)
505 .mode(vk::BuildAccelerationStructureModeKHR::UPDATE)
506 .src_acceleration_structure(self.resource(info.src_accel_struct).handle)
507 .dst_acceleration_structure(self.resource(info.dst_accel_struct).handle)
508 .geometries(&tls.geometries[start..end])
509 .scratch_data(info.scratch_addr.into()),
510 );
511 vk_max_primitive_counts.push(&tls.max_primitive_counts[start..end]);
512 start = end;
513
514 tls.range_bases.push(info.range_base);
515 tls.range_strides.push(info.range_stride);
516 }
517
518 (vk_infos, vk_max_primitive_counts)
519 };
520
521 let khr_acceleration_structure =
522 Device::expect_vk_khr_acceleration_structure(&self.cmd.device);
523
524 unsafe {
525 khr_acceleration_structure.cmd_build_acceleration_structures_indirect(
526 self.cmd.handle,
527 &vk_infos,
528 &tls.range_bases,
529 &tls.range_strides,
530 &vk_max_primitive_counts,
531 );
532 }
533 });
534
535 self
536 }
537
538 /// Returns a borrow of the original Vulkan resource (buffer, image or acceleration structure)
539 /// which the given bound resource node represents.
540 pub fn resource<N>(&self, resource_node: N) -> &N::Resource
541 where
542 N: Node,
543 {
544 #[cfg(feature = "checked")]
545 resource_node.assert_owner(self.graph_id);
546
547 let mut node_idx = resource_node.index();
548 if let Some(node_map) = self.node_map {
549 node_idx = node_map[node_idx];
550 }
551
552 /*
553 You must have called an access function for this node on this execution before borrowing
554 the resource!
555
556 Code that attempts to access this function is attempting to get access to the Vulkan
557 resource (buffer, image, or acceleration structure). In order to access any resources the
558 access type must first be specified so the correct barriers may be added.
559
560 See: https://attackgoat.github.io/vk-graph/pipeline_sync.html
561 */
562 #[cfg(feature = "checked")]
563 assert!(
564 self.exec.accesses.contains(node_idx),
565 "unexpected node access: call an access function first"
566 );
567
568 resource_node.borrow_at(self.resources, node_idx)
569 }
570}
571
572impl<'a> Deref for CommandRef<'a> {
573 type Target = crate::driver::cmd_buf::CommandBuffer;
574
575 fn deref(&self) -> &Self::Target {
576 self.cmd
577 }
578}
579
580/// Specifies the information and data used to build an acceleration structure.
581///
582/// See [`vkCmdBuildAccelerationStructuresKHR`](https://registry.khronos.org/vulkan/specs/latest/man/html/vkCmdBuildAccelerationStructuresKHR.html).
583#[derive(Clone, Debug)]
584pub struct BuildAccelerationStructureInfo {
585 /// The acceleration structure to be written.
586 pub accel_struct: AnyAccelerationStructureNode,
587
588 /// Specifies the geometry data to use when building the acceleration structure.
589 pub build_data: AccelerationStructureGeometryInfo<(
590 AccelerationStructureGeometry,
591 vk::AccelerationStructureBuildRangeInfoKHR,
592 )>,
593
594 /// The temporary buffer or host address (with enough capacity per
595 /// `AccelerationStructure::size_of`).
596 pub scratch_addr: DeviceOrHostAddress,
597}
598
599impl BuildAccelerationStructureInfo {
600 /// Constructs new acceleration structure build information.
601 pub fn new(
602 accel_struct: impl Into<AnyAccelerationStructureNode>,
603 scratch_addr: impl Into<DeviceOrHostAddress>,
604 build_data: AccelerationStructureGeometryInfo<(
605 AccelerationStructureGeometry,
606 vk::AccelerationStructureBuildRangeInfoKHR,
607 )>,
608 ) -> Self {
609 let accel_struct = accel_struct.into();
610 let scratch_addr = scratch_addr.into();
611
612 Self {
613 accel_struct,
614 build_data,
615 scratch_addr,
616 }
617 }
618}
619
620/// Specifies the information and data used to build an acceleration structure with some parameters
621/// sourced on the device.
622///
623/// See [`vkCmdBuildAccelerationStructuresKHR`](https://registry.khronos.org/vulkan/specs/latest/man/html/vkCmdBuildAccelerationStructuresKHR.html).
624#[derive(Clone, Debug)]
625pub struct BuildAccelerationStructureIndirectInfo {
626 /// The acceleration structure to be written.
627 pub accel_struct: AnyAccelerationStructureNode,
628
629 /// Specifies the geometry data to use when building the acceleration structure.
630 pub build_data: AccelerationStructureGeometryInfo<AccelerationStructureGeometry>,
631
632 /// A buffer device address which points to `data.geometry.len()`
633 /// [vk::AccelerationStructureBuildRangeInfoKHR] structures defining dynamic offsets to the
634 /// addresses where geometry data is stored.
635 pub range_base: vk::DeviceAddress,
636
637 /// Byte stride between elements of [`Self::range_base`].
638 pub range_stride: u32,
639
640 /// The temporary buffer or host address (with enough capacity per
641 /// `AccelerationStructure::size_of`).
642 pub scratch_data: DeviceOrHostAddress,
643}
644
645impl BuildAccelerationStructureIndirectInfo {
646 /// Constructs new acceleration structure indirect build information.
647 pub fn new(
648 accel_struct: impl Into<AnyAccelerationStructureNode>,
649 scratch_data: impl Into<DeviceOrHostAddress>,
650 build_data: AccelerationStructureGeometryInfo<AccelerationStructureGeometry>,
651 range_base: vk::DeviceAddress,
652 range_stride: u32,
653 ) -> Self {
654 let accel_struct = accel_struct.into();
655 let scratch_data = scratch_data.into();
656
657 Self {
658 accel_struct,
659 build_data,
660 range_base,
661 range_stride,
662 scratch_data,
663 }
664 }
665}
666
667/// Specifies the information and data used to update an acceleration structure with some parameters
668/// sourced on the device.
669///
670/// See [`vkCmdBuildAccelerationStructuresKHR`](https://registry.khronos.org/vulkan/specs/latest/man/html/vkCmdBuildAccelerationStructuresKHR.html).
671#[derive(Clone, Debug)]
672pub struct UpdateAccelerationStructureIndirectInfo {
673 /// The acceleration structure to be written.
674 pub dst_accel_struct: AnyAccelerationStructureNode,
675
676 /// A buffer device address which points to `data.geometry.len()`
677 /// [vk::AccelerationStructureBuildRangeInfoKHR] structures defining dynamic offsets to the
678 /// addresses where geometry data is stored.
679 pub range_base: vk::DeviceAddress,
680
681 /// Byte stride between elements of [`Self::range_base`].
682 pub range_stride: u32,
683
684 /// The temporary buffer or host address (with enough capacity per
685 /// `AccelerationStructure::size_of`).
686 pub scratch_addr: DeviceOrHostAddress,
687
688 /// The source acceleration structure to be read.
689 pub src_accel_struct: AnyAccelerationStructureNode,
690
691 /// Specifies the geometry data to use when building the acceleration structure.
692 pub update_data: AccelerationStructureGeometryInfo<AccelerationStructureGeometry>,
693}
694
695impl UpdateAccelerationStructureIndirectInfo {
696 /// Constructs new acceleration structure indirect update information.
697 pub fn new(
698 src_accel_struct: impl Into<AnyAccelerationStructureNode>,
699 dst_accel_struct: impl Into<AnyAccelerationStructureNode>,
700 scratch_addr: impl Into<DeviceOrHostAddress>,
701 update_data: AccelerationStructureGeometryInfo<AccelerationStructureGeometry>,
702 range_base: vk::DeviceAddress,
703 range_stride: u32,
704 ) -> Self {
705 let src_accel_struct = src_accel_struct.into();
706 let dst_accel_struct = dst_accel_struct.into();
707 let scratch_addr = scratch_addr.into();
708
709 Self {
710 dst_accel_struct,
711 range_base,
712 range_stride,
713 scratch_addr,
714 src_accel_struct,
715 update_data,
716 }
717 }
718}
719
720/// Specifies the information and data used to update an acceleration structure.
721#[derive(Clone, Debug)]
722pub struct UpdateAccelerationStructureInfo {
723 /// The acceleration structure to be written.
724 pub dst_accel_struct: AnyAccelerationStructureNode,
725
726 /// The temporary buffer or host address (with enough capacity per
727 /// `AccelerationStructure::size_of`).
728 pub scratch_addr: DeviceOrHostAddress,
729
730 /// The source acceleration structure to be read.
731 pub src_accel_struct: AnyAccelerationStructureNode,
732
733 /// Specifies the geometry data to use when updating the acceleration structure.
734 pub update_data: AccelerationStructureGeometryInfo<(
735 AccelerationStructureGeometry,
736 vk::AccelerationStructureBuildRangeInfoKHR,
737 )>,
738}
739
740impl UpdateAccelerationStructureInfo {
741 /// Constructs new acceleration structure update information.
742 pub fn new(
743 src_accel_struct: impl Into<AnyAccelerationStructureNode>,
744 dst_accel_struct: impl Into<AnyAccelerationStructureNode>,
745 scratch_addr: impl Into<DeviceOrHostAddress>,
746 update_data: AccelerationStructureGeometryInfo<(
747 AccelerationStructureGeometry,
748 vk::AccelerationStructureBuildRangeInfoKHR,
749 )>,
750 ) -> Self {
751 let src_accel_struct = src_accel_struct.into();
752 let dst_accel_struct = dst_accel_struct.into();
753 let scratch_addr = scratch_addr.into();
754
755 Self {
756 dst_accel_struct,
757 scratch_addr,
758 src_accel_struct,
759 update_data,
760 }
761 }
762}