Skip to main content

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). [&minus;127, 127] converted to float [&minus;1, 1] `f32` in shaders.
159    Snorm8 = 9,
160    /// Two signed bytes (i8). [&minus;127, 127] converted to float [&minus;1, 1] `vec2<f32>` in shaders.
161    Snorm8x2 = 10,
162    /// Four signed bytes (i8). [&minus;127, 127] converted to float [&minus;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). [&minus;32767, 32767] converted to float [&minus;1, 1] `f32` in shaders.
183    Snorm16 = 21,
184    /// Two signed shorts (i16). [&minus;32767, 32767] converted to float [&minus;1, 1] `vec2<f32>` in shaders.
185    Snorm16x2 = 22,
186    /// Four signed shorts (i16). [&minus;32767, 32767] converted to float [&minus;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). [&minus;511, 511] and [&minus;1, 1] converted to float [&minus;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}