naga_types/
lib.rs

1#![cfg_attr(docsrs, feature(doc_cfg))]
2#![no_std]
3extern crate alloc;
4#[cfg(feature = "std")]
5extern crate std;
6
7pub mod glsl;
8pub mod hlsl;
9pub mod msl;
10pub mod spv;
11
12/// Create a Markdown link definition referring to the `wgpu` crate.
13///
14/// This macro should be used inside a `#[doc = ...]` attribute.
15/// The two arguments should be string literals or macros that expand to string literals.
16/// If the module in which the item using this macro is located is not the crate root,
17/// use the `../` syntax.
18///
19/// We cannot simply use rustdoc links to `wgpu` because it is one of our dependents.
20/// This link adapts to work in locally generated documentation (`cargo doc`) by default,
21/// and work with `docs.rs` URL structure when building for `docs.rs`.
22///
23/// Note: This macro cannot be used outside this crate, because `cfg(docsrs)` will not apply.
24#[cfg(not(docsrs))]
25#[macro_export]
26macro_rules! link_to_wgpu_docs {
27    ([$reference:expr]: $url_path:expr) => {
28        concat!("[", $reference, "]: ../wgpu/", $url_path)
29    };
30
31    (../ [$reference:expr]: $url_path:expr) => {
32        concat!("[", $reference, "]: ../../wgpu/", $url_path)
33    };
34}
35#[cfg(docsrs)]
36#[macro_export]
37macro_rules! link_to_wgpu_docs {
38    ($(../)? [$reference:expr]: $url_path:expr) => {
39        concat!(
40            "[",
41            $reference,
42            // URL path will have a base URL of https://docs.rs/
43            "]: /wgpu/",
44            // The version of wgpu-types is not necessarily the same as the version of wgpu
45            // if a patch release of either has been published, so we cannot use the full version
46            // number. docs.rs will interpret this single number as a Cargo-style version
47            // requirement and redirect to the latest compatible version.
48            //
49            // This technique would break if `wgpu` and `wgpu-types` ever switch to having distinct
50            // major version numbering. An alternative would be to hardcode the corresponding `wgpu`
51            // version, but that would give us another thing to forget to update.
52            env!("CARGO_PKG_VERSION_MAJOR"),
53            "/wgpu/",
54            $url_path
55        )
56    };
57}
58
59/// Create a Markdown link definition referring to an item in the `wgpu` crate.
60///
61/// This macro should be used inside a `#[doc = ...]` attribute.
62/// See [`link_to_wgpu_docs`] for more details.
63#[macro_export]
64macro_rules! link_to_wgpu_item {
65    ($kind:ident $name:ident) => {
66        $crate::link_to_wgpu_docs!(
67            [concat!("`", stringify!($name), "`")]: concat!(stringify!($kind), ".", stringify!($name), ".html")
68        )
69    };
70}
71
72/// Create a Markdown link definition referring to the `wgpu_core` crate.
73///
74/// This macro should be used inside a `#[doc = ...]` attribute.
75/// See [`link_to_wgpu_docs`] for more details.
76#[cfg(not(docsrs))]
77#[macro_export]
78macro_rules! link_to_wgc_docs {
79    ([$reference:expr]: $url_path:expr) => {
80        concat!("[", $reference, "]: ../wgpu_core/", $url_path)
81    };
82
83    (../ [$reference:expr]: $url_path:expr) => {
84        concat!("[", $reference, "]: ../../wgpu_core/", $url_path)
85    };
86}
87#[cfg(docsrs)]
88#[macro_export]
89macro_rules! link_to_wgc_docs {
90    ($(../)? [$reference:expr]: $url_path:expr) => {
91        concat!(
92            "[",
93            $reference,
94            // URL path will have a base URL of https://docs.rs/
95            "]: /wgpu_core/",
96            // The version of wgpu-types is not necessarily the same as the version of wgpu_core
97            // if a patch release of either has been published, so we cannot use the full version
98            // number. docs.rs will interpret this single number as a Cargo-style version
99            // requirement and redirect to the latest compatible version.
100            //
101            // This technique would break if `wgpu_core` and `wgpu-types` ever switch to having
102            // distinct major version numbering. An alternative would be to hardcode the
103            // corresponding `wgpu_core` version, but that would give us another thing to forget
104            // to update.
105            env!("CARGO_PKG_VERSION_MAJOR"),
106            "/wgpu_core/",
107            $url_path
108        )
109    };
110}
111
112/// Stage of the programmable pipeline.
113#[derive(Clone, Copy, Debug, Hash, Eq, Ord, PartialEq, PartialOrd)]
114#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
115#[cfg_attr(feature = "deserialize", derive(serde::Deserialize))]
116#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
117pub enum ShaderStage {
118    /// A vertex shader, in a render pipeline.
119    Vertex,
120
121    /// A task shader, in a mesh render pipeline.
122    Task,
123
124    /// A mesh shader, in a mesh render pipeline.
125    Mesh,
126
127    /// A fragment shader, in a render pipeline.
128    Fragment,
129
130    /// Compute pipeline shader.
131    Compute,
132
133    /// A ray generation shader, in a ray tracing pipeline.
134    RayGeneration,
135
136    /// A miss shader, in a ray tracing pipeline.
137    Miss,
138
139    /// A any hit shader, in a ray tracing pipeline.
140    AnyHit,
141
142    /// A closest hit shader, in a ray tracing pipeline.
143    ClosestHit,
144}
145
146impl ShaderStage {
147    pub const fn compute_like(self) -> bool {
148        match self {
149            Self::Vertex | Self::Fragment => false,
150            Self::Compute | Self::Task | Self::Mesh => true,
151            Self::RayGeneration | Self::AnyHit | Self::ClosestHit | Self::Miss => false,
152        }
153    }
154
155    /// Mesh or task shader
156    pub const fn mesh_like(self) -> bool {
157        matches!(self, Self::Task | Self::Mesh)
158    }
159}
160
161/// Hash map that is faster but not resilient to DoS attacks.
162/// (Similar to rustc_hash::FxHashMap but using hashbrown::HashMap instead of alloc::collections::HashMap.)
163/// To construct a new instance: `FastHashMap::default()`
164pub type FastHashMap<K, T> =
165    hashbrown::HashMap<K, T, core::hash::BuildHasherDefault<rustc_hash::FxHasher>>;
166
167/// Hash set that is faster but not resilient to DoS attacks.
168/// (Similar to rustc_hash::FxHashSet but using hashbrown::HashSet instead of alloc::collections::HashMap.)
169pub type FastHashSet<K> =
170    hashbrown::HashSet<K, core::hash::BuildHasherDefault<rustc_hash::FxHasher>>;
171
172/// Insertion-order-preserving hash set (`IndexSet<K>`), but with the same
173/// hasher as `FastHashSet<K>` (faster but not resilient to DoS attacks).
174pub type FastIndexSet<K> =
175    indexmap::IndexSet<K, core::hash::BuildHasherDefault<rustc_hash::FxHasher>>;
176
177/// Insertion-order-preserving hash map (`IndexMap<K, V>`), but with the same
178/// hasher as `FastHashMap<K, V>` (faster but not resilient to DoS attacks).
179pub type FastIndexMap<K, V> =
180    indexmap::IndexMap<K, V, core::hash::BuildHasherDefault<rustc_hash::FxHasher>>;
181
182/// Pipeline binding information for global resources.
183#[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
184#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
185#[cfg_attr(feature = "deserialize", derive(serde::Deserialize))]
186#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
187pub struct ResourceBinding {
188    /// The bind group index.
189    pub group: u32,
190    /// Binding number within the group.
191    pub binding: u32,
192}
193
194#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
195#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
196#[cfg_attr(feature = "deserialize", derive(serde::Deserialize))]
197pub struct TaskDispatchLimits {
198    pub max_mesh_workgroups_per_dim: u32,
199    pub max_mesh_workgroups_total: u32,
200}
201
202/// Corresponds to [WebGPU `GPUVertexFormat`](
203/// https://gpuweb.github.io/gpuweb/#enumdef-gpuvertexformat).
204#[repr(u32)]
205#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
206#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
207#[cfg_attr(feature = "deserialize", derive(serde::Deserialize))]
208#[cfg_attr(
209    any(feature = "serialize", feature = "deserialize"),
210    serde(rename_all = "lowercase")
211)]
212pub enum VertexFormat {
213    /// One unsigned byte (u8). `u32` in shaders.
214    Uint8 = 0,
215    /// Two unsigned bytes (u8). `vec2<u32>` in shaders.
216    Uint8x2 = 1,
217    /// Four unsigned bytes (u8). `vec4<u32>` in shaders.
218    Uint8x4 = 2,
219    /// One signed byte (i8). `i32` in shaders.
220    Sint8 = 3,
221    /// Two signed bytes (i8). `vec2<i32>` in shaders.
222    Sint8x2 = 4,
223    /// Four signed bytes (i8). `vec4<i32>` in shaders.
224    Sint8x4 = 5,
225    /// One unsigned byte (u8). [0, 255] converted to float [0, 1] `f32` in shaders.
226    Unorm8 = 6,
227    /// Two unsigned bytes (u8). [0, 255] converted to float [0, 1] `vec2<f32>` in shaders.
228    Unorm8x2 = 7,
229    /// Four unsigned bytes (u8). [0, 255] converted to float [0, 1] `vec4<f32>` in shaders.
230    Unorm8x4 = 8,
231    /// One signed byte (i8). [&minus;127, 127] converted to float [&minus;1, 1] `f32` in shaders.
232    Snorm8 = 9,
233    /// Two signed bytes (i8). [&minus;127, 127] converted to float [&minus;1, 1] `vec2<f32>` in shaders.
234    Snorm8x2 = 10,
235    /// Four signed bytes (i8). [&minus;127, 127] converted to float [&minus;1, 1] `vec4<f32>` in shaders.
236    Snorm8x4 = 11,
237    /// One unsigned short (u16). `u32` in shaders.
238    Uint16 = 12,
239    /// Two unsigned shorts (u16). `vec2<u32>` in shaders.
240    Uint16x2 = 13,
241    /// Four unsigned shorts (u16). `vec4<u32>` in shaders.
242    Uint16x4 = 14,
243    /// One signed short (i16). `i32` in shaders.
244    Sint16 = 15,
245    /// Two signed shorts (i16). `vec2<i32>` in shaders.
246    Sint16x2 = 16,
247    /// Four signed shorts (i16). `vec4<i32>` in shaders.
248    Sint16x4 = 17,
249    /// One unsigned short (u16). [0, 65535] converted to float [0, 1] `f32` in shaders.
250    Unorm16 = 18,
251    /// Two unsigned shorts (u16). [0, 65535] converted to float [0, 1] `vec2<f32>` in shaders.
252    Unorm16x2 = 19,
253    /// Four unsigned shorts (u16). [0, 65535] converted to float [0, 1] `vec4<f32>` in shaders.
254    Unorm16x4 = 20,
255    /// One signed short (i16). [&minus;32767, 32767] converted to float [&minus;1, 1] `f32` in shaders.
256    Snorm16 = 21,
257    /// Two signed shorts (i16). [&minus;32767, 32767] converted to float [&minus;1, 1] `vec2<f32>` in shaders.
258    Snorm16x2 = 22,
259    /// Four signed shorts (i16). [&minus;32767, 32767] converted to float [&minus;1, 1] `vec4<f32>` in shaders.
260    Snorm16x4 = 23,
261    /// One half-precision float (no Rust equiv). `f32` in shaders.
262    Float16 = 24,
263    /// Two half-precision floats (no Rust equiv). `vec2<f32>` in shaders.
264    Float16x2 = 25,
265    /// Four half-precision floats (no Rust equiv). `vec4<f32>` in shaders.
266    Float16x4 = 26,
267    /// One single-precision float (f32). `f32` in shaders.
268    Float32 = 27,
269    /// Two single-precision floats (f32). `vec2<f32>` in shaders.
270    Float32x2 = 28,
271    /// Three single-precision floats (f32). `vec3<f32>` in shaders.
272    Float32x3 = 29,
273    /// Four single-precision floats (f32). `vec4<f32>` in shaders.
274    Float32x4 = 30,
275    /// One unsigned int (u32). `u32` in shaders.
276    Uint32 = 31,
277    /// Two unsigned ints (u32). `vec2<u32>` in shaders.
278    Uint32x2 = 32,
279    /// Three unsigned ints (u32). `vec3<u32>` in shaders.
280    Uint32x3 = 33,
281    /// Four unsigned ints (u32). `vec4<u32>` in shaders.
282    Uint32x4 = 34,
283    /// One signed int (i32). `i32` in shaders.
284    Sint32 = 35,
285    /// Two signed ints (i32). `vec2<i32>` in shaders.
286    Sint32x2 = 36,
287    /// Three signed ints (i32). `vec3<i32>` in shaders.
288    Sint32x3 = 37,
289    /// Four signed ints (i32). `vec4<i32>` in shaders.
290    Sint32x4 = 38,
291    /// One double-precision float (f64). `f32` in shaders. Requires [`Features::VERTEX_ATTRIBUTE_64BIT`].
292    ///
293    /// [`Features::VERTEX_ATTRIBUTE_64BIT`]: ../wgpu/struct.Features.html#associatedconstant.VERTEX_ATTRIBUTE_64BIT
294    Float64 = 39,
295    /// Two double-precision floats (f64). `vec2<f32>` in shaders. Requires [`Features::VERTEX_ATTRIBUTE_64BIT`].
296    ///
297    /// [`Features::VERTEX_ATTRIBUTE_64BIT`]: ../wgpu/struct.Features.html#associatedconstant.VERTEX_ATTRIBUTE_64BIT
298    Float64x2 = 40,
299    /// Three double-precision floats (f64). `vec3<f32>` in shaders. Requires [`Features::VERTEX_ATTRIBUTE_64BIT`].
300    ///
301    /// [`Features::VERTEX_ATTRIBUTE_64BIT`]: ../wgpu/struct.Features.html#associatedconstant.VERTEX_ATTRIBUTE_64BIT
302    Float64x3 = 41,
303    /// Four double-precision floats (f64). `vec4<f32>` in shaders. Requires [`Features::VERTEX_ATTRIBUTE_64BIT`].
304    ///
305    /// [`Features::VERTEX_ATTRIBUTE_64BIT`]: ../wgpu/struct.Features.html#associatedconstant.VERTEX_ATTRIBUTE_64BIT
306    Float64x4 = 42,
307    /// 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.
308    #[cfg_attr(
309        any(feature = "serialize", feature = "deserialize"),
310        serde(rename = "unorm10-10-10-2")
311    )]
312    Unorm10_10_10_2 = 43,
313    /// Four unsigned 8-bit integers (u8) in BGRA. [0, 255] converted to float [0, 1] `vec4<f32>` RGBA in shaders.
314    #[cfg_attr(
315        any(feature = "serialize", feature = "deserialize"),
316        serde(rename = "unorm8x4-bgra")
317    )]
318    Unorm8x4Bgra = 44,
319}
320
321impl VertexFormat {
322    /// Returns the byte size of the format.
323    #[must_use]
324    pub const fn size(&self) -> u64 {
325        match self {
326            Self::Uint8 | Self::Sint8 | Self::Unorm8 | Self::Snorm8 => 1,
327            Self::Uint8x2
328            | Self::Sint8x2
329            | Self::Unorm8x2
330            | Self::Snorm8x2
331            | Self::Uint16
332            | Self::Sint16
333            | Self::Unorm16
334            | Self::Snorm16
335            | Self::Float16 => 2,
336            Self::Uint8x4
337            | Self::Sint8x4
338            | Self::Unorm8x4
339            | Self::Snorm8x4
340            | Self::Uint16x2
341            | Self::Sint16x2
342            | Self::Unorm16x2
343            | Self::Snorm16x2
344            | Self::Float16x2
345            | Self::Float32
346            | Self::Uint32
347            | Self::Sint32
348            | Self::Unorm10_10_10_2
349            | Self::Unorm8x4Bgra => 4,
350            Self::Uint16x4
351            | Self::Sint16x4
352            | Self::Unorm16x4
353            | Self::Snorm16x4
354            | Self::Float16x4
355            | Self::Float32x2
356            | Self::Uint32x2
357            | Self::Sint32x2
358            | Self::Float64 => 8,
359            Self::Float32x3 | Self::Uint32x3 | Self::Sint32x3 => 12,
360            Self::Float32x4 | Self::Uint32x4 | Self::Sint32x4 | Self::Float64x2 => 16,
361            Self::Float64x3 => 24,
362            Self::Float64x4 => 32,
363        }
364    }
365
366    /// Returns the size read by an acceleration structure build of the vertex format. This is
367    /// slightly different from [`Self::size`] because the alpha component of 4-component formats
368    /// are not read in an acceleration structure build, allowing for a smaller stride.
369    #[must_use]
370    pub const fn min_acceleration_structure_vertex_stride(&self) -> u64 {
371        match self {
372            Self::Float16x2 | Self::Snorm16x2 => 4,
373            Self::Float32x3 => 12,
374            Self::Float32x2 => 8,
375            // This is the minimum value from DirectX
376            // > A16 component is ignored, other data can be packed there, such as setting vertex stride to 6 bytes
377            //
378            // https://microsoft.github.io/DirectX-Specs/d3d/Raytracing.html#d3d12_raytracing_geometry_triangles_desc
379            //
380            // Vulkan does not express a minimum stride.
381            Self::Float16x4 | Self::Snorm16x4 => 6,
382            _ => unreachable!(),
383        }
384    }
385
386    /// Returns the alignment required for `wgpu::BlasTriangleGeometry::vertex_stride`
387    #[must_use]
388    pub const fn acceleration_structure_stride_alignment(&self) -> u64 {
389        match self {
390            Self::Float16x4 | Self::Float16x2 | Self::Snorm16x4 | Self::Snorm16x2 => 2,
391            Self::Float32x2 | Self::Float32x3 => 4,
392            _ => unreachable!(),
393        }
394    }
395}