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