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