1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
use alloc::vec::Vec;
#[cfg(any(feature = "serde", test))]
use serde::{Deserialize, Serialize};
#[cfg(doc)]
use crate::{Features, VertexFormat};
#[derive(Clone, Debug, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
/// Descriptor for all size defining attributes of a single triangle geometry inside a bottom level acceleration structure.
pub struct BlasTriangleGeometrySizeDescriptor {
/// Format of a vertex position, must be [`VertexFormat::Float32x3`]
/// with just [`Features::EXPERIMENTAL_RAY_QUERY`]
/// but [`Features::EXTENDED_ACCELERATION_STRUCTURE_VERTEX_FORMATS`] adds more.
pub vertex_format: crate::VertexFormat,
/// Number of vertices.
pub vertex_count: u32,
/// Format of an index. Only needed if an index buffer is used.
/// If `index_format` is provided `index_count` is required.
pub index_format: Option<crate::IndexFormat>,
/// Number of indices. Only needed if an index buffer is used.
/// If `index_count` is provided `index_format` is required.
pub index_count: Option<u32>,
/// Flags for the geometry.
pub flags: AccelerationStructureGeometryFlags,
}
#[derive(Clone, Debug)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
/// Descriptor for all size defining attributes of all geometries inside a bottom level acceleration structure.
pub enum BlasGeometrySizeDescriptors {
/// Triangle geometry version.
Triangles {
/// Descriptor for each triangle geometry.
descriptors: Vec<BlasTriangleGeometrySizeDescriptor>,
},
}
#[repr(u8)]
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
/// Update mode for acceleration structure builds.
pub enum AccelerationStructureUpdateMode {
/// Always perform a full build.
Build,
/// If possible, perform an incremental update.
///
/// Not advised for major topology changes.
/// (Useful for e.g. skinning)
PreferUpdate,
}
#[repr(C)]
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
/// Descriptor for creating a bottom level acceleration structure.
pub struct CreateBlasDescriptor<L> {
/// Label for the bottom level acceleration structure.
pub label: L,
/// Flags for the bottom level acceleration structure.
pub flags: AccelerationStructureFlags,
/// Update mode for the bottom level acceleration structure.
pub update_mode: AccelerationStructureUpdateMode,
}
impl<L> CreateBlasDescriptor<L> {
/// Takes a closure and maps the label of the blas descriptor into another.
pub fn map_label<K>(&self, fun: impl FnOnce(&L) -> K) -> CreateBlasDescriptor<K> {
CreateBlasDescriptor {
label: fun(&self.label),
flags: self.flags,
update_mode: self.update_mode,
}
}
}
#[repr(C)]
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
/// Descriptor for creating a top level acceleration structure.
pub struct CreateTlasDescriptor<L> {
/// Label for the top level acceleration structure.
pub label: L,
/// Number of instances that can be stored in the acceleration structure.
pub max_instances: u32,
/// Flags for the bottom level acceleration structure.
pub flags: AccelerationStructureFlags,
/// Update mode for the bottom level acceleration structure.
pub update_mode: AccelerationStructureUpdateMode,
}
impl<L> CreateTlasDescriptor<L> {
/// Takes a closure and maps the label of the blas descriptor into another.
pub fn map_label<K>(&self, fun: impl FnOnce(&L) -> K) -> CreateTlasDescriptor<K> {
CreateTlasDescriptor {
label: fun(&self.label),
flags: self.flags,
update_mode: self.update_mode,
max_instances: self.max_instances,
}
}
}
bitflags::bitflags!(
/// Flags for acceleration structures
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "serde", serde(transparent))]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct AccelerationStructureFlags: u8 {
/// Allow for incremental updates (no change in size), currently this is unimplemented
/// and will build as normal (this is fine, update vs build should be unnoticeable)
const ALLOW_UPDATE = 1 << 0;
/// Allow the acceleration structure to be compacted in a copy operation
/// (`Blas::prepare_for_compaction`, `CommandEncoder::compact_blas`).
const ALLOW_COMPACTION = 1 << 1;
/// Optimize for fast ray tracing performance, recommended if the geometry is unlikely
/// to change (e.g. in a game: non-interactive scene geometry)
const PREFER_FAST_TRACE = 1 << 2;
/// Optimize for fast build time, recommended if geometry is likely to change frequently
/// (e.g. in a game: player model).
const PREFER_FAST_BUILD = 1 << 3;
/// Optimize for low memory footprint (both while building and in the output BLAS).
const LOW_MEMORY = 1 << 4;
/// Use `BlasTriangleGeometry::transform_buffer` when building a BLAS (only allowed in
/// BLAS creation)
const USE_TRANSFORM = 1 << 5;
/// Allow retrieval of the vertices of the triangle hit by a ray.
const ALLOW_RAY_HIT_VERTEX_RETURN = 1 << 6;
}
);
bitflags::bitflags!(
/// Flags for acceleration structure geometries
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "serde", serde(transparent))]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct AccelerationStructureGeometryFlags: u8 {
/// Is OPAQUE (is there no alpha test) recommended as currently in naga there is no
/// candidate intersections yet so currently BLASes without this flag will not have hits.
/// Not enabling this makes the BLAS unable to be interacted with in WGSL.
const OPAQUE = 1 << 0;
/// NO_DUPLICATE_ANY_HIT_INVOCATION, not useful unless using hal with wgpu, ray-tracing
/// pipelines are not supported in wgpu so any-hit shaders do not exist. For when any-hit
/// shaders are implemented (or experienced users who combine this with an underlying library:
/// for any primitive (triangle or AABB) multiple any-hit shaders sometimes may be invoked
/// (especially in AABBs like a sphere), if this flag in present only one hit on a primitive may
/// invoke an any-hit shader.
const NO_DUPLICATE_ANY_HIT_INVOCATION = 1 << 1;
}
);
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
/// What a copy between acceleration structures should do
pub enum AccelerationStructureCopy {
/// Directly duplicate an acceleration structure to another
Clone,
/// Duplicate and compact an acceleration structure
Compact,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
/// What type the data of an acceleration structure is
pub enum AccelerationStructureType {
/// The types of the acceleration structure are triangles
Triangles,
/// The types of the acceleration structure are axis aligned bounding boxes
AABBs,
/// The types of the acceleration structure are instances
Instances,
}
/// Alignment requirement for transform buffers used in acceleration structure builds
pub const TRANSFORM_BUFFER_ALIGNMENT: crate::BufferAddress = 16;
/// Alignment requirement for instance buffers used in acceleration structure builds (`build_acceleration_structures_unsafe_tlas`)
pub const INSTANCE_BUFFER_ALIGNMENT: crate::BufferAddress = 16;