wgpu/api/blas.rs
1use crate::dispatch;
2use crate::{Buffer, Label};
3use wgt::WasmNotSendSync;
4
5/// Descriptor for the size defining attributes of a triangle geometry, for a bottom level acceleration structure.
6pub type BlasTriangleGeometrySizeDescriptor = wgt::BlasTriangleGeometrySizeDescriptor;
7static_assertions::assert_impl_all!(BlasTriangleGeometrySizeDescriptor: Send, Sync);
8
9/// Descriptor for the size defining attributes, for a bottom level acceleration structure.
10pub type BlasGeometrySizeDescriptors = wgt::BlasGeometrySizeDescriptors;
11static_assertions::assert_impl_all!(BlasGeometrySizeDescriptors: Send, Sync);
12
13/// Flags for an acceleration structure.
14pub type AccelerationStructureFlags = wgt::AccelerationStructureFlags;
15static_assertions::assert_impl_all!(AccelerationStructureFlags: Send, Sync);
16
17/// Flags for a geometry inside a bottom level acceleration structure.
18pub type AccelerationStructureGeometryFlags = wgt::AccelerationStructureGeometryFlags;
19static_assertions::assert_impl_all!(AccelerationStructureGeometryFlags: Send, Sync);
20
21/// Update mode for acceleration structure builds.
22pub type AccelerationStructureUpdateMode = wgt::AccelerationStructureUpdateMode;
23static_assertions::assert_impl_all!(AccelerationStructureUpdateMode: Send, Sync);
24
25/// Descriptor to create bottom level acceleration structures.
26pub type CreateBlasDescriptor<'a> = wgt::CreateBlasDescriptor<Label<'a>>;
27static_assertions::assert_impl_all!(CreateBlasDescriptor<'_>: Send, Sync);
28
29/// Safe instance for a [Tlas].
30///
31/// A TlasInstance may be made invalid, if a TlasInstance is invalid, any attempt to build a [TlasPackage] containing an
32/// invalid TlasInstance will generate a validation error
33///
34/// Each one contains:
35/// - A reference to a BLAS, this ***must*** be interacted with using [TlasInstance::new] or [TlasInstance::set_blas], a
36/// TlasInstance that references a BLAS keeps that BLAS from being dropped
37/// - A user accessible transformation matrix
38/// - A user accessible mask
39/// - A user accessible custom index
40///
41/// [Tlas]: crate::Tlas
42/// [TlasPackage]: crate::TlasPackage
43#[derive(Debug, Clone)]
44pub struct TlasInstance {
45 pub(crate) blas: dispatch::DispatchBlas,
46 /// Affine transform matrix 3x4 (rows x columns, row major order).
47 pub transform: [f32; 12],
48 /// Custom index for the instance used inside the shader.
49 ///
50 /// This must only use the lower 24 bits, if any bits are outside that range (byte 4 does not equal 0) the TlasInstance becomes
51 /// invalid and generates a validation error when built
52 pub custom_index: u32,
53 /// Mask for the instance used inside the shader to filter instances.
54 /// Reports hit only if `(shader_cull_mask & tlas_instance.mask) != 0u`.
55 pub mask: u8,
56}
57
58impl TlasInstance {
59 /// Construct TlasInstance.
60 /// - blas: Reference to the bottom level acceleration structure
61 /// - transform: Transform buffer offset in bytes (optional, required if transform buffer is present)
62 /// - custom_index: Custom index for the instance used inside the shader (max 24 bits)
63 /// - mask: Mask for the instance used inside the shader to filter instances
64 ///
65 /// Note: while one of these contains a reference to a BLAS that BLAS will not be dropped,
66 /// but it can still be destroyed. Destroying a BLAS that is referenced by one or more
67 /// TlasInstance(s) will immediately make them invalid. If one or more of those invalid
68 /// TlasInstances is inside a TlasPackage that is attempted to be built, the build will
69 /// generate a validation error.
70 pub fn new(blas: &Blas, transform: [f32; 12], custom_index: u32, mask: u8) -> Self {
71 Self {
72 blas: blas.inner.clone(),
73 transform,
74 custom_index,
75 mask,
76 }
77 }
78
79 /// Set the bottom level acceleration structure.
80 ///
81 /// See the note on [TlasInstance] about the
82 /// guarantees of keeping a BLAS alive.
83 pub fn set_blas(&mut self, blas: &Blas) {
84 self.blas = blas.inner.clone();
85 }
86}
87
88#[derive(Debug)]
89/// Definition for a triangle geometry for a Bottom Level Acceleration Structure (BLAS).
90///
91/// The size must match the rest of the structures fields, otherwise the build will fail.
92/// (e.g. if index count is present in the size, the index buffer must be present as well.)
93pub struct BlasTriangleGeometry<'a> {
94 /// Sub descriptor for the size defining attributes of a triangle geometry.
95 pub size: &'a BlasTriangleGeometrySizeDescriptor,
96 /// Vertex buffer.
97 pub vertex_buffer: &'a Buffer,
98 /// Offset into the vertex buffer as a factor of the vertex stride.
99 pub first_vertex: u32,
100 /// Vertex stride.
101 pub vertex_stride: wgt::BufferAddress,
102 /// Index buffer (optional).
103 pub index_buffer: Option<&'a Buffer>,
104 /// Number of indexes to skip in the index buffer (optional, required if index buffer is present).
105 pub first_index: Option<u32>,
106 /// Transform buffer containing 3x4 (rows x columns, row major) affine transform matrices `[f32; 12]` (optional).
107 pub transform_buffer: Option<&'a Buffer>,
108 /// Transform buffer offset in bytes (optional, required if transform buffer is present).
109 pub transform_buffer_offset: Option<wgt::BufferAddress>,
110}
111static_assertions::assert_impl_all!(BlasTriangleGeometry<'_>: WasmNotSendSync);
112
113/// Contains the sets of geometry that go into a [Blas].
114pub enum BlasGeometries<'a> {
115 /// Triangle geometry variant.
116 TriangleGeometries(Vec<BlasTriangleGeometry<'a>>),
117}
118static_assertions::assert_impl_all!(BlasGeometries<'_>: WasmNotSendSync);
119
120/// Builds the given sets of geometry into the given [Blas].
121pub struct BlasBuildEntry<'a> {
122 /// Reference to the acceleration structure.
123 pub blas: &'a Blas,
124 /// Geometries.
125 pub geometry: BlasGeometries<'a>,
126}
127static_assertions::assert_impl_all!(BlasBuildEntry<'_>: WasmNotSendSync);
128
129#[derive(Debug, Clone)]
130/// Bottom Level Acceleration Structure (BLAS).
131///
132/// A BLAS is a device-specific raytracing acceleration structure that contains geometry data.
133///
134/// These BLASes are combined with transform in a [TlasInstance] to create a [Tlas].
135///
136/// [Tlas]: crate::Tlas
137pub struct Blas {
138 pub(crate) handle: Option<u64>,
139 pub(crate) inner: dispatch::DispatchBlas,
140}
141static_assertions::assert_impl_all!(Blas: WasmNotSendSync);
142
143crate::cmp::impl_eq_ord_hash_proxy!(Blas => .inner);
144
145impl Blas {
146 /// Raw handle to the acceleration structure, used inside raw instance buffers.
147 pub fn handle(&self) -> Option<u64> {
148 self.handle
149 }
150}
151
152/// Context version of [BlasTriangleGeometry].
153pub struct ContextBlasTriangleGeometry<'a> {
154 #[expect(dead_code)]
155 pub(crate) size: &'a BlasTriangleGeometrySizeDescriptor,
156 #[expect(dead_code)]
157 pub(crate) vertex_buffer: &'a dispatch::DispatchBuffer,
158 #[expect(dead_code)]
159 pub(crate) index_buffer: Option<&'a dispatch::DispatchBuffer>,
160 #[expect(dead_code)]
161 pub(crate) transform_buffer: Option<&'a dispatch::DispatchBuffer>,
162 #[expect(dead_code)]
163 pub(crate) first_vertex: u32,
164 #[expect(dead_code)]
165 pub(crate) vertex_stride: wgt::BufferAddress,
166 #[expect(dead_code)]
167 pub(crate) index_buffer_offset: Option<wgt::BufferAddress>,
168 #[expect(dead_code)]
169 pub(crate) transform_buffer_offset: Option<wgt::BufferAddress>,
170}
171
172/// Context version of [BlasGeometries].
173pub enum ContextBlasGeometries<'a> {
174 /// Triangle geometries.
175 TriangleGeometries(Box<dyn Iterator<Item = ContextBlasTriangleGeometry<'a>> + 'a>),
176}
177
178/// Context version see [BlasBuildEntry].
179pub struct ContextBlasBuildEntry<'a> {
180 #[expect(dead_code)]
181 pub(crate) blas: &'a dispatch::DispatchBlas,
182 #[expect(dead_code)]
183 pub(crate) geometries: ContextBlasGeometries<'a>,
184}