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