naga_types/lib.rs
1#![cfg_attr(docsrs, feature(doc_cfg))]
2#![no_std]
3extern crate alloc;
4#[cfg(any(feature = "std", test))]
5extern crate std;
6
7pub mod glsl;
8pub mod hlsl;
9pub mod msl;
10pub mod spv;
11pub mod wgsl;
12
13/// Stage of the programmable pipeline.
14#[derive(Clone, Copy, Debug, Hash, Eq, Ord, PartialEq, PartialOrd)]
15#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
16#[cfg_attr(feature = "deserialize", derive(serde::Deserialize))]
17#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
18pub enum ShaderStage {
19 /// A vertex shader, in a render pipeline.
20 Vertex,
21
22 /// A task shader, in a mesh render pipeline.
23 Task,
24
25 /// A mesh shader, in a mesh render pipeline.
26 Mesh,
27
28 /// A fragment shader, in a render pipeline.
29 Fragment,
30
31 /// Compute pipeline shader.
32 Compute,
33
34 /// A ray generation shader, in a ray tracing pipeline.
35 RayGeneration,
36
37 /// A miss shader, in a ray tracing pipeline.
38 Miss,
39
40 /// A any hit shader, in a ray tracing pipeline.
41 AnyHit,
42
43 /// A closest hit shader, in a ray tracing pipeline.
44 ClosestHit,
45}
46
47impl ShaderStage {
48 pub const fn compute_like(self) -> bool {
49 match self {
50 Self::Vertex | Self::Fragment => false,
51 Self::Compute | Self::Task | Self::Mesh => true,
52 Self::RayGeneration | Self::AnyHit | Self::ClosestHit | Self::Miss => false,
53 }
54 }
55
56 /// Mesh or task shader
57 pub const fn mesh_like(self) -> bool {
58 matches!(self, Self::Task | Self::Mesh)
59 }
60}
61
62/// Hash map that is faster but not resilient to DoS attacks.
63/// (Similar to rustc_hash::FxHashMap but using hashbrown::HashMap instead of alloc::collections::HashMap.)
64/// To construct a new instance: `FastHashMap::default()`
65pub type FastHashMap<K, T> =
66 hashbrown::HashMap<K, T, core::hash::BuildHasherDefault<rustc_hash::FxHasher>>;
67
68/// Hash set that is faster but not resilient to DoS attacks.
69/// (Similar to rustc_hash::FxHashSet but using hashbrown::HashSet instead of alloc::collections::HashMap.)
70pub type FastHashSet<K> =
71 hashbrown::HashSet<K, core::hash::BuildHasherDefault<rustc_hash::FxHasher>>;
72
73/// Insertion-order-preserving hash set (`IndexSet<K>`), but with the same
74/// hasher as `FastHashSet<K>` (faster but not resilient to DoS attacks).
75pub type FastIndexSet<K> =
76 indexmap::IndexSet<K, core::hash::BuildHasherDefault<rustc_hash::FxHasher>>;
77
78/// Insertion-order-preserving hash map (`IndexMap<K, V>`), but with the same
79/// hasher as `FastHashMap<K, V>` (faster but not resilient to DoS attacks).
80pub type FastIndexMap<K, V> =
81 indexmap::IndexMap<K, V, core::hash::BuildHasherDefault<rustc_hash::FxHasher>>;
82
83/// Pipeline binding information for global resources.
84#[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
85#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
86#[cfg_attr(feature = "deserialize", derive(serde::Deserialize))]
87#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
88pub struct ResourceBinding {
89 /// The bind group index.
90 pub group: u32,
91 /// Binding number within the group.
92 pub binding: u32,
93}
94
95#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
96#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
97#[cfg_attr(feature = "deserialize", derive(serde::Deserialize))]
98pub struct TaskDispatchLimits {
99 pub max_mesh_workgroups_per_dim: u32,
100 pub max_mesh_workgroups_total: u32,
101}
102
103/// Parameters describing a gamma encoding transfer function in the form
104/// tf = { k * linear | linear < b
105/// { a * pow(linear, 1/g) - (a-1) | linear >= b
106#[repr(C)]
107#[derive(Clone, Copy, Debug, PartialEq, bytemuck::Zeroable, bytemuck::Pod)]
108#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
109#[cfg_attr(feature = "deserialize", derive(serde::Deserialize))]
110#[allow(missing_docs)]
111pub struct ExternalTextureTransferFunction {
112 pub a: f32,
113 pub b: f32,
114 pub g: f32,
115 pub k: f32,
116}
117
118impl Default for ExternalTextureTransferFunction {
119 fn default() -> Self {
120 Self {
121 a: 1.0,
122 b: 1.0,
123 g: 1.0,
124 k: 1.0,
125 }
126 }
127}
128
129/// Corresponds to [WebGPU `GPUVertexFormat`](
130/// https://gpuweb.github.io/gpuweb/#enumdef-gpuvertexformat).
131#[repr(u32)]
132#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
133#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
134#[cfg_attr(feature = "deserialize", derive(serde::Deserialize))]
135#[cfg_attr(
136 any(feature = "serialize", feature = "deserialize"),
137 serde(rename_all = "lowercase")
138)]
139pub enum VertexFormat {
140 /// One unsigned byte (u8). `u32` in shaders.
141 Uint8 = 0,
142 /// Two unsigned bytes (u8). `vec2<u32>` in shaders.
143 Uint8x2 = 1,
144 /// Four unsigned bytes (u8). `vec4<u32>` in shaders.
145 Uint8x4 = 2,
146 /// One signed byte (i8). `i32` in shaders.
147 Sint8 = 3,
148 /// Two signed bytes (i8). `vec2<i32>` in shaders.
149 Sint8x2 = 4,
150 /// Four signed bytes (i8). `vec4<i32>` in shaders.
151 Sint8x4 = 5,
152 /// One unsigned byte (u8). [0, 255] converted to float [0, 1] `f32` in shaders.
153 Unorm8 = 6,
154 /// Two unsigned bytes (u8). [0, 255] converted to float [0, 1] `vec2<f32>` in shaders.
155 Unorm8x2 = 7,
156 /// Four unsigned bytes (u8). [0, 255] converted to float [0, 1] `vec4<f32>` in shaders.
157 Unorm8x4 = 8,
158 /// One signed byte (i8). [−127, 127] converted to float [−1, 1] `f32` in shaders.
159 Snorm8 = 9,
160 /// Two signed bytes (i8). [−127, 127] converted to float [−1, 1] `vec2<f32>` in shaders.
161 Snorm8x2 = 10,
162 /// Four signed bytes (i8). [−127, 127] converted to float [−1, 1] `vec4<f32>` in shaders.
163 Snorm8x4 = 11,
164 /// One unsigned short (u16). `u32` in shaders.
165 Uint16 = 12,
166 /// Two unsigned shorts (u16). `vec2<u32>` in shaders.
167 Uint16x2 = 13,
168 /// Four unsigned shorts (u16). `vec4<u32>` in shaders.
169 Uint16x4 = 14,
170 /// One signed short (i16). `i32` in shaders.
171 Sint16 = 15,
172 /// Two signed shorts (i16). `vec2<i32>` in shaders.
173 Sint16x2 = 16,
174 /// Four signed shorts (i16). `vec4<i32>` in shaders.
175 Sint16x4 = 17,
176 /// One unsigned short (u16). [0, 65535] converted to float [0, 1] `f32` in shaders.
177 Unorm16 = 18,
178 /// Two unsigned shorts (u16). [0, 65535] converted to float [0, 1] `vec2<f32>` in shaders.
179 Unorm16x2 = 19,
180 /// Four unsigned shorts (u16). [0, 65535] converted to float [0, 1] `vec4<f32>` in shaders.
181 Unorm16x4 = 20,
182 /// One signed short (i16). [−32767, 32767] converted to float [−1, 1] `f32` in shaders.
183 Snorm16 = 21,
184 /// Two signed shorts (i16). [−32767, 32767] converted to float [−1, 1] `vec2<f32>` in shaders.
185 Snorm16x2 = 22,
186 /// Four signed shorts (i16). [−32767, 32767] converted to float [−1, 1] `vec4<f32>` in shaders.
187 Snorm16x4 = 23,
188 /// One half-precision float (no Rust equiv). `f32` in shaders.
189 Float16 = 24,
190 /// Two half-precision floats (no Rust equiv). `vec2<f32>` in shaders.
191 Float16x2 = 25,
192 /// Four half-precision floats (no Rust equiv). `vec4<f32>` in shaders.
193 Float16x4 = 26,
194 /// One single-precision float (f32). `f32` in shaders.
195 Float32 = 27,
196 /// Two single-precision floats (f32). `vec2<f32>` in shaders.
197 Float32x2 = 28,
198 /// Three single-precision floats (f32). `vec3<f32>` in shaders.
199 Float32x3 = 29,
200 /// Four single-precision floats (f32). `vec4<f32>` in shaders.
201 Float32x4 = 30,
202 /// One unsigned int (u32). `u32` in shaders.
203 Uint32 = 31,
204 /// Two unsigned ints (u32). `vec2<u32>` in shaders.
205 Uint32x2 = 32,
206 /// Three unsigned ints (u32). `vec3<u32>` in shaders.
207 Uint32x3 = 33,
208 /// Four unsigned ints (u32). `vec4<u32>` in shaders.
209 Uint32x4 = 34,
210 /// One signed int (i32). `i32` in shaders.
211 Sint32 = 35,
212 /// Two signed ints (i32). `vec2<i32>` in shaders.
213 Sint32x2 = 36,
214 /// Three signed ints (i32). `vec3<i32>` in shaders.
215 Sint32x3 = 37,
216 /// Four signed ints (i32). `vec4<i32>` in shaders.
217 Sint32x4 = 38,
218 /// One double-precision float (f64). `f32` in shaders. Requires [`Features::VERTEX_ATTRIBUTE_64BIT`].
219 ///
220 /// [`Features::VERTEX_ATTRIBUTE_64BIT`]: ../wgpu/struct.Features.html#associatedconstant.VERTEX_ATTRIBUTE_64BIT
221 Float64 = 39,
222 /// Two double-precision floats (f64). `vec2<f32>` in shaders. Requires [`Features::VERTEX_ATTRIBUTE_64BIT`].
223 ///
224 /// [`Features::VERTEX_ATTRIBUTE_64BIT`]: ../wgpu/struct.Features.html#associatedconstant.VERTEX_ATTRIBUTE_64BIT
225 Float64x2 = 40,
226 /// Three double-precision floats (f64). `vec3<f32>` in shaders. Requires [`Features::VERTEX_ATTRIBUTE_64BIT`].
227 ///
228 /// [`Features::VERTEX_ATTRIBUTE_64BIT`]: ../wgpu/struct.Features.html#associatedconstant.VERTEX_ATTRIBUTE_64BIT
229 Float64x3 = 41,
230 /// Four double-precision floats (f64). `vec4<f32>` in shaders. Requires [`Features::VERTEX_ATTRIBUTE_64BIT`].
231 ///
232 /// [`Features::VERTEX_ATTRIBUTE_64BIT`]: ../wgpu/struct.Features.html#associatedconstant.VERTEX_ATTRIBUTE_64BIT
233 Float64x4 = 42,
234 /// Three unsigned 10-bit integers and one 2-bit integer, packed into a 32-bit integer (u32). [0, 1023] and [0, 3] converted to float [0, 1] `vec4<f32>` in shaders.
235 #[cfg_attr(
236 any(feature = "serialize", feature = "deserialize"),
237 serde(rename = "unorm10-10-10-2")
238 )]
239 Unorm10_10_10_2 = 43,
240 /// Four unsigned 8-bit integers (u8) in BGRA. [0, 255] converted to float [0, 1] `vec4<f32>` RGBA in shaders.
241 #[cfg_attr(
242 any(feature = "serialize", feature = "deserialize"),
243 serde(rename = "unorm8x4-bgra")
244 )]
245 Unorm8x4Bgra = 44,
246 /// Three signed 10-bit integers and one 2-bit integer, packed into a 32-bit integer (u32). [−511, 511] and [−1, 1] converted to float [−1, 1] `vec4<f32>` in shaders.
247 #[cfg_attr(
248 any(feature = "serialize", feature = "deserialize"),
249 serde(rename = "snorm10-10-10-2")
250 )]
251 Snorm10_10_10_2 = 45,
252}
253
254impl VertexFormat {
255 /// Returns the byte size of the format.
256 #[must_use]
257 pub const fn size(&self) -> u64 {
258 match self {
259 Self::Uint8 | Self::Sint8 | Self::Unorm8 | Self::Snorm8 => 1,
260 Self::Uint8x2
261 | Self::Sint8x2
262 | Self::Unorm8x2
263 | Self::Snorm8x2
264 | Self::Uint16
265 | Self::Sint16
266 | Self::Unorm16
267 | Self::Snorm16
268 | Self::Float16 => 2,
269 Self::Uint8x4
270 | Self::Sint8x4
271 | Self::Unorm8x4
272 | Self::Snorm8x4
273 | Self::Uint16x2
274 | Self::Sint16x2
275 | Self::Unorm16x2
276 | Self::Snorm16x2
277 | Self::Float16x2
278 | Self::Float32
279 | Self::Uint32
280 | Self::Sint32
281 | Self::Unorm10_10_10_2
282 | Self::Unorm8x4Bgra
283 | Self::Snorm10_10_10_2 => 4,
284 Self::Uint16x4
285 | Self::Sint16x4
286 | Self::Unorm16x4
287 | Self::Snorm16x4
288 | Self::Float16x4
289 | Self::Float32x2
290 | Self::Uint32x2
291 | Self::Sint32x2
292 | Self::Float64 => 8,
293 Self::Float32x3 | Self::Uint32x3 | Self::Sint32x3 => 12,
294 Self::Float32x4 | Self::Uint32x4 | Self::Sint32x4 | Self::Float64x2 => 16,
295 Self::Float64x3 => 24,
296 Self::Float64x4 => 32,
297 }
298 }
299
300 /// Returns the size read by an acceleration structure build of the vertex format. This is
301 /// slightly different from [`Self::size`] because the alpha component of 4-component formats
302 /// are not read in an acceleration structure build, allowing for a smaller stride.
303 #[must_use]
304 pub const fn min_acceleration_structure_vertex_stride(&self) -> u64 {
305 match self {
306 Self::Float16x2 | Self::Snorm16x2 => 4,
307 Self::Float32x3 => 12,
308 Self::Float32x2 => 8,
309 // This is the minimum value from DirectX
310 // > A16 component is ignored, other data can be packed there, such as setting vertex stride to 6 bytes
311 //
312 // https://microsoft.github.io/DirectX-Specs/d3d/Raytracing.html#d3d12_raytracing_geometry_triangles_desc
313 //
314 // Vulkan does not express a minimum stride.
315 Self::Float16x4 | Self::Snorm16x4 => 6,
316 _ => unreachable!(),
317 }
318 }
319
320 /// Returns the alignment required for `wgpu::BlasTriangleGeometry::vertex_stride`
321 #[must_use]
322 pub const fn acceleration_structure_stride_alignment(&self) -> u64 {
323 match self {
324 Self::Float16x4 | Self::Float16x2 | Self::Snorm16x4 | Self::Snorm16x2 => 2,
325 Self::Float32x2 | Self::Float32x3 => 4,
326 _ => unreachable!(),
327 }
328 }
329}