wgpu_hal/
lib.rs

1/*! A cross-platform unsafe graphics abstraction.
2 *
3 * This crate defines a set of traits abstracting over modern graphics APIs,
4 * with implementations ("backends") for Vulkan, Metal, Direct3D, and GL.
5 *
6 * `wgpu-hal` is a spiritual successor to
7 * [gfx-hal](https://github.com/gfx-rs/gfx), but with reduced scope, and
8 * oriented towards WebGPU implementation goals. It has no overhead for
9 * validation or tracking, and the API translation overhead is kept to the bare
10 * minimum by the design of WebGPU. This API can be used for resource-demanding
11 * applications and engines.
12 *
13 * The `wgpu-hal` crate's main design choices:
14 *
15 * - Our traits are meant to be *portable*: proper use
16 *   should get equivalent results regardless of the backend.
17 *
18 * - Our traits' contracts are *unsafe*: implementations perform minimal
19 *   validation, if any, and incorrect use will often cause undefined behavior.
20 *   This allows us to minimize the overhead we impose over the underlying
21 *   graphics system. If you need safety, the [`wgpu-core`] crate provides a
22 *   safe API for driving `wgpu-hal`, implementing all necessary validation,
23 *   resource state tracking, and so on. (Note that `wgpu-core` is designed for
24 *   use via FFI; the [`wgpu`] crate provides more idiomatic Rust bindings for
25 *   `wgpu-core`.) Or, you can do your own validation.
26 *
27 * - In the same vein, returned errors *only cover cases the user can't
28 *   anticipate*, like running out of memory or losing the device. Any errors
29 *   that the user could reasonably anticipate are their responsibility to
30 *   avoid. For example, `wgpu-hal` returns no error for mapping a buffer that's
31 *   not mappable: as the buffer creator, the user should already know if they
32 *   can map it.
33 *
34 * - We use *static dispatch*. The traits are not
35 *   generally object-safe. You must select a specific backend type
36 *   like [`vulkan::Api`] or [`metal::Api`], and then use that
37 *   according to the main traits, or call backend-specific methods.
38 *
39 * - We use *idiomatic Rust parameter passing*,
40 *   taking objects by reference, returning them by value, and so on,
41 *   unlike `wgpu-core`, which refers to objects by ID.
42 *
43 * - We map buffer contents *persistently*. This means that the buffer
44 *   can remain mapped on the CPU while the GPU reads or writes to it.
45 *   You must explicitly indicate when data might need to be
46 *   transferred between CPU and GPU, if `wgpu-hal` indicates that the
47 *   mapping is not coherent (that is, automatically synchronized
48 *   between the two devices).
49 *
50 * - You must record *explicit barriers* between different usages of a
51 *   resource. For example, if a buffer is written to by a compute
52 *   shader, and then used as and index buffer to a draw call, you
53 *   must use [`CommandEncoder::transition_buffers`] between those two
54 *   operations.
55 *
56 * - Pipeline layouts are *explicitly specified* when setting bind
57 *   group. Incompatible layouts disturb groups bound at higher indices.
58 *
59 * - The API *accepts collections as iterators*, to avoid forcing the user to
60 *   store data in particular containers. The implementation doesn't guarantee
61 *   that any of the iterators are drained, unless stated otherwise by the
62 *   function documentation. For this reason, we recommend that iterators don't
63 *   do any mutating work.
64 *
65 * Unfortunately, `wgpu-hal`'s safety requirements are not fully documented.
66 * Ideally, all trait methods would have doc comments setting out the
67 * requirements users must meet to ensure correct and portable behavior. If you
68 * are aware of a specific requirement that a backend imposes that is not
69 * ensured by the traits' documented rules, please file an issue. Or, if you are
70 * a capable technical writer, please file a pull request!
71 *
72 * [`wgpu-core`]: https://crates.io/crates/wgpu-core
73 * [`wgpu`]: https://crates.io/crates/wgpu
74 * [`vulkan::Api`]: vulkan/struct.Api.html
75 * [`metal::Api`]: metal/struct.Api.html
76 *
77 * ## Primary backends
78 *
79 * The `wgpu-hal` crate has full-featured backends implemented on the following
80 * platform graphics APIs:
81 *
82 * - Vulkan, available on Linux, Android, and Windows, using the [`ash`] crate's
83 *   Vulkan bindings. It's also available on macOS, if you install [MoltenVK].
84 *
85 * - Metal on macOS, using the [`metal`] crate's bindings.
86 *
87 * - Direct3D 12 on Windows, using the [`d3d12`] crate's bindings.
88 *
89 * [`ash`]: https://crates.io/crates/ash
90 * [MoltenVK]: https://github.com/KhronosGroup/MoltenVK
91 * [`metal`]: https://crates.io/crates/metal
92 * [`d3d12`]: ahttps://crates.io/crates/d3d12
93 *
94 * ## Secondary backends
95 *
96 * The `wgpu-hal` crate has a partial implementation based on the following
97 * platform graphics API:
98 *
99 * - The GL backend is available anywhere OpenGL, OpenGL ES, or WebGL are
100 *   available. See the [`gles`] module documentation for details.
101 *
102 * [`gles`]: gles/index.html
103 *
104 * You can see what capabilities an adapter is missing by checking the
105 * [`DownlevelCapabilities`][tdc] in [`ExposedAdapter::capabilities`], available
106 * from [`Instance::enumerate_adapters`].
107 *
108 * The API is generally designed to fit the primary backends better than the
109 * secondary backends, so the latter may impose more overhead.
110 *
111 * [tdc]: wgt::DownlevelCapabilities
112 *
113 * ## Traits
114 *
115 * The `wgpu-hal` crate defines a handful of traits that together
116 * represent a cross-platform abstraction for modern GPU APIs.
117 *
118 * - The [`Api`] trait represents a `wgpu-hal` backend. It has no methods of its
119 *   own, only a collection of associated types.
120 *
121 * - [`Api::Instance`] implements the [`Instance`] trait. [`Instance::init`]
122 *   creates an instance value, which you can use to enumerate the adapters
123 *   available on the system. For example, [`vulkan::Api::Instance::init`][Ii]
124 *   returns an instance that can enumerate the Vulkan physical devices on your
125 *   system.
126 *
127 * - [`Api::Adapter`] implements the [`Adapter`] trait, representing a
128 *   particular device from a particular backend. For example, a Vulkan instance
129 *   might have a Lavapipe software adapter and a GPU-based adapter.
130 *
131 * - [`Api::Device`] implements the [`Device`] trait, representing an active
132 *   link to a device. You get a device value by calling [`Adapter::open`], and
133 *   then use it to create buffers, textures, shader modules, and so on.
134 *
135 * - [`Api::Queue`] implements the [`Queue`] trait, which you use to submit
136 *   command buffers to a given device.
137 *
138 * - [`Api::CommandEncoder`] implements the [`CommandEncoder`] trait, which you
139 *   use to build buffers of commands to submit to a queue. This has all the
140 *   methods for drawing and running compute shaders, which is presumably what
141 *   you're here for.
142 *
143 * - [`Api::Surface`] implements the [`Surface`] trait, which represents a
144 *   swapchain for presenting images on the screen, via interaction with the
145 *   system's window manager.
146 *
147 * The [`Api`] trait has various other associated types like [`Api::Buffer`] and
148 * [`Api::Texture`] that represent resources the rest of the interface can
149 * operate on, but these generally do not have their own traits.
150 *
151 * [Ii]: Instance::init
152 *
153 * ## Validation is the calling code's responsibility, not `wgpu-hal`'s
154 *
155 * As much as possible, `wgpu-hal` traits place the burden of validation,
156 * resource tracking, and state tracking on the caller, not on the trait
157 * implementations themselves. Anything which can reasonably be handled in
158 * backend-independent code should be. A `wgpu_hal` backend's sole obligation is
159 * to provide portable behavior, and report conditions that the calling code
160 * can't reasonably anticipate, like device loss or running out of memory.
161 *
162 * The `wgpu` crate collection is intended for use in security-sensitive
163 * applications, like web browsers, where the API is available to untrusted
164 * code. This means that `wgpu-core`'s validation is not simply a service to
165 * developers, to be provided opportunistically when the performance costs are
166 * acceptable and the necessary data is ready at hand. Rather, `wgpu-core`'s
167 * validation must be exhaustive, to ensure that even malicious content cannot
168 * provoke and exploit undefined behavior in the platform's graphics API.
169 *
170 * Because graphics APIs' requirements are complex, the only practical way for
171 * `wgpu` to provide exhaustive validation is to comprehensively track the
172 * lifetime and state of all the resources in the system. Implementing this
173 * separately for each backend is infeasible; effort would be better spent
174 * making the cross-platform validation in `wgpu-core` legible and trustworthy.
175 * Fortunately, the requirements are largely similar across the various
176 * platforms, so cross-platform validation is practical.
177 *
178 * Some backends have specific requirements that aren't practical to foist off
179 * on the `wgpu-hal` user. For example, properly managing macOS Objective-C or
180 * Microsoft COM reference counts is best handled by using appropriate pointer
181 * types within the backend.
182 *
183 * A desire for "defense in depth" may suggest performing additional validation
184 * in `wgpu-hal` when the opportunity arises, but this must be done with
185 * caution. Even experienced contributors infer the expectations their changes
186 * must meet by considering not just requirements made explicit in types, tests,
187 * assertions, and comments, but also those implicit in the surrounding code.
188 * When one sees validation or state-tracking code in `wgpu-hal`, it is tempting
189 * to conclude, "Oh, `wgpu-hal` checks for this, so `wgpu-core` needn't worry
190 * about it - that would be redundant!" The responsibility for exhaustive
191 * validation always rests with `wgpu-core`, regardless of what may or may not
192 * be checked in `wgpu-hal`.
193 *
194 * To this end, any "defense in depth" validation that does appear in `wgpu-hal`
195 * for requirements that `wgpu-core` should have enforced should report failure
196 * via the `unreachable!` macro, because problems detected at this stage always
197 * indicate a bug in `wgpu-core`.
198 *
199 * ## Debugging
200 *
201 * Most of the information on the wiki [Debugging wgpu Applications][wiki-debug]
202 * page still applies to this API, with the exception of API tracing/replay
203 * functionality, which is only available in `wgpu-core`.
204 *
205 * [wiki-debug]: https://github.com/gfx-rs/wgpu/wiki/Debugging-wgpu-Applications
206 */
207
208#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
209#![allow(
210    // this happens on the GL backend, where it is both thread safe and non-thread safe in the same code.
211    clippy::arc_with_non_send_sync,
212    // for `if_then_panic` until it reaches stable
213    unknown_lints,
214    // We use loops for getting early-out of scope without closures.
215    clippy::never_loop,
216    // We don't use syntax sugar where it's not necessary.
217    clippy::match_like_matches_macro,
218    // Redundant matching is more explicit.
219    clippy::redundant_pattern_matching,
220    // Explicit lifetimes are often easier to reason about.
221    clippy::needless_lifetimes,
222    // No need for defaults in the internal types.
223    clippy::new_without_default,
224    // Matches are good and extendable, no need to make an exception here.
225    clippy::single_match,
226    // Push commands are more regular than macros.
227    clippy::vec_init_then_push,
228    // "if panic" is a good uniform construct.
229    clippy::if_then_panic,
230    // We unsafe impl `Send` for a reason.
231    clippy::non_send_fields_in_send_ty,
232    // TODO!
233    clippy::missing_safety_doc,
234    // Clashes with clippy::pattern_type_mismatch
235    clippy::needless_borrowed_reference,
236)]
237#![warn(
238    trivial_casts,
239    trivial_numeric_casts,
240    unsafe_op_in_unsafe_fn,
241    unused_extern_crates,
242    unused_qualifications,
243    // We don't match on a reference, unless required.
244    clippy::pattern_type_mismatch,
245)]
246
247/// DirectX12 API internals.
248#[cfg(dx12)]
249pub mod dx12;
250/// A dummy API implementation.
251pub mod empty;
252/// GLES API internals.
253#[cfg(gles)]
254pub mod gles;
255/// Metal API internals.
256#[cfg(metal)]
257pub mod metal;
258/// Vulkan API internals.
259#[cfg(vulkan)]
260pub mod vulkan;
261
262pub mod auxil;
263pub mod api {
264    #[cfg(dx12)]
265    pub use super::dx12::Api as Dx12;
266    pub use super::empty::Api as Empty;
267    #[cfg(gles)]
268    pub use super::gles::Api as Gles;
269    #[cfg(metal)]
270    pub use super::metal::Api as Metal;
271    #[cfg(vulkan)]
272    pub use super::vulkan::Api as Vulkan;
273}
274
275use std::{
276    borrow::{Borrow, Cow},
277    fmt,
278    num::NonZeroU32,
279    ops::{Range, RangeInclusive},
280    ptr::NonNull,
281    sync::Arc,
282};
283
284use bitflags::bitflags;
285use parking_lot::Mutex;
286use thiserror::Error;
287use wgt::WasmNotSendSync;
288
289// - Vertex + Fragment
290// - Compute
291pub const MAX_CONCURRENT_SHADER_STAGES: usize = 2;
292pub const MAX_ANISOTROPY: u8 = 16;
293pub const MAX_BIND_GROUPS: usize = 8;
294pub const MAX_VERTEX_BUFFERS: usize = 16;
295pub const MAX_COLOR_ATTACHMENTS: usize = 8;
296pub const MAX_MIP_LEVELS: u32 = 16;
297/// Size of a single occlusion/timestamp query, when copied into a buffer, in bytes.
298pub const QUERY_SIZE: wgt::BufferAddress = 8;
299
300pub type Label<'a> = Option<&'a str>;
301pub type MemoryRange = Range<wgt::BufferAddress>;
302pub type FenceValue = u64;
303
304/// Drop guard to signal wgpu-hal is no longer using an externally created object.
305pub type DropGuard = Box<dyn std::any::Any + Send + Sync>;
306
307#[derive(Clone, Debug, PartialEq, Eq, Error)]
308pub enum DeviceError {
309    #[error("Out of memory")]
310    OutOfMemory,
311    #[error("Device is lost")]
312    Lost,
313    #[error("Creation of a resource failed for a reason other than running out of memory.")]
314    ResourceCreationFailed,
315}
316
317#[derive(Clone, Debug, Eq, PartialEq, Error)]
318pub enum ShaderError {
319    #[error("Compilation failed: {0:?}")]
320    Compilation(String),
321    #[error(transparent)]
322    Device(#[from] DeviceError),
323}
324
325#[derive(Clone, Debug, Eq, PartialEq, Error)]
326pub enum PipelineError {
327    #[error("Linkage failed for stage {0:?}: {1}")]
328    Linkage(wgt::ShaderStages, String),
329    #[error("Entry point for stage {0:?} is invalid")]
330    EntryPoint(naga::ShaderStage),
331    #[error(transparent)]
332    Device(#[from] DeviceError),
333}
334
335#[derive(Clone, Debug, Eq, PartialEq, Error)]
336pub enum SurfaceError {
337    #[error("Surface is lost")]
338    Lost,
339    #[error("Surface is outdated, needs to be re-created")]
340    Outdated,
341    #[error(transparent)]
342    Device(#[from] DeviceError),
343    #[error("Other reason: {0}")]
344    Other(&'static str),
345}
346
347/// Error occurring while trying to create an instance, or create a surface from an instance;
348/// typically relating to the state of the underlying graphics API or hardware.
349#[derive(Clone, Debug, Error)]
350#[error("{message}")]
351pub struct InstanceError {
352    /// These errors are very platform specific, so do not attempt to encode them as an enum.
353    ///
354    /// This message should describe the problem in sufficient detail to be useful for a
355    /// user-to-developer “why won't this work on my machine” bug report, and otherwise follow
356    /// <https://rust-lang.github.io/api-guidelines/interoperability.html#error-types-are-meaningful-and-well-behaved-c-good-err>.
357    message: String,
358
359    /// Underlying error value, if any is available.
360    #[source]
361    source: Option<Arc<dyn std::error::Error + Send + Sync + 'static>>,
362}
363
364impl InstanceError {
365    #[allow(dead_code)] // may be unused on some platforms
366    pub(crate) fn new(message: String) -> Self {
367        Self {
368            message,
369            source: None,
370        }
371    }
372    #[allow(dead_code)] // may be unused on some platforms
373    pub(crate) fn with_source(
374        message: String,
375        source: impl std::error::Error + Send + Sync + 'static,
376    ) -> Self {
377        Self {
378            message,
379            source: Some(Arc::new(source)),
380        }
381    }
382}
383
384pub trait Api: Clone + fmt::Debug + Sized {
385    type Instance: Instance<A = Self>;
386    type Surface: Surface<A = Self>;
387    type Adapter: Adapter<A = Self>;
388    type Device: Device<A = Self>;
389
390    type Queue: Queue<A = Self>;
391    type CommandEncoder: CommandEncoder<A = Self>;
392
393    /// This API's command buffer type.
394    ///
395    /// The only thing you can do with `CommandBuffer`s is build them
396    /// with a [`CommandEncoder`] and then pass them to
397    /// [`Queue::submit`] for execution, or destroy them by passing
398    /// them to [`CommandEncoder::reset_all`].
399    ///
400    /// [`CommandEncoder`]: Api::CommandEncoder
401    type CommandBuffer: WasmNotSendSync + fmt::Debug;
402
403    type Buffer: fmt::Debug + WasmNotSendSync + 'static;
404    type Texture: fmt::Debug + WasmNotSendSync + 'static;
405    type SurfaceTexture: fmt::Debug + WasmNotSendSync + Borrow<Self::Texture>;
406    type TextureView: fmt::Debug + WasmNotSendSync;
407    type Sampler: fmt::Debug + WasmNotSendSync;
408    type QuerySet: fmt::Debug + WasmNotSendSync;
409
410    /// A value you can block on to wait for something to finish.
411    ///
412    /// A `Fence` holds a monotonically increasing [`FenceValue`]. You can call
413    /// [`Device::wait`] to block until a fence reaches or passes a value you
414    /// choose. [`Queue::submit`] can take a `Fence` and a [`FenceValue`] to
415    /// store in it when the submitted work is complete.
416    ///
417    /// Attempting to set a fence to a value less than its current value has no
418    /// effect.
419    ///
420    /// Waiting on a fence returns as soon as the fence reaches *or passes* the
421    /// requested value. This implies that, in order to reliably determine when
422    /// an operation has completed, operations must finish in order of
423    /// increasing fence values: if a higher-valued operation were to finish
424    /// before a lower-valued operation, then waiting for the fence to reach the
425    /// lower value could return before the lower-valued operation has actually
426    /// finished.
427    type Fence: fmt::Debug + WasmNotSendSync;
428
429    type BindGroupLayout: fmt::Debug + WasmNotSendSync;
430    type BindGroup: fmt::Debug + WasmNotSendSync;
431    type PipelineLayout: fmt::Debug + WasmNotSendSync;
432    type ShaderModule: fmt::Debug + WasmNotSendSync;
433    type RenderPipeline: fmt::Debug + WasmNotSendSync;
434    type ComputePipeline: fmt::Debug + WasmNotSendSync;
435
436    type AccelerationStructure: fmt::Debug + WasmNotSendSync + 'static;
437}
438
439pub trait Instance: Sized + WasmNotSendSync {
440    type A: Api;
441
442    unsafe fn init(desc: &InstanceDescriptor) -> Result<Self, InstanceError>;
443    unsafe fn create_surface(
444        &self,
445        display_handle: raw_window_handle::RawDisplayHandle,
446        window_handle: raw_window_handle::RawWindowHandle,
447    ) -> Result<<Self::A as Api>::Surface, InstanceError>;
448    unsafe fn destroy_surface(&self, surface: <Self::A as Api>::Surface);
449    unsafe fn enumerate_adapters(&self) -> Vec<ExposedAdapter<Self::A>>;
450}
451
452pub trait Surface: WasmNotSendSync {
453    type A: Api;
454
455    /// Configure `self` to use `device`.
456    ///
457    /// # Safety
458    ///
459    /// - All GPU work using `self` must have been completed.
460    /// - All [`AcquiredSurfaceTexture`]s must have been destroyed.
461    /// - All [`Api::TextureView`]s derived from the [`AcquiredSurfaceTexture`]s must have been destroyed.
462    /// - The surface `self` must not currently be configured to use any other [`Device`].
463    unsafe fn configure(
464        &self,
465        device: &<Self::A as Api>::Device,
466        config: &SurfaceConfiguration,
467    ) -> Result<(), SurfaceError>;
468
469    /// Unconfigure `self` on `device`.
470    ///
471    /// # Safety
472    ///
473    /// - All GPU work that uses `surface` must have been completed.
474    /// - All [`AcquiredSurfaceTexture`]s must have been destroyed.
475    /// - All [`Api::TextureView`]s derived from the [`AcquiredSurfaceTexture`]s must have been destroyed.
476    /// - The surface `self` must have been configured on `device`.
477    unsafe fn unconfigure(&self, device: &<Self::A as Api>::Device);
478
479    /// Return the next texture to be presented by `self`, for the caller to draw on.
480    ///
481    /// On success, return an [`AcquiredSurfaceTexture`] representing the
482    /// texture into which the caller should draw the image to be displayed on
483    /// `self`.
484    ///
485    /// If `timeout` elapses before `self` has a texture ready to be acquired,
486    /// return `Ok(None)`. If `timeout` is `None`, wait indefinitely, with no
487    /// timeout.
488    ///
489    /// # Using an [`AcquiredSurfaceTexture`]
490    ///
491    /// On success, this function returns an [`AcquiredSurfaceTexture`] whose
492    /// [`texture`] field is a [`SurfaceTexture`] from which the caller can
493    /// [`borrow`] a [`Texture`] to draw on. The [`AcquiredSurfaceTexture`] also
494    /// carries some metadata about that [`SurfaceTexture`].
495    ///
496    /// All calls to [`Queue::submit`] that draw on that [`Texture`] must also
497    /// include the [`SurfaceTexture`] in the `surface_textures` argument.
498    ///
499    /// When you are done drawing on the texture, you can display it on `self`
500    /// by passing the [`SurfaceTexture`] and `self` to [`Queue::present`].
501    ///
502    /// If you do not wish to display the texture, you must pass the
503    /// [`SurfaceTexture`] to [`self.discard_texture`], so that it can be reused
504    /// by future acquisitions.
505    ///
506    /// # Portability
507    ///
508    /// Some backends can't support a timeout when acquiring a texture. On these
509    /// backends, `timeout` is ignored.
510    ///
511    /// # Safety
512    ///
513    /// - The surface `self` must currently be configured on some [`Device`].
514    ///
515    /// - The `fence` argument must be the same [`Fence`] passed to all calls to
516    ///   [`Queue::submit`] that used [`Texture`]s acquired from this surface.
517    ///
518    /// - You may only have one texture acquired from `self` at a time. When
519    ///   `acquire_texture` returns `Ok(Some(ast))`, you must pass the returned
520    ///   [`SurfaceTexture`] `ast.texture` to either [`Queue::present`] or
521    ///   [`Surface::discard_texture`] before calling `acquire_texture` again.
522    ///
523    /// [`texture`]: AcquiredSurfaceTexture::texture
524    /// [`SurfaceTexture`]: Api::SurfaceTexture
525    /// [`borrow`]: std::borrow::Borrow::borrow
526    /// [`Texture`]: Api::Texture
527    /// [`Fence`]: Api::Fence
528    /// [`self.discard_texture`]: Surface::discard_texture
529    unsafe fn acquire_texture(
530        &self,
531        timeout: Option<std::time::Duration>,
532        fence: &<Self::A as Api>::Fence,
533    ) -> Result<Option<AcquiredSurfaceTexture<Self::A>>, SurfaceError>;
534
535    /// Relinquish an acquired texture without presenting it.
536    ///
537    /// After this call, the texture underlying [`SurfaceTexture`] may be
538    /// returned by subsequent calls to [`self.acquire_texture`].
539    ///
540    /// # Safety
541    ///
542    /// - The surface `self` must currently be configured on some [`Device`].
543    ///
544    /// - `texture` must be a [`SurfaceTexture`] returned by a call to
545    ///   [`self.acquire_texture`] that has not yet been passed to
546    ///   [`Queue::present`].
547    ///
548    /// [`SurfaceTexture`]: Api::SurfaceTexture
549    /// [`self.acquire_texture`]: Surface::acquire_texture
550    unsafe fn discard_texture(&self, texture: <Self::A as Api>::SurfaceTexture);
551}
552
553pub trait Adapter: WasmNotSendSync {
554    type A: Api;
555
556    unsafe fn open(
557        &self,
558        features: wgt::Features,
559        limits: &wgt::Limits,
560    ) -> Result<OpenDevice<Self::A>, DeviceError>;
561
562    /// Return the set of supported capabilities for a texture format.
563    unsafe fn texture_format_capabilities(
564        &self,
565        format: wgt::TextureFormat,
566    ) -> TextureFormatCapabilities;
567
568    /// Returns the capabilities of working with a specified surface.
569    ///
570    /// `None` means presentation is not supported for it.
571    unsafe fn surface_capabilities(
572        &self,
573        surface: &<Self::A as Api>::Surface,
574    ) -> Option<SurfaceCapabilities>;
575
576    /// Creates a [`PresentationTimestamp`] using the adapter's WSI.
577    ///
578    /// [`PresentationTimestamp`]: wgt::PresentationTimestamp
579    unsafe fn get_presentation_timestamp(&self) -> wgt::PresentationTimestamp;
580}
581
582pub trait Device: WasmNotSendSync {
583    type A: Api;
584
585    /// Exit connection to this logical device.
586    unsafe fn exit(self, queue: <Self::A as Api>::Queue);
587    /// Creates a new buffer.
588    ///
589    /// The initial usage is `BufferUses::empty()`.
590    unsafe fn create_buffer(
591        &self,
592        desc: &BufferDescriptor,
593    ) -> Result<<Self::A as Api>::Buffer, DeviceError>;
594    unsafe fn destroy_buffer(&self, buffer: <Self::A as Api>::Buffer);
595    //TODO: clarify if zero-sized mapping is allowed
596    unsafe fn map_buffer(
597        &self,
598        buffer: &<Self::A as Api>::Buffer,
599        range: MemoryRange,
600    ) -> Result<BufferMapping, DeviceError>;
601    unsafe fn unmap_buffer(&self, buffer: &<Self::A as Api>::Buffer) -> Result<(), DeviceError>;
602    unsafe fn flush_mapped_ranges<I>(&self, buffer: &<Self::A as Api>::Buffer, ranges: I)
603    where
604        I: Iterator<Item = MemoryRange>;
605    unsafe fn invalidate_mapped_ranges<I>(&self, buffer: &<Self::A as Api>::Buffer, ranges: I)
606    where
607        I: Iterator<Item = MemoryRange>;
608
609    /// Creates a new texture.
610    ///
611    /// The initial usage for all subresources is `TextureUses::UNINITIALIZED`.
612    unsafe fn create_texture(
613        &self,
614        desc: &TextureDescriptor,
615    ) -> Result<<Self::A as Api>::Texture, DeviceError>;
616    unsafe fn destroy_texture(&self, texture: <Self::A as Api>::Texture);
617    unsafe fn create_texture_view(
618        &self,
619        texture: &<Self::A as Api>::Texture,
620        desc: &TextureViewDescriptor,
621    ) -> Result<<Self::A as Api>::TextureView, DeviceError>;
622    unsafe fn destroy_texture_view(&self, view: <Self::A as Api>::TextureView);
623    unsafe fn create_sampler(
624        &self,
625        desc: &SamplerDescriptor,
626    ) -> Result<<Self::A as Api>::Sampler, DeviceError>;
627    unsafe fn destroy_sampler(&self, sampler: <Self::A as Api>::Sampler);
628
629    /// Create a fresh [`CommandEncoder`].
630    ///
631    /// The new `CommandEncoder` is in the "closed" state.
632    unsafe fn create_command_encoder(
633        &self,
634        desc: &CommandEncoderDescriptor<Self::A>,
635    ) -> Result<<Self::A as Api>::CommandEncoder, DeviceError>;
636    unsafe fn destroy_command_encoder(&self, pool: <Self::A as Api>::CommandEncoder);
637
638    /// Creates a bind group layout.
639    unsafe fn create_bind_group_layout(
640        &self,
641        desc: &BindGroupLayoutDescriptor,
642    ) -> Result<<Self::A as Api>::BindGroupLayout, DeviceError>;
643    unsafe fn destroy_bind_group_layout(&self, bg_layout: <Self::A as Api>::BindGroupLayout);
644    unsafe fn create_pipeline_layout(
645        &self,
646        desc: &PipelineLayoutDescriptor<Self::A>,
647    ) -> Result<<Self::A as Api>::PipelineLayout, DeviceError>;
648    unsafe fn destroy_pipeline_layout(&self, pipeline_layout: <Self::A as Api>::PipelineLayout);
649    unsafe fn create_bind_group(
650        &self,
651        desc: &BindGroupDescriptor<Self::A>,
652    ) -> Result<<Self::A as Api>::BindGroup, DeviceError>;
653    unsafe fn destroy_bind_group(&self, group: <Self::A as Api>::BindGroup);
654
655    unsafe fn create_shader_module(
656        &self,
657        desc: &ShaderModuleDescriptor,
658        shader: ShaderInput,
659    ) -> Result<<Self::A as Api>::ShaderModule, ShaderError>;
660    unsafe fn destroy_shader_module(&self, module: <Self::A as Api>::ShaderModule);
661    unsafe fn create_render_pipeline(
662        &self,
663        desc: &RenderPipelineDescriptor<Self::A>,
664    ) -> Result<<Self::A as Api>::RenderPipeline, PipelineError>;
665    unsafe fn destroy_render_pipeline(&self, pipeline: <Self::A as Api>::RenderPipeline);
666    unsafe fn create_compute_pipeline(
667        &self,
668        desc: &ComputePipelineDescriptor<Self::A>,
669    ) -> Result<<Self::A as Api>::ComputePipeline, PipelineError>;
670    unsafe fn destroy_compute_pipeline(&self, pipeline: <Self::A as Api>::ComputePipeline);
671
672    unsafe fn create_query_set(
673        &self,
674        desc: &wgt::QuerySetDescriptor<Label>,
675    ) -> Result<<Self::A as Api>::QuerySet, DeviceError>;
676    unsafe fn destroy_query_set(&self, set: <Self::A as Api>::QuerySet);
677    unsafe fn create_fence(&self) -> Result<<Self::A as Api>::Fence, DeviceError>;
678    unsafe fn destroy_fence(&self, fence: <Self::A as Api>::Fence);
679    unsafe fn get_fence_value(
680        &self,
681        fence: &<Self::A as Api>::Fence,
682    ) -> Result<FenceValue, DeviceError>;
683
684    /// Wait for `fence` to reach `value`.
685    ///
686    /// Operations like [`Queue::submit`] can accept a [`Fence`] and a
687    /// [`FenceValue`] to store in it, so you can use this `wait` function
688    /// to wait for a given queue submission to finish execution.
689    ///
690    /// The `value` argument must be a value that some actual operation you have
691    /// already presented to the device is going to store in `fence`. You cannot
692    /// wait for values yet to be submitted. (This restriction accommodates
693    /// implementations like the `vulkan` backend's [`FencePool`] that must
694    /// allocate a distinct synchronization object for each fence value one is
695    /// able to wait for.)
696    ///
697    /// Calling `wait` with a lower [`FenceValue`] than `fence`'s current value
698    /// returns immediately.
699    ///
700    /// [`Fence`]: Api::Fence
701    /// [`FencePool`]: vulkan/enum.Fence.html#variant.FencePool
702    unsafe fn wait(
703        &self,
704        fence: &<Self::A as Api>::Fence,
705        value: FenceValue,
706        timeout_ms: u32,
707    ) -> Result<bool, DeviceError>;
708
709    unsafe fn start_capture(&self) -> bool;
710    unsafe fn stop_capture(&self);
711
712    unsafe fn create_acceleration_structure(
713        &self,
714        desc: &AccelerationStructureDescriptor,
715    ) -> Result<<Self::A as Api>::AccelerationStructure, DeviceError>;
716    unsafe fn get_acceleration_structure_build_sizes(
717        &self,
718        desc: &GetAccelerationStructureBuildSizesDescriptor<Self::A>,
719    ) -> AccelerationStructureBuildSizes;
720    unsafe fn get_acceleration_structure_device_address(
721        &self,
722        acceleration_structure: &<Self::A as Api>::AccelerationStructure,
723    ) -> wgt::BufferAddress;
724    unsafe fn destroy_acceleration_structure(
725        &self,
726        acceleration_structure: <Self::A as Api>::AccelerationStructure,
727    );
728}
729
730pub trait Queue: WasmNotSendSync {
731    type A: Api;
732
733    /// Submit `command_buffers` for execution on GPU.
734    ///
735    /// Update `fence` to `value` when the operation is complete. See
736    /// [`Fence`] for details.
737    ///
738    /// A `wgpu_hal` queue is "single threaded": all command buffers are
739    /// executed in the order they're submitted, with each buffer able to see
740    /// previous buffers' results. Specifically:
741    ///
742    /// - If two calls to `submit` on a single `Queue` occur in a particular
743    ///   order (that is, they happen on the same thread, or on two threads that
744    ///   have synchronized to establish an ordering), then the first
745    ///   submission's commands all complete execution before any of the second
746    ///   submission's commands begin. All results produced by one submission
747    ///   are visible to the next.
748    ///
749    /// - Within a submission, command buffers execute in the order in which they
750    ///   appear in `command_buffers`. All results produced by one buffer are
751    ///   visible to the next.
752    ///
753    /// If two calls to `submit` on a single `Queue` from different threads are
754    /// not synchronized to occur in a particular order, they must pass distinct
755    /// [`Fence`]s. As explained in the [`Fence`] documentation, waiting for
756    /// operations to complete is only trustworthy when operations finish in
757    /// order of increasing fence value, but submissions from different threads
758    /// cannot determine how to order the fence values if the submissions
759    /// themselves are unordered. If each thread uses a separate [`Fence`], this
760    /// problem does not arise.
761    ///
762    /// Valid usage:
763    ///
764    /// - All of the [`CommandBuffer`][cb]s were created from
765    ///   [`CommandEncoder`][ce]s that are associated with this queue.
766    ///
767    /// - All of those [`CommandBuffer`][cb]s must remain alive until
768    ///   the submitted commands have finished execution. (Since
769    ///   command buffers must not outlive their encoders, this
770    ///   implies that the encoders must remain alive as well.)
771    ///
772    /// - All resources used by a submitted [`CommandBuffer`][cb]
773    ///   ([`Texture`][t]s, [`BindGroup`][bg]s, [`RenderPipeline`][rp]s, and so
774    ///   on) must remain alive until the command buffer finishes execution.
775    ///
776    /// - Every [`SurfaceTexture`][st] that any command in `command_buffers`
777    ///   writes to must appear in the `surface_textures` argument.
778    ///
779    /// - No [`SurfaceTexture`][st] may appear in the `surface_textures`
780    ///   argument more than once.
781    ///
782    /// - Each [`SurfaceTexture`][st] in `surface_textures` must be configured
783    ///   for use with the [`Device`][d] associated with this [`Queue`],
784    ///   typically by calling [`Surface::configure`].
785    ///
786    /// - All calls to this function that include a given [`SurfaceTexture`][st]
787    ///   in `surface_textures` must use the same [`Fence`].
788    ///
789    /// [`Fence`]: Api::Fence
790    /// [cb]: Api::CommandBuffer
791    /// [ce]: Api::CommandEncoder
792    /// [st]: Api::SurfaceTexture
793    /// [t]: Api::Texture
794    /// [bg]: Api::BindGroup
795    /// [rp]: Api::RenderPipeline
796    /// [d]: Api::Device
797    unsafe fn submit(
798        &self,
799        command_buffers: &[&<Self::A as Api>::CommandBuffer],
800        surface_textures: &[&<Self::A as Api>::SurfaceTexture],
801        signal_fence: (&mut <Self::A as Api>::Fence, FenceValue),
802    ) -> Result<(), DeviceError>;
803    unsafe fn present(
804        &self,
805        surface: &<Self::A as Api>::Surface,
806        texture: <Self::A as Api>::SurfaceTexture,
807    ) -> Result<(), SurfaceError>;
808    unsafe fn get_timestamp_period(&self) -> f32;
809}
810
811/// Encoder and allocation pool for `CommandBuffer`s.
812///
813/// A `CommandEncoder` not only constructs `CommandBuffer`s but also
814/// acts as the allocation pool that owns the buffers' underlying
815/// storage. Thus, `CommandBuffer`s must not outlive the
816/// `CommandEncoder` that created them.
817///
818/// The life cycle of a `CommandBuffer` is as follows:
819///
820/// - Call [`Device::create_command_encoder`] to create a new
821///   `CommandEncoder`, in the "closed" state.
822///
823/// - Call `begin_encoding` on a closed `CommandEncoder` to begin
824///   recording commands. This puts the `CommandEncoder` in the
825///   "recording" state.
826///
827/// - Call methods like `copy_buffer_to_buffer`, `begin_render_pass`,
828///   etc. on a "recording" `CommandEncoder` to add commands to the
829///   list. (If an error occurs, you must call `discard_encoding`; see
830///   below.)
831///
832/// - Call `end_encoding` on a recording `CommandEncoder` to close the
833///   encoder and construct a fresh `CommandBuffer` consisting of the
834///   list of commands recorded up to that point.
835///
836/// - Call `discard_encoding` on a recording `CommandEncoder` to drop
837///   the commands recorded thus far and close the encoder. This is
838///   the only safe thing to do on a `CommandEncoder` if an error has
839///   occurred while recording commands.
840///
841/// - Call `reset_all` on a closed `CommandEncoder`, passing all the
842///   live `CommandBuffers` built from it. All the `CommandBuffer`s
843///   are destroyed, and their resources are freed.
844///
845/// # Safety
846///
847/// - The `CommandEncoder` must be in the states described above to
848///   make the given calls.
849///
850/// - A `CommandBuffer` that has been submitted for execution on the
851///   GPU must live until its execution is complete.
852///
853/// - A `CommandBuffer` must not outlive the `CommandEncoder` that
854///   built it.
855///
856/// - A `CommandEncoder` must not outlive its `Device`.
857///
858/// It is the user's responsibility to meet this requirements. This
859/// allows `CommandEncoder` implementations to keep their state
860/// tracking to a minimum.
861pub trait CommandEncoder: WasmNotSendSync + fmt::Debug {
862    type A: Api;
863
864    /// Begin encoding a new command buffer.
865    ///
866    /// This puts this `CommandEncoder` in the "recording" state.
867    ///
868    /// # Safety
869    ///
870    /// This `CommandEncoder` must be in the "closed" state.
871    unsafe fn begin_encoding(&mut self, label: Label) -> Result<(), DeviceError>;
872
873    /// Discard the command list under construction.
874    ///
875    /// If an error has occurred while recording commands, this
876    /// is the only safe thing to do with the encoder.
877    ///
878    /// This puts this `CommandEncoder` in the "closed" state.
879    ///
880    /// # Safety
881    ///
882    /// This `CommandEncoder` must be in the "recording" state.
883    ///
884    /// Callers must not assume that implementations of this
885    /// function are idempotent, and thus should not call it
886    /// multiple times in a row.
887    unsafe fn discard_encoding(&mut self);
888
889    /// Return a fresh [`CommandBuffer`] holding the recorded commands.
890    ///
891    /// The returned [`CommandBuffer`] holds all the commands recorded
892    /// on this `CommandEncoder` since the last call to
893    /// [`begin_encoding`].
894    ///
895    /// This puts this `CommandEncoder` in the "closed" state.
896    ///
897    /// # Safety
898    ///
899    /// This `CommandEncoder` must be in the "recording" state.
900    ///
901    /// The returned [`CommandBuffer`] must not outlive this
902    /// `CommandEncoder`. Implementations are allowed to build
903    /// `CommandBuffer`s that depend on storage owned by this
904    /// `CommandEncoder`.
905    ///
906    /// [`CommandBuffer`]: Api::CommandBuffer
907    /// [`begin_encoding`]: CommandEncoder::begin_encoding
908    unsafe fn end_encoding(&mut self) -> Result<<Self::A as Api>::CommandBuffer, DeviceError>;
909
910    /// Reclaim all resources belonging to this `CommandEncoder`.
911    ///
912    /// # Safety
913    ///
914    /// This `CommandEncoder` must be in the "closed" state.
915    ///
916    /// The `command_buffers` iterator must produce all the live
917    /// [`CommandBuffer`]s built using this `CommandEncoder` --- that
918    /// is, every extant `CommandBuffer` returned from `end_encoding`.
919    ///
920    /// [`CommandBuffer`]: Api::CommandBuffer
921    unsafe fn reset_all<I>(&mut self, command_buffers: I)
922    where
923        I: Iterator<Item = <Self::A as Api>::CommandBuffer>;
924
925    unsafe fn transition_buffers<'a, T>(&mut self, barriers: T)
926    where
927        T: Iterator<Item = BufferBarrier<'a, Self::A>>;
928
929    unsafe fn transition_textures<'a, T>(&mut self, barriers: T)
930    where
931        T: Iterator<Item = TextureBarrier<'a, Self::A>>;
932
933    // copy operations
934
935    unsafe fn clear_buffer(&mut self, buffer: &<Self::A as Api>::Buffer, range: MemoryRange);
936
937    unsafe fn copy_buffer_to_buffer<T>(
938        &mut self,
939        src: &<Self::A as Api>::Buffer,
940        dst: &<Self::A as Api>::Buffer,
941        regions: T,
942    ) where
943        T: Iterator<Item = BufferCopy>;
944
945    /// Copy from an external image to an internal texture.
946    /// Works with a single array layer.
947    /// Note: `dst` current usage has to be `TextureUses::COPY_DST`.
948    /// Note: the copy extent is in physical size (rounded to the block size)
949    #[cfg(webgl)]
950    unsafe fn copy_external_image_to_texture<T>(
951        &mut self,
952        src: &wgt::ImageCopyExternalImage,
953        dst: &<Self::A as Api>::Texture,
954        dst_premultiplication: bool,
955        regions: T,
956    ) where
957        T: Iterator<Item = TextureCopy>;
958
959    /// Copy from one texture to another.
960    /// Works with a single array layer.
961    /// Note: `dst` current usage has to be `TextureUses::COPY_DST`.
962    /// Note: the copy extent is in physical size (rounded to the block size)
963    unsafe fn copy_texture_to_texture<T>(
964        &mut self,
965        src: &<Self::A as Api>::Texture,
966        src_usage: TextureUses,
967        dst: &<Self::A as Api>::Texture,
968        regions: T,
969    ) where
970        T: Iterator<Item = TextureCopy>;
971
972    /// Copy from buffer to texture.
973    /// Works with a single array layer.
974    /// Note: `dst` current usage has to be `TextureUses::COPY_DST`.
975    /// Note: the copy extent is in physical size (rounded to the block size)
976    unsafe fn copy_buffer_to_texture<T>(
977        &mut self,
978        src: &<Self::A as Api>::Buffer,
979        dst: &<Self::A as Api>::Texture,
980        regions: T,
981    ) where
982        T: Iterator<Item = BufferTextureCopy>;
983
984    /// Copy from texture to buffer.
985    /// Works with a single array layer.
986    /// Note: the copy extent is in physical size (rounded to the block size)
987    unsafe fn copy_texture_to_buffer<T>(
988        &mut self,
989        src: &<Self::A as Api>::Texture,
990        src_usage: TextureUses,
991        dst: &<Self::A as Api>::Buffer,
992        regions: T,
993    ) where
994        T: Iterator<Item = BufferTextureCopy>;
995
996    // pass common
997
998    /// Sets the bind group at `index` to `group`, assuming the layout
999    /// of all the preceding groups to be taken from `layout`.
1000    unsafe fn set_bind_group(
1001        &mut self,
1002        layout: &<Self::A as Api>::PipelineLayout,
1003        index: u32,
1004        group: &<Self::A as Api>::BindGroup,
1005        dynamic_offsets: &[wgt::DynamicOffset],
1006    );
1007
1008    /// Sets a range in push constant data.
1009    ///
1010    /// IMPORTANT: while the data is passed as words, the offset is in bytes!
1011    ///
1012    /// # Safety
1013    ///
1014    /// - `offset_bytes` must be a multiple of 4.
1015    /// - The range of push constants written must be valid for the pipeline layout at draw time.
1016    unsafe fn set_push_constants(
1017        &mut self,
1018        layout: &<Self::A as Api>::PipelineLayout,
1019        stages: wgt::ShaderStages,
1020        offset_bytes: u32,
1021        data: &[u32],
1022    );
1023
1024    unsafe fn insert_debug_marker(&mut self, label: &str);
1025    unsafe fn begin_debug_marker(&mut self, group_label: &str);
1026    unsafe fn end_debug_marker(&mut self);
1027
1028    // queries
1029
1030    /// # Safety:
1031    ///
1032    /// - If `set` is an occlusion query set, it must be the same one as used in the [`RenderPassDescriptor::occlusion_query_set`] parameter.
1033    unsafe fn begin_query(&mut self, set: &<Self::A as Api>::QuerySet, index: u32);
1034    /// # Safety:
1035    ///
1036    /// - If `set` is an occlusion query set, it must be the same one as used in the [`RenderPassDescriptor::occlusion_query_set`] parameter.
1037    unsafe fn end_query(&mut self, set: &<Self::A as Api>::QuerySet, index: u32);
1038    unsafe fn write_timestamp(&mut self, set: &<Self::A as Api>::QuerySet, index: u32);
1039    unsafe fn reset_queries(&mut self, set: &<Self::A as Api>::QuerySet, range: Range<u32>);
1040    unsafe fn copy_query_results(
1041        &mut self,
1042        set: &<Self::A as Api>::QuerySet,
1043        range: Range<u32>,
1044        buffer: &<Self::A as Api>::Buffer,
1045        offset: wgt::BufferAddress,
1046        stride: wgt::BufferSize,
1047    );
1048
1049    // render passes
1050
1051    // Begins a render pass, clears all active bindings.
1052    unsafe fn begin_render_pass(&mut self, desc: &RenderPassDescriptor<Self::A>);
1053    unsafe fn end_render_pass(&mut self);
1054
1055    unsafe fn set_render_pipeline(&mut self, pipeline: &<Self::A as Api>::RenderPipeline);
1056
1057    unsafe fn set_index_buffer<'a>(
1058        &mut self,
1059        binding: BufferBinding<'a, Self::A>,
1060        format: wgt::IndexFormat,
1061    );
1062    unsafe fn set_vertex_buffer<'a>(&mut self, index: u32, binding: BufferBinding<'a, Self::A>);
1063    unsafe fn set_viewport(&mut self, rect: &Rect<f32>, depth_range: Range<f32>);
1064    unsafe fn set_scissor_rect(&mut self, rect: &Rect<u32>);
1065    unsafe fn set_stencil_reference(&mut self, value: u32);
1066    unsafe fn set_blend_constants(&mut self, color: &[f32; 4]);
1067
1068    unsafe fn draw(
1069        &mut self,
1070        first_vertex: u32,
1071        vertex_count: u32,
1072        first_instance: u32,
1073        instance_count: u32,
1074    );
1075    unsafe fn draw_indexed(
1076        &mut self,
1077        first_index: u32,
1078        index_count: u32,
1079        base_vertex: i32,
1080        first_instance: u32,
1081        instance_count: u32,
1082    );
1083    unsafe fn draw_indirect(
1084        &mut self,
1085        buffer: &<Self::A as Api>::Buffer,
1086        offset: wgt::BufferAddress,
1087        draw_count: u32,
1088    );
1089    unsafe fn draw_indexed_indirect(
1090        &mut self,
1091        buffer: &<Self::A as Api>::Buffer,
1092        offset: wgt::BufferAddress,
1093        draw_count: u32,
1094    );
1095    unsafe fn draw_indirect_count(
1096        &mut self,
1097        buffer: &<Self::A as Api>::Buffer,
1098        offset: wgt::BufferAddress,
1099        count_buffer: &<Self::A as Api>::Buffer,
1100        count_offset: wgt::BufferAddress,
1101        max_count: u32,
1102    );
1103    unsafe fn draw_indexed_indirect_count(
1104        &mut self,
1105        buffer: &<Self::A as Api>::Buffer,
1106        offset: wgt::BufferAddress,
1107        count_buffer: &<Self::A as Api>::Buffer,
1108        count_offset: wgt::BufferAddress,
1109        max_count: u32,
1110    );
1111
1112    // compute passes
1113
1114    // Begins a compute pass, clears all active bindings.
1115    unsafe fn begin_compute_pass(&mut self, desc: &ComputePassDescriptor<Self::A>);
1116    unsafe fn end_compute_pass(&mut self);
1117
1118    unsafe fn set_compute_pipeline(&mut self, pipeline: &<Self::A as Api>::ComputePipeline);
1119
1120    unsafe fn dispatch(&mut self, count: [u32; 3]);
1121    unsafe fn dispatch_indirect(
1122        &mut self,
1123        buffer: &<Self::A as Api>::Buffer,
1124        offset: wgt::BufferAddress,
1125    );
1126
1127    /// To get the required sizes for the buffer allocations use `get_acceleration_structure_build_sizes` per descriptor
1128    /// All buffers must be synchronized externally
1129    /// All buffer regions, which are written to may only be passed once per function call,
1130    /// with the exception of updates in the same descriptor.
1131    /// Consequences of this limitation:
1132    /// - scratch buffers need to be unique
1133    /// - a tlas can't be build in the same call with a blas it contains
1134    unsafe fn build_acceleration_structures<'a, T>(
1135        &mut self,
1136        descriptor_count: u32,
1137        descriptors: T,
1138    ) where
1139        Self::A: 'a,
1140        T: IntoIterator<Item = BuildAccelerationStructureDescriptor<'a, Self::A>>;
1141
1142    unsafe fn place_acceleration_structure_barrier(
1143        &mut self,
1144        barrier: AccelerationStructureBarrier,
1145    );
1146}
1147
1148bitflags!(
1149    /// Pipeline layout creation flags.
1150    #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
1151    pub struct PipelineLayoutFlags: u32 {
1152        /// Include support for `first_vertex` / `first_instance` drawing.
1153        const FIRST_VERTEX_INSTANCE = 1 << 0;
1154        /// Include support for num work groups builtin.
1155        const NUM_WORK_GROUPS = 1 << 1;
1156    }
1157);
1158
1159bitflags!(
1160    /// Pipeline layout creation flags.
1161    #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
1162    pub struct BindGroupLayoutFlags: u32 {
1163        /// Allows for bind group binding arrays to be shorter than the array in the BGL.
1164        const PARTIALLY_BOUND = 1 << 0;
1165    }
1166);
1167
1168bitflags!(
1169    /// Texture format capability flags.
1170    #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
1171    pub struct TextureFormatCapabilities: u32 {
1172        /// Format can be sampled.
1173        const SAMPLED = 1 << 0;
1174        /// Format can be sampled with a linear sampler.
1175        const SAMPLED_LINEAR = 1 << 1;
1176        /// Format can be sampled with a min/max reduction sampler.
1177        const SAMPLED_MINMAX = 1 << 2;
1178
1179        /// Format can be used as storage with write-only access.
1180        const STORAGE = 1 << 3;
1181        /// Format can be used as storage with read and read/write access.
1182        const STORAGE_READ_WRITE = 1 << 4;
1183        /// Format can be used as storage with atomics.
1184        const STORAGE_ATOMIC = 1 << 5;
1185
1186        /// Format can be used as color and input attachment.
1187        const COLOR_ATTACHMENT = 1 << 6;
1188        /// Format can be used as color (with blending) and input attachment.
1189        const COLOR_ATTACHMENT_BLEND = 1 << 7;
1190        /// Format can be used as depth-stencil and input attachment.
1191        const DEPTH_STENCIL_ATTACHMENT = 1 << 8;
1192
1193        /// Format can be multisampled by x2.
1194        const MULTISAMPLE_X2   = 1 << 9;
1195        /// Format can be multisampled by x4.
1196        const MULTISAMPLE_X4   = 1 << 10;
1197        /// Format can be multisampled by x8.
1198        const MULTISAMPLE_X8   = 1 << 11;
1199        /// Format can be multisampled by x16.
1200        const MULTISAMPLE_X16  = 1 << 12;
1201
1202        /// Format can be used for render pass resolve targets.
1203        const MULTISAMPLE_RESOLVE = 1 << 13;
1204
1205        /// Format can be copied from.
1206        const COPY_SRC = 1 << 14;
1207        /// Format can be copied to.
1208        const COPY_DST = 1 << 15;
1209    }
1210);
1211
1212bitflags!(
1213    /// Texture format capability flags.
1214    #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
1215    pub struct FormatAspects: u8 {
1216        const COLOR = 1 << 0;
1217        const DEPTH = 1 << 1;
1218        const STENCIL = 1 << 2;
1219        const PLANE_0 = 1 << 3;
1220        const PLANE_1 = 1 << 4;
1221        const PLANE_2 = 1 << 5;
1222
1223        const DEPTH_STENCIL = Self::DEPTH.bits() | Self::STENCIL.bits();
1224    }
1225);
1226
1227impl FormatAspects {
1228    pub fn new(format: wgt::TextureFormat, aspect: wgt::TextureAspect) -> Self {
1229        let aspect_mask = match aspect {
1230            wgt::TextureAspect::All => Self::all(),
1231            wgt::TextureAspect::DepthOnly => Self::DEPTH,
1232            wgt::TextureAspect::StencilOnly => Self::STENCIL,
1233            wgt::TextureAspect::Plane0 => Self::PLANE_0,
1234            wgt::TextureAspect::Plane1 => Self::PLANE_1,
1235            wgt::TextureAspect::Plane2 => Self::PLANE_2,
1236        };
1237        Self::from(format) & aspect_mask
1238    }
1239
1240    /// Returns `true` if only one flag is set
1241    pub fn is_one(&self) -> bool {
1242        self.bits().count_ones() == 1
1243    }
1244
1245    pub fn map(&self) -> wgt::TextureAspect {
1246        match *self {
1247            Self::COLOR => wgt::TextureAspect::All,
1248            Self::DEPTH => wgt::TextureAspect::DepthOnly,
1249            Self::STENCIL => wgt::TextureAspect::StencilOnly,
1250            Self::PLANE_0 => wgt::TextureAspect::Plane0,
1251            Self::PLANE_1 => wgt::TextureAspect::Plane1,
1252            Self::PLANE_2 => wgt::TextureAspect::Plane2,
1253            _ => unreachable!(),
1254        }
1255    }
1256}
1257
1258impl From<wgt::TextureFormat> for FormatAspects {
1259    fn from(format: wgt::TextureFormat) -> Self {
1260        match format {
1261            wgt::TextureFormat::Stencil8 => Self::STENCIL,
1262            wgt::TextureFormat::Depth16Unorm
1263            | wgt::TextureFormat::Depth32Float
1264            | wgt::TextureFormat::Depth24Plus => Self::DEPTH,
1265            wgt::TextureFormat::Depth32FloatStencil8 | wgt::TextureFormat::Depth24PlusStencil8 => {
1266                Self::DEPTH_STENCIL
1267            }
1268            wgt::TextureFormat::NV12 => Self::PLANE_0 | Self::PLANE_1,
1269            _ => Self::COLOR,
1270        }
1271    }
1272}
1273
1274bitflags!(
1275    #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
1276    pub struct MemoryFlags: u32 {
1277        const TRANSIENT = 1 << 0;
1278        const PREFER_COHERENT = 1 << 1;
1279    }
1280);
1281
1282//TODO: it's not intuitive for the backends to consider `LOAD` being optional.
1283
1284bitflags!(
1285    #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
1286    pub struct AttachmentOps: u8 {
1287        const LOAD = 1 << 0;
1288        const STORE = 1 << 1;
1289    }
1290);
1291
1292bitflags::bitflags! {
1293    /// Similar to `wgt::BufferUsages` but for internal use.
1294    #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
1295    pub struct BufferUses: u16 {
1296        /// The argument to a read-only mapping.
1297        const MAP_READ = 1 << 0;
1298        /// The argument to a write-only mapping.
1299        const MAP_WRITE = 1 << 1;
1300        /// The source of a hardware copy.
1301        const COPY_SRC = 1 << 2;
1302        /// The destination of a hardware copy.
1303        const COPY_DST = 1 << 3;
1304        /// The index buffer used for drawing.
1305        const INDEX = 1 << 4;
1306        /// A vertex buffer used for drawing.
1307        const VERTEX = 1 << 5;
1308        /// A uniform buffer bound in a bind group.
1309        const UNIFORM = 1 << 6;
1310        /// A read-only storage buffer used in a bind group.
1311        const STORAGE_READ = 1 << 7;
1312        /// A read-write or write-only buffer used in a bind group.
1313        const STORAGE_READ_WRITE = 1 << 8;
1314        /// The indirect or count buffer in a indirect draw or dispatch.
1315        const INDIRECT = 1 << 9;
1316        /// A buffer used to store query results.
1317        const QUERY_RESOLVE = 1 << 10;
1318        const ACCELERATION_STRUCTURE_SCRATCH = 1 << 11;
1319        const BOTTOM_LEVEL_ACCELERATION_STRUCTURE_INPUT = 1 << 12;
1320        const TOP_LEVEL_ACCELERATION_STRUCTURE_INPUT = 1 << 13;
1321        /// The combination of states that a buffer may be in _at the same time_.
1322        const INCLUSIVE = Self::MAP_READ.bits() | Self::COPY_SRC.bits() |
1323            Self::INDEX.bits() | Self::VERTEX.bits() | Self::UNIFORM.bits() |
1324            Self::STORAGE_READ.bits() | Self::INDIRECT.bits() | Self::BOTTOM_LEVEL_ACCELERATION_STRUCTURE_INPUT.bits() | Self::TOP_LEVEL_ACCELERATION_STRUCTURE_INPUT.bits();
1325        /// The combination of states that a buffer must exclusively be in.
1326        const EXCLUSIVE = Self::MAP_WRITE.bits() | Self::COPY_DST.bits() | Self::STORAGE_READ_WRITE.bits() | Self::ACCELERATION_STRUCTURE_SCRATCH.bits();
1327        /// The combination of all usages that the are guaranteed to be be ordered by the hardware.
1328        /// If a usage is ordered, then if the buffer state doesn't change between draw calls, there
1329        /// are no barriers needed for synchronization.
1330        const ORDERED = Self::INCLUSIVE.bits() | Self::MAP_WRITE.bits();
1331    }
1332}
1333
1334bitflags::bitflags! {
1335    /// Similar to `wgt::TextureUsages` but for internal use.
1336    #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
1337    pub struct TextureUses: u16 {
1338        /// The texture is in unknown state.
1339        const UNINITIALIZED = 1 << 0;
1340        /// Ready to present image to the surface.
1341        const PRESENT = 1 << 1;
1342        /// The source of a hardware copy.
1343        const COPY_SRC = 1 << 2;
1344        /// The destination of a hardware copy.
1345        const COPY_DST = 1 << 3;
1346        /// Read-only sampled or fetched resource.
1347        const RESOURCE = 1 << 4;
1348        /// The color target of a renderpass.
1349        const COLOR_TARGET = 1 << 5;
1350        /// Read-only depth stencil usage.
1351        const DEPTH_STENCIL_READ = 1 << 6;
1352        /// Read-write depth stencil usage
1353        const DEPTH_STENCIL_WRITE = 1 << 7;
1354        /// Read-only storage buffer usage. Corresponds to a UAV in d3d, so is exclusive, despite being read only.
1355        const STORAGE_READ = 1 << 8;
1356        /// Read-write or write-only storage buffer usage.
1357        const STORAGE_READ_WRITE = 1 << 9;
1358        /// The combination of states that a texture may be in _at the same time_.
1359        const INCLUSIVE = Self::COPY_SRC.bits() | Self::RESOURCE.bits() | Self::DEPTH_STENCIL_READ.bits();
1360        /// The combination of states that a texture must exclusively be in.
1361        const EXCLUSIVE = Self::COPY_DST.bits() | Self::COLOR_TARGET.bits() | Self::DEPTH_STENCIL_WRITE.bits() | Self::STORAGE_READ.bits() | Self::STORAGE_READ_WRITE.bits() | Self::PRESENT.bits();
1362        /// The combination of all usages that the are guaranteed to be be ordered by the hardware.
1363        /// If a usage is ordered, then if the texture state doesn't change between draw calls, there
1364        /// are no barriers needed for synchronization.
1365        const ORDERED = Self::INCLUSIVE.bits() | Self::COLOR_TARGET.bits() | Self::DEPTH_STENCIL_WRITE.bits() | Self::STORAGE_READ.bits();
1366
1367        /// Flag used by the wgpu-core texture tracker to say a texture is in different states for every sub-resource
1368        const COMPLEX = 1 << 10;
1369        /// Flag used by the wgpu-core texture tracker to say that the tracker does not know the state of the sub-resource.
1370        /// This is different from UNINITIALIZED as that says the tracker does know, but the texture has not been initialized.
1371        const UNKNOWN = 1 << 11;
1372    }
1373}
1374
1375#[derive(Clone, Debug)]
1376pub struct InstanceDescriptor<'a> {
1377    pub name: &'a str,
1378    pub flags: wgt::InstanceFlags,
1379    pub dx12_shader_compiler: wgt::Dx12Compiler,
1380    pub gles_minor_version: wgt::Gles3MinorVersion,
1381}
1382
1383#[derive(Clone, Debug)]
1384pub struct Alignments {
1385    /// The alignment of the start of the buffer used as a GPU copy source.
1386    pub buffer_copy_offset: wgt::BufferSize,
1387    /// The alignment of the row pitch of the texture data stored in a buffer that is
1388    /// used in a GPU copy operation.
1389    pub buffer_copy_pitch: wgt::BufferSize,
1390}
1391
1392#[derive(Clone, Debug)]
1393pub struct Capabilities {
1394    pub limits: wgt::Limits,
1395    pub alignments: Alignments,
1396    pub downlevel: wgt::DownlevelCapabilities,
1397}
1398
1399#[derive(Debug)]
1400pub struct ExposedAdapter<A: Api> {
1401    pub adapter: A::Adapter,
1402    pub info: wgt::AdapterInfo,
1403    pub features: wgt::Features,
1404    pub capabilities: Capabilities,
1405}
1406
1407/// Describes information about what a `Surface`'s presentation capabilities are.
1408/// Fetch this with [Adapter::surface_capabilities].
1409#[derive(Debug, Clone)]
1410pub struct SurfaceCapabilities {
1411    /// List of supported texture formats.
1412    ///
1413    /// Must be at least one.
1414    pub formats: Vec<wgt::TextureFormat>,
1415
1416    /// Range for the number of queued frames.
1417    ///
1418    /// This adjusts either the swapchain frame count to value + 1 - or sets SetMaximumFrameLatency to the value given,
1419    /// or uses a wait-for-present in the acquire method to limit rendering such that it acts like it's a value + 1 swapchain frame set.
1420    ///
1421    /// - `maximum_frame_latency.start` must be at least 1.
1422    /// - `maximum_frame_latency.end` must be larger or equal to `maximum_frame_latency.start`.
1423    pub maximum_frame_latency: RangeInclusive<u32>,
1424
1425    /// Current extent of the surface, if known.
1426    pub current_extent: Option<wgt::Extent3d>,
1427
1428    /// Supported texture usage flags.
1429    ///
1430    /// Must have at least `TextureUses::COLOR_TARGET`
1431    pub usage: TextureUses,
1432
1433    /// List of supported V-sync modes.
1434    ///
1435    /// Must be at least one.
1436    pub present_modes: Vec<wgt::PresentMode>,
1437
1438    /// List of supported alpha composition modes.
1439    ///
1440    /// Must be at least one.
1441    pub composite_alpha_modes: Vec<wgt::CompositeAlphaMode>,
1442}
1443
1444#[derive(Debug)]
1445pub struct AcquiredSurfaceTexture<A: Api> {
1446    pub texture: A::SurfaceTexture,
1447    /// The presentation configuration no longer matches
1448    /// the surface properties exactly, but can still be used to present
1449    /// to the surface successfully.
1450    pub suboptimal: bool,
1451}
1452
1453#[derive(Debug)]
1454pub struct OpenDevice<A: Api> {
1455    pub device: A::Device,
1456    pub queue: A::Queue,
1457}
1458
1459#[derive(Clone, Debug)]
1460pub struct BufferMapping {
1461    pub ptr: NonNull<u8>,
1462    pub is_coherent: bool,
1463}
1464
1465#[derive(Clone, Debug)]
1466pub struct BufferDescriptor<'a> {
1467    pub label: Label<'a>,
1468    pub size: wgt::BufferAddress,
1469    pub usage: BufferUses,
1470    pub memory_flags: MemoryFlags,
1471}
1472
1473#[derive(Clone, Debug)]
1474pub struct TextureDescriptor<'a> {
1475    pub label: Label<'a>,
1476    pub size: wgt::Extent3d,
1477    pub mip_level_count: u32,
1478    pub sample_count: u32,
1479    pub dimension: wgt::TextureDimension,
1480    pub format: wgt::TextureFormat,
1481    pub usage: TextureUses,
1482    pub memory_flags: MemoryFlags,
1483    /// Allows views of this texture to have a different format
1484    /// than the texture does.
1485    pub view_formats: Vec<wgt::TextureFormat>,
1486}
1487
1488impl TextureDescriptor<'_> {
1489    pub fn copy_extent(&self) -> CopyExtent {
1490        CopyExtent::map_extent_to_copy_size(&self.size, self.dimension)
1491    }
1492
1493    pub fn is_cube_compatible(&self) -> bool {
1494        self.dimension == wgt::TextureDimension::D2
1495            && self.size.depth_or_array_layers % 6 == 0
1496            && self.sample_count == 1
1497            && self.size.width == self.size.height
1498    }
1499
1500    pub fn array_layer_count(&self) -> u32 {
1501        match self.dimension {
1502            wgt::TextureDimension::D1 | wgt::TextureDimension::D3 => 1,
1503            wgt::TextureDimension::D2 => self.size.depth_or_array_layers,
1504        }
1505    }
1506}
1507
1508/// TextureView descriptor.
1509///
1510/// Valid usage:
1511///. - `format` has to be the same as `TextureDescriptor::format`
1512///. - `dimension` has to be compatible with `TextureDescriptor::dimension`
1513///. - `usage` has to be a subset of `TextureDescriptor::usage`
1514///. - `range` has to be a subset of parent texture
1515#[derive(Clone, Debug)]
1516pub struct TextureViewDescriptor<'a> {
1517    pub label: Label<'a>,
1518    pub format: wgt::TextureFormat,
1519    pub dimension: wgt::TextureViewDimension,
1520    pub usage: TextureUses,
1521    pub range: wgt::ImageSubresourceRange,
1522}
1523
1524#[derive(Clone, Debug)]
1525pub struct SamplerDescriptor<'a> {
1526    pub label: Label<'a>,
1527    pub address_modes: [wgt::AddressMode; 3],
1528    pub mag_filter: wgt::FilterMode,
1529    pub min_filter: wgt::FilterMode,
1530    pub mipmap_filter: wgt::FilterMode,
1531    pub lod_clamp: Range<f32>,
1532    pub compare: Option<wgt::CompareFunction>,
1533    // Must in the range [1, 16].
1534    //
1535    // Anisotropic filtering must be supported if this is not 1.
1536    pub anisotropy_clamp: u16,
1537    pub border_color: Option<wgt::SamplerBorderColor>,
1538}
1539
1540/// BindGroupLayout descriptor.
1541///
1542/// Valid usage:
1543/// - `entries` are sorted by ascending `wgt::BindGroupLayoutEntry::binding`
1544#[derive(Clone, Debug)]
1545pub struct BindGroupLayoutDescriptor<'a> {
1546    pub label: Label<'a>,
1547    pub flags: BindGroupLayoutFlags,
1548    pub entries: &'a [wgt::BindGroupLayoutEntry],
1549}
1550
1551#[derive(Clone, Debug)]
1552pub struct PipelineLayoutDescriptor<'a, A: Api> {
1553    pub label: Label<'a>,
1554    pub flags: PipelineLayoutFlags,
1555    pub bind_group_layouts: &'a [&'a A::BindGroupLayout],
1556    pub push_constant_ranges: &'a [wgt::PushConstantRange],
1557}
1558
1559#[derive(Debug)]
1560pub struct BufferBinding<'a, A: Api> {
1561    /// The buffer being bound.
1562    pub buffer: &'a A::Buffer,
1563
1564    /// The offset at which the bound region starts.
1565    ///
1566    /// This must be less than the size of the buffer. Some back ends
1567    /// cannot tolerate zero-length regions; for example, see
1568    /// [VUID-VkDescriptorBufferInfo-offset-00340][340] and
1569    /// [VUID-VkDescriptorBufferInfo-range-00341][341], or the
1570    /// documentation for GLES's [glBindBufferRange][bbr].
1571    ///
1572    /// [340]: https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-VkDescriptorBufferInfo-offset-00340
1573    /// [341]: https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-VkDescriptorBufferInfo-range-00341
1574    /// [bbr]: https://registry.khronos.org/OpenGL-Refpages/es3.0/html/glBindBufferRange.xhtml
1575    pub offset: wgt::BufferAddress,
1576
1577    /// The size of the region bound, in bytes.
1578    ///
1579    /// If `None`, the region extends from `offset` to the end of the
1580    /// buffer. Given the restrictions on `offset`, this means that
1581    /// the size is always greater than zero.
1582    pub size: Option<wgt::BufferSize>,
1583}
1584
1585// Rust gets confused about the impl requirements for `A`
1586impl<A: Api> Clone for BufferBinding<'_, A> {
1587    fn clone(&self) -> Self {
1588        Self {
1589            buffer: self.buffer,
1590            offset: self.offset,
1591            size: self.size,
1592        }
1593    }
1594}
1595
1596#[derive(Debug)]
1597pub struct TextureBinding<'a, A: Api> {
1598    pub view: &'a A::TextureView,
1599    pub usage: TextureUses,
1600}
1601
1602// Rust gets confused about the impl requirements for `A`
1603impl<A: Api> Clone for TextureBinding<'_, A> {
1604    fn clone(&self) -> Self {
1605        Self {
1606            view: self.view,
1607            usage: self.usage,
1608        }
1609    }
1610}
1611
1612#[derive(Clone, Debug)]
1613pub struct BindGroupEntry {
1614    pub binding: u32,
1615    pub resource_index: u32,
1616    pub count: u32,
1617}
1618
1619/// BindGroup descriptor.
1620///
1621/// Valid usage:
1622///. - `entries` has to be sorted by ascending `BindGroupEntry::binding`
1623///. - `entries` has to have the same set of `BindGroupEntry::binding` as `layout`
1624///. - each entry has to be compatible with the `layout`
1625///. - each entry's `BindGroupEntry::resource_index` is within range
1626///    of the corresponding resource array, selected by the relevant
1627///    `BindGroupLayoutEntry`.
1628#[derive(Clone, Debug)]
1629pub struct BindGroupDescriptor<'a, A: Api> {
1630    pub label: Label<'a>,
1631    pub layout: &'a A::BindGroupLayout,
1632    pub buffers: &'a [BufferBinding<'a, A>],
1633    pub samplers: &'a [&'a A::Sampler],
1634    pub textures: &'a [TextureBinding<'a, A>],
1635    pub entries: &'a [BindGroupEntry],
1636    pub acceleration_structures: &'a [&'a A::AccelerationStructure],
1637}
1638
1639#[derive(Clone, Debug)]
1640pub struct CommandEncoderDescriptor<'a, A: Api> {
1641    pub label: Label<'a>,
1642    pub queue: &'a A::Queue,
1643}
1644
1645/// Naga shader module.
1646pub struct NagaShader {
1647    /// Shader module IR.
1648    pub module: Cow<'static, naga::Module>,
1649    /// Analysis information of the module.
1650    pub info: naga::valid::ModuleInfo,
1651    /// Source codes for debug
1652    pub debug_source: Option<DebugSource>,
1653}
1654
1655// Custom implementation avoids the need to generate Debug impl code
1656// for the whole Naga module and info.
1657impl fmt::Debug for NagaShader {
1658    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
1659        write!(formatter, "Naga shader")
1660    }
1661}
1662
1663/// Shader input.
1664#[allow(clippy::large_enum_variant)]
1665pub enum ShaderInput<'a> {
1666    Naga(NagaShader),
1667    SpirV(&'a [u32]),
1668}
1669
1670pub struct ShaderModuleDescriptor<'a> {
1671    pub label: Label<'a>,
1672    pub runtime_checks: bool,
1673}
1674
1675#[derive(Debug, Clone)]
1676pub struct DebugSource {
1677    pub file_name: Cow<'static, str>,
1678    pub source_code: Cow<'static, str>,
1679}
1680
1681/// Describes a programmable pipeline stage.
1682#[derive(Debug)]
1683pub struct ProgrammableStage<'a, A: Api> {
1684    /// The compiled shader module for this stage.
1685    pub module: &'a A::ShaderModule,
1686    /// The name of the entry point in the compiled shader. There must be a function with this name
1687    ///  in the shader.
1688    pub entry_point: &'a str,
1689    /// Pipeline constants
1690    pub constants: &'a naga::back::PipelineConstants,
1691    /// Whether workgroup scoped memory will be initialized with zero values for this stage.
1692    ///
1693    /// This is required by the WebGPU spec, but may have overhead which can be avoided
1694    /// for cross-platform applications
1695    pub zero_initialize_workgroup_memory: bool,
1696}
1697
1698// Rust gets confused about the impl requirements for `A`
1699impl<A: Api> Clone for ProgrammableStage<'_, A> {
1700    fn clone(&self) -> Self {
1701        Self {
1702            module: self.module,
1703            entry_point: self.entry_point,
1704            constants: self.constants,
1705            zero_initialize_workgroup_memory: self.zero_initialize_workgroup_memory,
1706        }
1707    }
1708}
1709
1710/// Describes a compute pipeline.
1711#[derive(Clone, Debug)]
1712pub struct ComputePipelineDescriptor<'a, A: Api> {
1713    pub label: Label<'a>,
1714    /// The layout of bind groups for this pipeline.
1715    pub layout: &'a A::PipelineLayout,
1716    /// The compiled compute stage and its entry point.
1717    pub stage: ProgrammableStage<'a, A>,
1718}
1719
1720/// Describes how the vertex buffer is interpreted.
1721#[derive(Clone, Debug)]
1722pub struct VertexBufferLayout<'a> {
1723    /// The stride, in bytes, between elements of this buffer.
1724    pub array_stride: wgt::BufferAddress,
1725    /// How often this vertex buffer is "stepped" forward.
1726    pub step_mode: wgt::VertexStepMode,
1727    /// The list of attributes which comprise a single vertex.
1728    pub attributes: &'a [wgt::VertexAttribute],
1729}
1730
1731/// Describes a render (graphics) pipeline.
1732#[derive(Clone, Debug)]
1733pub struct RenderPipelineDescriptor<'a, A: Api> {
1734    pub label: Label<'a>,
1735    /// The layout of bind groups for this pipeline.
1736    pub layout: &'a A::PipelineLayout,
1737    /// The format of any vertex buffers used with this pipeline.
1738    pub vertex_buffers: &'a [VertexBufferLayout<'a>],
1739    /// The vertex stage for this pipeline.
1740    pub vertex_stage: ProgrammableStage<'a, A>,
1741    /// The properties of the pipeline at the primitive assembly and rasterization level.
1742    pub primitive: wgt::PrimitiveState,
1743    /// The effect of draw calls on the depth and stencil aspects of the output target, if any.
1744    pub depth_stencil: Option<wgt::DepthStencilState>,
1745    /// The multi-sampling properties of the pipeline.
1746    pub multisample: wgt::MultisampleState,
1747    /// The fragment stage for this pipeline.
1748    pub fragment_stage: Option<ProgrammableStage<'a, A>>,
1749    /// The effect of draw calls on the color aspect of the output target.
1750    pub color_targets: &'a [Option<wgt::ColorTargetState>],
1751    /// If the pipeline will be used with a multiview render pass, this indicates how many array
1752    /// layers the attachments will have.
1753    pub multiview: Option<NonZeroU32>,
1754}
1755
1756#[derive(Debug, Clone)]
1757pub struct SurfaceConfiguration {
1758    /// Maximum number of queued frames. Must be in
1759    /// `SurfaceCapabilities::maximum_frame_latency` range.
1760    pub maximum_frame_latency: u32,
1761    /// Vertical synchronization mode.
1762    pub present_mode: wgt::PresentMode,
1763    /// Alpha composition mode.
1764    pub composite_alpha_mode: wgt::CompositeAlphaMode,
1765    /// Format of the surface textures.
1766    pub format: wgt::TextureFormat,
1767    /// Requested texture extent. Must be in
1768    /// `SurfaceCapabilities::extents` range.
1769    pub extent: wgt::Extent3d,
1770    /// Allowed usage of surface textures,
1771    pub usage: TextureUses,
1772    /// Allows views of swapchain texture to have a different format
1773    /// than the texture does.
1774    pub view_formats: Vec<wgt::TextureFormat>,
1775}
1776
1777#[derive(Debug, Clone)]
1778pub struct Rect<T> {
1779    pub x: T,
1780    pub y: T,
1781    pub w: T,
1782    pub h: T,
1783}
1784
1785#[derive(Debug, Clone)]
1786pub struct BufferBarrier<'a, A: Api> {
1787    pub buffer: &'a A::Buffer,
1788    pub usage: Range<BufferUses>,
1789}
1790
1791#[derive(Debug, Clone)]
1792pub struct TextureBarrier<'a, A: Api> {
1793    pub texture: &'a A::Texture,
1794    pub range: wgt::ImageSubresourceRange,
1795    pub usage: Range<TextureUses>,
1796}
1797
1798#[derive(Clone, Copy, Debug)]
1799pub struct BufferCopy {
1800    pub src_offset: wgt::BufferAddress,
1801    pub dst_offset: wgt::BufferAddress,
1802    pub size: wgt::BufferSize,
1803}
1804
1805#[derive(Clone, Debug)]
1806pub struct TextureCopyBase {
1807    pub mip_level: u32,
1808    pub array_layer: u32,
1809    /// Origin within a texture.
1810    /// Note: for 1D and 2D textures, Z must be 0.
1811    pub origin: wgt::Origin3d,
1812    pub aspect: FormatAspects,
1813}
1814
1815#[derive(Clone, Copy, Debug)]
1816pub struct CopyExtent {
1817    pub width: u32,
1818    pub height: u32,
1819    pub depth: u32,
1820}
1821
1822#[derive(Clone, Debug)]
1823pub struct TextureCopy {
1824    pub src_base: TextureCopyBase,
1825    pub dst_base: TextureCopyBase,
1826    pub size: CopyExtent,
1827}
1828
1829#[derive(Clone, Debug)]
1830pub struct BufferTextureCopy {
1831    pub buffer_layout: wgt::ImageDataLayout,
1832    pub texture_base: TextureCopyBase,
1833    pub size: CopyExtent,
1834}
1835
1836#[derive(Debug)]
1837pub struct Attachment<'a, A: Api> {
1838    pub view: &'a A::TextureView,
1839    /// Contains either a single mutating usage as a target,
1840    /// or a valid combination of read-only usages.
1841    pub usage: TextureUses,
1842}
1843
1844// Rust gets confused about the impl requirements for `A`
1845impl<A: Api> Clone for Attachment<'_, A> {
1846    fn clone(&self) -> Self {
1847        Self {
1848            view: self.view,
1849            usage: self.usage,
1850        }
1851    }
1852}
1853
1854#[derive(Debug)]
1855pub struct ColorAttachment<'a, A: Api> {
1856    pub target: Attachment<'a, A>,
1857    pub resolve_target: Option<Attachment<'a, A>>,
1858    pub ops: AttachmentOps,
1859    pub clear_value: wgt::Color,
1860}
1861
1862// Rust gets confused about the impl requirements for `A`
1863impl<A: Api> Clone for ColorAttachment<'_, A> {
1864    fn clone(&self) -> Self {
1865        Self {
1866            target: self.target.clone(),
1867            resolve_target: self.resolve_target.clone(),
1868            ops: self.ops,
1869            clear_value: self.clear_value,
1870        }
1871    }
1872}
1873
1874#[derive(Clone, Debug)]
1875pub struct DepthStencilAttachment<'a, A: Api> {
1876    pub target: Attachment<'a, A>,
1877    pub depth_ops: AttachmentOps,
1878    pub stencil_ops: AttachmentOps,
1879    pub clear_value: (f32, u32),
1880}
1881
1882#[derive(Debug)]
1883pub struct RenderPassTimestampWrites<'a, A: Api> {
1884    pub query_set: &'a A::QuerySet,
1885    pub beginning_of_pass_write_index: Option<u32>,
1886    pub end_of_pass_write_index: Option<u32>,
1887}
1888
1889// Rust gets confused about the impl requirements for `A`
1890impl<A: Api> Clone for RenderPassTimestampWrites<'_, A> {
1891    fn clone(&self) -> Self {
1892        Self {
1893            query_set: self.query_set,
1894            beginning_of_pass_write_index: self.beginning_of_pass_write_index,
1895            end_of_pass_write_index: self.end_of_pass_write_index,
1896        }
1897    }
1898}
1899
1900#[derive(Clone, Debug)]
1901pub struct RenderPassDescriptor<'a, A: Api> {
1902    pub label: Label<'a>,
1903    pub extent: wgt::Extent3d,
1904    pub sample_count: u32,
1905    pub color_attachments: &'a [Option<ColorAttachment<'a, A>>],
1906    pub depth_stencil_attachment: Option<DepthStencilAttachment<'a, A>>,
1907    pub multiview: Option<NonZeroU32>,
1908    pub timestamp_writes: Option<RenderPassTimestampWrites<'a, A>>,
1909    pub occlusion_query_set: Option<&'a A::QuerySet>,
1910}
1911
1912#[derive(Debug)]
1913pub struct ComputePassTimestampWrites<'a, A: Api> {
1914    pub query_set: &'a A::QuerySet,
1915    pub beginning_of_pass_write_index: Option<u32>,
1916    pub end_of_pass_write_index: Option<u32>,
1917}
1918
1919// Rust gets confused about the impl requirements for `A`
1920impl<A: Api> Clone for ComputePassTimestampWrites<'_, A> {
1921    fn clone(&self) -> Self {
1922        Self {
1923            query_set: self.query_set,
1924            beginning_of_pass_write_index: self.beginning_of_pass_write_index,
1925            end_of_pass_write_index: self.end_of_pass_write_index,
1926        }
1927    }
1928}
1929
1930#[derive(Clone, Debug)]
1931pub struct ComputePassDescriptor<'a, A: Api> {
1932    pub label: Label<'a>,
1933    pub timestamp_writes: Option<ComputePassTimestampWrites<'a, A>>,
1934}
1935
1936/// Stores the text of any validation errors that have occurred since
1937/// the last call to `get_and_reset`.
1938///
1939/// Each value is a validation error and a message associated with it,
1940/// or `None` if the error has no message from the api.
1941///
1942/// This is used for internal wgpu testing only and _must not_ be used
1943/// as a way to check for errors.
1944///
1945/// This works as a static because `cargo nextest` runs all of our
1946/// tests in separate processes, so each test gets its own canary.
1947///
1948/// This prevents the issue of one validation error terminating the
1949/// entire process.
1950pub static VALIDATION_CANARY: ValidationCanary = ValidationCanary {
1951    inner: Mutex::new(Vec::new()),
1952};
1953
1954/// Flag for internal testing.
1955pub struct ValidationCanary {
1956    inner: Mutex<Vec<String>>,
1957}
1958
1959impl ValidationCanary {
1960    #[allow(dead_code)] // in some configurations this function is dead
1961    fn add(&self, msg: String) {
1962        self.inner.lock().push(msg);
1963    }
1964
1965    /// Returns any API validation errors that have occurred in this process
1966    /// since the last call to this function.
1967    pub fn get_and_reset(&self) -> Vec<String> {
1968        self.inner.lock().drain(..).collect()
1969    }
1970}
1971
1972#[test]
1973fn test_default_limits() {
1974    let limits = wgt::Limits::default();
1975    assert!(limits.max_bind_groups <= MAX_BIND_GROUPS as u32);
1976}
1977
1978#[derive(Clone, Debug)]
1979pub struct AccelerationStructureDescriptor<'a> {
1980    pub label: Label<'a>,
1981    pub size: wgt::BufferAddress,
1982    pub format: AccelerationStructureFormat,
1983}
1984
1985#[derive(Debug, Clone, Copy, Eq, PartialEq)]
1986pub enum AccelerationStructureFormat {
1987    TopLevel,
1988    BottomLevel,
1989}
1990
1991#[derive(Debug, Clone, Copy, Eq, PartialEq)]
1992pub enum AccelerationStructureBuildMode {
1993    Build,
1994    Update,
1995}
1996
1997/// Information of the required size for a corresponding entries struct (+ flags)
1998#[derive(Copy, Clone, Debug, Default, Eq, PartialEq)]
1999pub struct AccelerationStructureBuildSizes {
2000    pub acceleration_structure_size: wgt::BufferAddress,
2001    pub update_scratch_size: wgt::BufferAddress,
2002    pub build_scratch_size: wgt::BufferAddress,
2003}
2004
2005/// Updates use source_acceleration_structure if present, else the update will be performed in place.
2006/// For updates, only the data is allowed to change (not the meta data or sizes).
2007#[derive(Clone, Debug)]
2008pub struct BuildAccelerationStructureDescriptor<'a, A: Api> {
2009    pub entries: &'a AccelerationStructureEntries<'a, A>,
2010    pub mode: AccelerationStructureBuildMode,
2011    pub flags: AccelerationStructureBuildFlags,
2012    pub source_acceleration_structure: Option<&'a A::AccelerationStructure>,
2013    pub destination_acceleration_structure: &'a A::AccelerationStructure,
2014    pub scratch_buffer: &'a A::Buffer,
2015    pub scratch_buffer_offset: wgt::BufferAddress,
2016}
2017
2018/// - All buffers, buffer addresses and offsets will be ignored.
2019/// - The build mode will be ignored.
2020/// - Reducing the amount of Instances, Triangle groups or AABB groups (or the number of Triangles/AABBs in corresponding groups),
2021/// may result in reduced size requirements.
2022/// - Any other change may result in a bigger or smaller size requirement.
2023#[derive(Clone, Debug)]
2024pub struct GetAccelerationStructureBuildSizesDescriptor<'a, A: Api> {
2025    pub entries: &'a AccelerationStructureEntries<'a, A>,
2026    pub flags: AccelerationStructureBuildFlags,
2027}
2028
2029/// Entries for a single descriptor
2030/// * `Instances` - Multiple instances for a top level acceleration structure
2031/// * `Triangles` - Multiple triangle meshes for a bottom level acceleration structure
2032/// * `AABBs` - List of list of axis aligned bounding boxes for a bottom level acceleration structure
2033#[derive(Debug)]
2034pub enum AccelerationStructureEntries<'a, A: Api> {
2035    Instances(AccelerationStructureInstances<'a, A>),
2036    Triangles(Vec<AccelerationStructureTriangles<'a, A>>),
2037    AABBs(Vec<AccelerationStructureAABBs<'a, A>>),
2038}
2039
2040/// * `first_vertex` - offset in the vertex buffer (as number of vertices)
2041/// * `indices` - optional index buffer with attributes
2042/// * `transform` - optional transform
2043#[derive(Clone, Debug)]
2044pub struct AccelerationStructureTriangles<'a, A: Api> {
2045    pub vertex_buffer: Option<&'a A::Buffer>,
2046    pub vertex_format: wgt::VertexFormat,
2047    pub first_vertex: u32,
2048    pub vertex_count: u32,
2049    pub vertex_stride: wgt::BufferAddress,
2050    pub indices: Option<AccelerationStructureTriangleIndices<'a, A>>,
2051    pub transform: Option<AccelerationStructureTriangleTransform<'a, A>>,
2052    pub flags: AccelerationStructureGeometryFlags,
2053}
2054
2055/// * `offset` - offset in bytes
2056#[derive(Clone, Debug)]
2057pub struct AccelerationStructureAABBs<'a, A: Api> {
2058    pub buffer: Option<&'a A::Buffer>,
2059    pub offset: u32,
2060    pub count: u32,
2061    pub stride: wgt::BufferAddress,
2062    pub flags: AccelerationStructureGeometryFlags,
2063}
2064
2065/// * `offset` - offset in bytes
2066#[derive(Clone, Debug)]
2067pub struct AccelerationStructureInstances<'a, A: Api> {
2068    pub buffer: Option<&'a A::Buffer>,
2069    pub offset: u32,
2070    pub count: u32,
2071}
2072
2073/// * `offset` - offset in bytes
2074#[derive(Clone, Debug)]
2075pub struct AccelerationStructureTriangleIndices<'a, A: Api> {
2076    pub format: wgt::IndexFormat,
2077    pub buffer: Option<&'a A::Buffer>,
2078    pub offset: u32,
2079    pub count: u32,
2080}
2081
2082/// * `offset` - offset in bytes
2083#[derive(Clone, Debug)]
2084pub struct AccelerationStructureTriangleTransform<'a, A: Api> {
2085    pub buffer: &'a A::Buffer,
2086    pub offset: u32,
2087}
2088
2089pub use wgt::AccelerationStructureFlags as AccelerationStructureBuildFlags;
2090pub use wgt::AccelerationStructureGeometryFlags;
2091
2092bitflags::bitflags! {
2093    #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
2094    pub struct AccelerationStructureUses: u8 {
2095        // For blas used as input for tlas
2096        const BUILD_INPUT = 1 << 0;
2097        // Target for acceleration structure build
2098        const BUILD_OUTPUT = 1 << 1;
2099        // Tlas used in a shader
2100        const SHADER_INPUT = 1 << 2;
2101    }
2102}
2103
2104#[derive(Debug, Clone)]
2105pub struct AccelerationStructureBarrier {
2106    pub usage: Range<AccelerationStructureUses>,
2107}