1use alloc::{boxed::Box, sync::Arc, vec::Vec};
11
12use thiserror::Error;
13use wgt::{AccelerationStructureGeometryFlags, BufferAddress, IndexFormat, VertexFormat};
14
15use crate::{
16 command::CommandEncoderError,
17 device::{DeviceError, MissingFeatures},
18 id::{BlasId, BufferId, TlasId},
19 resource::{
20 Blas, DestroyedResourceError, InvalidResourceError, MissingBufferUsageError,
21 ResourceErrorIdent, Tlas,
22 },
23};
24
25#[derive(Clone, Debug, Error)]
26pub enum CreateBlasError {
27 #[error(transparent)]
28 Device(#[from] DeviceError),
29 #[error(transparent)]
30 MissingFeatures(#[from] MissingFeatures),
31 #[error(
32 "Only one of 'index_count' and 'index_format' was provided (either provide both or none)"
33 )]
34 MissingIndexData,
35 #[error("Provided format was not within allowed formats. Provided format: {0:?}. Allowed formats: {1:?}")]
36 InvalidVertexFormat(VertexFormat, Vec<VertexFormat>),
37}
38
39#[derive(Clone, Debug, Error)]
40pub enum CreateTlasError {
41 #[error(transparent)]
42 Device(#[from] DeviceError),
43 #[error(transparent)]
44 MissingFeatures(#[from] MissingFeatures),
45 #[error("Flag {0:?} is not allowed on a TLAS")]
46 DisallowedFlag(wgt::AccelerationStructureFlags),
47}
48
49#[derive(Clone, Debug, Error)]
51pub enum BuildAccelerationStructureError {
52 #[error(transparent)]
53 Encoder(#[from] CommandEncoderError),
54
55 #[error(transparent)]
56 Device(#[from] DeviceError),
57
58 #[error(transparent)]
59 InvalidResource(#[from] InvalidResourceError),
60
61 #[error(transparent)]
62 DestroyedResource(#[from] DestroyedResourceError),
63
64 #[error(transparent)]
65 MissingBufferUsage(#[from] MissingBufferUsageError),
66
67 #[error(transparent)]
68 MissingFeatures(#[from] MissingFeatures),
69
70 #[error(
71 "Buffer {0:?} size is insufficient for provided size information (size: {1}, required: {2}"
72 )]
73 InsufficientBufferSize(ResourceErrorIdent, u64, u64),
74
75 #[error("Buffer {0:?} associated offset doesn't align with the index type")]
76 UnalignedIndexBufferOffset(ResourceErrorIdent),
77
78 #[error("Buffer {0:?} associated offset is unaligned")]
79 UnalignedTransformBufferOffset(ResourceErrorIdent),
80
81 #[error("Buffer {0:?} associated index count not divisible by 3 (count: {1}")]
82 InvalidIndexCount(ResourceErrorIdent, u32),
83
84 #[error("Buffer {0:?} associated data contains None")]
85 MissingAssociatedData(ResourceErrorIdent),
86
87 #[error(
88 "Blas {0:?} build sizes to may be greater than the descriptor at build time specified"
89 )]
90 IncompatibleBlasBuildSizes(ResourceErrorIdent),
91
92 #[error("Blas {0:?} flags are different, creation flags: {1:?}, provided: {2:?}")]
93 IncompatibleBlasFlags(
94 ResourceErrorIdent,
95 AccelerationStructureGeometryFlags,
96 AccelerationStructureGeometryFlags,
97 ),
98
99 #[error("Blas {0:?} build vertex count is greater than creation count (needs to be less than or equal to), creation: {1:?}, build: {2:?}")]
100 IncompatibleBlasVertexCount(ResourceErrorIdent, u32, u32),
101
102 #[error("Blas {0:?} vertex formats are different, creation format: {1:?}, provided: {2:?}")]
103 DifferentBlasVertexFormats(ResourceErrorIdent, VertexFormat, VertexFormat),
104
105 #[error("Blas {0:?} index count was provided at creation or building, but not the other")]
106 BlasIndexCountProvidedMismatch(ResourceErrorIdent),
107
108 #[error("Blas {0:?} build index count is greater than creation count (needs to be less than or equal to), creation: {1:?}, build: {2:?}")]
109 IncompatibleBlasIndexCount(ResourceErrorIdent, u32, u32),
110
111 #[error("Blas {0:?} index formats are different, creation format: {1:?}, provided: {2:?}")]
112 DifferentBlasIndexFormats(ResourceErrorIdent, Option<IndexFormat>, Option<IndexFormat>),
113
114 #[error("Blas {0:?} build sizes require index buffer but none was provided")]
115 MissingIndexBuffer(ResourceErrorIdent),
116
117 #[error(
118 "Tlas {0:?} an associated instances contains an invalid custom index (more than 24bits)"
119 )]
120 TlasInvalidCustomIndex(ResourceErrorIdent),
121
122 #[error(
123 "Tlas {0:?} has {1} active instances but only {2} are allowed as specified by the descriptor at creation"
124 )]
125 TlasInstanceCountExceeded(ResourceErrorIdent, u32, u32),
126
127 #[error("Blas {0:?} has flag USE_TRANSFORM but the transform buffer is missing")]
128 TransformMissing(ResourceErrorIdent),
129
130 #[error("Blas {0:?} is missing the flag USE_TRANSFORM but the transform buffer is set")]
131 UseTransformMissing(ResourceErrorIdent),
132 #[error(
133 "Tlas {0:?} dependent {1:?} is missing AccelerationStructureFlags::ALLOW_RAY_HIT_VERTEX_RETURN"
134 )]
135 TlasDependentMissingVertexReturn(ResourceErrorIdent, ResourceErrorIdent),
136}
137
138#[derive(Clone, Debug, Error)]
139pub enum ValidateAsActionsError {
140 #[error(transparent)]
141 DestroyedResource(#[from] DestroyedResourceError),
142
143 #[error("Tlas {0:?} is used before it is built")]
144 UsedUnbuiltTlas(ResourceErrorIdent),
145
146 #[error("Blas {0:?} is used before it is built (in Tlas {1:?})")]
147 UsedUnbuiltBlas(ResourceErrorIdent, ResourceErrorIdent),
148
149 #[error("Blas {0:?} is newer than the containing Tlas {1:?}")]
150 BlasNewerThenTlas(ResourceErrorIdent, ResourceErrorIdent),
151}
152
153#[derive(Debug)]
154pub struct BlasTriangleGeometry<'a> {
155 pub size: &'a wgt::BlasTriangleGeometrySizeDescriptor,
156 pub vertex_buffer: BufferId,
157 pub index_buffer: Option<BufferId>,
158 pub transform_buffer: Option<BufferId>,
159 pub first_vertex: u32,
160 pub vertex_stride: BufferAddress,
161 pub first_index: Option<u32>,
162 pub transform_buffer_offset: Option<BufferAddress>,
163}
164
165pub enum BlasGeometries<'a> {
166 TriangleGeometries(Box<dyn Iterator<Item = BlasTriangleGeometry<'a>> + 'a>),
167}
168
169pub struct BlasBuildEntry<'a> {
170 pub blas_id: BlasId,
171 pub geometries: BlasGeometries<'a>,
172}
173
174#[derive(Debug, Clone)]
175#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
176pub struct TlasBuildEntry {
177 pub tlas_id: TlasId,
178 pub instance_buffer_id: BufferId,
179 pub instance_count: u32,
180}
181
182#[derive(Debug)]
183pub struct TlasInstance<'a> {
184 pub blas_id: BlasId,
185 pub transform: &'a [f32; 12],
186 pub custom_data: u32,
187 pub mask: u8,
188}
189
190pub struct TlasPackage<'a> {
191 pub tlas_id: TlasId,
192 pub instances: Box<dyn Iterator<Item = Option<TlasInstance<'a>>> + 'a>,
193 pub lowest_unmodified: u32,
194}
195
196#[derive(Debug, Clone)]
197pub(crate) struct TlasBuild {
198 pub tlas: Arc<Tlas>,
199 pub dependencies: Vec<Arc<Blas>>,
200}
201
202#[derive(Debug, Clone, Default)]
203pub(crate) struct AsBuild {
204 pub blas_s_built: Vec<Arc<Blas>>,
205 pub tlas_s_built: Vec<TlasBuild>,
206}
207
208#[derive(Debug, Clone)]
209pub(crate) enum AsAction {
210 Build(AsBuild),
211 UseTlas(Arc<Tlas>),
212}
213
214#[derive(Debug, Clone)]
215#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
216pub struct TraceBlasTriangleGeometry {
217 pub size: wgt::BlasTriangleGeometrySizeDescriptor,
218 pub vertex_buffer: BufferId,
219 pub index_buffer: Option<BufferId>,
220 pub transform_buffer: Option<BufferId>,
221 pub first_vertex: u32,
222 pub vertex_stride: BufferAddress,
223 pub first_index: Option<u32>,
224 pub transform_buffer_offset: Option<BufferAddress>,
225}
226
227#[derive(Debug, Clone)]
228#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
229pub enum TraceBlasGeometries {
230 TriangleGeometries(Vec<TraceBlasTriangleGeometry>),
231}
232
233#[derive(Debug, Clone)]
234#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
235pub struct TraceBlasBuildEntry {
236 pub blas_id: BlasId,
237 pub geometries: TraceBlasGeometries,
238}
239
240#[derive(Debug, Clone)]
241#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
242pub struct TraceTlasInstance {
243 pub blas_id: BlasId,
244 pub transform: [f32; 12],
245 pub custom_data: u32,
246 pub mask: u8,
247}
248
249#[derive(Debug, Clone)]
250#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
251pub struct TraceTlasPackage {
252 pub tlas_id: TlasId,
253 pub instances: Vec<Option<TraceTlasInstance>>,
254 pub lowest_unmodified: u32,
255}