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