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}