Skip to main content

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