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