wgpu_types/
lib.rs

1//! This library describes the API surface of WebGPU that is agnostic of the backend.
2//! This API is used for targeting both Web and Native.
3
4#![cfg_attr(docsrs, feature(doc_cfg))]
5#![allow(
6    // We don't use syntax sugar where it's not necessary.
7    clippy::match_like_matches_macro,
8)]
9#![warn(
10    clippy::ptr_as_ptr,
11    missing_docs,
12    unsafe_op_in_unsafe_fn,
13    unused_qualifications
14)]
15#![no_std]
16
17#[cfg(feature = "std")]
18extern crate std;
19
20extern crate alloc;
21
22use core::{fmt, hash::Hash, ops::Range, time::Duration};
23
24#[cfg(any(feature = "serde", test))]
25use serde::{Deserialize, Serialize};
26
27mod adapter;
28pub mod assertions;
29mod backend;
30mod binding;
31mod buffer;
32mod cast_utils;
33mod counters;
34mod device;
35mod env;
36pub mod error;
37mod features;
38pub mod instance;
39mod limits;
40pub mod math;
41mod origin_extent;
42mod ray_tracing;
43mod render;
44#[doc(hidden)] // without this we get spurious missing_docs warnings
45mod send_sync;
46mod shader;
47mod surface;
48mod texture;
49mod tokens;
50mod transfers;
51mod vertex;
52
53pub use adapter::*;
54pub use backend::*;
55pub use binding::*;
56pub use buffer::*;
57pub use counters::*;
58pub use device::*;
59pub use features::*;
60pub use instance::*;
61pub use limits::*;
62pub use origin_extent::*;
63pub use ray_tracing::*;
64pub use render::*;
65#[doc(hidden)]
66pub use send_sync::*;
67pub use shader::*;
68pub use surface::*;
69pub use texture::*;
70pub use tokens::*;
71pub use transfers::*;
72pub use vertex::*;
73
74/// Create a Markdown link definition referring to the `wgpu` crate.
75///
76/// This macro should be used inside a `#[doc = ...]` attribute.
77/// The two arguments should be string literals or macros that expand to string literals.
78/// If the module in which the item using this macro is located is not the crate root,
79/// use the `../` syntax.
80///
81/// We cannot simply use rustdoc links to `wgpu` because it is one of our dependents.
82/// This link adapts to work in locally generated documentation (`cargo doc`) by default,
83/// and work with `docs.rs` URL structure when building for `docs.rs`.
84///
85/// Note: This macro cannot be used outside this crate, because `cfg(docsrs)` will not apply.
86#[cfg(not(docsrs))]
87macro_rules! link_to_wgpu_docs {
88    ([$reference:expr]: $url_path:expr) => {
89        concat!("[", $reference, "]: ../wgpu/", $url_path)
90    };
91
92    (../ [$reference:expr]: $url_path:expr) => {
93        concat!("[", $reference, "]: ../../wgpu/", $url_path)
94    };
95}
96#[cfg(docsrs)]
97macro_rules! link_to_wgpu_docs {
98    ($(../)? [$reference:expr]: $url_path:expr) => {
99        concat!(
100            "[",
101            $reference,
102            // URL path will have a base URL of https://docs.rs/
103            "]: /wgpu/",
104            // The version of wgpu-types is not necessarily the same as the version of wgpu
105            // if a patch release of either has been published, so we cannot use the full version
106            // number. docs.rs will interpret this single number as a Cargo-style version
107            // requirement and redirect to the latest compatible version.
108            //
109            // This technique would break if `wgpu` and `wgpu-types` ever switch to having distinct
110            // major version numbering. An alternative would be to hardcode the corresponding `wgpu`
111            // version, but that would give us another thing to forget to update.
112            env!("CARGO_PKG_VERSION_MAJOR"),
113            "/wgpu/",
114            $url_path
115        )
116    };
117}
118
119/// Create a Markdown link definition referring to an item in the `wgpu` crate.
120///
121/// This macro should be used inside a `#[doc = ...]` attribute.
122/// See [`link_to_wgpu_docs`] for more details.
123macro_rules! link_to_wgpu_item {
124    ($kind:ident $name:ident) => {
125        $crate::link_to_wgpu_docs!(
126            [concat!("`", stringify!($name), "`")]: concat!("$kind.", stringify!($name), ".html")
127        )
128    };
129}
130
131pub(crate) use {link_to_wgpu_docs, link_to_wgpu_item};
132
133/// Integral type used for [`Buffer`] offsets and sizes.
134///
135#[doc = link_to_wgpu_item!(struct Buffer)]
136pub type BufferAddress = u64;
137
138/// Integral type used for [`BufferSlice`] sizes.
139///
140/// Note that while this type is non-zero, a [`Buffer`] *per se* can have a size of zero,
141/// but no slice or mapping can be created from it.
142///
143#[doc = link_to_wgpu_item!(struct Buffer)]
144#[doc = link_to_wgpu_item!(struct BufferSlice)]
145pub type BufferSize = core::num::NonZeroU64;
146
147/// Integral type used for binding locations in shaders.
148///
149/// Used in [`VertexAttribute`]s and errors.
150///
151#[doc = link_to_wgpu_item!(struct VertexAttribute)]
152pub type ShaderLocation = u32;
153
154/// Integral type used for
155/// [dynamic bind group offsets](../wgpu/struct.RenderPass.html#method.set_bind_group).
156pub type DynamicOffset = u32;
157
158/// Buffer-texture copies must have [`bytes_per_row`] aligned to this number.
159///
160/// This doesn't apply to [`Queue::write_texture`][Qwt], only to [`copy_buffer_to_texture()`]
161/// and [`copy_texture_to_buffer()`].
162///
163/// [`bytes_per_row`]: TexelCopyBufferLayout::bytes_per_row
164#[doc = link_to_wgpu_docs!(["`copy_buffer_to_texture()`"]: "struct.Queue.html#method.copy_buffer_to_texture")]
165#[doc = link_to_wgpu_docs!(["`copy_texture_to_buffer()`"]: "struct.Queue.html#method.copy_texture_to_buffer")]
166#[doc = link_to_wgpu_docs!(["Qwt"]: "struct.Queue.html#method.write_texture")]
167pub const COPY_BYTES_PER_ROW_ALIGNMENT: u32 = 256;
168
169/// An [offset into the query resolve buffer] has to be aligned to this.
170///
171#[doc = link_to_wgpu_docs!(["offset into the query resolve buffer"]: "struct.CommandEncoder.html#method.resolve_query_set")]
172pub const QUERY_RESOLVE_BUFFER_ALIGNMENT: BufferAddress = 256;
173
174/// Buffer to buffer copy as well as buffer clear offsets and sizes must be aligned to this number.
175pub const COPY_BUFFER_ALIGNMENT: BufferAddress = 4;
176
177/// Minimum alignment of buffer mappings.
178///
179/// The range passed to [`map_async()`] or [`get_mapped_range()`] must be at least this aligned.
180///
181#[doc = link_to_wgpu_docs!(["`map_async()`"]: "struct.Buffer.html#method.map_async")]
182#[doc = link_to_wgpu_docs!(["`get_mapped_range()`"]: "struct.Buffer.html#method.get_mapped_range")]
183pub const MAP_ALIGNMENT: BufferAddress = 8;
184
185/// [Vertex buffer offsets] and [strides] have to be a multiple of this number.
186///
187#[doc = link_to_wgpu_docs!(["Vertex buffer offsets"]: "util/trait.RenderEncoder.html#tymethod.set_vertex_buffer")]
188#[doc = link_to_wgpu_docs!(["strides"]: "struct.VertexBufferLayout.html#structfield.array_stride")]
189pub const VERTEX_ALIGNMENT: BufferAddress = 4;
190
191/// [Vertex buffer strides] have to be a multiple of this number.
192///
193#[doc = link_to_wgpu_docs!(["Vertex buffer strides"]: "struct.VertexBufferLayout.html#structfield.array_stride")]
194#[deprecated(note = "Use `VERTEX_ALIGNMENT` instead", since = "27.0.0")]
195pub const VERTEX_STRIDE_ALIGNMENT: BufferAddress = 4;
196
197/// Ranges of [writes to immediate data] must be at least this aligned.
198///
199#[doc = link_to_wgpu_docs!(["writes to immediate data"]: "struct.RenderPass.html#method.set_immediates")]
200pub const IMMEDIATES_ALIGNMENT: u32 = 4;
201
202/// Maximum queries in a [`QuerySetDescriptor`].
203pub const QUERY_SET_MAX_QUERIES: u32 = 4096;
204
205/// Size in bytes of a single piece of [query] data.
206///
207#[doc = link_to_wgpu_docs!(["query"]: "struct.QuerySet.html")]
208pub const QUERY_SIZE: u32 = 8;
209
210/// The minimum allowed value for [`AdapterInfo::subgroup_min_size`].
211///
212/// See <https://gpuweb.github.io/gpuweb/#gpuadapterinfo>
213/// where you can always use these values on all devices
214pub const MINIMUM_SUBGROUP_MIN_SIZE: u32 = 4;
215/// The maximum allowed value for [`AdapterInfo::subgroup_max_size`].
216///
217/// See <https://gpuweb.github.io/gpuweb/#gpuadapterinfo>
218/// where you can always use these values on all devices.
219pub const MAXIMUM_SUBGROUP_MAX_SIZE: u32 = 128;
220
221/// Passed to `Device::poll` to control how and if it should block.
222#[derive(Clone, Debug)]
223pub enum PollType<T> {
224    /// On wgpu-core based backends, block until the given submission has
225    /// completed execution, and any callbacks have been invoked.
226    ///
227    /// On WebGPU, this has no effect. Callbacks are invoked from the
228    /// window event loop.
229    Wait {
230        /// Submission index to wait for.
231        ///
232        /// If not specified, will wait for the most recent submission at the time of the poll.
233        /// By the time the method returns, more submissions may have taken place.
234        submission_index: Option<T>,
235
236        /// Max time to wait for the submission to complete.
237        ///
238        /// If not specified, will wait indefinitely (or until an error is detected).
239        /// If waiting for the GPU device takes this long or longer, the poll will return [`PollError::Timeout`].
240        timeout: Option<Duration>,
241    },
242
243    /// Check the device for a single time without blocking.
244    Poll,
245}
246
247impl<T> PollType<T> {
248    /// Wait indefinitely until for the most recent submission to complete.
249    ///
250    /// This is a convenience function that creates a [`Self::Wait`] variant with
251    /// no timeout and no submission index.
252    #[must_use]
253    pub const fn wait_indefinitely() -> Self {
254        Self::Wait {
255            submission_index: None,
256            timeout: None,
257        }
258    }
259
260    /// This `PollType` represents a wait of some kind.
261    #[must_use]
262    pub fn is_wait(&self) -> bool {
263        match *self {
264            Self::Wait { .. } => true,
265            Self::Poll => false,
266        }
267    }
268
269    /// Map on the wait index type.
270    #[must_use]
271    pub fn map_index<U, F>(self, func: F) -> PollType<U>
272    where
273        F: FnOnce(T) -> U,
274    {
275        match self {
276            Self::Wait {
277                submission_index,
278                timeout,
279            } => PollType::Wait {
280                submission_index: submission_index.map(func),
281                timeout,
282            },
283            Self::Poll => PollType::Poll,
284        }
285    }
286}
287
288/// Error states after a device poll.
289#[derive(Debug)]
290pub enum PollError {
291    /// The requested Wait timed out before the submission was completed.
292    Timeout,
293    /// The requested Wait was given a wrong submission index.
294    WrongSubmissionIndex(u64, u64),
295}
296
297// This impl could be derived by `thiserror`, but by not doing so, we can reduce the number of
298// dependencies this early in the dependency graph, which may improve build parallelism.
299impl fmt::Display for PollError {
300    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
301        match self {
302            PollError::Timeout => {
303                f.write_str("The requested Wait timed out before the submission was completed.")
304            }
305            PollError::WrongSubmissionIndex(requested, successful) => write!(
306                f,
307                "Tried to wait using a submission index ({requested}) \
308                that has not been returned by a successful submission \
309                (last successful submission: {successful}"
310            ),
311        }
312    }
313}
314
315impl core::error::Error for PollError {}
316
317/// Status of device poll operation.
318#[derive(Debug, PartialEq, Eq)]
319pub enum PollStatus {
320    /// There are no active submissions in flight as of the beginning of the poll call.
321    /// Other submissions may have been queued on other threads during the call.
322    ///
323    /// This implies that the given Wait was satisfied before the timeout.
324    QueueEmpty,
325
326    /// The requested Wait was satisfied before the timeout.
327    WaitSucceeded,
328
329    /// This was a poll.
330    Poll,
331}
332
333impl PollStatus {
334    /// Returns true if the result is [`Self::QueueEmpty`].
335    #[must_use]
336    pub fn is_queue_empty(&self) -> bool {
337        matches!(self, Self::QueueEmpty)
338    }
339
340    /// Returns true if the result is either [`Self::WaitSucceeded`] or [`Self::QueueEmpty`].
341    #[must_use]
342    pub fn wait_finished(&self) -> bool {
343        matches!(self, Self::WaitSucceeded | Self::QueueEmpty)
344    }
345}
346
347/// Describes a [`CommandEncoder`](../wgpu/struct.CommandEncoder.html).
348///
349/// Corresponds to [WebGPU `GPUCommandEncoderDescriptor`](
350/// https://gpuweb.github.io/gpuweb/#dictdef-gpucommandencoderdescriptor).
351#[repr(C)]
352#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
353#[derive(Clone, Debug, PartialEq, Eq, Hash)]
354pub struct CommandEncoderDescriptor<L> {
355    /// Debug label for the command encoder. This will show up in graphics debuggers for easy identification.
356    pub label: L,
357}
358
359impl<L> CommandEncoderDescriptor<L> {
360    /// Takes a closure and maps the label of the command encoder descriptor into another.
361    #[must_use]
362    pub fn map_label<K>(&self, fun: impl FnOnce(&L) -> K) -> CommandEncoderDescriptor<K> {
363        CommandEncoderDescriptor {
364            label: fun(&self.label),
365        }
366    }
367}
368
369impl<T> Default for CommandEncoderDescriptor<Option<T>> {
370    fn default() -> Self {
371        Self { label: None }
372    }
373}
374
375/// RGBA double precision color.
376///
377/// This is not to be used as a generic color type, only for specific wgpu interfaces.
378#[repr(C)]
379#[derive(Clone, Copy, Debug, Default, PartialEq)]
380#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
381#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
382pub struct Color {
383    /// Red component of the color
384    pub r: f64,
385    /// Green component of the color
386    pub g: f64,
387    /// Blue component of the color
388    pub b: f64,
389    /// Alpha component of the color
390    pub a: f64,
391}
392
393#[allow(missing_docs)]
394impl Color {
395    pub const TRANSPARENT: Self = Self {
396        r: 0.0,
397        g: 0.0,
398        b: 0.0,
399        a: 0.0,
400    };
401    pub const BLACK: Self = Self {
402        r: 0.0,
403        g: 0.0,
404        b: 0.0,
405        a: 1.0,
406    };
407    pub const WHITE: Self = Self {
408        r: 1.0,
409        g: 1.0,
410        b: 1.0,
411        a: 1.0,
412    };
413    pub const RED: Self = Self {
414        r: 1.0,
415        g: 0.0,
416        b: 0.0,
417        a: 1.0,
418    };
419    pub const GREEN: Self = Self {
420        r: 0.0,
421        g: 1.0,
422        b: 0.0,
423        a: 1.0,
424    };
425    pub const BLUE: Self = Self {
426        r: 0.0,
427        g: 0.0,
428        b: 1.0,
429        a: 1.0,
430    };
431}
432
433/// A range of immediate data memory to pass to a shader stage.
434#[derive(Clone, Debug, PartialEq, Eq, Hash)]
435#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
436pub struct ImmediateRange {
437    /// Stage immediate data range is visible from. Each stage can only be served by at most one range.
438    /// One range can serve multiple stages however.
439    pub stages: ShaderStages,
440    /// Range in immediate data memory to use for the stage. Must be less than [`Limits::max_immediate_size`].
441    /// Start and end must be aligned to the 4s.
442    pub range: Range<u32>,
443}
444
445/// Describes a [`CommandBuffer`](../wgpu/struct.CommandBuffer.html).
446///
447/// Corresponds to [WebGPU `GPUCommandBufferDescriptor`](
448/// https://gpuweb.github.io/gpuweb/#dictdef-gpucommandbufferdescriptor).
449#[repr(C)]
450#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
451#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
452pub struct CommandBufferDescriptor<L> {
453    /// Debug label of this command buffer.
454    pub label: L,
455}
456
457impl<L> CommandBufferDescriptor<L> {
458    /// Takes a closure and maps the label of the command buffer descriptor into another.
459    #[must_use]
460    pub fn map_label<K>(&self, fun: impl FnOnce(&L) -> K) -> CommandBufferDescriptor<K> {
461        CommandBufferDescriptor {
462            label: fun(&self.label),
463        }
464    }
465}
466
467/// Describes how to create a `QuerySet`.
468///
469/// Corresponds to [WebGPU `GPUQuerySetDescriptor`](
470/// https://gpuweb.github.io/gpuweb/#dictdef-gpuquerysetdescriptor).
471#[derive(Clone, Debug)]
472#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
473pub struct QuerySetDescriptor<L> {
474    /// Debug label for the query set.
475    pub label: L,
476    /// Kind of query that this query set should contain.
477    pub ty: QueryType,
478    /// Total count of queries the set contains. Must not be zero.
479    /// Must not be greater than [`QUERY_SET_MAX_QUERIES`].
480    pub count: u32,
481}
482
483impl<L> QuerySetDescriptor<L> {
484    /// Takes a closure and maps the label of the query set descriptor into another.
485    #[must_use]
486    pub fn map_label<'a, K>(&'a self, fun: impl FnOnce(&'a L) -> K) -> QuerySetDescriptor<K> {
487        QuerySetDescriptor {
488            label: fun(&self.label),
489            ty: self.ty,
490            count: self.count,
491        }
492    }
493}
494
495/// Type of query contained in a [`QuerySet`].
496///
497/// Corresponds to [WebGPU `GPUQueryType`](
498/// https://gpuweb.github.io/gpuweb/#enumdef-gpuquerytype).
499///
500#[doc = link_to_wgpu_item!(struct QuerySet)]
501#[derive(Copy, Clone, Debug)]
502#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
503pub enum QueryType {
504    /// Query returns a single 64-bit number, serving as an occlusion boolean.
505    Occlusion,
506    /// Query returns up to 5 64-bit numbers based on the given flags.
507    ///
508    /// See [`PipelineStatisticsTypes`]'s documentation for more information
509    /// on how they get resolved.
510    ///
511    /// [`Features::PIPELINE_STATISTICS_QUERY`] must be enabled to use this query type.
512    PipelineStatistics(PipelineStatisticsTypes),
513    /// Query returns a 64-bit number indicating the GPU-timestamp
514    /// where all previous commands have finished executing.
515    ///
516    /// Must be multiplied by [`Queue::get_timestamp_period`][Qgtp] to get
517    /// the value in nanoseconds. Absolute values have no meaning,
518    /// but timestamps can be subtracted to get the time it takes
519    /// for a string of operations to complete.
520    ///
521    /// [`Features::TIMESTAMP_QUERY`] must be enabled to use this query type.
522    ///
523    #[doc = link_to_wgpu_docs!(["Qgtp"]: "struct.Queue.html#method.get_timestamp_period")]
524    Timestamp,
525}
526
527bitflags::bitflags! {
528    /// Flags for which pipeline data should be recorded in a query.
529    ///
530    /// Used in [`QueryType`].
531    ///
532    /// The amount of values written when resolved depends
533    /// on the amount of flags set. For example, if 3 flags are set, 3
534    /// 64-bit values will be written per query.
535    ///
536    /// The order they are written is the order they are declared
537    /// in these bitflags. For example, if you enabled `CLIPPER_PRIMITIVES_OUT`
538    /// and `COMPUTE_SHADER_INVOCATIONS`, it would write 16 bytes,
539    /// the first 8 bytes being the primitive out value, the last 8
540    /// bytes being the compute shader invocation count.
541    #[repr(transparent)]
542    #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
543    #[cfg_attr(feature = "serde", serde(transparent))]
544    #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
545    pub struct PipelineStatisticsTypes : u8 {
546        /// Amount of times the vertex shader is ran. Accounts for
547        /// the vertex cache when doing indexed rendering.
548        const VERTEX_SHADER_INVOCATIONS = 1 << 0;
549        /// Amount of times the clipper is invoked. This
550        /// is also the amount of triangles output by the vertex shader.
551        const CLIPPER_INVOCATIONS = 1 << 1;
552        /// Amount of primitives that are not culled by the clipper.
553        /// This is the amount of triangles that are actually on screen
554        /// and will be rasterized and rendered.
555        const CLIPPER_PRIMITIVES_OUT = 1 << 2;
556        /// Amount of times the fragment shader is ran. Accounts for
557        /// fragment shaders running in 2x2 blocks in order to get
558        /// derivatives.
559        const FRAGMENT_SHADER_INVOCATIONS = 1 << 3;
560        /// Amount of times a compute shader is invoked. This will
561        /// be equivalent to the dispatch count times the workgroup size.
562        const COMPUTE_SHADER_INVOCATIONS = 1 << 4;
563    }
564}
565
566/// Corresponds to a [`GPUDeviceLostReason`].
567///
568/// [`GPUDeviceLostReason`]: https://www.w3.org/TR/webgpu/#enumdef-gpudevicelostreason
569#[repr(u8)]
570#[derive(Debug, Copy, Clone, Eq, PartialEq)]
571#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
572pub enum DeviceLostReason {
573    /// The device was lost for an unspecific reason, including driver errors.
574    Unknown = 0,
575    /// The device's `destroy` method was called.
576    Destroyed = 1,
577}