naga/front/type_gen.rs
1/*!
2Type generators.
3*/
4
5use crate::{arena::Handle, span::Span};
6
7impl crate::Module {
8 pub fn generate_atomic_compare_exchange_result(
9 &mut self,
10 kind: crate::ScalarKind,
11 width: crate::Bytes,
12 ) -> Handle<crate::Type> {
13 let bool_ty = self.types.insert(
14 crate::Type {
15 name: None,
16 inner: crate::TypeInner::Scalar {
17 kind: crate::ScalarKind::Bool,
18 width: crate::BOOL_WIDTH,
19 },
20 },
21 Span::UNDEFINED,
22 );
23 let scalar_ty = self.types.insert(
24 crate::Type {
25 name: None,
26 inner: crate::TypeInner::Scalar { kind, width },
27 },
28 Span::UNDEFINED,
29 );
30
31 self.types.insert(
32 crate::Type {
33 name: Some(format!(
34 "__atomic_compare_exchange_result<{kind:?},{width}>"
35 )),
36 inner: crate::TypeInner::Struct {
37 members: vec![
38 crate::StructMember {
39 name: Some("old_value".to_string()),
40 ty: scalar_ty,
41 binding: None,
42 offset: 0,
43 },
44 crate::StructMember {
45 name: Some("exchanged".to_string()),
46 ty: bool_ty,
47 binding: None,
48 offset: 4,
49 },
50 ],
51 span: 8,
52 },
53 },
54 Span::UNDEFINED,
55 )
56 }
57 /// Populate this module's [`SpecialTypes::ray_desc`] type.
58 ///
59 /// [`SpecialTypes::ray_desc`] is the type of the [`descriptor`] operand of
60 /// an [`Initialize`] [`RayQuery`] statement. In WGSL, it is a struct type
61 /// referred to as `RayDesc`.
62 ///
63 /// Backends consume values of this type to drive platform APIs, so if you
64 /// change any its fields, you must update the backends to match. Look for
65 /// backend code dealing with [`RayQueryFunction::Initialize`].
66 ///
67 /// [`SpecialTypes::ray_desc`]: crate::SpecialTypes::ray_desc
68 /// [`descriptor`]: crate::RayQueryFunction::Initialize::descriptor
69 /// [`Initialize`]: crate::RayQueryFunction::Initialize
70 /// [`RayQuery`]: crate::Statement::RayQuery
71 /// [`RayQueryFunction::Initialize`]: crate::RayQueryFunction::Initialize
72 pub fn generate_ray_desc_type(&mut self) -> Handle<crate::Type> {
73 if let Some(handle) = self.special_types.ray_desc {
74 return handle;
75 }
76
77 let width = 4;
78 let ty_flag = self.types.insert(
79 crate::Type {
80 name: None,
81 inner: crate::TypeInner::Scalar {
82 width,
83 kind: crate::ScalarKind::Uint,
84 },
85 },
86 Span::UNDEFINED,
87 );
88 let ty_scalar = self.types.insert(
89 crate::Type {
90 name: None,
91 inner: crate::TypeInner::Scalar {
92 width,
93 kind: crate::ScalarKind::Float,
94 },
95 },
96 Span::UNDEFINED,
97 );
98 let ty_vector = self.types.insert(
99 crate::Type {
100 name: None,
101 inner: crate::TypeInner::Vector {
102 size: crate::VectorSize::Tri,
103 kind: crate::ScalarKind::Float,
104 width,
105 },
106 },
107 Span::UNDEFINED,
108 );
109
110 let handle = self.types.insert(
111 crate::Type {
112 name: Some("RayDesc".to_string()),
113 inner: crate::TypeInner::Struct {
114 members: vec![
115 crate::StructMember {
116 name: Some("flags".to_string()),
117 ty: ty_flag,
118 binding: None,
119 offset: 0,
120 },
121 crate::StructMember {
122 name: Some("cull_mask".to_string()),
123 ty: ty_flag,
124 binding: None,
125 offset: 4,
126 },
127 crate::StructMember {
128 name: Some("tmin".to_string()),
129 ty: ty_scalar,
130 binding: None,
131 offset: 8,
132 },
133 crate::StructMember {
134 name: Some("tmax".to_string()),
135 ty: ty_scalar,
136 binding: None,
137 offset: 12,
138 },
139 crate::StructMember {
140 name: Some("origin".to_string()),
141 ty: ty_vector,
142 binding: None,
143 offset: 16,
144 },
145 crate::StructMember {
146 name: Some("dir".to_string()),
147 ty: ty_vector,
148 binding: None,
149 offset: 32,
150 },
151 ],
152 span: 48,
153 },
154 },
155 Span::UNDEFINED,
156 );
157
158 self.special_types.ray_desc = Some(handle);
159 handle
160 }
161
162 /// Populate this module's [`SpecialTypes::ray_intersection`] type.
163 ///
164 /// [`SpecialTypes::ray_intersection`] is the type of a
165 /// `RayQueryGetIntersection` expression. In WGSL, it is a struct type
166 /// referred to as `RayIntersection`.
167 ///
168 /// Backends construct values of this type based on platform APIs, so if you
169 /// change any its fields, you must update the backends to match. Look for
170 /// the backend's handling for [`Expression::RayQueryGetIntersection`].
171 ///
172 /// [`SpecialTypes::ray_intersection`]: crate::SpecialTypes::ray_intersection
173 /// [`Expression::RayQueryGetIntersection`]: crate::Expression::RayQueryGetIntersection
174 pub fn generate_ray_intersection_type(&mut self) -> Handle<crate::Type> {
175 if let Some(handle) = self.special_types.ray_intersection {
176 return handle;
177 }
178
179 let width = 4;
180 let ty_flag = self.types.insert(
181 crate::Type {
182 name: None,
183 inner: crate::TypeInner::Scalar {
184 width,
185 kind: crate::ScalarKind::Uint,
186 },
187 },
188 Span::UNDEFINED,
189 );
190 let ty_scalar = self.types.insert(
191 crate::Type {
192 name: None,
193 inner: crate::TypeInner::Scalar {
194 width,
195 kind: crate::ScalarKind::Float,
196 },
197 },
198 Span::UNDEFINED,
199 );
200 let ty_barycentrics = self.types.insert(
201 crate::Type {
202 name: None,
203 inner: crate::TypeInner::Vector {
204 width,
205 size: crate::VectorSize::Bi,
206 kind: crate::ScalarKind::Float,
207 },
208 },
209 Span::UNDEFINED,
210 );
211 let ty_bool = self.types.insert(
212 crate::Type {
213 name: None,
214 inner: crate::TypeInner::Scalar {
215 width: crate::BOOL_WIDTH,
216 kind: crate::ScalarKind::Bool,
217 },
218 },
219 Span::UNDEFINED,
220 );
221 let ty_transform = self.types.insert(
222 crate::Type {
223 name: None,
224 inner: crate::TypeInner::Matrix {
225 columns: crate::VectorSize::Quad,
226 rows: crate::VectorSize::Tri,
227 width,
228 },
229 },
230 Span::UNDEFINED,
231 );
232
233 let handle = self.types.insert(
234 crate::Type {
235 name: Some("RayIntersection".to_string()),
236 inner: crate::TypeInner::Struct {
237 members: vec![
238 crate::StructMember {
239 name: Some("kind".to_string()),
240 ty: ty_flag,
241 binding: None,
242 offset: 0,
243 },
244 crate::StructMember {
245 name: Some("t".to_string()),
246 ty: ty_scalar,
247 binding: None,
248 offset: 4,
249 },
250 crate::StructMember {
251 name: Some("instance_custom_index".to_string()),
252 ty: ty_flag,
253 binding: None,
254 offset: 8,
255 },
256 crate::StructMember {
257 name: Some("instance_id".to_string()),
258 ty: ty_flag,
259 binding: None,
260 offset: 12,
261 },
262 crate::StructMember {
263 name: Some("sbt_record_offset".to_string()),
264 ty: ty_flag,
265 binding: None,
266 offset: 16,
267 },
268 crate::StructMember {
269 name: Some("geometry_index".to_string()),
270 ty: ty_flag,
271 binding: None,
272 offset: 20,
273 },
274 crate::StructMember {
275 name: Some("primitive_index".to_string()),
276 ty: ty_flag,
277 binding: None,
278 offset: 24,
279 },
280 crate::StructMember {
281 name: Some("barycentrics".to_string()),
282 ty: ty_barycentrics,
283 binding: None,
284 offset: 28,
285 },
286 crate::StructMember {
287 name: Some("front_face".to_string()),
288 ty: ty_bool,
289 binding: None,
290 offset: 36,
291 },
292 crate::StructMember {
293 name: Some("object_to_world".to_string()),
294 ty: ty_transform,
295 binding: None,
296 offset: 48,
297 },
298 crate::StructMember {
299 name: Some("world_to_object".to_string()),
300 ty: ty_transform,
301 binding: None,
302 offset: 112,
303 },
304 ],
305 span: 176,
306 },
307 },
308 Span::UNDEFINED,
309 );
310
311 self.special_types.ray_intersection = Some(handle);
312 handle
313 }
314}