Bug 1797755 - Part 5: Use a single initial mark stack size regardless of whether...
[gecko.git] / third_party / rust / wgpu-types / src / lib.rs
blob8718d797942abccd651d898d9a476818fe0fc012
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  */
5 #![allow(
6     // We don't use syntax sugar where it's not necessary.
7     clippy::match_like_matches_macro,
8 )]
9 #![warn(missing_docs)]
11 #[cfg(feature = "serde")]
12 use serde::{Deserialize, Serialize};
13 use std::{num::NonZeroU32, ops::Range};
15 /// Integral type used for buffer offsets.
16 pub type BufferAddress = u64;
17 /// Integral type used for buffer slice sizes.
18 pub type BufferSize = std::num::NonZeroU64;
19 /// Integral type used for binding locations in shaders.
20 pub type ShaderLocation = u32;
21 /// Integral type used for dynamic bind group offsets.
22 pub type DynamicOffset = u32;
24 /// Buffer-Texture copies must have [`bytes_per_row`] aligned to this number.
25 ///
26 /// This doesn't apply to [`Queue::write_texture`][Qwt].
27 ///
28 /// [`bytes_per_row`]: ImageDataLayout::bytes_per_row
29 /// [Qwt]: ../wgpu/struct.Queue.html#method.write_texture
30 pub const COPY_BYTES_PER_ROW_ALIGNMENT: u32 = 256;
31 /// An offset into the query resolve buffer has to be aligned to this.
32 pub const QUERY_RESOLVE_BUFFER_ALIGNMENT: BufferAddress = 256;
33 /// Buffer to buffer copy as well as buffer clear offsets and sizes must be aligned to this number.
34 pub const COPY_BUFFER_ALIGNMENT: BufferAddress = 4;
35 /// Size to align mappings.
36 pub const MAP_ALIGNMENT: BufferAddress = 8;
37 /// Vertex buffer strides have to be aligned to this number.
38 pub const VERTEX_STRIDE_ALIGNMENT: BufferAddress = 4;
39 /// Alignment all push constants need
40 pub const PUSH_CONSTANT_ALIGNMENT: u32 = 4;
41 /// Maximum queries in a query set
42 pub const QUERY_SET_MAX_QUERIES: u32 = 8192;
43 /// Size of a single piece of query data.
44 pub const QUERY_SIZE: u32 = 8;
46 /// Backends supported by wgpu.
47 #[repr(u8)]
48 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
49 #[cfg_attr(feature = "trace", derive(Serialize))]
50 #[cfg_attr(feature = "replay", derive(Deserialize))]
51 pub enum Backend {
52     /// Dummy backend, used for testing.
53     Empty = 0,
54     /// Vulkan API
55     Vulkan = 1,
56     /// Metal API (Apple platforms)
57     Metal = 2,
58     /// Direct3D-12 (Windows)
59     Dx12 = 3,
60     /// Direct3D-11 (Windows)
61     Dx11 = 4,
62     /// OpenGL ES-3 (Linux, Android)
63     Gl = 5,
64     /// WebGPU in the browser
65     BrowserWebGpu = 6,
68 /// Power Preference when choosing a physical adapter.
69 ///
70 /// Corresponds to [WebGPU `GPUPowerPreference`](
71 /// https://gpuweb.github.io/gpuweb/#enumdef-gpupowerpreference).
72 #[repr(C)]
73 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
74 #[cfg_attr(feature = "trace", derive(Serialize))]
75 #[cfg_attr(feature = "replay", derive(Deserialize))]
76 #[cfg_attr(feature = "serde", serde(rename_all = "kebab-case"))]
77 pub enum PowerPreference {
78     /// Adapter that uses the least possible power. This is often an integrated GPU.
79     LowPower = 0,
80     /// Adapter that has the highest performance. This is often a discrete GPU.
81     HighPerformance = 1,
84 impl Default for PowerPreference {
85     fn default() -> Self {
86         Self::LowPower
87     }
90 bitflags::bitflags! {
91     /// Represents the backends that wgpu will use.
92     #[repr(transparent)]
93     pub struct Backends: u32 {
94         /// Supported on Windows, Linux/Android, and macOS/iOS via Vulkan Portability (with the Vulkan feature enabled)
95         const VULKAN = 1 << Backend::Vulkan as u32;
96         /// Currently unsupported
97         const GL = 1 << Backend::Gl as u32;
98         /// Supported on macOS/iOS
99         const METAL = 1 << Backend::Metal as u32;
100         /// Supported on Windows 10
101         const DX12 = 1 << Backend::Dx12 as u32;
102         /// Supported on Windows 7+
103         const DX11 = 1 << Backend::Dx11 as u32;
104         /// Supported when targeting the web through webassembly
105         const BROWSER_WEBGPU = 1 << Backend::BrowserWebGpu as u32;
106         /// All the apis that wgpu offers first tier of support for.
107         ///
108         /// Vulkan + Metal + DX12 + Browser WebGPU
109         const PRIMARY = Self::VULKAN.bits
110             | Self::METAL.bits
111             | Self::DX12.bits
112             | Self::BROWSER_WEBGPU.bits;
113         /// All the apis that wgpu offers second tier of support for. These may
114         /// be unsupported/still experimental.
115         ///
116         /// OpenGL + DX11
117         const SECONDARY = Self::GL.bits | Self::DX11.bits;
118     }
121 #[cfg(feature = "bitflags_serde_shim")]
122 bitflags_serde_shim::impl_serde_for_bitflags!(Backends);
124 impl From<Backend> for Backends {
125     fn from(backend: Backend) -> Self {
126         Self::from_bits(1 << backend as u32).unwrap()
127     }
130 /// Options for requesting adapter.
132 /// Corresponds to [WebGPU `GPURequestAdapterOptions`](
133 /// https://gpuweb.github.io/gpuweb/#dictdef-gpurequestadapteroptions).
134 #[repr(C)]
135 #[derive(Clone, Debug, PartialEq, Eq, Hash)]
136 #[cfg_attr(feature = "trace", derive(Serialize))]
137 #[cfg_attr(feature = "replay", derive(Deserialize))]
138 pub struct RequestAdapterOptions<S> {
139     /// Power preference for the adapter.
140     pub power_preference: PowerPreference,
141     /// Indicates that only a fallback adapter can be returned. This is generally a "software"
142     /// implementation on the system.
143     pub force_fallback_adapter: bool,
144     /// Surface that is required to be presentable with the requested adapter. This does not
145     /// create the surface, only guarantees that the adapter can present to said surface.
146     pub compatible_surface: Option<S>,
149 impl<S> Default for RequestAdapterOptions<S> {
150     fn default() -> Self {
151         Self {
152             power_preference: PowerPreference::default(),
153             force_fallback_adapter: false,
154             compatible_surface: None,
155         }
156     }
159 //TODO: make robust resource access configurable
161 bitflags::bitflags! {
162     /// Features that are not guaranteed to be supported.
163     ///
164     /// These are either part of the webgpu standard, or are extension features supported by
165     /// wgpu when targeting native.
166     ///
167     /// If you want to use a feature, you need to first verify that the adapter supports
168     /// the feature. If the adapter does not support the feature, requesting a device with it enabled
169     /// will panic.
170     ///
171     /// Corresponds to [WebGPU `GPUFeatureName`](
172     /// https://gpuweb.github.io/gpuweb/#enumdef-gpufeaturename).
173     #[repr(transparent)]
174     #[derive(Default)]
175     pub struct Features: u64 {
176         //
177         // ---- Start numbering at 1 << 0 ----
178         //
179         // WebGPU features:
180         //
182         /// By default, polygon depth is clipped to 0-1 range before/during rasterization.
183         /// Anything outside of that range is rejected, and respective fragments are not touched.
184         ///
185         /// With this extension, we can disabling clipping. That allows
186         /// shadow map occluders to be rendered into a tighter depth range.
187         ///
188         /// Supported platforms:
189         /// - desktops
190         /// - some mobile chips
191         ///
192         /// This is a web and native feature.
193         const DEPTH_CLIP_CONTROL = 1 << 0;
194         /// Allows for explicit creation of textures of format [`TextureFormat::Depth24UnormStencil8`]
195         ///
196         /// Supported platforms:
197         /// - Vulkan (some)
198         /// - DX12
199         /// - Metal (Macs with amd GPUs)
200         ///
201         /// This is a web and native feature.
202         const DEPTH24UNORM_STENCIL8 = 1 << 1;
203         /// Allows for explicit creation of textures of format [`TextureFormat::Depth32FloatStencil8`]
204         ///
205         /// Supported platforms:
206         /// - Vulkan (mostly)
207         /// - DX12
208         /// - Metal
209         ///
210         /// This is a web and native feature.
211         const DEPTH32FLOAT_STENCIL8 = 1 << 2;
212         /// Enables BCn family of compressed textures. All BCn textures use 4x4 pixel blocks
213         /// with 8 or 16 bytes per block.
214         ///
215         /// Compressed textures sacrifice some quality in exchange for significantly reduced
216         /// bandwidth usage.
217         ///
218         /// Support for this feature guarantees availability of [`TextureUsages::COPY_SRC | TextureUsages::COPY_DST | TextureUsages::TEXTURE_BINDING`] for BCn formats.
219         /// [`Features::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES`] may enable additional usages.
220         ///
221         /// Supported Platforms:
222         /// - desktops
223         ///
224         /// This is a web and native feature.
225         const TEXTURE_COMPRESSION_BC = 1 << 3;
226         /// Enables ETC family of compressed textures. All ETC textures use 4x4 pixel blocks.
227         /// ETC2 RGB and RGBA1 are 8 bytes per block. RTC2 RGBA8 and EAC are 16 bytes per block.
228         ///
229         /// Compressed textures sacrifice some quality in exchange for significantly reduced
230         /// bandwidth usage.
231         ///
232         /// Support for this feature guarantees availability of [`TextureUsages::COPY_SRC | TextureUsages::COPY_DST | TextureUsages::TEXTURE_BINDING`] for ETC2 formats.
233         /// [`Features::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES`] may enable additional usages.
234         ///
235         /// Supported Platforms:
236         /// - Intel/Vulkan
237         /// - Mobile (some)
238         ///
239         /// This is a web and native feature.
240         const TEXTURE_COMPRESSION_ETC2 = 1 << 4;
241         /// Enables ASTC family of compressed textures. ASTC textures use pixel blocks varying from 4x4 to 12x12.
242         /// Blocks are always 16 bytes.
243         ///
244         /// Compressed textures sacrifice some quality in exchange for significantly reduced
245         /// bandwidth usage.
246         ///
247         /// Support for this feature guarantees availability of [`TextureUsages::COPY_SRC | TextureUsages::COPY_DST | TextureUsages::TEXTURE_BINDING`] for ASTC formats.
248         /// [`Features::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES`] may enable additional usages.
249         ///
250         /// Supported Platforms:
251         /// - Intel/Vulkan
252         /// - Mobile (some)
253         ///
254         /// This is a web and native feature.
255         const TEXTURE_COMPRESSION_ASTC_LDR = 1 << 5;
256         /// Allows non-zero value for the "first instance" in indirect draw calls.
257         ///
258         /// Supported Platforms:
259         /// - Vulkan (mostly)
260         /// - DX12
261         /// - Metal
262         ///
263         /// This is a web and native feature.
264         const INDIRECT_FIRST_INSTANCE = 1 << 6;
265         /// Enables use of Timestamp Queries. These queries tell the current gpu timestamp when
266         /// all work before the query is finished. Call [`CommandEncoder::write_timestamp`],
267         /// [`RenderPassEncoder::write_timestamp`], or [`ComputePassEncoder::write_timestamp`] to
268         /// write out a timestamp.
269         ///
270         /// They must be resolved using [`CommandEncoder::resolve_query_sets`] into a buffer,
271         /// then the result must be multiplied by the timestamp period [`Queue::get_timestamp_period`]
272         /// to get the timestamp in nanoseconds. Multiple timestamps can then be diffed to get the
273         /// time for operations between them to finish.
274         ///
275         /// Due to wgpu-hal limitations, this is only supported on vulkan for now.
276         ///
277         /// Supported Platforms:
278         /// - Vulkan (works)
279         /// - DX12 (works)
280         ///
281         /// This is a web and native feature.
282         const TIMESTAMP_QUERY = 1 << 7;
283         /// Enables use of Pipeline Statistics Queries. These queries tell the count of various operations
284         /// performed between the start and stop call. Call [`RenderPassEncoder::begin_pipeline_statistics_query`] to start
285         /// a query, then call [`RenderPassEncoder::end_pipeline_statistics_query`] to stop one.
286         ///
287         /// They must be resolved using [`CommandEncoder::resolve_query_sets`] into a buffer.
288         /// The rules on how these resolve into buffers are detailed in the documentation for [`PipelineStatisticsTypes`].
289         ///
290         /// Due to wgpu-hal limitations, this is only supported on vulkan for now.
291         ///
292         /// Supported Platforms:
293         /// - Vulkan (works)
294         /// - DX12 (works)
295         ///
296         /// This is a web and native feature.
297         const PIPELINE_STATISTICS_QUERY = 1 << 8;
298         /// Allows shaders to acquire the FP16 ability
299         ///
300         /// Note: this is not supported in naga yet,only through spir-v passthrough right now.
301         ///
302         /// Supported Platforms:
303         /// - Vulkan
304         /// - Metal
305         ///
306         /// This is a web and native feature.
307         const SHADER_FLOAT16 = 1 << 9;
309         //
310         // ---- Restart Numbering for Native Features ---
311         //
312         // Native Features:
313         //
315         /// Webgpu only allows the MAP_READ and MAP_WRITE buffer usage to be matched with
316         /// COPY_DST and COPY_SRC respectively. This removes this requirement.
317         ///
318         /// This is only beneficial on systems that share memory between CPU and GPU. If enabled
319         /// on a system that doesn't, this can severely hinder performance. Only use if you understand
320         /// the consequences.
321         ///
322         /// Supported platforms:
323         /// - All
324         ///
325         /// This is a native only feature.
326         const MAPPABLE_PRIMARY_BUFFERS = 1 << 16;
327         /// Allows the user to create uniform arrays of textures in shaders:
328         ///
329         /// ex.
330         /// `var textures: binding_array<texture_2d<f32>, 10>` (WGSL)\
331         /// `uniform texture2D textures[10]` (GLSL)
332         ///
333         /// If [`Features::STORAGE_RESOURCE_BINDING_ARRAY`] is supported as well as this, the user
334         /// may also create uniform arrays of storage textures.
335         ///
336         /// ex.
337         /// `var textures: array<texture_storage_2d<f32, write>, 10>` (WGSL)\
338         /// `uniform image2D textures[10]` (GLSL)
339         ///
340         /// This capability allows them to exist and to be indexed by dynamically uniform
341         /// values.
342         ///
343         /// Supported platforms:
344         /// - DX12
345         /// - Metal (with MSL 2.0+ on macOS 10.13+)
346         /// - Vulkan
347         ///
348         /// This is a native only feature.
349         const TEXTURE_BINDING_ARRAY = 1 << 17;
350         /// Allows the user to create arrays of buffers in shaders:
351         ///
352         /// ex.
353         /// `var<uniform> buffer_array: array<MyBuffer, 10>` (WGSL)\
354         /// `uniform myBuffer { ... } buffer_array[10]` (GLSL)
355         ///
356         /// This capability allows them to exist and to be indexed by dynamically uniform
357         /// values.
358         ///
359         /// If [`Features::STORAGE_RESOURCE_BINDING_ARRAY`] is supported as well as this, the user
360         /// may also create arrays of storage buffers.
361         ///
362         /// ex.
363         /// `var<storage> buffer_array: array<MyBuffer, 10>` (WGSL)\
364         /// `buffer myBuffer { ... } buffer_array[10]` (GLSL)
365         ///
366         /// Supported platforms:
367         /// - DX12
368         /// - Vulkan
369         ///
370         /// This is a native only feature.
371         const BUFFER_BINDING_ARRAY = 1 << 18;
372         /// Allows the user to create uniform arrays of storage buffers or textures in shaders,
373         /// if resp. [`Features::BUFFER_BINDING_ARRAY`] or [`Features::TEXTURE_BINDING_ARRAY`]
374         /// is supported.
375         ///
376         /// This capability allows them to exist and to be indexed by dynamically uniform
377         /// values.
378         ///
379         /// Supported platforms:
380         /// - Metal (with MSL 2.2+ on macOS 10.13+)
381         /// - Vulkan
382         ///
383         /// This is a native only feature.
384         const STORAGE_RESOURCE_BINDING_ARRAY = 1 << 19;
385         /// Allows shaders to index sampled texture and storage buffer resource arrays with dynamically non-uniform values:
386         ///
387         /// ex. `texture_array[vertex_data]`
388         ///
389         /// In order to use this capability, the corresponding GLSL extension must be enabled like so:
390         ///
391         /// `#extension GL_EXT_nonuniform_qualifier : require`
392         ///
393         /// and then used either as `nonuniformEXT` qualifier in variable declaration:
394         ///
395         /// ex. `layout(location = 0) nonuniformEXT flat in int vertex_data;`
396         ///
397         /// or as `nonuniformEXT` constructor:
398         ///
399         /// ex. `texture_array[nonuniformEXT(vertex_data)]`
400         ///
401         /// WGSL and HLSL do not need any extension.
402         ///
403         /// Supported platforms:
404         /// - DX12
405         /// - Metal (with MSL 2.0+ on macOS 10.13+)
406         /// - Vulkan 1.2+ (or VK_EXT_descriptor_indexing)'s shaderSampledImageArrayNonUniformIndexing & shaderStorageBufferArrayNonUniformIndexing feature)
407         ///
408         /// This is a native only feature.
409         const SAMPLED_TEXTURE_AND_STORAGE_BUFFER_ARRAY_NON_UNIFORM_INDEXING = 1 << 20;
410         /// Allows shaders to index uniform buffer and storage texture resource arrays with dynamically non-uniform values:
411         ///
412         /// ex. `texture_array[vertex_data]`
413         ///
414         /// In order to use this capability, the corresponding GLSL extension must be enabled like so:
415         ///
416         /// `#extension GL_EXT_nonuniform_qualifier : require`
417         ///
418         /// and then used either as `nonuniformEXT` qualifier in variable declaration:
419         ///
420         /// ex. `layout(location = 0) nonuniformEXT flat in int vertex_data;`
421         ///
422         /// or as `nonuniformEXT` constructor:
423         ///
424         /// ex. `texture_array[nonuniformEXT(vertex_data)]`
425         ///
426         /// WGSL and HLSL do not need any extension.
427         ///
428         /// Supported platforms:
429         /// - DX12
430         /// - Metal (with MSL 2.0+ on macOS 10.13+)
431         /// - Vulkan 1.2+ (or VK_EXT_descriptor_indexing)'s shaderUniformBufferArrayNonUniformIndexing & shaderStorageTextureArrayNonUniformIndexing feature)
432         ///
433         /// This is a native only feature.
434         const UNIFORM_BUFFER_AND_STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING = 1 << 21;
435         /// Allows the user to create bind groups continaing arrays with less bindings than the BindGroupLayout.
436         ///
437         /// This is a native only feature.
438         const PARTIALLY_BOUND_BINDING_ARRAY = 1 << 22;
439         /// Allows the user to call [`RenderPass::multi_draw_indirect`] and [`RenderPass::multi_draw_indexed_indirect`].
440         ///
441         /// Allows multiple indirect calls to be dispatched from a single buffer.
442         ///
443         /// Supported platforms:
444         /// - DX12
445         /// - Vulkan
446         /// - Metal (Emulated on top of `draw_indirect` and `draw_indexed_indirect`)
447         ///
448         /// This is a native only feature.
449         const MULTI_DRAW_INDIRECT = 1 << 23;
450         /// Allows the user to call [`RenderPass::multi_draw_indirect_count`] and [`RenderPass::multi_draw_indexed_indirect_count`].
451         ///
452         /// This allows the use of a buffer containing the actual number of draw calls.
453         ///
454         /// Supported platforms:
455         /// - DX12
456         /// - Vulkan 1.2+ (or VK_KHR_draw_indirect_count)
457         ///
458         /// This is a native only feature.
459         const MULTI_DRAW_INDIRECT_COUNT = 1 << 24;
460         /// Allows the use of push constants: small, fast bits of memory that can be updated
461         /// inside a [`RenderPass`].
462         ///
463         /// Allows the user to call [`RenderPass::set_push_constants`], provide a non-empty array
464         /// to [`PipelineLayoutDescriptor`], and provide a non-zero limit to [`Limits::max_push_constant_size`].
465         ///
466         /// A block of push constants can be declared with `layout(push_constant) uniform Name {..}` in shaders.
467         ///
468         /// Supported platforms:
469         /// - DX12
470         /// - Vulkan
471         /// - Metal
472         /// - DX11 (emulated with uniforms)
473         /// - OpenGL (emulated with uniforms)
474         ///
475         /// This is a native only feature.
476         const PUSH_CONSTANTS = 1 << 25;
477         /// Allows the use of [`AddressMode::ClampToBorder`] with a border color
478         /// other than [`SamplerBorderColor::Zero`].
479         ///
480         /// Supported platforms:
481         /// - DX12
482         /// - Vulkan
483         /// - Metal (macOS 10.12+ only)
484         /// - DX11
485         /// - OpenGL
486         ///
487         /// This is a web and native feature.
488         const ADDRESS_MODE_CLAMP_TO_BORDER = 1 << 26;
489         /// Allows the user to set [`PolygonMode::Line`] in [`PrimitiveState::polygon_mode`]
490         ///
491         /// This allows drawing polygons/triangles as lines (wireframe) instead of filled
492         ///
493         /// Supported platforms:
494         /// - DX12
495         /// - Vulkan
496         /// - Metal
497         ///
498         /// This is a native only feature.
499         const POLYGON_MODE_LINE = 1 << 27;
500         /// Allows the user to set [`PolygonMode::Point`] in [`PrimitiveState::polygon_mode`]
501         ///
502         /// This allows only drawing the vertices of polygons/triangles instead of filled
503         ///
504         /// Supported platforms:
505         /// - DX12
506         /// - Vulkan
507         ///
508         /// This is a native only feature.
509         const POLYGON_MODE_POINT = 1 << 28;
510         /// Enables device specific texture format features.
511         ///
512         /// See `TextureFormatFeatures` for a listing of the features in question.
513         ///
514         /// By default only texture format properties as defined by the WebGPU specification are allowed.
515         /// Enabling this feature flag extends the features of each format to the ones supported by the current device.
516         /// Note that without this flag, read/write storage access is not allowed at all.
517         ///
518         /// This extension does not enable additional formats.
519         ///
520         /// This is a native-only feature.
521         const TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES = 1 << 29;
522         /// Enables 64-bit floating point types in SPIR-V shaders.
523         ///
524         /// Note: even when supported by GPU hardware, 64-bit floating point operations are
525         /// frequently between 16 and 64 _times_ slower than equivalent operations on 32-bit floats.
526         ///
527         /// Supported Platforms:
528         /// - Vulkan
529         ///
530         /// This is a native-only feature.
531         const SHADER_FLOAT64 = 1 << 30;
532         /// Enables using 64-bit types for vertex attributes.
533         ///
534         /// Requires SHADER_FLOAT64.
535         ///
536         /// Supported Platforms: N/A
537         ///
538         /// This is a native-only feature.
539         const VERTEX_ATTRIBUTE_64BIT = 1 << 31;
540         /// Allows the user to set a overestimation-conservative-rasterization in [`PrimitiveState::conservative`]
541         ///
542         /// Processing of degenerate triangles/lines is hardware specific.
543         /// Only triangles are supported.
544         ///
545         /// Supported platforms:
546         /// - Vulkan
547         ///
548         /// This is a native only feature.
549         const CONSERVATIVE_RASTERIZATION = 1 << 32;
550         /// Enables bindings of writable storage buffers and textures visible to vertex shaders.
551         ///
552         /// Note: some (tiled-based) platforms do not support vertex shaders with any side-effects.
553         ///
554         /// Supported Platforms:
555         /// - All
556         ///
557         /// This is a native-only feature.
558         const VERTEX_WRITABLE_STORAGE = 1 << 33;
559         /// Enables clear to zero for textures.
560         ///
561         /// Supported platforms:
562         /// - All
563         ///
564         /// This is a native only feature.
565         const CLEAR_TEXTURE = 1 << 34;
566         /// Enables creating shader modules from SPIR-V binary data (unsafe).
567         ///
568         /// SPIR-V data is not parsed or interpreted in any way; you can use
569         /// [`wgpu::make_spirv_raw!`] to check for alignment and magic number when converting from
570         /// raw bytes.
571         ///
572         /// Supported platforms:
573         /// - Vulkan, in case shader's requested capabilities and extensions agree with
574         /// Vulkan implementation.
575         ///
576         /// This is a native only feature.
577         const SPIRV_SHADER_PASSTHROUGH = 1 << 35;
578         /// Enables `builtin(primitive_index)` in fragment shaders.
579         ///
580         /// Note: enables geometry processing for pipelines using the builtin.
581         /// This may come with a significant performance impact on some hardware.
582         /// Other pipelines are not affected.
583         ///
584         /// Supported platforms:
585         /// - Vulkan
586         ///
587         /// This is a native only feature.
588         const SHADER_PRIMITIVE_INDEX = 1 << 36;
589         /// Enables multiview render passes and `builtin(view_index)` in vertex shaders.
590         ///
591         /// Supported platforms:
592         /// - Vulkan
593         ///
594         /// This is a native only feature.
595         const MULTIVIEW = 1 << 37;
596         /// Enables normalized `16-bit` texture formats.
597         ///
598         /// Supported platforms:
599         /// - Vulkan
600         /// - DX12
601         /// - Metal
602         ///
603         /// This is a native only feature.
604         const TEXTURE_FORMAT_16BIT_NORM = 1 << 38;
605         /// Allows the use of [`AddressMode::ClampToBorder`] with a border color
606         /// of [`SamplerBorderColor::Zero`].
607         ///
608         /// Supported platforms:
609         /// - DX12
610         /// - Vulkan
611         /// - Metal
612         /// - DX11
613         /// - OpenGL
614         ///
615         /// This is a native only feature.
616         const ADDRESS_MODE_CLAMP_TO_ZERO = 1 << 39;
617         /// Enables ASTC HDR family of compressed textures.
618         ///
619         /// Compressed textures sacrifice some quality in exchange for significantly reduced
620         /// bandwidth usage.
621         ///
622         /// Support for this feature guarantees availability of [`TextureUsages::COPY_SRC | TextureUsages::COPY_DST | TextureUsages::TEXTURE_BINDING`] for BCn formats.
623         /// [`Features::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES`] may enable additional usages.
624         ///
625         /// Supported Platforms:
626         /// - Metal
627         /// - Vulkan
628         ///
629         /// This is a native-only feature.
630         const TEXTURE_COMPRESSION_ASTC_HDR = 1 << 40;
631         /// Allows for timestamp queries inside renderpasses. Metal does not allow this
632         /// on Apple GPUs.
633         ///
634         /// Implies [`Features::TIMESTAMP_QUERIES`] is supported.
635         ///
636         /// Supported platforms:
637         /// - Vulkan
638         /// - DX12
639         /// - Metal (Intel and AMD GPUs)
640         const WRITE_TIMESTAMP_INSIDE_PASSES = 1 << 41;
641     }
644 #[cfg(feature = "bitflags_serde_shim")]
645 bitflags_serde_shim::impl_serde_for_bitflags!(Features);
647 impl Features {
648     /// Mask of all features which are part of the upstream WebGPU standard.
649     pub const fn all_webgpu_mask() -> Self {
650         Self::from_bits_truncate(0x0000_0000_0000_FFFF)
651     }
653     /// Mask of all features that are only available when targeting native (not web).
654     pub const fn all_native_mask() -> Self {
655         Self::from_bits_truncate(0xFFFF_FFFF_FFFF_0000)
656     }
659 /// Represents the sets of limits an adapter/device supports.
661 /// We provide three different defaults.
662 /// - [`Limits::downlevel_defaults()`]. This is a set of limits that is guaranteed to work on almost
663 ///   all backends, including "downlevel" backends such as OpenGL and D3D11, other than WebGL. For
664 ///   most applications we recommend using these limits, assuming they are high enough for your
665 ///   application, and you do not intent to support WebGL.
666 /// - [`Limits::downlevel_webgl2_defaults()`] This is a set of limits that is lower even than the
667 ///   [`downlevel_defaults()`], configured to be low enough to support running in the browser using
668 ///   WebGL2.
669 /// - [`Limits::default()`]. This is the set of limits that is guarenteed to work on all modern
670 ///   backends and is guarenteed to be supported by WebGPU. Applications needing more modern
671 ///   features can use this as a reasonable set of limits if they are targetting only desktop and
672 ///   modern mobile devices.
674 /// We recommend starting with the most restrictive limits you can and manually increasing the
675 /// limits you need boosted. This will let you stay running on all hardware that supports the limits
676 /// you need.
678 /// Limits "better" than the default must be supported by the adapter and requested when requesting
679 /// a device. If limits "better" than the adapter supports are requested, requesting a device will
680 /// panic. Once a device is requested, you may only use resources up to the limits requested _even_
681 /// if the adapter supports "better" limits.
683 /// Requesting limits that are "better" than you need may cause performance to decrease because the
684 /// implementation needs to support more than is needed. You should ideally only request exactly
685 /// what you need.
687 /// Corresponds to [WebGPU `GPUSupportedLimits`](
688 /// https://gpuweb.github.io/gpuweb/#gpusupportedlimits).
690 /// [`downlevel_defaults()`]: Limits::downlevel_defaults
691 #[repr(C)]
692 #[derive(Clone, Debug, PartialEq, Eq, Hash)]
693 #[cfg_attr(feature = "trace", derive(Serialize))]
694 #[cfg_attr(feature = "replay", derive(Deserialize))]
695 #[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
696 pub struct Limits {
697     /// Maximum allowed value for the `size.width` of a texture created with `TextureDimension::D1`.
698     /// Defaults to 8192. Higher is "better".
699     pub max_texture_dimension_1d: u32,
700     /// Maximum allowed value for the `size.width` and `size.height` of a texture created with `TextureDimension::D2`.
701     /// Defaults to 8192. Higher is "better".
702     pub max_texture_dimension_2d: u32,
703     /// Maximum allowed value for the `size.width`, `size.height`, and `size.depth_or_array_layers`
704     /// of a texture created with `TextureDimension::D3`.
705     /// Defaults to 2048. Higher is "better".
706     pub max_texture_dimension_3d: u32,
707     /// Maximum allowed value for the `size.depth_or_array_layers` of a texture created with
708     /// `TextureDimension::D1` or `TextureDimension::D2`.
709     /// Defaults to 256. Higher is "better".
710     pub max_texture_array_layers: u32,
711     /// Amount of bind groups that can be attached to a pipeline at the same time. Defaults to 4. Higher is "better".
712     pub max_bind_groups: u32,
713     /// Amount of uniform buffer bindings that can be dynamic in a single pipeline. Defaults to 8. Higher is "better".
714     pub max_dynamic_uniform_buffers_per_pipeline_layout: u32,
715     /// Amount of storage buffer bindings that can be dynamic in a single pipeline. Defaults to 4. Higher is "better".
716     pub max_dynamic_storage_buffers_per_pipeline_layout: u32,
717     /// Amount of sampled textures visible in a single shader stage. Defaults to 16. Higher is "better".
718     pub max_sampled_textures_per_shader_stage: u32,
719     /// Amount of samplers visible in a single shader stage. Defaults to 16. Higher is "better".
720     pub max_samplers_per_shader_stage: u32,
721     /// Amount of storage buffers visible in a single shader stage. Defaults to 8. Higher is "better".
722     pub max_storage_buffers_per_shader_stage: u32,
723     /// Amount of storage textures visible in a single shader stage. Defaults to 8. Higher is "better".
724     pub max_storage_textures_per_shader_stage: u32,
725     /// Amount of uniform buffers visible in a single shader stage. Defaults to 12. Higher is "better".
726     pub max_uniform_buffers_per_shader_stage: u32,
727     /// Maximum size in bytes of a binding to a uniform buffer. Defaults to 64 KB. Higher is "better".
728     pub max_uniform_buffer_binding_size: u32,
729     /// Maximum size in bytes of a binding to a storage buffer. Defaults to 128 MB. Higher is "better".
730     pub max_storage_buffer_binding_size: u32,
731     /// Maximum length of `VertexState::buffers` when creating a `RenderPipeline`.
732     /// Defaults to 8. Higher is "better".
733     pub max_vertex_buffers: u32,
734     /// Maximum length of `VertexBufferLayout::attributes`, summed over all `VertexState::buffers`,
735     /// when creating a `RenderPipeline`.
736     /// Defaults to 16. Higher is "better".
737     pub max_vertex_attributes: u32,
738     /// Maximum value for `VertexBufferLayout::array_stride` when creating a `RenderPipeline`.
739     /// Defaults to 2048. Higher is "better".
740     pub max_vertex_buffer_array_stride: u32,
741     /// Amount of storage available for push constants in bytes. Defaults to 0. Higher is "better".
742     /// Requesting more than 0 during device creation requires [`Features::PUSH_CONSTANTS`] to be enabled.
743     ///
744     /// Expect the size to be:
745     /// - Vulkan: 128-256 bytes
746     /// - DX12: 256 bytes
747     /// - Metal: 4096 bytes
748     /// - DX11 & OpenGL don't natively support push constants, and are emulated with uniforms,
749     ///   so this number is less useful but likely 256.
750     pub max_push_constant_size: u32,
751     /// Required `BufferBindingType::Uniform` alignment for `BufferBinding::offset`
752     /// when creating a `BindGroup`, or for `set_bind_group` `dynamicOffsets`.
753     /// Defaults to 256. Lower is "better".
754     pub min_uniform_buffer_offset_alignment: u32,
755     /// Required `BufferBindingType::Storage` alignment for `BufferBinding::offset`
756     /// when creating a `BindGroup`, or for `set_bind_group` `dynamicOffsets`.
757     /// Defaults to 256. Lower is "better".
758     pub min_storage_buffer_offset_alignment: u32,
759     /// Maximum allowed number of components (scalars) of input or output locations for
760     /// inter-stage communication (vertex outputs to fragment inputs). Defaults to 60.
761     pub max_inter_stage_shader_components: u32,
762     /// Maximum number of bytes used for workgroup memory in a compute entry point. Defaults to
763     /// 16352.
764     pub max_compute_workgroup_storage_size: u32,
765     /// Maximum value of the product of the `workgroup_size` dimensions for a compute entry-point.
766     /// Defaults to 256.
767     pub max_compute_invocations_per_workgroup: u32,
768     /// The maximum value of the workgroup_size X dimension for a compute stage `ShaderModule` entry-point.
769     /// Defaults to 256.
770     pub max_compute_workgroup_size_x: u32,
771     /// The maximum value of the workgroup_size Y dimension for a compute stage `ShaderModule` entry-point.
772     /// Defaults to 256.
773     pub max_compute_workgroup_size_y: u32,
774     /// The maximum value of the workgroup_size Z dimension for a compute stage `ShaderModule` entry-point.
775     /// Defaults to 64.
776     pub max_compute_workgroup_size_z: u32,
777     /// The maximum value for each dimension of a `ComputePass::dispatch(x, y, z)` operation.
778     /// Defaults to 65535.
779     pub max_compute_workgroups_per_dimension: u32,
780     /// A limit above which buffer allocations are guaranteed to fail.
781     ///
782     /// Buffer allocations below the maximum buffer size may not succed depending on available memory,
783     /// fragmentation and other factors.
784     pub max_buffer_size: u64,
787 impl Default for Limits {
788     fn default() -> Self {
789         Self {
790             max_texture_dimension_1d: 8192,
791             max_texture_dimension_2d: 8192,
792             max_texture_dimension_3d: 2048,
793             max_texture_array_layers: 256,
794             max_bind_groups: 4,
795             max_dynamic_uniform_buffers_per_pipeline_layout: 8,
796             max_dynamic_storage_buffers_per_pipeline_layout: 4,
797             max_sampled_textures_per_shader_stage: 16,
798             max_samplers_per_shader_stage: 16,
799             max_storage_buffers_per_shader_stage: 8,
800             max_storage_textures_per_shader_stage: 8,
801             max_uniform_buffers_per_shader_stage: 12,
802             max_uniform_buffer_binding_size: 64 << 10,
803             max_storage_buffer_binding_size: 128 << 20,
804             max_vertex_buffers: 8,
805             max_vertex_attributes: 16,
806             max_vertex_buffer_array_stride: 2048,
807             max_push_constant_size: 0,
808             min_uniform_buffer_offset_alignment: 256,
809             min_storage_buffer_offset_alignment: 256,
810             max_inter_stage_shader_components: 60,
811             max_compute_workgroup_storage_size: 16352,
812             max_compute_invocations_per_workgroup: 256,
813             max_compute_workgroup_size_x: 256,
814             max_compute_workgroup_size_y: 256,
815             max_compute_workgroup_size_z: 64,
816             max_compute_workgroups_per_dimension: 65535,
817             max_buffer_size: 1 << 30,
818         }
819     }
822 impl Limits {
823     /// These default limits are guarenteed to be compatible with GLES-3.1, and D3D11
824     pub fn downlevel_defaults() -> Self {
825         Self {
826             max_texture_dimension_1d: 2048,
827             max_texture_dimension_2d: 2048,
828             max_texture_dimension_3d: 256,
829             max_texture_array_layers: 256,
830             max_bind_groups: 4,
831             max_dynamic_uniform_buffers_per_pipeline_layout: 8,
832             max_dynamic_storage_buffers_per_pipeline_layout: 4,
833             max_sampled_textures_per_shader_stage: 16,
834             max_samplers_per_shader_stage: 16,
835             max_storage_buffers_per_shader_stage: 4,
836             max_storage_textures_per_shader_stage: 4,
837             max_uniform_buffers_per_shader_stage: 12,
838             max_uniform_buffer_binding_size: 16 << 10,
839             max_storage_buffer_binding_size: 128 << 20,
840             max_vertex_buffers: 8,
841             max_vertex_attributes: 16,
842             max_vertex_buffer_array_stride: 2048,
843             max_push_constant_size: 0,
844             min_uniform_buffer_offset_alignment: 256,
845             min_storage_buffer_offset_alignment: 256,
846             max_inter_stage_shader_components: 60,
847             max_compute_workgroup_storage_size: 16352,
848             max_compute_invocations_per_workgroup: 256,
849             max_compute_workgroup_size_x: 256,
850             max_compute_workgroup_size_y: 256,
851             max_compute_workgroup_size_z: 64,
852             max_compute_workgroups_per_dimension: 65535,
853             max_buffer_size: 1 << 28,
854         }
855     }
857     /// These default limits are guarenteed to be compatible with GLES-3.0, and D3D11, and WebGL2
858     pub fn downlevel_webgl2_defaults() -> Self {
859         Self {
860             max_uniform_buffers_per_shader_stage: 11,
861             max_storage_buffers_per_shader_stage: 0,
862             max_storage_textures_per_shader_stage: 0,
863             max_dynamic_storage_buffers_per_pipeline_layout: 0,
864             max_storage_buffer_binding_size: 0,
865             max_vertex_buffer_array_stride: 255,
866             max_compute_workgroup_storage_size: 0,
867             max_compute_invocations_per_workgroup: 0,
868             max_compute_workgroup_size_x: 0,
869             max_compute_workgroup_size_y: 0,
870             max_compute_workgroup_size_z: 0,
871             max_compute_workgroups_per_dimension: 0,
873             // Most of the values should be the same as the downlevel defaults
874             ..Self::downlevel_defaults()
875         }
876     }
878     /// Modify the current limits to use the resolution limits of the other.
879     ///
880     /// This is useful because the swapchain might need to be larger than any other image in the application.
881     ///
882     /// If your application only needs 512x512, you might be running on a 4k display and need extremely high resolution limits.
883     pub fn using_resolution(self, other: Self) -> Self {
884         Self {
885             max_texture_dimension_1d: other.max_texture_dimension_1d,
886             max_texture_dimension_2d: other.max_texture_dimension_2d,
887             max_texture_dimension_3d: other.max_texture_dimension_3d,
888             ..self
889         }
890     }
892     /// Modify the current limits to use the buffer alignment limits of the adapter.
893     ///
894     /// This is useful for when you'd like to dynamically use the "best" supported buffer alignments.
895     pub fn using_alignment(self, other: Self) -> Self {
896         Self {
897             min_uniform_buffer_offset_alignment: other.min_uniform_buffer_offset_alignment,
898             min_storage_buffer_offset_alignment: other.min_storage_buffer_offset_alignment,
899             ..self
900         }
901     }
903     /// Compares every limits within self is within the limits given in `allowed`.
904     ///
905     /// If you need detailed information on failures, look at [`Limits::check_limits_with_fail_fn`].
906     pub fn check_limits(&self, allowed: &Self) -> bool {
907         let mut within = true;
908         self.check_limits_with_fail_fn(allowed, true, |_, _, _| within = false);
909         within
910     }
912     /// Compares every limits within self is within the limits given in `allowed`.
913     /// For an easy to use binary choice, use [`Limits::check_limits`].
914     ///
915     /// If a value is not within the allowed limit, this function calls the `fail_fn`
916     /// with the:
917     ///  - limit name
918     ///  - self's limit
919     ///  - allowed's limit.
920     ///
921     /// If fatal is true, a single failure bails out the comparison after a single failure.
922     pub fn check_limits_with_fail_fn(
923         &self,
924         allowed: &Self,
925         fatal: bool,
926         mut fail_fn: impl FnMut(&'static str, u64, u64),
927     ) {
928         use std::cmp::Ordering;
930         macro_rules! compare {
931             ($name:ident, $ordering:ident) => {
932                 match self.$name.cmp(&allowed.$name) {
933                     Ordering::$ordering | Ordering::Equal => (),
934                     _ => {
935                         fail_fn(stringify!($name), self.$name as u64, allowed.$name as u64);
936                         if fatal {
937                             return;
938                         }
939                     }
940                 }
941             };
942         }
944         compare!(max_texture_dimension_1d, Less);
945         compare!(max_texture_dimension_2d, Less);
946         compare!(max_texture_dimension_3d, Less);
947         compare!(max_texture_array_layers, Less);
948         compare!(max_bind_groups, Less);
949         compare!(max_dynamic_uniform_buffers_per_pipeline_layout, Less);
950         compare!(max_dynamic_storage_buffers_per_pipeline_layout, Less);
951         compare!(max_sampled_textures_per_shader_stage, Less);
952         compare!(max_samplers_per_shader_stage, Less);
953         compare!(max_storage_buffers_per_shader_stage, Less);
954         compare!(max_storage_textures_per_shader_stage, Less);
955         compare!(max_uniform_buffers_per_shader_stage, Less);
956         compare!(max_uniform_buffer_binding_size, Less);
957         compare!(max_storage_buffer_binding_size, Less);
958         compare!(max_vertex_buffers, Less);
959         compare!(max_vertex_attributes, Less);
960         compare!(max_vertex_buffer_array_stride, Less);
961         compare!(max_push_constant_size, Less);
962         compare!(min_uniform_buffer_offset_alignment, Greater);
963         compare!(min_storage_buffer_offset_alignment, Greater);
964         compare!(max_inter_stage_shader_components, Less);
965         compare!(max_compute_workgroup_storage_size, Less);
966         compare!(max_compute_invocations_per_workgroup, Less);
967         compare!(max_compute_workgroup_size_x, Less);
968         compare!(max_compute_workgroup_size_y, Less);
969         compare!(max_compute_workgroup_size_z, Less);
970         compare!(max_compute_workgroups_per_dimension, Less);
971         compare!(max_buffer_size, Less);
972     }
975 /// Represents the sets of additional limits on an adapter,
976 /// which take place when running on downlevel backends.
977 #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
978 pub struct DownlevelLimits {}
980 #[allow(unknown_lints)] // derivable_impls is nightly only currently
981 #[allow(clippy::derivable_impls)]
982 impl Default for DownlevelLimits {
983     fn default() -> Self {
984         DownlevelLimits {}
985     }
988 /// Lists various ways the underlying platform does not conform to the WebGPU standard.
989 #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
990 pub struct DownlevelCapabilities {
991     /// Combined boolean flags.
992     pub flags: DownlevelFlags,
993     /// Additional limits
994     pub limits: DownlevelLimits,
995     /// Which collections of features shaders support. Defined in terms of D3D's shader models.
996     pub shader_model: ShaderModel,
999 impl Default for DownlevelCapabilities {
1000     fn default() -> Self {
1001         Self {
1002             flags: DownlevelFlags::all(),
1003             limits: DownlevelLimits::default(),
1004             shader_model: ShaderModel::Sm5,
1005         }
1006     }
1009 impl DownlevelCapabilities {
1010     /// Returns true if the underlying platform offers complete support of the baseline WebGPU standard.
1011     ///
1012     /// If this returns false, some parts of the API will result in validation errors where they would not normally.
1013     /// These parts can be determined by the values in this structure.
1014     pub fn is_webgpu_compliant(&self) -> bool {
1015         self.flags.contains(DownlevelFlags::compliant())
1016             && self.limits == DownlevelLimits::default()
1017             && self.shader_model >= ShaderModel::Sm5
1018     }
1021 bitflags::bitflags! {
1022     /// Binary flags listing features that may or may not be present on downlevel adapters.
1023     ///
1024     /// A downlevel adapter is a GPU adapter that WGPU supports, but with potentially limited
1025     /// features, due to the lack of hardware feature support.
1026     ///
1027     /// Flags that are **not** present for a downlevel adapter or device usually indicates
1028     /// non-compliance with the WebGPU specification, but not always.
1029     ///
1030     /// You can check whether a set of flags is compliant through the
1031     /// [`DownlevelCapabilities::is_webgpu_compliant()`] function.
1032     pub struct DownlevelFlags: u32 {
1033         /// The device supports compiling and using compute shaders.
1034         ///
1035         /// DX11 on FL10 level hardware, WebGL2, and GLES3.0 devices do not support compute.
1036         const COMPUTE_SHADERS = 1 << 0;
1037         /// Supports binding storage buffers and textures to fragment shaders.
1038         const FRAGMENT_WRITABLE_STORAGE = 1 << 1;
1039         /// Supports indirect drawing and dispatching.
1040         ///
1041         /// DX11 on FL10 level hardware, WebGL2, and GLES 3.0 devices do not support indirect.
1042         const INDIRECT_EXECUTION = 1 << 2;
1043         /// Supports non-zero `base_vertex` parameter to indexed draw calls.
1044         const BASE_VERTEX = 1 << 3;
1045         /// Supports reading from a depth/stencil buffer while using as a read-only depth/stencil
1046         /// attachment.
1047         ///
1048         /// The WebGL2 and GLES backends do not support RODS.
1049         const READ_ONLY_DEPTH_STENCIL = 1 << 4;
1050         /// Supports textures with mipmaps which have a non power of two size.
1051         const NON_POWER_OF_TWO_MIPMAPPED_TEXTURES = 1 << 5;
1052         /// Supports textures that are cube arrays.
1053         const CUBE_ARRAY_TEXTURES = 1 << 6;
1054         /// Supports comparison samplers.
1055         const COMPARISON_SAMPLERS = 1 << 7;
1056         /// Supports different blend operations per color attachment.
1057         const INDEPENDENT_BLEND = 1 << 8;
1058         /// Supports storage buffers in vertex shaders.
1059         const VERTEX_STORAGE = 1 << 9;
1061         /// Supports samplers with anisotropic filtering. Note this isn't actually required by
1062         /// WebGPU, the implementation is allowed to completely ignore aniso clamp. This flag is
1063         /// here for native backends so they can comunicate to the user of aniso is enabled.
1064         ///
1065         /// All backends and all devices support anisotropic filtering.
1066         const ANISOTROPIC_FILTERING = 1 << 10;
1068         /// Supports storage buffers in fragment shaders.
1069         const FRAGMENT_STORAGE = 1 << 11;
1071         /// Supports sample-rate shading.
1072         const MULTISAMPLED_SHADING = 1 << 12;
1074         /// Supports copies between depth textures and buffers.
1075         ///
1076         /// GLES/WebGL don't support this.
1077         const DEPTH_TEXTURE_AND_BUFFER_COPIES = 1 << 13;
1079         /// Supports all the texture usages described in WebGPU. If this isn't supported, you
1080         /// should call `get_texture_format_features` to get how you can use textures of a given format
1081         const WEBGPU_TEXTURE_FORMAT_SUPPORT = 1 << 14;
1083         /// Supports buffer bindings with sizes that aren't a multiple of 16.
1084         ///
1085         /// WebGL doesn't support this.
1086         const BUFFER_BINDINGS_NOT_16_BYTE_ALIGNED = 1 << 15;
1087     }
1090 #[cfg(feature = "bitflags_serde_shim")]
1091 bitflags_serde_shim::impl_serde_for_bitflags!(DownlevelFlags);
1093 impl DownlevelFlags {
1094     /// All flags that indicate if the backend is WebGPU compliant
1095     pub const fn compliant() -> Self {
1096         // We use manual bit twiddling to make this a const fn as `Sub` and `.remove` aren't const
1098         // WebGPU doesn't actually require aniso
1099         Self::from_bits_truncate(Self::all().bits() & !Self::ANISOTROPIC_FILTERING.bits)
1100     }
1103 /// Collections of shader features a device supports if they support less than WebGPU normally allows.
1104 // TODO: Fill out the differences between shader models more completely
1105 #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
1106 pub enum ShaderModel {
1107     /// Extremely limited shaders, including a total instruction limit.
1108     Sm2,
1109     /// Missing minor features and storage images.
1110     Sm4,
1111     /// WebGPU supports shader module 5.
1112     Sm5,
1115 /// Supported physical device types.
1116 #[repr(u8)]
1117 #[derive(Clone, Copy, Debug, Eq, PartialEq)]
1118 #[cfg_attr(feature = "trace", derive(serde::Serialize))]
1119 #[cfg_attr(feature = "replay", derive(serde::Deserialize))]
1120 pub enum DeviceType {
1121     /// Other or Unknown.
1122     Other,
1123     /// Integrated GPU with shared CPU/GPU memory.
1124     IntegratedGpu,
1125     /// Discrete GPU with separate CPU/GPU memory.
1126     DiscreteGpu,
1127     /// Virtual / Hosted.
1128     VirtualGpu,
1129     /// Cpu / Software Rendering.
1130     Cpu,
1133 //TODO: convert `vendor` and `device` to `u32`
1135 /// Information about an adapter.
1136 #[derive(Clone, Debug, Eq, PartialEq)]
1137 #[cfg_attr(feature = "trace", derive(serde::Serialize))]
1138 #[cfg_attr(feature = "replay", derive(serde::Deserialize))]
1139 pub struct AdapterInfo {
1140     /// Adapter name
1141     pub name: String,
1142     /// Vendor PCI id of the adapter
1143     pub vendor: usize,
1144     /// PCI id of the adapter
1145     pub device: usize,
1146     /// Type of device
1147     pub device_type: DeviceType,
1148     /// Backend used for device
1149     pub backend: Backend,
1152 /// Describes a [`Device`](../wgpu/struct.Device.html).
1154 /// Corresponds to [WebGPU `GPUDeviceDescriptor`](
1155 /// https://gpuweb.github.io/gpuweb/#gpudevicedescriptor).
1156 #[repr(C)]
1157 #[derive(Clone, Debug, Default)]
1158 #[cfg_attr(feature = "trace", derive(Serialize))]
1159 #[cfg_attr(feature = "replay", derive(Deserialize))]
1160 pub struct DeviceDescriptor<L> {
1161     /// Debug label for the device.
1162     pub label: L,
1163     /// Features that the device should support. If any feature is not supported by
1164     /// the adapter, creating a device will panic.
1165     pub features: Features,
1166     /// Limits that the device should support. If any limit is "better" than the limit exposed by
1167     /// the adapter, creating a device will panic.
1168     pub limits: Limits,
1171 impl<L> DeviceDescriptor<L> {
1172     ///
1173     pub fn map_label<K>(&self, fun: impl FnOnce(&L) -> K) -> DeviceDescriptor<K> {
1174         DeviceDescriptor {
1175             label: fun(&self.label),
1176             features: self.features,
1177             limits: self.limits.clone(),
1178         }
1179     }
1182 bitflags::bitflags! {
1183     /// Describes the shader stages that a binding will be visible from.
1184     ///
1185     /// These can be combined so something that is visible from both vertex and fragment shaders can be defined as:
1186     ///
1187     /// `ShaderStages::VERTEX | ShaderStages::FRAGMENT`
1188     ///
1189     /// Corresponds to [WebGPU `GPUShaderStageFlags`](
1190     /// https://gpuweb.github.io/gpuweb/#typedefdef-gpushaderstageflags).
1191     #[repr(transparent)]
1192     pub struct ShaderStages: u32 {
1193         /// Binding is not visible from any shader stage.
1194         const NONE = 0;
1195         /// Binding is visible from the vertex shader of a render pipeline.
1196         const VERTEX = 1 << 0;
1197         /// Binding is visible from the fragment shader of a render pipeline.
1198         const FRAGMENT = 1 << 1;
1199         /// Binding is visible from the compute shader of a compute pipeline.
1200         const COMPUTE = 1 << 2;
1201         /// Binding is visible from the vertex and fragment shaders of a render pipeline.
1202         const VERTEX_FRAGMENT = Self::VERTEX.bits | Self::FRAGMENT.bits;
1203     }
1206 #[cfg(feature = "bitflags_serde_shim")]
1207 bitflags_serde_shim::impl_serde_for_bitflags!(ShaderStages);
1209 /// Dimensions of a particular texture view.
1211 /// Corresponds to [WebGPU `GPUTextureViewDimension`](
1212 /// https://gpuweb.github.io/gpuweb/#enumdef-gputextureviewdimension).
1213 #[repr(C)]
1214 #[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
1215 #[cfg_attr(feature = "trace", derive(Serialize))]
1216 #[cfg_attr(feature = "replay", derive(Deserialize))]
1217 pub enum TextureViewDimension {
1218     /// A one dimensional texture. `texture_1d` in WGSL and `texture1D` in GLSL.
1219     #[cfg_attr(feature = "serde", serde(rename = "1d"))]
1220     D1,
1221     /// A two dimensional texture. `texture_2d` in WGSL and `texture2D` in GLSL.
1222     #[cfg_attr(feature = "serde", serde(rename = "2d"))]
1223     D2,
1224     /// A two dimensional array texture. `texture_2d_array` in WGSL and `texture2DArray` in GLSL.
1225     #[cfg_attr(feature = "serde", serde(rename = "2d-array"))]
1226     D2Array,
1227     /// A cubemap texture. `texture_cube` in WGSL and `textureCube` in GLSL.
1228     #[cfg_attr(feature = "serde", serde(rename = "cube"))]
1229     Cube,
1230     /// A cubemap array texture. `texture_cube_array` in WGSL and `textureCubeArray` in GLSL.
1231     #[cfg_attr(feature = "serde", serde(rename = "cube-array"))]
1232     CubeArray,
1233     /// A three dimensional texture. `texture_3d` in WGSL and `texture3D` in GLSL.
1234     #[cfg_attr(feature = "serde", serde(rename = "3d"))]
1235     D3,
1238 impl Default for TextureViewDimension {
1239     fn default() -> Self {
1240         Self::D2
1241     }
1244 impl TextureViewDimension {
1245     /// Get the texture dimension required of this texture view dimension.
1246     pub fn compatible_texture_dimension(self) -> TextureDimension {
1247         match self {
1248             Self::D1 => TextureDimension::D1,
1249             Self::D2 | Self::D2Array | Self::Cube | Self::CubeArray => TextureDimension::D2,
1250             Self::D3 => TextureDimension::D3,
1251         }
1252     }
1255 /// Alpha blend factor.
1257 /// Alpha blending is very complicated: see the OpenGL or Vulkan spec for more information.
1259 /// Corresponds to [WebGPU `GPUBlendFactor`](
1260 /// https://gpuweb.github.io/gpuweb/#enumdef-gpublendfactor).
1261 #[repr(C)]
1262 #[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
1263 #[cfg_attr(feature = "trace", derive(Serialize))]
1264 #[cfg_attr(feature = "replay", derive(Deserialize))]
1265 #[cfg_attr(feature = "serde", serde(rename_all = "kebab-case"))]
1266 pub enum BlendFactor {
1267     /// 0.0
1268     Zero = 0,
1269     /// 1.0
1270     One = 1,
1271     /// S.component
1272     Src = 2,
1273     /// 1.0 - S.component
1274     OneMinusSrc = 3,
1275     /// S.alpha
1276     SrcAlpha = 4,
1277     /// 1.0 - S.alpha
1278     OneMinusSrcAlpha = 5,
1279     /// D.component
1280     Dst = 6,
1281     /// 1.0 - D.component
1282     OneMinusDst = 7,
1283     /// D.alpha
1284     DstAlpha = 8,
1285     /// 1.0 - D.alpha
1286     OneMinusDstAlpha = 9,
1287     /// min(S.alpha, 1.0 - D.alpha)
1288     SrcAlphaSaturated = 10,
1289     /// Constant
1290     Constant = 11,
1291     /// 1.0 - Constant
1292     OneMinusConstant = 12,
1295 /// Alpha blend operation.
1297 /// Alpha blending is very complicated: see the OpenGL or Vulkan spec for more information.
1299 /// Corresponds to [WebGPU `GPUBlendOperation`](
1300 /// https://gpuweb.github.io/gpuweb/#enumdef-gpublendoperation).
1301 #[repr(C)]
1302 #[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
1303 #[cfg_attr(feature = "trace", derive(Serialize))]
1304 #[cfg_attr(feature = "replay", derive(Deserialize))]
1305 #[cfg_attr(feature = "serde", serde(rename_all = "kebab-case"))]
1306 pub enum BlendOperation {
1307     /// Src + Dst
1308     Add = 0,
1309     /// Src - Dst
1310     Subtract = 1,
1311     /// Dst - Src
1312     ReverseSubtract = 2,
1313     /// min(Src, Dst)
1314     Min = 3,
1315     /// max(Src, Dst)
1316     Max = 4,
1319 impl Default for BlendOperation {
1320     fn default() -> Self {
1321         Self::Add
1322     }
1325 /// Describes a blend component of a [`BlendState`].
1327 /// Corresponds to [WebGPU `GPUBlendComponent`](
1328 /// https://gpuweb.github.io/gpuweb/#dictdef-gpublendcomponent).
1329 #[repr(C)]
1330 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
1331 #[cfg_attr(feature = "trace", derive(Serialize))]
1332 #[cfg_attr(feature = "replay", derive(Deserialize))]
1333 #[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
1334 pub struct BlendComponent {
1335     /// Multiplier for the source, which is produced by the fragment shader.
1336     pub src_factor: BlendFactor,
1337     /// Multiplier for the destination, which is stored in the target.
1338     pub dst_factor: BlendFactor,
1339     /// The binary operation applied to the source and destination,
1340     /// multiplied by their respective factors.
1341     pub operation: BlendOperation,
1344 impl BlendComponent {
1345     /// Default blending state that replaces destination with the source.
1346     pub const REPLACE: Self = Self {
1347         src_factor: BlendFactor::One,
1348         dst_factor: BlendFactor::Zero,
1349         operation: BlendOperation::Add,
1350     };
1352     /// Blend state of (1 * src) + ((1 - src_alpha) * dst)
1353     pub const OVER: Self = Self {
1354         src_factor: BlendFactor::One,
1355         dst_factor: BlendFactor::OneMinusSrcAlpha,
1356         operation: BlendOperation::Add,
1357     };
1359     /// Returns true if the state relies on the constant color, which is
1360     /// set independently on a render command encoder.
1361     pub fn uses_constant(&self) -> bool {
1362         match (self.src_factor, self.dst_factor) {
1363             (BlendFactor::Constant, _)
1364             | (BlendFactor::OneMinusConstant, _)
1365             | (_, BlendFactor::Constant)
1366             | (_, BlendFactor::OneMinusConstant) => true,
1367             (_, _) => false,
1368         }
1369     }
1372 impl Default for BlendComponent {
1373     fn default() -> Self {
1374         Self::REPLACE
1375     }
1378 /// Describe the blend state of a render pipeline,
1379 /// within [`ColorTargetState`].
1381 /// See the OpenGL or Vulkan spec for more information.
1383 /// Corresponds to [WebGPU `GPUBlendState`](
1384 /// https://gpuweb.github.io/gpuweb/#dictdef-gpublendstate).
1385 #[repr(C)]
1386 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
1387 #[cfg_attr(feature = "trace", derive(Serialize))]
1388 #[cfg_attr(feature = "replay", derive(Deserialize))]
1389 #[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
1390 pub struct BlendState {
1391     /// Color equation.
1392     pub color: BlendComponent,
1393     /// Alpha equation.
1394     pub alpha: BlendComponent,
1397 impl BlendState {
1398     /// Blend mode that does no color blending, just overwrites the output with the contents of the shader.
1399     pub const REPLACE: Self = Self {
1400         color: BlendComponent::REPLACE,
1401         alpha: BlendComponent::REPLACE,
1402     };
1404     /// Blend mode that does standard alpha blending with non-premultiplied alpha.
1405     pub const ALPHA_BLENDING: Self = Self {
1406         color: BlendComponent {
1407             src_factor: BlendFactor::SrcAlpha,
1408             dst_factor: BlendFactor::OneMinusSrcAlpha,
1409             operation: BlendOperation::Add,
1410         },
1411         alpha: BlendComponent::OVER,
1412     };
1414     /// Blend mode that does standard alpha blending with premultiplied alpha.
1415     pub const PREMULTIPLIED_ALPHA_BLENDING: Self = Self {
1416         color: BlendComponent::OVER,
1417         alpha: BlendComponent::OVER,
1418     };
1421 /// Describes the color state of a render pipeline.
1423 /// Corresponds to [WebGPU `GPUColorTargetState`](
1424 /// https://gpuweb.github.io/gpuweb/#dictdef-gpucolortargetstate).
1425 #[repr(C)]
1426 #[derive(Clone, Debug, PartialEq, Eq, Hash)]
1427 #[cfg_attr(feature = "trace", derive(Serialize))]
1428 #[cfg_attr(feature = "replay", derive(Deserialize))]
1429 #[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
1430 pub struct ColorTargetState {
1431     /// The [`TextureFormat`] of the image that this pipeline will render to. Must match the the format
1432     /// of the corresponding color attachment in [`CommandEncoder::begin_render_pass`][CEbrp]
1433     ///
1434     /// [CEbrp]: ../wgpu/struct.CommandEncoder.html#method.begin_render_pass
1435     pub format: TextureFormat,
1436     /// The blending that is used for this pipeline.
1437     #[cfg_attr(feature = "serde", serde(default))]
1438     pub blend: Option<BlendState>,
1439     /// Mask which enables/disables writes to different color/alpha channel.
1440     #[cfg_attr(feature = "serde", serde(default))]
1441     pub write_mask: ColorWrites,
1444 impl From<TextureFormat> for ColorTargetState {
1445     fn from(format: TextureFormat) -> Self {
1446         Self {
1447             format,
1448             blend: None,
1449             write_mask: ColorWrites::ALL,
1450         }
1451     }
1454 /// Primitive type the input mesh is composed of.
1456 /// Corresponds to [WebGPU `GPUPrimitiveTopology`](
1457 /// https://gpuweb.github.io/gpuweb/#enumdef-gpuprimitivetopology).
1458 #[repr(C)]
1459 #[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
1460 #[cfg_attr(feature = "trace", derive(Serialize))]
1461 #[cfg_attr(feature = "replay", derive(Deserialize))]
1462 #[cfg_attr(feature = "serde", serde(rename_all = "kebab-case"))]
1463 pub enum PrimitiveTopology {
1464     /// Vertex data is a list of points. Each vertex is a new point.
1465     PointList = 0,
1466     /// Vertex data is a list of lines. Each pair of vertices composes a new line.
1467     ///
1468     /// Vertices `0 1 2 3` create two lines `0 1` and `2 3`
1469     LineList = 1,
1470     /// Vertex data is a strip of lines. Each set of two adjacent vertices form a line.
1471     ///
1472     /// Vertices `0 1 2 3` create three lines `0 1`, `1 2`, and `2 3`.
1473     LineStrip = 2,
1474     /// Vertex data is a list of triangles. Each set of 3 vertices composes a new triangle.
1475     ///
1476     /// Vertices `0 1 2 3 4 5` create two triangles `0 1 2` and `3 4 5`
1477     TriangleList = 3,
1478     /// Vertex data is a triangle strip. Each set of three adjacent vertices form a triangle.
1479     ///
1480     /// Vertices `0 1 2 3 4 5` creates four triangles `0 1 2`, `2 1 3`, `2 3 4`, and `4 3 5`
1481     TriangleStrip = 4,
1484 impl Default for PrimitiveTopology {
1485     fn default() -> Self {
1486         PrimitiveTopology::TriangleList
1487     }
1490 impl PrimitiveTopology {
1491     /// Returns true for strip topologies.
1492     pub fn is_strip(&self) -> bool {
1493         match *self {
1494             Self::PointList | Self::LineList | Self::TriangleList => false,
1495             Self::LineStrip | Self::TriangleStrip => true,
1496         }
1497     }
1500 /// Vertex winding order which classifies the "front" face of a triangle.
1502 /// Corresponds to [WebGPU `GPUFrontFace`](
1503 /// https://gpuweb.github.io/gpuweb/#enumdef-gpufrontface).
1504 #[repr(C)]
1505 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
1506 #[cfg_attr(feature = "trace", derive(Serialize))]
1507 #[cfg_attr(feature = "replay", derive(Deserialize))]
1508 #[cfg_attr(feature = "serde", serde(rename_all = "kebab-case"))]
1509 pub enum FrontFace {
1510     /// Triangles with vertices in counter clockwise order are considered the front face.
1511     ///
1512     /// This is the default with right handed coordinate spaces.
1513     Ccw = 0,
1514     /// Triangles with vertices in clockwise order are considered the front face.
1515     ///
1516     /// This is the default with left handed coordinate spaces.
1517     Cw = 1,
1520 impl Default for FrontFace {
1521     fn default() -> Self {
1522         Self::Ccw
1523     }
1526 /// Face of a vertex.
1528 /// Corresponds to [WebGPU `GPUCullMode`](
1529 /// https://gpuweb.github.io/gpuweb/#enumdef-gpucullmode),
1530 /// except that the `"none"` value is represented using `Option<Face>` instead.
1531 #[repr(C)]
1532 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
1533 #[cfg_attr(feature = "trace", derive(Serialize))]
1534 #[cfg_attr(feature = "replay", derive(Deserialize))]
1535 #[cfg_attr(feature = "serde", serde(rename_all = "kebab-case"))]
1536 pub enum Face {
1537     /// Front face
1538     Front = 0,
1539     /// Back face
1540     Back = 1,
1543 /// Type of drawing mode for polygons
1544 #[repr(C)]
1545 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
1546 #[cfg_attr(feature = "trace", derive(Serialize))]
1547 #[cfg_attr(feature = "replay", derive(Deserialize))]
1548 #[cfg_attr(feature = "serde", serde(rename_all = "kebab-case"))]
1549 pub enum PolygonMode {
1550     /// Polygons are filled
1551     Fill = 0,
1552     /// Polygons are drawn as line segments
1553     Line = 1,
1554     /// Polygons are drawn as points
1555     Point = 2,
1558 impl Default for PolygonMode {
1559     fn default() -> Self {
1560         Self::Fill
1561     }
1564 /// Describes the state of primitive assembly and rasterization in a render pipeline.
1566 /// Corresponds to [WebGPU `GPUPrimitiveState`](
1567 /// https://gpuweb.github.io/gpuweb/#dictdef-gpuprimitivestate).
1568 #[repr(C)]
1569 #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
1570 #[cfg_attr(feature = "trace", derive(Serialize))]
1571 #[cfg_attr(feature = "replay", derive(Deserialize))]
1572 #[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
1573 pub struct PrimitiveState {
1574     /// The primitive topology used to interpret vertices.
1575     pub topology: PrimitiveTopology,
1576     /// When drawing strip topologies with indices, this is the required format for the index buffer.
1577     /// This has no effect on non-indexed or non-strip draws.
1578     #[cfg_attr(feature = "serde", serde(default))]
1579     pub strip_index_format: Option<IndexFormat>,
1580     /// The face to consider the front for the purpose of culling and stencil operations.
1581     #[cfg_attr(feature = "serde", serde(default))]
1582     pub front_face: FrontFace,
1583     /// The face culling mode.
1584     #[cfg_attr(feature = "serde", serde(default))]
1585     pub cull_mode: Option<Face>,
1586     /// If set to true, the polygon depth is not clipped to 0-1 before rasterization.
1587     ///
1588     /// Enabling this requires `Features::DEPTH_CLIP_CONTROL` to be enabled.
1589     #[cfg_attr(feature = "serde", serde(default))]
1590     pub unclipped_depth: bool,
1591     /// Controls the way each polygon is rasterized. Can be either `Fill` (default), `Line` or `Point`
1592     ///
1593     /// Setting this to `Line` requires `Features::POLYGON_MODE_LINE` to be enabled.
1594     ///
1595     /// Setting this to `Point` requires `Features::POLYGON_MODE_POINT` to be enabled.
1596     #[cfg_attr(feature = "serde", serde(default))]
1597     pub polygon_mode: PolygonMode,
1598     /// If set to true, the primitives are rendered with conservative overestimation. I.e. any rastered pixel touched by it is filled.
1599     /// Only valid for PolygonMode::Fill!
1600     ///
1601     /// Enabling this requires `Features::CONSERVATIVE_RASTERIZATION` to be enabled.
1602     pub conservative: bool,
1605 /// Describes the multi-sampling state of a render pipeline.
1607 /// Corresponds to [WebGPU `GPUMultisampleState`](
1608 /// https://gpuweb.github.io/gpuweb/#dictdef-gpumultisamplestate).
1609 #[repr(C)]
1610 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
1611 #[cfg_attr(feature = "trace", derive(Serialize))]
1612 #[cfg_attr(feature = "replay", derive(Deserialize))]
1613 #[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
1614 pub struct MultisampleState {
1615     /// The number of samples calculated per pixel (for MSAA). For non-multisampled textures,
1616     /// this should be `1`
1617     pub count: u32,
1618     /// Bitmask that restricts the samples of a pixel modified by this pipeline. All samples
1619     /// can be enabled using the value `!0`
1620     pub mask: u64,
1621     /// When enabled, produces another sample mask per pixel based on the alpha output value, that
1622     /// is ANDed with the sample_mask and the primitive coverage to restrict the set of samples
1623     /// affected by a primitive.
1624     ///
1625     /// The implicit mask produced for alpha of zero is guaranteed to be zero, and for alpha of one
1626     /// is guaranteed to be all 1-s.
1627     pub alpha_to_coverage_enabled: bool,
1630 impl Default for MultisampleState {
1631     fn default() -> Self {
1632         MultisampleState {
1633             count: 1,
1634             mask: !0,
1635             alpha_to_coverage_enabled: false,
1636         }
1637     }
1640 bitflags::bitflags! {
1641     /// Feature flags for a texture format.
1642     #[repr(transparent)]
1643     pub struct TextureFormatFeatureFlags: u32 {
1644         /// If not present, the texture can't be sampled with a filtering sampler.
1645         /// This may overwrite TextureSampleType::Float.filterable
1646         const FILTERABLE = 1 << 0;
1647         /// Allows [`TextureDescriptor::sample_count`] greater than `1`.
1648         const MULTISAMPLE = 1 << 1;
1649         /// Allows a texture of this format to back a view passed as `resolve_target`
1650         /// to a render pass for an automatic driver-implemented resolve.
1651         const MULTISAMPLE_RESOLVE = 1 << 2;
1652         /// When used as a STORAGE texture, then a texture with this format can be bound with
1653         /// [`StorageTextureAccess::ReadOnly`] or [`StorageTextureAccess::ReadWrite`].
1654         const STORAGE_READ_WRITE = 1 << 3;
1655         /// When used as a STORAGE texture, then a texture with this format can be written to with atomics.
1656         // TODO: No access flag exposed as of writing
1657         const STORAGE_ATOMICS = 1 << 4;
1658     }
1661 #[cfg(feature = "bitflags_serde_shim")]
1662 bitflags_serde_shim::impl_serde_for_bitflags!(TextureFormatFeatureFlags);
1664 /// Features supported by a given texture format
1666 /// Features are defined by WebGPU specification unless `Features::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES` is enabled.
1667 #[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
1668 pub struct TextureFormatFeatures {
1669     /// Valid bits for `TextureDescriptor::Usage` provided for format creation.
1670     pub allowed_usages: TextureUsages,
1671     /// Additional property flags for the format.
1672     pub flags: TextureFormatFeatureFlags,
1675 /// Information about a texture format.
1676 #[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
1677 pub struct TextureFormatInfo {
1678     /// Features required (if any) to use the texture.
1679     pub required_features: Features,
1680     /// Type of sampling that is valid for the texture.
1681     pub sample_type: TextureSampleType,
1682     /// Dimension of a "block" of texels. This is always (1, 1) on uncompressed textures.
1683     pub block_dimensions: (u8, u8),
1684     /// Size in bytes of a "block" of texels. This is the size per pixel on uncompressed textures.
1685     pub block_size: u8,
1686     /// Count of components in the texture. This determines which components there will be actual data in the shader for.
1687     pub components: u8,
1688     /// Format will have colors be converted from srgb to linear on read and from linear to srgb on write.
1689     pub srgb: bool,
1690     /// Format features guaranteed by the WebGPU spec. Additional features are available if `Features::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES` is enabled.
1691     pub guaranteed_format_features: TextureFormatFeatures,
1694 impl TextureFormatInfo {
1695     /// Return `true` for compressed formats.
1696     pub fn is_compressed(&self) -> bool {
1697         self.block_dimensions != (1, 1)
1698     }
1701 /// ASTC block dimensions
1702 #[repr(C)]
1703 #[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
1704 #[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
1705 pub enum AstcBlock {
1706     /// 4x4 block compressed texture. 16 bytes per block (8 bit/px).
1707     B4x4,
1708     /// 5x4 block compressed texture. 16 bytes per block (6.4 bit/px).
1709     B5x4,
1710     /// 5x5 block compressed texture. 16 bytes per block (5.12 bit/px).
1711     B5x5,
1712     /// 6x5 block compressed texture. 16 bytes per block (4.27 bit/px).
1713     B6x5,
1714     /// 6x6 block compressed texture. 16 bytes per block (3.56 bit/px).
1715     B6x6,
1716     /// 8x5 block compressed texture. 16 bytes per block (3.2 bit/px).
1717     B8x5,
1718     /// 8x6 block compressed texture. 16 bytes per block (2.67 bit/px).
1719     B8x6,
1720     /// 8x8 block compressed texture. 16 bytes per block (2 bit/px).
1721     B8x8,
1722     /// 10x5 block compressed texture. 16 bytes per block (2.56 bit/px).
1723     B10x5,
1724     /// 10x6 block compressed texture. 16 bytes per block (2.13 bit/px).
1725     B10x6,
1726     /// 10x8 block compressed texture. 16 bytes per block (1.6 bit/px).
1727     B10x8,
1728     /// 10x10 block compressed texture. 16 bytes per block (1.28 bit/px).
1729     B10x10,
1730     /// 12x10 block compressed texture. 16 bytes per block (1.07 bit/px).
1731     B12x10,
1732     /// 12x12 block compressed texture. 16 bytes per block (0.89 bit/px).
1733     B12x12,
1736 /// ASTC RGBA channel
1737 #[repr(C)]
1738 #[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
1739 #[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
1740 pub enum AstcChannel {
1741     /// 8 bit integer RGBA, [0, 255] converted to/from linear-color float [0, 1] in shader.
1742     ///
1743     /// [`Features::TEXTURE_COMPRESSION_ASTC_LDR`] must be enabled to use this channel.
1744     Unorm,
1745     /// 8 bit integer RGBA, Srgb-color [0, 255] converted to/from linear-color float [0, 1] in shader.
1746     ///
1747     /// [`Features::TEXTURE_COMPRESSION_ASTC_LDR`] must be enabled to use this channel.
1748     UnormSrgb,
1749     /// floating-point RGBA, linear-color float can be outside of the [0, 1] range.
1750     ///
1751     /// [`Features::TEXTURE_COMPRESSION_ASTC_HDR`] must be enabled to use this channel.
1752     Hdr,
1755 /// Underlying texture data format.
1757 /// If there is a conversion in the format (such as srgb -> linear), the conversion listed here is for
1758 /// loading from texture in a shader. When writing to the texture, the opposite conversion takes place.
1760 /// Corresponds to [WebGPU `GPUTextureFormat`](
1761 /// https://gpuweb.github.io/gpuweb/#enumdef-gputextureformat).
1762 #[repr(C)]
1763 #[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
1764 #[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
1765 pub enum TextureFormat {
1766     // Normal 8 bit formats
1767     /// Red channel only. 8 bit integer per channel. [0, 255] converted to/from float [0, 1] in shader.
1768     #[cfg_attr(feature = "serde", serde(rename = "r8unorm"))]
1769     R8Unorm,
1770     /// Red channel only. 8 bit integer per channel. [-127, 127] converted to/from float [-1, 1] in shader.
1771     #[cfg_attr(feature = "serde", serde(rename = "r8snorm"))]
1772     R8Snorm,
1773     /// Red channel only. 8 bit integer per channel. Unsigned in shader.
1774     #[cfg_attr(feature = "serde", serde(rename = "r8uint"))]
1775     R8Uint,
1776     /// Red channel only. 8 bit integer per channel. Signed in shader.
1777     #[cfg_attr(feature = "serde", serde(rename = "r8sint"))]
1778     R8Sint,
1780     // Normal 16 bit formats
1781     /// Red channel only. 16 bit integer per channel. Unsigned in shader.
1782     #[cfg_attr(feature = "serde", serde(rename = "r16uint"))]
1783     R16Uint,
1784     /// Red channel only. 16 bit integer per channel. Signed in shader.
1785     #[cfg_attr(feature = "serde", serde(rename = "r16sint"))]
1786     R16Sint,
1787     /// Red channel only. 16 bit integer per channel. [0, 65535] converted to/from float [0, 1] in shader.
1788     ///
1789     /// [`Features::TEXTURE_FORMAT_16BIT_NORM`] must be enabled to use this texture format.
1790     #[cfg_attr(feature = "serde", serde(rename = "r16unorm"))]
1791     R16Unorm,
1792     /// Red channel only. 16 bit integer per channel. [0, 65535] converted to/from float [-1, 1] in shader.
1793     ///
1794     /// [`Features::TEXTURE_FORMAT_16BIT_NORM`] must be enabled to use this texture format.
1795     #[cfg_attr(feature = "serde", serde(rename = "r16snorm"))]
1796     R16Snorm,
1797     /// Red channel only. 16 bit float per channel. Float in shader.
1798     #[cfg_attr(feature = "serde", serde(rename = "r16float"))]
1799     R16Float,
1800     /// Red and green channels. 8 bit integer per channel. [0, 255] converted to/from float [0, 1] in shader.
1801     #[cfg_attr(feature = "serde", serde(rename = "rg8unorm"))]
1802     Rg8Unorm,
1803     /// Red and green channels. 8 bit integer per channel. [-127, 127] converted to/from float [-1, 1] in shader.
1804     #[cfg_attr(feature = "serde", serde(rename = "rg8snorm"))]
1805     Rg8Snorm,
1806     /// Red and green channels. 8 bit integer per channel. Unsigned in shader.
1807     #[cfg_attr(feature = "serde", serde(rename = "rg8uint"))]
1808     Rg8Uint,
1809     /// Red and green channels. 8 bit integer per channel. Signed in shader.
1810     #[cfg_attr(feature = "serde", serde(rename = "rg8sint"))]
1811     Rg8Sint,
1813     // Normal 32 bit formats
1814     /// Red channel only. 32 bit integer per channel. Unsigned in shader.
1815     #[cfg_attr(feature = "serde", serde(rename = "r32uint"))]
1816     R32Uint,
1817     /// Red channel only. 32 bit integer per channel. Signed in shader.
1818     #[cfg_attr(feature = "serde", serde(rename = "r32sint"))]
1819     R32Sint,
1820     /// Red channel only. 32 bit float per channel. Float in shader.
1821     #[cfg_attr(feature = "serde", serde(rename = "r32float"))]
1822     R32Float,
1823     /// Red and green channels. 16 bit integer per channel. Unsigned in shader.
1824     #[cfg_attr(feature = "serde", serde(rename = "rg16uint"))]
1825     Rg16Uint,
1826     /// Red and green channels. 16 bit integer per channel. Signed in shader.
1827     #[cfg_attr(feature = "serde", serde(rename = "rg16sint"))]
1828     Rg16Sint,
1829     /// Red and green channels. 16 bit integer per channel. [0, 65535] converted to/from float [0, 1] in shader.
1830     ///
1831     /// [`Features::TEXTURE_FORMAT_16BIT_NORM`] must be enabled to use this texture format.
1832     #[cfg_attr(feature = "serde", serde(rename = "rg16unorm"))]
1833     Rg16Unorm,
1834     /// Red and green channels. 16 bit integer per channel. [0, 65535] converted to/from float [-1, 1] in shader.
1835     ///
1836     /// [`Features::TEXTURE_FORMAT_16BIT_NORM`] must be enabled to use this texture format.
1837     #[cfg_attr(feature = "serde", serde(rename = "rg16snorm"))]
1838     Rg16Snorm,
1839     /// Red and green channels. 16 bit float per channel. Float in shader.
1840     #[cfg_attr(feature = "serde", serde(rename = "rg16float"))]
1841     Rg16Float,
1842     /// Red, green, blue, and alpha channels. 8 bit integer per channel. [0, 255] converted to/from float [0, 1] in shader.
1843     #[cfg_attr(feature = "serde", serde(rename = "rgba8unorm"))]
1844     Rgba8Unorm,
1845     /// Red, green, blue, and alpha channels. 8 bit integer per channel. Srgb-color [0, 255] converted to/from linear-color float [0, 1] in shader.
1846     #[cfg_attr(feature = "serde", serde(rename = "rgba8unorm-srgb"))]
1847     Rgba8UnormSrgb,
1848     /// Red, green, blue, and alpha channels. 8 bit integer per channel. [-127, 127] converted to/from float [-1, 1] in shader.
1849     #[cfg_attr(feature = "serde", serde(rename = "rgba8snorm"))]
1850     Rgba8Snorm,
1851     /// Red, green, blue, and alpha channels. 8 bit integer per channel. Unsigned in shader.
1852     #[cfg_attr(feature = "serde", serde(rename = "rgba8uint"))]
1853     Rgba8Uint,
1854     /// Red, green, blue, and alpha channels. 8 bit integer per channel. Signed in shader.
1855     #[cfg_attr(feature = "serde", serde(rename = "rgba8sint"))]
1856     Rgba8Sint,
1857     /// Blue, green, red, and alpha channels. 8 bit integer per channel. [0, 255] converted to/from float [0, 1] in shader.
1858     #[cfg_attr(feature = "serde", serde(rename = "bgra8unorm"))]
1859     Bgra8Unorm,
1860     /// Blue, green, red, and alpha channels. 8 bit integer per channel. Srgb-color [0, 255] converted to/from linear-color float [0, 1] in shader.
1861     #[cfg_attr(feature = "serde", serde(rename = "bgra8unorm-srgb"))]
1862     Bgra8UnormSrgb,
1864     // Packed 32 bit formats
1865     /// Red, green, blue, and alpha channels. 10 bit integer for RGB channels, 2 bit integer for alpha channel. [0, 1023] ([0, 3] for alpha) converted to/from float [0, 1] in shader.
1866     #[cfg_attr(feature = "serde", serde(rename = "rgb10a2unorm"))]
1867     Rgb10a2Unorm,
1868     /// Red, green, and blue channels. 11 bit float with no sign bit for RG channels. 10 bit float with no sign bit for blue channel. Float in shader.
1869     #[cfg_attr(feature = "serde", serde(rename = "rg11b10ufloat"))]
1870     Rg11b10Float,
1872     // Normal 64 bit formats
1873     /// Red and green channels. 32 bit integer per channel. Unsigned in shader.
1874     #[cfg_attr(feature = "serde", serde(rename = "rg32uint"))]
1875     Rg32Uint,
1876     /// Red and green channels. 32 bit integer per channel. Signed in shader.
1877     #[cfg_attr(feature = "serde", serde(rename = "rg32sint"))]
1878     Rg32Sint,
1879     /// Red and green channels. 32 bit float per channel. Float in shader.
1880     #[cfg_attr(feature = "serde", serde(rename = "rg32float"))]
1881     Rg32Float,
1882     /// Red, green, blue, and alpha channels. 16 bit integer per channel. Unsigned in shader.
1883     #[cfg_attr(feature = "serde", serde(rename = "rgba16uint"))]
1884     Rgba16Uint,
1885     /// Red, green, blue, and alpha channels. 16 bit integer per channel. Signed in shader.
1886     #[cfg_attr(feature = "serde", serde(rename = "rgba16sint"))]
1887     Rgba16Sint,
1888     /// Red, green, blue, and alpha channels. 16 bit integer per channel. [0, 65535] converted to/from float [0, 1] in shader.
1889     ///
1890     /// [`Features::TEXTURE_FORMAT_16BIT_NORM`] must be enabled to use this texture format.
1891     #[cfg_attr(feature = "serde", serde(rename = "rgba16unorm"))]
1892     Rgba16Unorm,
1893     /// Red, green, blue, and alpha. 16 bit integer per channel. [0, 65535] converted to/from float [-1, 1] in shader.
1894     ///
1895     /// [`Features::TEXTURE_FORMAT_16BIT_NORM`] must be enabled to use this texture format.
1896     #[cfg_attr(feature = "serde", serde(rename = "rgba16snorm"))]
1897     Rgba16Snorm,
1898     /// Red, green, blue, and alpha channels. 16 bit float per channel. Float in shader.
1899     #[cfg_attr(feature = "serde", serde(rename = "rgba16float"))]
1900     Rgba16Float,
1902     // Normal 128 bit formats
1903     /// Red, green, blue, and alpha channels. 32 bit integer per channel. Unsigned in shader.
1904     #[cfg_attr(feature = "serde", serde(rename = "rgba32uint"))]
1905     Rgba32Uint,
1906     /// Red, green, blue, and alpha channels. 32 bit integer per channel. Signed in shader.
1907     #[cfg_attr(feature = "serde", serde(rename = "rgba32sint"))]
1908     Rgba32Sint,
1909     /// Red, green, blue, and alpha channels. 32 bit float per channel. Float in shader.
1910     #[cfg_attr(feature = "serde", serde(rename = "rgba32float"))]
1911     Rgba32Float,
1913     // Depth and stencil formats
1914     /// Special depth format with 32 bit floating point depth.
1915     #[cfg_attr(feature = "serde", serde(rename = "depth32float"))]
1916     Depth32Float,
1917     /// Special depth/stencil format with 32 bit floating point depth and 8 bits integer stencil.
1918     #[cfg_attr(feature = "serde", serde(rename = "depth32float-stencil8"))]
1919     Depth32FloatStencil8,
1920     /// Special depth format with at least 24 bit integer depth.
1921     #[cfg_attr(feature = "serde", serde(rename = "depth24plus"))]
1922     Depth24Plus,
1923     /// Special depth/stencil format with at least 24 bit integer depth and 8 bits integer stencil.
1924     #[cfg_attr(feature = "serde", serde(rename = "depth24plus-stencil8"))]
1925     Depth24PlusStencil8,
1926     /// Special depth/stencil format with 24 bit integer depth and 8 bits integer stencil.
1927     #[cfg_attr(feature = "serde", serde(rename = "depth24unorm-stencil8"))]
1928     Depth24UnormStencil8,
1930     // Packed uncompressed texture formats
1931     /// Packed unsigned float with 9 bits mantisa for each RGB component, then a common 5 bits exponent
1932     #[cfg_attr(feature = "serde", serde(rename = "rgb9e5ufloat"))]
1933     Rgb9e5Ufloat,
1935     // Compressed textures usable with `TEXTURE_COMPRESSION_BC` feature.
1936     /// 4x4 block compressed texture. 8 bytes per block (4 bit/px). 4 color + alpha pallet. 5 bit R + 6 bit G + 5 bit B + 1 bit alpha.
1937     /// [0, 63] ([0, 1] for alpha) converted to/from float [0, 1] in shader.
1938     ///
1939     /// Also known as DXT1.
1940     ///
1941     /// [`Features::TEXTURE_COMPRESSION_BC`] must be enabled to use this texture format.
1942     #[cfg_attr(feature = "serde", serde(rename = "bc1-rgba-unorm"))]
1943     Bc1RgbaUnorm,
1944     /// 4x4 block compressed texture. 8 bytes per block (4 bit/px). 4 color + alpha pallet. 5 bit R + 6 bit G + 5 bit B + 1 bit alpha.
1945     /// Srgb-color [0, 63] ([0, 1] for alpha) converted to/from linear-color float [0, 1] in shader.
1946     ///
1947     /// Also known as DXT1.
1948     ///
1949     /// [`Features::TEXTURE_COMPRESSION_BC`] must be enabled to use this texture format.
1950     #[cfg_attr(feature = "serde", serde(rename = "bc1-rgba-unorm-srgb"))]
1951     Bc1RgbaUnormSrgb,
1952     /// 4x4 block compressed texture. 16 bytes per block (8 bit/px). 4 color pallet. 5 bit R + 6 bit G + 5 bit B + 4 bit alpha.
1953     /// [0, 63] ([0, 15] for alpha) converted to/from float [0, 1] in shader.
1954     ///
1955     /// Also known as DXT3.
1956     ///
1957     /// [`Features::TEXTURE_COMPRESSION_BC`] must be enabled to use this texture format.
1958     #[cfg_attr(feature = "serde", serde(rename = "bc2-rgba-unorm"))]
1959     Bc2RgbaUnorm,
1960     /// 4x4 block compressed texture. 16 bytes per block (8 bit/px). 4 color pallet. 5 bit R + 6 bit G + 5 bit B + 4 bit alpha.
1961     /// Srgb-color [0, 63] ([0, 255] for alpha) converted to/from linear-color float [0, 1] in shader.
1962     ///
1963     /// Also known as DXT3.
1964     ///
1965     /// [`Features::TEXTURE_COMPRESSION_BC`] must be enabled to use this texture format.
1966     #[cfg_attr(feature = "serde", serde(rename = "bc2-rgba-unorm-srgb"))]
1967     Bc2RgbaUnormSrgb,
1968     /// 4x4 block compressed texture. 16 bytes per block (8 bit/px). 4 color pallet + 8 alpha pallet. 5 bit R + 6 bit G + 5 bit B + 8 bit alpha.
1969     /// [0, 63] ([0, 255] for alpha) converted to/from float [0, 1] in shader.
1970     ///
1971     /// Also known as DXT5.
1972     ///
1973     /// [`Features::TEXTURE_COMPRESSION_BC`] must be enabled to use this texture format.
1974     #[cfg_attr(feature = "serde", serde(rename = "bc3-rgba-unorm"))]
1975     Bc3RgbaUnorm,
1976     /// 4x4 block compressed texture. 16 bytes per block (8 bit/px). 4 color pallet + 8 alpha pallet. 5 bit R + 6 bit G + 5 bit B + 8 bit alpha.
1977     /// Srgb-color [0, 63] ([0, 255] for alpha) converted to/from linear-color float [0, 1] in shader.
1978     ///
1979     /// Also known as DXT5.
1980     ///
1981     /// [`Features::TEXTURE_COMPRESSION_BC`] must be enabled to use this texture format.
1982     #[cfg_attr(feature = "serde", serde(rename = "bc3-rgba-unorm-srgb"))]
1983     Bc3RgbaUnormSrgb,
1984     /// 4x4 block compressed texture. 8 bytes per block (4 bit/px). 8 color pallet. 8 bit R.
1985     /// [0, 255] converted to/from float [0, 1] in shader.
1986     ///
1987     /// Also known as RGTC1.
1988     ///
1989     /// [`Features::TEXTURE_COMPRESSION_BC`] must be enabled to use this texture format.
1990     #[cfg_attr(feature = "serde", serde(rename = "bc4-r-unorm"))]
1991     Bc4RUnorm,
1992     /// 4x4 block compressed texture. 8 bytes per block (4 bit/px). 8 color pallet. 8 bit R.
1993     /// [-127, 127] converted to/from float [-1, 1] in shader.
1994     ///
1995     /// Also known as RGTC1.
1996     ///
1997     /// [`Features::TEXTURE_COMPRESSION_BC`] must be enabled to use this texture format.
1998     #[cfg_attr(feature = "serde", serde(rename = "bc4-r-snorm"))]
1999     Bc4RSnorm,
2000     /// 4x4 block compressed texture. 16 bytes per block (8 bit/px). 8 color red pallet + 8 color green pallet. 8 bit RG.
2001     /// [0, 255] converted to/from float [0, 1] in shader.
2002     ///
2003     /// Also known as RGTC2.
2004     ///
2005     /// [`Features::TEXTURE_COMPRESSION_BC`] must be enabled to use this texture format.
2006     #[cfg_attr(feature = "serde", serde(rename = "bc5-rg-unorm"))]
2007     Bc5RgUnorm,
2008     /// 4x4 block compressed texture. 16 bytes per block (8 bit/px). 8 color red pallet + 8 color green pallet. 8 bit RG.
2009     /// [-127, 127] converted to/from float [-1, 1] in shader.
2010     ///
2011     /// Also known as RGTC2.
2012     ///
2013     /// [`Features::TEXTURE_COMPRESSION_BC`] must be enabled to use this texture format.
2014     #[cfg_attr(feature = "serde", serde(rename = "bc5-rg-snorm"))]
2015     Bc5RgSnorm,
2016     /// 4x4 block compressed texture. 16 bytes per block (8 bit/px). Variable sized pallet. 16 bit unsigned float RGB. Float in shader.
2017     ///
2018     /// Also known as BPTC (float).
2019     ///
2020     /// [`Features::TEXTURE_COMPRESSION_BC`] must be enabled to use this texture format.
2021     #[cfg_attr(feature = "serde", serde(rename = "bc6h-rgb-ufloat"))]
2022     Bc6hRgbUfloat,
2023     /// 4x4 block compressed texture. 16 bytes per block (8 bit/px). Variable sized pallet. 16 bit signed float RGB. Float in shader.
2024     ///
2025     /// Also known as BPTC (float).
2026     ///
2027     /// [`Features::TEXTURE_COMPRESSION_BC`] must be enabled to use this texture format.
2028     #[cfg_attr(feature = "serde", serde(rename = "bc6h-rgb-float"))]
2029     Bc6hRgbSfloat,
2030     /// 4x4 block compressed texture. 16 bytes per block (8 bit/px). Variable sized pallet. 8 bit integer RGBA.
2031     /// [0, 255] converted to/from float [0, 1] in shader.
2032     ///
2033     /// Also known as BPTC (unorm).
2034     ///
2035     /// [`Features::TEXTURE_COMPRESSION_BC`] must be enabled to use this texture format.
2036     #[cfg_attr(feature = "serde", serde(rename = "bc7-rgba-unorm"))]
2037     Bc7RgbaUnorm,
2038     /// 4x4 block compressed texture. 16 bytes per block (8 bit/px). Variable sized pallet. 8 bit integer RGBA.
2039     /// Srgb-color [0, 255] converted to/from linear-color float [0, 1] in shader.
2040     ///
2041     /// Also known as BPTC (unorm).
2042     ///
2043     /// [`Features::TEXTURE_COMPRESSION_BC`] must be enabled to use this texture format.
2044     #[cfg_attr(feature = "serde", serde(rename = "bc7-rgba-unorm-srgb"))]
2045     Bc7RgbaUnormSrgb,
2046     /// 4x4 block compressed texture. 8 bytes per block (4 bit/px). Complex pallet. 8 bit integer RGB.
2047     /// [0, 255] converted to/from float [0, 1] in shader.
2048     ///
2049     /// [`Features::TEXTURE_COMPRESSION_ETC2`] must be enabled to use this texture format.
2050     #[cfg_attr(feature = "serde", serde(rename = "etc2-rgb8unorm"))]
2051     Etc2Rgb8Unorm,
2052     /// 4x4 block compressed texture. 8 bytes per block (4 bit/px). Complex pallet. 8 bit integer RGB.
2053     /// Srgb-color [0, 255] converted to/from linear-color float [0, 1] in shader.
2054     ///
2055     /// [`Features::TEXTURE_COMPRESSION_ETC2`] must be enabled to use this texture format.
2056     #[cfg_attr(feature = "serde", serde(rename = "etc2-rgb8unorm-srgb"))]
2057     Etc2Rgb8UnormSrgb,
2058     /// 4x4 block compressed texture. 8 bytes per block (4 bit/px). Complex pallet. 8 bit integer RGB + 1 bit alpha.
2059     /// [0, 255] ([0, 1] for alpha) converted to/from float [0, 1] in shader.
2060     ///
2061     /// [`Features::TEXTURE_COMPRESSION_ETC2`] must be enabled to use this texture format.
2062     #[cfg_attr(feature = "serde", serde(rename = "etc2-rgb8a1unorm"))]
2063     Etc2Rgb8A1Unorm,
2064     /// 4x4 block compressed texture. 8 bytes per block (4 bit/px). Complex pallet. 8 bit integer RGB + 1 bit alpha.
2065     /// Srgb-color [0, 255] ([0, 1] for alpha) converted to/from linear-color float [0, 1] in shader.
2066     ///
2067     /// [`Features::TEXTURE_COMPRESSION_ETC2`] must be enabled to use this texture format.
2068     #[cfg_attr(feature = "serde", serde(rename = "etc2-rgb8a1unorm-srgb"))]
2069     Etc2Rgb8A1UnormSrgb,
2070     /// 4x4 block compressed texture. 16 bytes per block (8 bit/px). Complex pallet. 8 bit integer RGB + 8 bit alpha.
2071     /// [0, 255] converted to/from float [0, 1] in shader.
2072     ///
2073     /// [`Features::TEXTURE_COMPRESSION_ETC2`] must be enabled to use this texture format.
2074     #[cfg_attr(feature = "serde", serde(rename = "etc2-rgba8unorm"))]
2075     Etc2Rgba8Unorm,
2076     /// 4x4 block compressed texture. 16 bytes per block (8 bit/px). Complex pallet. 8 bit integer RGB + 8 bit alpha.
2077     /// Srgb-color [0, 255] converted to/from linear-color float [0, 1] in shader.
2078     ///
2079     /// [`Features::TEXTURE_COMPRESSION_ETC2`] must be enabled to use this texture format.
2080     #[cfg_attr(feature = "serde", serde(rename = "etc2-rgba8unorm-srgb"))]
2081     Etc2Rgba8UnormSrgb,
2082     /// 4x4 block compressed texture. 8 bytes per block (4 bit/px). Complex pallet. 11 bit integer R.
2083     /// [0, 255] converted to/from float [0, 1] in shader.
2084     ///
2085     /// [`Features::TEXTURE_COMPRESSION_ETC2`] must be enabled to use this texture format.
2086     #[cfg_attr(feature = "serde", serde(rename = "eac-r11unorm"))]
2087     EacR11Unorm,
2088     /// 4x4 block compressed texture. 8 bytes per block (4 bit/px). Complex pallet. 11 bit integer R.
2089     /// [-127, 127] converted to/from float [-1, 1] in shader.
2090     ///
2091     /// [`Features::TEXTURE_COMPRESSION_ETC2`] must be enabled to use this texture format.
2092     #[cfg_attr(feature = "serde", serde(rename = "eac-r11snorm"))]
2093     EacR11Snorm,
2094     /// 4x4 block compressed texture. 16 bytes per block (8 bit/px). Complex pallet. 11 bit integer R + 11 bit integer G.
2095     /// [0, 255] converted to/from float [0, 1] in shader.
2096     ///
2097     /// [`Features::TEXTURE_COMPRESSION_ETC2`] must be enabled to use this texture format.
2098     #[cfg_attr(feature = "serde", serde(rename = "eac-rg11unorm"))]
2099     EacRg11Unorm,
2100     /// 4x4 block compressed texture. 16 bytes per block (8 bit/px). Complex pallet. 11 bit integer R + 11 bit integer G.
2101     /// [-127, 127] converted to/from float [-1, 1] in shader.
2102     ///
2103     /// [`Features::TEXTURE_COMPRESSION_ETC2`] must be enabled to use this texture format.
2104     #[cfg_attr(feature = "serde", serde(rename = "eac-rg11snorm"))]
2105     EacRg11Snorm,
2106     /// block compressed texture. 16 bytes per block.
2107     ///
2108     /// Features [`TEXTURE_COMPRESSION_ASTC_LDR`] or [`TEXTURE_COMPRESSION_ASTC_HDR`]
2109     /// must be enabled to use this texture format.
2110     ///
2111     /// [`TEXTURE_COMPRESSION_ASTC_LDR`]: Features::TEXTURE_COMPRESSION_ASTC_LDR
2112     /// [`TEXTURE_COMPRESSION_ASTC_HDR`]: Features::TEXTURE_COMPRESSION_ASTC_HDR
2113     Astc {
2114         /// compressed block dimensions
2115         block: AstcBlock,
2116         ///
2117         channel: AstcChannel,
2118     },
2121 impl TextureFormat {
2122     /// Get useful information about the texture format.
2123     pub fn describe(&self) -> TextureFormatInfo {
2124         // Features
2125         let native = Features::empty();
2126         let bc = Features::TEXTURE_COMPRESSION_BC;
2127         let etc2 = Features::TEXTURE_COMPRESSION_ETC2;
2128         let astc_ldr = Features::TEXTURE_COMPRESSION_ASTC_LDR;
2129         let astc_hdr = Features::TEXTURE_COMPRESSION_ASTC_HDR;
2130         let norm16bit = Features::TEXTURE_FORMAT_16BIT_NORM;
2131         let d32_s8 = Features::DEPTH32FLOAT_STENCIL8;
2132         let d24_s8 = Features::DEPTH24UNORM_STENCIL8;
2134         // Sample Types
2135         let uint = TextureSampleType::Uint;
2136         let sint = TextureSampleType::Sint;
2137         let nearest = TextureSampleType::Float { filterable: false };
2138         let float = TextureSampleType::Float { filterable: true };
2139         let depth = TextureSampleType::Depth;
2141         enum ColorSpace {
2142             Linear,
2143             Corrected,
2144         }
2145         let linear = ColorSpace::Linear;
2146         let corrected = ColorSpace::Corrected;
2148         // Multisampling
2149         let noaa = TextureFormatFeatureFlags::empty();
2150         let msaa = TextureFormatFeatureFlags::MULTISAMPLE;
2151         let msaa_resolve =
2152             TextureFormatFeatureFlags::MULTISAMPLE | TextureFormatFeatureFlags::MULTISAMPLE_RESOLVE;
2154         // Flags
2155         let basic =
2156             TextureUsages::COPY_SRC | TextureUsages::COPY_DST | TextureUsages::TEXTURE_BINDING;
2157         let attachment = basic | TextureUsages::RENDER_ATTACHMENT;
2158         let storage = basic | TextureUsages::STORAGE_BINDING;
2159         let all_flags = TextureUsages::all();
2161         // See <https://gpuweb.github.io/gpuweb/#texture-format-caps> for reference
2162         #[rustfmt::skip] // lets make a nice table
2163         let (
2164             required_features,
2165             sample_type,
2166             color_space,
2167             msaa_flags,
2168             block_dimensions,
2169             block_size,
2170             allowed_usages,
2171             components,
2172         ) = match self {
2173             // Normal 8 bit textures
2174             Self::R8Unorm =>             (   native,   float,    linear, msaa_resolve, (1, 1),  1, attachment, 1),
2175             Self::R8Snorm =>             (   native,   float,    linear,         msaa, (1, 1),  1,      basic, 1),
2176             Self::R8Uint =>              (   native,    uint,    linear,         msaa, (1, 1),  1, attachment, 1),
2177             Self::R8Sint =>              (   native,    sint,    linear,         msaa, (1, 1),  1, attachment, 1),
2179             // Normal 16 bit textures
2180             Self::R16Uint =>             (   native,    uint,    linear,         msaa, (1, 1),  2, attachment, 1),
2181             Self::R16Sint =>             (   native,    sint,    linear,         msaa, (1, 1),  2, attachment, 1),
2182             Self::R16Float =>            (   native,   float,    linear, msaa_resolve, (1, 1),  2, attachment, 1),
2183             Self::Rg8Unorm =>            (   native,   float,    linear, msaa_resolve, (1, 1),  2, attachment, 2),
2184             Self::Rg8Snorm =>            (   native,   float,    linear,         msaa, (1, 1),  2, attachment, 2),
2185             Self::Rg8Uint =>             (   native,    uint,    linear,         msaa, (1, 1),  2, attachment, 2),
2186             Self::Rg8Sint =>             (   native,    sint,    linear,         msaa, (1, 1),  2,      basic, 2),
2188             // Normal 32 bit textures
2189             Self::R32Uint =>             (   native,    uint,    linear,         noaa, (1, 1),  4,  all_flags, 1),
2190             Self::R32Sint =>             (   native,    sint,    linear,         noaa, (1, 1),  4,  all_flags, 1),
2191             Self::R32Float =>            (   native, nearest,    linear,         msaa, (1, 1),  4,  all_flags, 1),
2192             Self::Rg16Uint =>            (   native,    uint,    linear,         msaa, (1, 1),  4, attachment, 2),
2193             Self::Rg16Sint =>            (   native,    sint,    linear,         msaa, (1, 1),  4, attachment, 2),
2194             Self::Rg16Float =>           (   native,   float,    linear, msaa_resolve, (1, 1),  4, attachment, 2),
2195             Self::Rgba8Unorm =>          (   native,   float,    linear, msaa_resolve, (1, 1),  4,  all_flags, 4),
2196             Self::Rgba8UnormSrgb =>      (   native,   float, corrected, msaa_resolve, (1, 1),  4, attachment, 4),
2197             Self::Rgba8Snorm =>          (   native,   float,    linear,         msaa, (1, 1),  4,    storage, 4),
2198             Self::Rgba8Uint =>           (   native,    uint,    linear,         msaa, (1, 1),  4,  all_flags, 4),
2199             Self::Rgba8Sint =>           (   native,    sint,    linear,         msaa, (1, 1),  4,  all_flags, 4),
2200             Self::Bgra8Unorm =>          (   native,   float,    linear, msaa_resolve, (1, 1),  4, attachment, 4),
2201             Self::Bgra8UnormSrgb =>      (   native,   float, corrected, msaa_resolve, (1, 1),  4, attachment, 4),
2203             // Packed 32 bit textures
2204             Self::Rgb10a2Unorm =>        (   native,   float,    linear, msaa_resolve, (1, 1),  4, attachment, 4),
2205             Self::Rg11b10Float =>        (   native,   float,    linear,         msaa, (1, 1),  4,      basic, 3),
2207             // Packed 32 bit textures
2208             Self::Rg32Uint =>            (   native,    uint,    linear,         noaa, (1, 1),  8,  all_flags, 2),
2209             Self::Rg32Sint =>            (   native,    sint,    linear,         noaa, (1, 1),  8,  all_flags, 2),
2210             Self::Rg32Float =>           (   native, nearest,    linear,         noaa, (1, 1),  8,  all_flags, 2),
2211             Self::Rgba16Uint =>          (   native,    uint,    linear,         msaa, (1, 1),  8,  all_flags, 4),
2212             Self::Rgba16Sint =>          (   native,    sint,    linear,         msaa, (1, 1),  8,  all_flags, 4),
2213             Self::Rgba16Float =>         (   native,   float,    linear, msaa_resolve, (1, 1),  8,  all_flags, 4),
2215             // Packed 32 bit textures
2216             Self::Rgba32Uint =>          (   native,    uint,    linear,         noaa, (1, 1), 16,  all_flags, 4),
2217             Self::Rgba32Sint =>          (   native,    sint,    linear,         noaa, (1, 1), 16,  all_flags, 4),
2218             Self::Rgba32Float =>         (   native, nearest,    linear,         noaa, (1, 1), 16,  all_flags, 4),
2220             // Depth-stencil textures
2221             Self::Depth32Float =>        (   native,   depth,    linear,         msaa, (1, 1),  4, attachment, 1),
2222             Self::Depth32FloatStencil8 =>(   d32_s8,   depth,    linear,         msaa, (1, 1),  4, attachment, 2),
2223             Self::Depth24Plus =>         (   native,   depth,    linear,         msaa, (1, 1),  4, attachment, 1),
2224             Self::Depth24PlusStencil8 => (   native,   depth,    linear,         msaa, (1, 1),  4, attachment, 2),
2225             Self::Depth24UnormStencil8 => (  d24_s8,   depth,    linear,         msaa, (1, 1),  4, attachment, 2),
2227             // Packed uncompressed
2228             Self::Rgb9e5Ufloat =>        (   native,   float,    linear,         noaa, (1, 1),  4,      basic, 3),
2230             // Optional normalized 16-bit-per-channel formats
2231             Self::R16Unorm =>            (norm16bit,   float,    linear,         msaa, (1, 1),  2,    storage, 1),
2232             Self::R16Snorm =>            (norm16bit,   float,    linear,         msaa, (1, 1),  2,    storage, 1),
2233             Self::Rg16Unorm =>           (norm16bit,   float,    linear,         msaa, (1, 1),  4,    storage, 2),
2234             Self::Rg16Snorm =>           (norm16bit,   float,    linear,         msaa, (1, 1),  4,    storage, 2),
2235             Self::Rgba16Unorm =>         (norm16bit,   float,    linear,         msaa, (1, 1),  8,    storage, 4),
2236             Self::Rgba16Snorm =>         (norm16bit,   float,    linear,         msaa, (1, 1),  8,    storage, 4),
2238             // BCn compressed textures
2239             Self::Bc1RgbaUnorm =>        (       bc,   float,    linear,         noaa, (4, 4),  8,      basic, 4),
2240             Self::Bc1RgbaUnormSrgb =>    (       bc,   float, corrected,         noaa, (4, 4),  8,      basic, 4),
2241             Self::Bc2RgbaUnorm =>        (       bc,   float,    linear,         noaa, (4, 4), 16,      basic, 4),
2242             Self::Bc2RgbaUnormSrgb =>    (       bc,   float, corrected,         noaa, (4, 4), 16,      basic, 4),
2243             Self::Bc3RgbaUnorm =>        (       bc,   float,    linear,         noaa, (4, 4), 16,      basic, 4),
2244             Self::Bc3RgbaUnormSrgb =>    (       bc,   float, corrected,         noaa, (4, 4), 16,      basic, 4),
2245             Self::Bc4RUnorm =>           (       bc,   float,    linear,         noaa, (4, 4),  8,      basic, 1),
2246             Self::Bc4RSnorm =>           (       bc,   float,    linear,         noaa, (4, 4),  8,      basic, 1),
2247             Self::Bc5RgUnorm =>          (       bc,   float,    linear,         noaa, (4, 4), 16,      basic, 2),
2248             Self::Bc5RgSnorm =>          (       bc,   float,    linear,         noaa, (4, 4), 16,      basic, 2),
2249             Self::Bc6hRgbUfloat =>       (       bc,   float,    linear,         noaa, (4, 4), 16,      basic, 3),
2250             Self::Bc6hRgbSfloat =>       (       bc,   float,    linear,         noaa, (4, 4), 16,      basic, 3),
2251             Self::Bc7RgbaUnorm =>        (       bc,   float,    linear,         noaa, (4, 4), 16,      basic, 4),
2252             Self::Bc7RgbaUnormSrgb =>    (       bc,   float, corrected,         noaa, (4, 4), 16,      basic, 4),
2254             // ETC compressed textures
2255             Self::Etc2Rgb8Unorm =>       (     etc2,   float,    linear,         noaa, (4, 4),  8,      basic, 3),
2256             Self::Etc2Rgb8UnormSrgb =>   (     etc2,   float, corrected,         noaa, (4, 4),  8,      basic, 3),
2257             Self::Etc2Rgb8A1Unorm =>     (     etc2,   float,    linear,         noaa, (4, 4),  8,      basic, 4),
2258             Self::Etc2Rgb8A1UnormSrgb => (     etc2,   float, corrected,         noaa, (4, 4),  8,      basic, 4),
2259             Self::Etc2Rgba8Unorm =>      (     etc2,   float,    linear,         noaa, (4, 4), 16,      basic, 4),
2260             Self::Etc2Rgba8UnormSrgb =>  (     etc2,   float, corrected,         noaa, (4, 4), 16,      basic, 4),
2261             Self::EacR11Unorm =>         (     etc2,   float,    linear,         noaa, (4, 4),  8,      basic, 1),
2262             Self::EacR11Snorm =>         (     etc2,   float,    linear,         noaa, (4, 4),  8,      basic, 1),
2263             Self::EacRg11Unorm =>        (     etc2,   float,    linear,         noaa, (4, 4), 16,      basic, 2),
2264             Self::EacRg11Snorm =>        (     etc2,   float,    linear,         noaa, (4, 4), 16,      basic, 2),
2266             // ASTC compressed textures
2267             Self::Astc { block, channel } => {
2268                 let (feature, color_space) = match channel {
2269                     AstcChannel::Hdr => (astc_hdr, linear),
2270                     AstcChannel::Unorm => (astc_ldr, linear),
2271                     AstcChannel::UnormSrgb => (astc_ldr, corrected),
2272                 };
2273                 let dimensions = match block {
2274                     AstcBlock::B4x4 => (4, 4),
2275                     AstcBlock::B5x4 => (5, 4),
2276                     AstcBlock::B5x5 => (5, 5),
2277                     AstcBlock::B6x5 => (6, 5),
2278                     AstcBlock::B6x6 => (6, 6),
2279                     AstcBlock::B8x5 => (8, 5),
2280                     AstcBlock::B8x6 => (8, 6),
2281                     AstcBlock::B8x8 => (8, 8),
2282                     AstcBlock::B10x5 => (10, 5),
2283                     AstcBlock::B10x6 => (10, 6),
2284                     AstcBlock::B10x8 => (10, 8),
2285                     AstcBlock::B10x10 => (10, 10),
2286                     AstcBlock::B12x10 => (12, 10),
2287                     AstcBlock::B12x12 => (12, 12),
2288                 };
2289                 (feature, float, color_space, noaa, dimensions, 16, basic, 4)
2290             }
2291         };
2293         let mut flags = msaa_flags;
2294         flags.set(
2295             TextureFormatFeatureFlags::FILTERABLE,
2296             sample_type == TextureSampleType::Float { filterable: true },
2297         );
2299         TextureFormatInfo {
2300             required_features,
2301             sample_type,
2302             block_dimensions,
2303             block_size,
2304             components,
2305             srgb: match color_space {
2306                 ColorSpace::Linear => false,
2307                 ColorSpace::Corrected => true,
2308             },
2309             guaranteed_format_features: TextureFormatFeatures {
2310                 allowed_usages,
2311                 flags,
2312             },
2313         }
2314     }
2317 bitflags::bitflags! {
2318     /// Color write mask. Disabled color channels will not be written to.
2319     ///
2320     /// Corresponds to [WebGPU `GPUColorWriteFlags`](
2321     /// https://gpuweb.github.io/gpuweb/#typedefdef-gpucolorwriteflags).
2322     #[repr(transparent)]
2323     pub struct ColorWrites: u32 {
2324         /// Enable red channel writes
2325         const RED = 1 << 0;
2326         /// Enable green channel writes
2327         const GREEN = 1 << 1;
2328         /// Enable blue channel writes
2329         const BLUE = 1 << 2;
2330         /// Enable alpha channel writes
2331         const ALPHA = 1 << 3;
2332         /// Enable red, green, and blue channel writes
2333         const COLOR = Self::RED.bits | Self::GREEN.bits | Self::BLUE.bits;
2334         /// Enable writes to all channels.
2335         const ALL = Self::RED.bits | Self::GREEN.bits | Self::BLUE.bits | Self::ALPHA.bits;
2336     }
2339 #[cfg(feature = "bitflags_serde_shim")]
2340 bitflags_serde_shim::impl_serde_for_bitflags!(ColorWrites);
2342 impl Default for ColorWrites {
2343     fn default() -> Self {
2344         Self::ALL
2345     }
2348 /// Passed to `Device::poll` to control how and if it should block.
2349 #[derive(Clone)]
2350 pub enum Maintain<T> {
2351     /// On native backends, block until the given submission has
2352     /// completed execution, and any callbacks have been invoked.
2353     ///
2354     /// On the web, this has no effect. Callbacks are invoked from the
2355     /// window event loop.
2356     WaitForSubmissionIndex(T),
2357     /// Same as WaitForSubmissionIndex but waits for the most recent submission.
2358     Wait,
2359     /// Check the device for a single time without blocking.
2360     Poll,
2363 impl<T> Maintain<T> {
2364     /// This maintain represents a wait of some kind.
2365     pub fn is_wait(&self) -> bool {
2366         match *self {
2367             Self::WaitForSubmissionIndex(..) | Self::Wait => true,
2368             Self::Poll => false,
2369         }
2370     }
2372     /// Map on the wait index type.
2373     pub fn map_index<U, F>(self, func: F) -> Maintain<U>
2374     where
2375         F: FnOnce(T) -> U,
2376     {
2377         match self {
2378             Self::WaitForSubmissionIndex(i) => Maintain::WaitForSubmissionIndex(func(i)),
2379             Self::Wait => Maintain::Wait,
2380             Self::Poll => Maintain::Poll,
2381         }
2382     }
2385 /// State of the stencil operation (fixed-pipeline stage).
2387 /// For use in [`DepthStencilState`].
2389 /// Corresponds to a portion of [WebGPU `GPUDepthStencilState`](
2390 /// https://gpuweb.github.io/gpuweb/#dictdef-gpudepthstencilstate).
2391 #[repr(C)]
2392 #[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
2393 #[cfg_attr(feature = "trace", derive(Serialize))]
2394 #[cfg_attr(feature = "replay", derive(Deserialize))]
2395 pub struct StencilState {
2396     /// Front face mode.
2397     pub front: StencilFaceState,
2398     /// Back face mode.
2399     pub back: StencilFaceState,
2400     /// Stencil values are AND'd with this mask when reading and writing from the stencil buffer. Only low 8 bits are used.
2401     pub read_mask: u32,
2402     /// Stencil values are AND'd with this mask when writing to the stencil buffer. Only low 8 bits are used.
2403     pub write_mask: u32,
2406 impl StencilState {
2407     /// Returns true if the stencil test is enabled.
2408     pub fn is_enabled(&self) -> bool {
2409         (self.front != StencilFaceState::IGNORE || self.back != StencilFaceState::IGNORE)
2410             && (self.read_mask != 0 || self.write_mask != 0)
2411     }
2412     /// Returns true if the state doesn't mutate the target values.
2413     pub fn is_read_only(&self) -> bool {
2414         self.write_mask == 0
2415     }
2416     /// Returns true if the stencil state uses the reference value for testing.
2417     pub fn needs_ref_value(&self) -> bool {
2418         self.front.needs_ref_value() || self.back.needs_ref_value()
2419     }
2422 /// Describes the biasing setting for the depth target.
2424 /// For use in [`DepthStencilState`].
2426 /// Corresponds to a portion of [WebGPU `GPUDepthStencilState`](
2427 /// https://gpuweb.github.io/gpuweb/#dictdef-gpudepthstencilstate).
2428 #[repr(C)]
2429 #[derive(Clone, Copy, Debug, Default, PartialEq)]
2430 #[cfg_attr(feature = "trace", derive(Serialize))]
2431 #[cfg_attr(feature = "replay", derive(Deserialize))]
2432 pub struct DepthBiasState {
2433     /// Constant depth biasing factor, in basic units of the depth format.
2434     pub constant: i32,
2435     /// Slope depth biasing factor.
2436     pub slope_scale: f32,
2437     /// Depth bias clamp value (absolute).
2438     pub clamp: f32,
2441 impl DepthBiasState {
2442     /// Returns true if the depth biasing is enabled.
2443     pub fn is_enabled(&self) -> bool {
2444         self.constant != 0 || self.slope_scale != 0.0
2445     }
2448 /// Describes the depth/stencil state in a render pipeline.
2450 /// Corresponds to [WebGPU `GPUDepthStencilState`](
2451 /// https://gpuweb.github.io/gpuweb/#dictdef-gpudepthstencilstate).
2452 #[repr(C)]
2453 #[derive(Clone, Debug, PartialEq)]
2454 #[cfg_attr(feature = "trace", derive(Serialize))]
2455 #[cfg_attr(feature = "replay", derive(Deserialize))]
2456 pub struct DepthStencilState {
2457     /// Format of the depth/stencil buffer, must be special depth format. Must match the the format
2458     /// of the depth/stencil attachment in [`CommandEncoder::begin_render_pass`][CEbrp].
2459     ///
2460     /// [CEbrp]: ../wgpu/struct.CommandEncoder.html#method.begin_render_pass
2461     pub format: TextureFormat,
2462     /// If disabled, depth will not be written to.
2463     pub depth_write_enabled: bool,
2464     /// Comparison function used to compare depth values in the depth test.
2465     pub depth_compare: CompareFunction,
2466     /// Stencil state.
2467     #[cfg_attr(any(feature = "trace", feature = "replay"), serde(default))]
2468     pub stencil: StencilState,
2469     /// Depth bias state.
2470     #[cfg_attr(any(feature = "trace", feature = "replay"), serde(default))]
2471     pub bias: DepthBiasState,
2474 impl DepthStencilState {
2475     /// Returns true if the depth testing is enabled.
2476     pub fn is_depth_enabled(&self) -> bool {
2477         self.depth_compare != CompareFunction::Always || self.depth_write_enabled
2478     }
2480     /// Returns true if the state doesn't mutate the depth buffer.
2481     pub fn is_depth_read_only(&self) -> bool {
2482         !self.depth_write_enabled
2483     }
2485     /// Returns true if the state doesn't mutate the stencil.
2486     pub fn is_stencil_read_only(&self) -> bool {
2487         self.stencil.is_read_only()
2488     }
2490     /// Returns true if the state doesn't mutate either depth or stencil of the target.
2491     pub fn is_read_only(&self) -> bool {
2492         self.is_depth_read_only() && self.is_stencil_read_only()
2493     }
2496 /// Format of indices used with pipeline.
2498 /// Corresponds to [WebGPU `GPUIndexFormat`](
2499 /// https://gpuweb.github.io/gpuweb/#enumdef-gpuindexformat).
2500 #[repr(C)]
2501 #[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
2502 #[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
2503 #[cfg_attr(feature = "serde", serde(rename_all = "kebab-case"))]
2504 pub enum IndexFormat {
2505     /// Indices are 16 bit unsigned integers.
2506     Uint16 = 0,
2507     /// Indices are 32 bit unsigned integers.
2508     Uint32 = 1,
2511 impl Default for IndexFormat {
2512     fn default() -> Self {
2513         Self::Uint32
2514     }
2517 /// Operation to perform on the stencil value.
2519 /// Corresponds to [WebGPU `GPUStencilOperation`](
2520 /// https://gpuweb.github.io/gpuweb/#enumdef-gpustenciloperation).
2521 #[repr(C)]
2522 #[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
2523 #[cfg_attr(feature = "trace", derive(Serialize))]
2524 #[cfg_attr(feature = "replay", derive(Deserialize))]
2525 #[cfg_attr(feature = "serde", serde(rename_all = "kebab-case"))]
2526 pub enum StencilOperation {
2527     /// Keep stencil value unchanged.
2528     Keep = 0,
2529     /// Set stencil value to zero.
2530     Zero = 1,
2531     /// Replace stencil value with value provided in most recent call to
2532     /// [`RenderPass::set_stencil_reference`][RPssr].
2533     ///
2534     /// [RPssr]: ../wgpu/struct.RenderPass.html#method.set_stencil_reference
2535     Replace = 2,
2536     /// Bitwise inverts stencil value.
2537     Invert = 3,
2538     /// Increments stencil value by one, clamping on overflow.
2539     IncrementClamp = 4,
2540     /// Decrements stencil value by one, clamping on underflow.
2541     DecrementClamp = 5,
2542     /// Increments stencil value by one, wrapping on overflow.
2543     IncrementWrap = 6,
2544     /// Decrements stencil value by one, wrapping on underflow.
2545     DecrementWrap = 7,
2548 impl Default for StencilOperation {
2549     fn default() -> Self {
2550         Self::Keep
2551     }
2554 /// Describes stencil state in a render pipeline.
2556 /// If you are not using stencil state, set this to [`StencilFaceState::IGNORE`].
2558 /// Corresponds to [WebGPU `GPUStencilFaceState`](
2559 /// https://gpuweb.github.io/gpuweb/#dictdef-gpustencilfacestate).
2560 #[repr(C)]
2561 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
2562 #[cfg_attr(feature = "trace", derive(Serialize))]
2563 #[cfg_attr(feature = "replay", derive(Deserialize))]
2564 #[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
2565 pub struct StencilFaceState {
2566     /// Comparison function that determines if the fail_op or pass_op is used on the stencil buffer.
2567     pub compare: CompareFunction,
2568     /// Operation that is preformed when stencil test fails.
2569     pub fail_op: StencilOperation,
2570     /// Operation that is performed when depth test fails but stencil test succeeds.
2571     pub depth_fail_op: StencilOperation,
2572     /// Operation that is performed when stencil test success.
2573     pub pass_op: StencilOperation,
2576 impl StencilFaceState {
2577     /// Ignore the stencil state for the face.
2578     pub const IGNORE: Self = StencilFaceState {
2579         compare: CompareFunction::Always,
2580         fail_op: StencilOperation::Keep,
2581         depth_fail_op: StencilOperation::Keep,
2582         pass_op: StencilOperation::Keep,
2583     };
2585     /// Returns true if the face state uses the reference value for testing or operation.
2586     pub fn needs_ref_value(&self) -> bool {
2587         self.compare.needs_ref_value()
2588             || self.fail_op == StencilOperation::Replace
2589             || self.depth_fail_op == StencilOperation::Replace
2590             || self.pass_op == StencilOperation::Replace
2591     }
2594 impl Default for StencilFaceState {
2595     fn default() -> Self {
2596         Self::IGNORE
2597     }
2600 /// Comparison function used for depth and stencil operations.
2602 /// Corresponds to [WebGPU `GPUCompareFunction`](
2603 /// https://gpuweb.github.io/gpuweb/#enumdef-gpucomparefunction).
2604 #[repr(C)]
2605 #[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
2606 #[cfg_attr(feature = "trace", derive(Serialize))]
2607 #[cfg_attr(feature = "replay", derive(Deserialize))]
2608 #[cfg_attr(feature = "serde", serde(rename_all = "kebab-case"))]
2609 pub enum CompareFunction {
2610     /// Function never passes
2611     Never = 1,
2612     /// Function passes if new value less than existing value
2613     Less = 2,
2614     /// Function passes if new value is equal to existing value. When using
2615     /// this compare function, make sure to mark your Vertex Shader's `@builtin(position)`
2616     /// output as `@invariant` to prevent artifacting.
2617     Equal = 3,
2618     /// Function passes if new value is less than or equal to existing value
2619     LessEqual = 4,
2620     /// Function passes if new value is greater than existing value
2621     Greater = 5,
2622     /// Function passes if new value is not equal to existing value. When using
2623     /// this compare function, make sure to mark your Vertex Shader's `@builtin(position)`
2624     /// output as `@invariant` to prevent artifacting.
2625     NotEqual = 6,
2626     /// Function passes if new value is greater than or equal to existing value
2627     GreaterEqual = 7,
2628     /// Function always passes
2629     Always = 8,
2632 impl CompareFunction {
2633     /// Returns true if the comparison depends on the reference value.
2634     pub fn needs_ref_value(self) -> bool {
2635         match self {
2636             Self::Never | Self::Always => false,
2637             _ => true,
2638         }
2639     }
2642 /// Whether a vertex buffer is indexed by vertex or by instance.
2644 /// Consider a call to [`RenderPass::draw`] like this:
2646 /// ```ignore
2647 /// render_pass.draw(vertices, instances)
2648 /// ```
2650 /// where `vertices` is a `Range<u32>` of vertex indices, and
2651 /// `instances` is a `Range<u32>` of instance indices.
2653 /// For this call, `wgpu` invokes the vertex shader entry point once
2654 /// for every possible `(v, i)` pair, where `v` is drawn from
2655 /// `vertices` and `i` is drawn from `instances`. These invocations
2656 /// may happen in any order, and will usually run in parallel.
2658 /// Each vertex buffer has a step mode, established by the
2659 /// [`step_mode`] field of its [`VertexBufferLayout`], given when the
2660 /// pipeline was created. Buffers whose step mode is [`Vertex`] use
2661 /// `v` as the index into their contents, whereas buffers whose step
2662 /// mode is [`Instance`] use `i`. The indicated buffer element then
2663 /// contributes zero or more attribute values for the `(v, i)` vertex
2664 /// shader invocation to use, based on the [`VertexBufferLayout`]'s
2665 /// [`attributes`] list.
2667 /// You can visualize the results from all these vertex shader
2668 /// invocations as a matrix with a row for each `i` from `instances`,
2669 /// and with a column for each `v` from `vertices`. In one sense, `v`
2670 /// and `i` are symmetrical: both are used to index vertex buffers and
2671 /// provide attribute values.  But the key difference between `v` and
2672 /// `i` is that line and triangle primitives are built from the values
2673 /// of each row, along which `i` is constant and `v` varies, not the
2674 /// columns.
2676 /// An indexed draw call works similarly:
2678 /// ```ignore
2679 /// render_pass.draw_indexed(indices, base_vertex, instances)
2680 /// ```
2682 /// The only difference is that `v` values are drawn from the contents
2683 /// of the index buffer&mdash;specifically, the subrange of the index
2684 /// buffer given by `indices`&mdash;instead of simply being sequential
2685 /// integers, as they are in a `draw` call.
2687 /// A non-instanced call, where `instances` is `0..1`, is simply a
2688 /// matrix with only one row.
2690 /// Corresponds to [WebGPU `GPUVertexStepMode`](
2691 /// https://gpuweb.github.io/gpuweb/#enumdef-gpuvertexstepmode).
2693 /// [`RenderPass::draw`]: ../wgpu/struct.RenderPass.html#method.draw
2694 /// [`VertexBufferLayout`]: ../wgpu/struct.VertexBufferLayout.html
2695 /// [`step_mode`]: ../wgpu/struct.VertexBufferLayout.html#structfield.step_mode
2696 /// [`attributes`]: ../wgpu/struct.VertexBufferLayout.html#structfield.attributes
2697 /// [`Vertex`]: VertexStepMode::Vertex
2698 /// [`Instance`]: VertexStepMode::Instance
2699 #[repr(C)]
2700 #[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
2701 #[cfg_attr(feature = "trace", derive(Serialize))]
2702 #[cfg_attr(feature = "replay", derive(Deserialize))]
2703 #[cfg_attr(feature = "serde", serde(rename_all = "kebab-case"))]
2704 pub enum VertexStepMode {
2705     /// Vertex data is advanced every vertex.
2706     Vertex = 0,
2707     /// Vertex data is advanced every instance.
2708     Instance = 1,
2711 impl Default for VertexStepMode {
2712     fn default() -> Self {
2713         VertexStepMode::Vertex
2714     }
2717 /// Vertex inputs (attributes) to shaders.
2719 /// Arrays of these can be made with the [`vertex_attr_array`]
2720 /// macro. Vertex attributes are assumed to be tightly packed.
2722 /// Corresponds to [WebGPU `GPUVertexAttribute`](
2723 /// https://gpuweb.github.io/gpuweb/#dictdef-gpuvertexattribute).
2725 /// [`vertex_attr_array`]: ../wgpu/macro.vertex_attr_array.html
2726 #[repr(C)]
2727 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
2728 #[cfg_attr(feature = "trace", derive(Serialize))]
2729 #[cfg_attr(feature = "replay", derive(Deserialize))]
2730 #[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
2731 pub struct VertexAttribute {
2732     /// Format of the input
2733     pub format: VertexFormat,
2734     /// Byte offset of the start of the input
2735     pub offset: BufferAddress,
2736     /// Location for this input. Must match the location in the shader.
2737     pub shader_location: ShaderLocation,
2740 /// Vertex Format for a [`VertexAttribute`] (input).
2742 /// Corresponds to [WebGPU `GPUVertexFormat`](
2743 /// https://gpuweb.github.io/gpuweb/#enumdef-gpuvertexformat).
2744 #[repr(C)]
2745 #[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
2746 #[cfg_attr(feature = "trace", derive(Serialize))]
2747 #[cfg_attr(feature = "replay", derive(Deserialize))]
2748 #[cfg_attr(feature = "serde", serde(rename_all = "lowercase"))]
2749 pub enum VertexFormat {
2750     /// Two unsigned bytes (u8). `uvec2` in shaders.
2751     Uint8x2 = 0,
2752     /// Four unsigned bytes (u8). `uvec4` in shaders.
2753     Uint8x4 = 1,
2754     /// Two signed bytes (i8). `ivec2` in shaders.
2755     Sint8x2 = 2,
2756     /// Four signed bytes (i8). `ivec4` in shaders.
2757     Sint8x4 = 3,
2758     /// Two unsigned bytes (u8). [0, 255] converted to float [0, 1] `vec2` in shaders.
2759     Unorm8x2 = 4,
2760     /// Four unsigned bytes (u8). [0, 255] converted to float [0, 1] `vec4` in shaders.
2761     Unorm8x4 = 5,
2762     /// Two signed bytes (i8). [-127, 127] converted to float [-1, 1] `vec2` in shaders.
2763     Snorm8x2 = 6,
2764     /// Four signed bytes (i8). [-127, 127] converted to float [-1, 1] `vec4` in shaders.
2765     Snorm8x4 = 7,
2766     /// Two unsigned shorts (u16). `uvec2` in shaders.
2767     Uint16x2 = 8,
2768     /// Four unsigned shorts (u16). `uvec4` in shaders.
2769     Uint16x4 = 9,
2770     /// Two signed shorts (i16). `ivec2` in shaders.
2771     Sint16x2 = 10,
2772     /// Four signed shorts (i16). `ivec4` in shaders.
2773     Sint16x4 = 11,
2774     /// Two unsigned shorts (u16). [0, 65535] converted to float [0, 1] `vec2` in shaders.
2775     Unorm16x2 = 12,
2776     /// Four unsigned shorts (u16). [0, 65535] converted to float [0, 1] `vec4` in shaders.
2777     Unorm16x4 = 13,
2778     /// Two signed shorts (i16). [-32767, 32767] converted to float [-1, 1] `vec2` in shaders.
2779     Snorm16x2 = 14,
2780     /// Four signed shorts (i16). [-32767, 32767] converted to float [-1, 1] `vec4` in shaders.
2781     Snorm16x4 = 15,
2782     /// Two half-precision floats (no Rust equiv). `vec2` in shaders.
2783     Float16x2 = 16,
2784     /// Four half-precision floats (no Rust equiv). `vec4` in shaders.
2785     Float16x4 = 17,
2786     /// One single-precision float (f32). `float` in shaders.
2787     Float32 = 18,
2788     /// Two single-precision floats (f32). `vec2` in shaders.
2789     Float32x2 = 19,
2790     /// Three single-precision floats (f32). `vec3` in shaders.
2791     Float32x3 = 20,
2792     /// Four single-precision floats (f32). `vec4` in shaders.
2793     Float32x4 = 21,
2794     /// One unsigned int (u32). `uint` in shaders.
2795     Uint32 = 22,
2796     /// Two unsigned ints (u32). `uvec2` in shaders.
2797     Uint32x2 = 23,
2798     /// Three unsigned ints (u32). `uvec3` in shaders.
2799     Uint32x3 = 24,
2800     /// Four unsigned ints (u32). `uvec4` in shaders.
2801     Uint32x4 = 25,
2802     /// One signed int (i32). `int` in shaders.
2803     Sint32 = 26,
2804     /// Two signed ints (i32). `ivec2` in shaders.
2805     Sint32x2 = 27,
2806     /// Three signed ints (i32). `ivec3` in shaders.
2807     Sint32x3 = 28,
2808     /// Four signed ints (i32). `ivec4` in shaders.
2809     Sint32x4 = 29,
2810     /// One double-precision float (f64). `double` in shaders. Requires VERTEX_ATTRIBUTE_64BIT features.
2811     Float64 = 30,
2812     /// Two double-precision floats (f64). `dvec2` in shaders. Requires VERTEX_ATTRIBUTE_64BIT features.
2813     Float64x2 = 31,
2814     /// Three double-precision floats (f64). `dvec3` in shaders. Requires VERTEX_ATTRIBUTE_64BIT features.
2815     Float64x3 = 32,
2816     /// Four double-precision floats (f64). `dvec4` in shaders. Requires VERTEX_ATTRIBUTE_64BIT features.
2817     Float64x4 = 33,
2820 impl VertexFormat {
2821     /// Returns the byte size of the format.
2822     pub const fn size(&self) -> u64 {
2823         match self {
2824             Self::Uint8x2 | Self::Sint8x2 | Self::Unorm8x2 | Self::Snorm8x2 => 2,
2825             Self::Uint8x4
2826             | Self::Sint8x4
2827             | Self::Unorm8x4
2828             | Self::Snorm8x4
2829             | Self::Uint16x2
2830             | Self::Sint16x2
2831             | Self::Unorm16x2
2832             | Self::Snorm16x2
2833             | Self::Float16x2
2834             | Self::Float32
2835             | Self::Uint32
2836             | Self::Sint32 => 4,
2837             Self::Uint16x4
2838             | Self::Sint16x4
2839             | Self::Unorm16x4
2840             | Self::Snorm16x4
2841             | Self::Float16x4
2842             | Self::Float32x2
2843             | Self::Uint32x2
2844             | Self::Sint32x2
2845             | Self::Float64 => 8,
2846             Self::Float32x3 | Self::Uint32x3 | Self::Sint32x3 => 12,
2847             Self::Float32x4 | Self::Uint32x4 | Self::Sint32x4 | Self::Float64x2 => 16,
2848             Self::Float64x3 => 24,
2849             Self::Float64x4 => 32,
2850         }
2851     }
2854 bitflags::bitflags! {
2855     /// Different ways that you can use a buffer.
2856     ///
2857     /// The usages determine what kind of memory the buffer is allocated from and what
2858     /// actions the buffer can partake in.
2859     ///
2860     /// Corresponds to [WebGPU `GPUBufferUsageFlags`](
2861     /// https://gpuweb.github.io/gpuweb/#typedefdef-gpubufferusageflags).
2862     #[repr(transparent)]
2863     pub struct BufferUsages: u32 {
2864         /// Allow a buffer to be mapped for reading using [`Buffer::map_async`] + [`Buffer::get_mapped_range`].
2865         /// This does not include creating a buffer with [`BufferDescriptor::mapped_at_creation`] set.
2866         ///
2867         /// If [`Features::MAPPABLE_PRIMARY_BUFFERS`] isn't enabled, the only other usage a buffer
2868         /// may have is COPY_DST.
2869         const MAP_READ = 1 << 0;
2870         /// Allow a buffer to be mapped for writing using [`Buffer::map_async`] + [`Buffer::get_mapped_range_mut`].
2871         /// This does not include creating a buffer with `mapped_at_creation` set.
2872         ///
2873         /// If [`Features::MAPPABLE_PRIMARY_BUFFERS`] feature isn't enabled, the only other usage a buffer
2874         /// may have is COPY_SRC.
2875         const MAP_WRITE = 1 << 1;
2876         /// Allow a buffer to be the source buffer for a [`CommandEncoder::copy_buffer_to_buffer`] or [`CommandEncoder::copy_buffer_to_texture`]
2877         /// operation.
2878         const COPY_SRC = 1 << 2;
2879         /// Allow a buffer to be the destination buffer for a [`CommandEncoder::copy_buffer_to_buffer`], [`CommandEncoder::copy_texture_to_buffer`],
2880         /// [`CommandEncoder::clear_buffer`] or [`Queue::write_buffer`] operation.
2881         const COPY_DST = 1 << 3;
2882         /// Allow a buffer to be the index buffer in a draw operation.
2883         const INDEX = 1 << 4;
2884         /// Allow a buffer to be the vertex buffer in a draw operation.
2885         const VERTEX = 1 << 5;
2886         /// Allow a buffer to be a [`BufferBindingType::Uniform`] inside a bind group.
2887         const UNIFORM = 1 << 6;
2888         /// Allow a buffer to be a [`BufferBindingType::Storage`] inside a bind group.
2889         const STORAGE = 1 << 7;
2890         /// Allow a buffer to be the indirect buffer in an indirect draw call.
2891         const INDIRECT = 1 << 8;
2892     }
2895 #[cfg(feature = "bitflags_serde_shim")]
2896 bitflags_serde_shim::impl_serde_for_bitflags!(BufferUsages);
2898 /// Describes a [`Buffer`](../wgpu/struct.Buffer.html).
2900 /// Corresponds to [WebGPU `GPUBufferDescriptor`](
2901 /// https://gpuweb.github.io/gpuweb/#dictdef-gpubufferdescriptor).
2902 #[repr(C)]
2903 #[derive(Clone, Debug, PartialEq, Eq, Hash)]
2904 #[cfg_attr(feature = "trace", derive(Serialize))]
2905 #[cfg_attr(feature = "replay", derive(Deserialize))]
2906 pub struct BufferDescriptor<L> {
2907     /// Debug label of a buffer. This will show up in graphics debuggers for easy identification.
2908     pub label: L,
2909     /// Size of a buffer.
2910     pub size: BufferAddress,
2911     /// Usages of a buffer. If the buffer is used in any way that isn't specified here, the operation
2912     /// will panic.
2913     pub usage: BufferUsages,
2914     /// Allows a buffer to be mapped immediately after they are made. It does not have to be [`BufferUsages::MAP_READ`] or
2915     /// [`BufferUsages::MAP_WRITE`], all buffers are allowed to be mapped at creation.
2916     pub mapped_at_creation: bool,
2919 impl<L> BufferDescriptor<L> {
2920     ///
2921     pub fn map_label<K>(&self, fun: impl FnOnce(&L) -> K) -> BufferDescriptor<K> {
2922         BufferDescriptor {
2923             label: fun(&self.label),
2924             size: self.size,
2925             usage: self.usage,
2926             mapped_at_creation: self.mapped_at_creation,
2927         }
2928     }
2931 /// Describes a [`CommandEncoder`](../wgpu/struct.CommandEncoder.html).
2933 /// Corresponds to [WebGPU `GPUCommandEncoderDescriptor`](
2934 /// https://gpuweb.github.io/gpuweb/#dictdef-gpucommandencoderdescriptor).
2935 #[repr(C)]
2936 #[cfg_attr(feature = "trace", derive(Serialize))]
2937 #[cfg_attr(feature = "replay", derive(Deserialize))]
2938 #[derive(Clone, Debug, PartialEq, Eq, Hash)]
2939 pub struct CommandEncoderDescriptor<L> {
2940     /// Debug label for the command encoder. This will show up in graphics debuggers for easy identification.
2941     pub label: L,
2944 impl<L> CommandEncoderDescriptor<L> {
2945     ///
2946     pub fn map_label<K>(&self, fun: impl FnOnce(&L) -> K) -> CommandEncoderDescriptor<K> {
2947         CommandEncoderDescriptor {
2948             label: fun(&self.label),
2949         }
2950     }
2953 impl<T> Default for CommandEncoderDescriptor<Option<T>> {
2954     fn default() -> Self {
2955         Self { label: None }
2956     }
2959 /// Behavior of the presentation engine based on frame rate.
2960 #[repr(C)]
2961 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
2962 #[cfg_attr(feature = "trace", derive(Serialize))]
2963 #[cfg_attr(feature = "replay", derive(Deserialize))]
2964 pub enum PresentMode {
2965     /// Chooses FifoRelaxed -> Fifo based on availability.
2966     ///
2967     /// Because of the fallback behavior, it is supported everywhere.
2968     AutoVsync = 0,
2969     /// Chooses Immediate -> Mailbox -> Fifo (on web) based on availability.
2970     ///
2971     /// Because of the fallback behavior, it is supported everywhere.
2972     AutoNoVsync = 1,
2973     /// Presentation frames are kept in a First-In-First-Out queue approximately 3 frames
2974     /// long. Every vertical blanking period, the presentation engine will pop a frame
2975     /// off the queue to display. If there is no frame to display, it will present the same
2976     /// frame again until the next vblank.
2977     ///
2978     /// When a present command is executed on the gpu, the presented image is added on the queue.
2979     ///
2980     /// No tearing will be observed.
2981     ///
2982     /// Calls to get_current_texture will block until there is a spot in the queue.
2983     ///
2984     /// Supported on all platforms.
2985     ///
2986     /// If you don't know what mode to choose, choose this mode. This is traditionally called "Vsync On".
2987     Fifo = 2,
2988     /// Presentation frames are kept in a First-In-First-Out queue approximately 3 frames
2989     /// long. Every vertical blanking period, the presentation engine will pop a frame
2990     /// off the queue to display. If there is no frame to display, it will present the
2991     /// same frame until there is a frame in the queue. The moment there is a frame in the
2992     /// queue, it will immediately pop the frame off the queue.
2993     ///
2994     /// When a present command is executed on the gpu, the presented image is added on the queue.
2995     ///
2996     /// Tearing will be observed if frames last more than one vblank as the front buffer.
2997     ///
2998     /// Calls to get_current_texture will block until there is a spot in the queue.
2999     ///
3000     /// Supported on AMD on Vulkan.
3001     ///
3002     /// This is traditionally called "Adaptive Vsync"
3003     FifoRelaxed = 3,
3004     /// Presentation frames are not queued at all. The moment a present command
3005     /// is executed on the GPU, the presented image is swapped onto the front buffer
3006     /// immediately.
3007     ///
3008     /// Tearing can be observed.
3009     ///
3010     /// Supported on most platforms except older DX12 and Wayland.
3011     ///
3012     /// This is traditionally called "Vsync Off".
3013     Immediate = 4,
3014     /// Presentation frames are kept in a single-frame queue. Every vertical blanking period,
3015     /// the presentation engine will pop a frame from the queue. If there is no frame to display,
3016     /// it will present the same frame again until the next vblank.
3017     ///
3018     /// When a present command is executed on the gpu, the frame will be put into the queue.
3019     /// If there was already a frame in the queue, the new frame will _replace_ the old frame
3020     /// on the queue.
3021     ///
3022     /// No tearing will be observed.
3023     ///
3024     /// Supported on DX11/12 on Windows 10, NVidia on Vulkan and Wayland on Vulkan.
3025     ///
3026     /// This is traditionally called "Fast Vsync"
3027     Mailbox = 5,
3030 impl Default for PresentMode {
3031     fn default() -> Self {
3032         Self::Fifo
3033     }
3036 bitflags::bitflags! {
3037     /// Different ways that you can use a texture.
3038     ///
3039     /// The usages determine what kind of memory the texture is allocated from and what
3040     /// actions the texture can partake in.
3041     ///
3042     /// Corresponds to [WebGPU `GPUTextureUsageFlags`](
3043     /// https://gpuweb.github.io/gpuweb/#typedefdef-gputextureusageflags).
3044     #[repr(transparent)]
3045     pub struct TextureUsages: u32 {
3046         /// Allows a texture to be the source in a [`CommandEncoder::copy_texture_to_buffer`] or
3047         /// [`CommandEncoder::copy_texture_to_texture`] operation.
3048         const COPY_SRC = 1 << 0;
3049         /// Allows a texture to be the destination in a  [`CommandEncoder::copy_buffer_to_texture`],
3050         /// [`CommandEncoder::copy_texture_to_texture`], or [`Queue::write_texture`] operation.
3051         const COPY_DST = 1 << 1;
3052         /// Allows a texture to be a [`BindingType::Texture`] in a bind group.
3053         const TEXTURE_BINDING = 1 << 2;
3054         /// Allows a texture to be a [`BindingType::StorageTexture`] in a bind group.
3055         const STORAGE_BINDING = 1 << 3;
3056         /// Allows a texture to be an output attachment of a renderpass.
3057         const RENDER_ATTACHMENT = 1 << 4;
3058     }
3061 #[cfg(feature = "bitflags_serde_shim")]
3062 bitflags_serde_shim::impl_serde_for_bitflags!(TextureUsages);
3064 /// Configures a [`Surface`] for presentation.
3066 /// [`Surface`]: ../wgpu/struct.Surface.html
3067 #[repr(C)]
3068 #[derive(Clone, Debug, PartialEq, Eq, Hash)]
3069 #[cfg_attr(feature = "trace", derive(Serialize))]
3070 #[cfg_attr(feature = "replay", derive(Deserialize))]
3071 pub struct SurfaceConfiguration {
3072     /// The usage of the swap chain. The only supported usage is `RENDER_ATTACHMENT`.
3073     pub usage: TextureUsages,
3074     /// The texture format of the swap chain. The only formats that are guaranteed are
3075     /// `Bgra8Unorm` and `Bgra8UnormSrgb`
3076     pub format: TextureFormat,
3077     /// Width of the swap chain. Must be the same size as the surface.
3078     pub width: u32,
3079     /// Height of the swap chain. Must be the same size as the surface.
3080     pub height: u32,
3081     /// Presentation mode of the swap chain. Fifo is the only mode guaranteed to be supported.
3082     /// FifoRelaxed, Immediate, and Mailbox will crash if unsupported, while AutoVsync and
3083     /// AutoNoVsync will gracefully do a designed sets of fallbacks if their primary modes are
3084     /// unsupported.
3085     pub present_mode: PresentMode,
3088 /// Status of the recieved surface image.
3089 #[repr(C)]
3090 #[derive(Debug)]
3091 pub enum SurfaceStatus {
3092     /// No issues.
3093     Good,
3094     /// The swap chain is operational, but it does no longer perfectly
3095     /// match the surface. A re-configuration is needed.
3096     Suboptimal,
3097     /// Unable to get the next frame, timed out.
3098     Timeout,
3099     /// The surface under the swap chain has changed.
3100     Outdated,
3101     /// The surface under the swap chain is lost.
3102     Lost,
3105 /// RGBA double precision color.
3107 /// This is not to be used as a generic color type, only for specific wgpu interfaces.
3108 #[repr(C)]
3109 #[derive(Clone, Copy, Debug, Default, PartialEq)]
3110 #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3111 #[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
3112 pub struct Color {
3113     ///
3114     pub r: f64,
3115     ///
3116     pub g: f64,
3117     ///
3118     pub b: f64,
3119     ///
3120     pub a: f64,
3123 #[allow(missing_docs)]
3124 impl Color {
3125     pub const TRANSPARENT: Self = Self {
3126         r: 0.0,
3127         g: 0.0,
3128         b: 0.0,
3129         a: 0.0,
3130     };
3131     pub const BLACK: Self = Self {
3132         r: 0.0,
3133         g: 0.0,
3134         b: 0.0,
3135         a: 1.0,
3136     };
3137     pub const WHITE: Self = Self {
3138         r: 1.0,
3139         g: 1.0,
3140         b: 1.0,
3141         a: 1.0,
3142     };
3143     pub const RED: Self = Self {
3144         r: 1.0,
3145         g: 0.0,
3146         b: 0.0,
3147         a: 1.0,
3148     };
3149     pub const GREEN: Self = Self {
3150         r: 0.0,
3151         g: 1.0,
3152         b: 0.0,
3153         a: 1.0,
3154     };
3155     pub const BLUE: Self = Self {
3156         r: 0.0,
3157         g: 0.0,
3158         b: 1.0,
3159         a: 1.0,
3160     };
3163 /// Dimensionality of a texture.
3165 /// Corresponds to [WebGPU `GPUTextureDimension`](
3166 /// https://gpuweb.github.io/gpuweb/#enumdef-gputexturedimension).
3167 #[repr(C)]
3168 #[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
3169 #[cfg_attr(feature = "trace", derive(Serialize))]
3170 #[cfg_attr(feature = "replay", derive(Deserialize))]
3171 pub enum TextureDimension {
3172     /// 1D texture
3173     #[cfg_attr(feature = "serde", serde(rename = "1d"))]
3174     D1,
3175     /// 2D texture
3176     #[cfg_attr(feature = "serde", serde(rename = "2d"))]
3177     D2,
3178     /// 3D texture
3179     #[cfg_attr(feature = "serde", serde(rename = "3d"))]
3180     D3,
3183 /// Origin of a copy to/from a texture.
3185 /// Corresponds to [WebGPU `GPUOrigin3D`](
3186 /// https://gpuweb.github.io/gpuweb/#typedefdef-gpuorigin3d).
3187 #[repr(C)]
3188 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
3189 #[cfg_attr(feature = "trace", derive(Serialize))]
3190 #[cfg_attr(feature = "replay", derive(Deserialize))]
3191 #[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
3192 pub struct Origin3d {
3193     ///
3194     pub x: u32,
3195     ///
3196     pub y: u32,
3197     ///
3198     pub z: u32,
3201 impl Origin3d {
3202     /// Zero origin.
3203     pub const ZERO: Self = Self { x: 0, y: 0, z: 0 };
3206 impl Default for Origin3d {
3207     fn default() -> Self {
3208         Self::ZERO
3209     }
3212 /// Extent of a texture related operation.
3214 /// Corresponds to [WebGPU `GPUExtent3D`](
3215 /// https://gpuweb.github.io/gpuweb/#typedefdef-gpuextent3d).
3216 #[repr(C)]
3217 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
3218 #[cfg_attr(feature = "trace", derive(Serialize))]
3219 #[cfg_attr(feature = "replay", derive(Deserialize))]
3220 #[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
3221 pub struct Extent3d {
3222     ///
3223     pub width: u32,
3224     ///
3225     pub height: u32,
3226     ///
3227     #[cfg_attr(feature = "serde", serde(default = "default_depth"))]
3228     pub depth_or_array_layers: u32,
3231 #[cfg(feature = "serde")]
3232 fn default_depth() -> u32 {
3233     1
3236 impl Default for Extent3d {
3237     fn default() -> Self {
3238         Self {
3239             width: 1,
3240             height: 1,
3241             depth_or_array_layers: 1,
3242         }
3243     }
3246 impl Extent3d {
3247     /// Calculates the [physical size] backing a texture of the given
3248     /// format and extent.  This includes padding to the block width
3249     /// and height of the format.
3250     ///
3251     /// This is the texture extent that you must upload at when uploading to _mipmaps_ of compressed textures.
3252     ///
3253     /// [physical size]: https://gpuweb.github.io/gpuweb/#physical-miplevel-specific-texture-extent
3254     pub fn physical_size(&self, format: TextureFormat) -> Self {
3255         let (block_width, block_height) = format.describe().block_dimensions;
3256         let block_width = block_width as u32;
3257         let block_height = block_height as u32;
3259         let width = ((self.width + block_width - 1) / block_width) * block_width;
3260         let height = ((self.height + block_height - 1) / block_height) * block_height;
3262         Self {
3263             width,
3264             height,
3265             depth_or_array_layers: self.depth_or_array_layers,
3266         }
3267     }
3269     /// Calculates the maximum possible count of mipmaps.
3270     ///
3271     /// Treats the depth as part of the mipmaps. If calculating
3272     /// for a 2DArray texture, which does not mipmap depth, set depth to 1.
3273     pub fn max_mips(&self, dim: TextureDimension) -> u32 {
3274         match dim {
3275             TextureDimension::D1 => 1,
3276             TextureDimension::D2 => {
3277                 let max_dim = self.width.max(self.height);
3278                 32 - max_dim.leading_zeros()
3279             }
3280             TextureDimension::D3 => {
3281                 let max_dim = self.width.max(self.height.max(self.depth_or_array_layers));
3282                 32 - max_dim.leading_zeros()
3283             }
3284         }
3285     }
3287     /// Calculates the extent at a given mip level.
3288     /// Does *not* account for memory size being a multiple of block size.
3289     pub fn mip_level_size(&self, level: u32, is_3d_texture: bool) -> Extent3d {
3290         Extent3d {
3291             width: u32::max(1, self.width >> level),
3292             height: u32::max(1, self.height >> level),
3293             depth_or_array_layers: match is_3d_texture {
3294                 false => self.depth_or_array_layers,
3295                 true => u32::max(1, self.depth_or_array_layers >> level),
3296             },
3297         }
3298     }
3301 #[test]
3302 fn test_physical_size() {
3303     let format = TextureFormat::Bc1RgbaUnormSrgb; // 4x4 blocks
3304     assert_eq!(
3305         Extent3d {
3306             width: 7,
3307             height: 7,
3308             depth_or_array_layers: 1
3309         }
3310         .physical_size(format),
3311         Extent3d {
3312             width: 8,
3313             height: 8,
3314             depth_or_array_layers: 1
3315         }
3316     );
3317     // Doesn't change, already aligned
3318     assert_eq!(
3319         Extent3d {
3320             width: 8,
3321             height: 8,
3322             depth_or_array_layers: 1
3323         }
3324         .physical_size(format),
3325         Extent3d {
3326             width: 8,
3327             height: 8,
3328             depth_or_array_layers: 1
3329         }
3330     );
3331     let format = TextureFormat::Astc {
3332         block: AstcBlock::B8x5,
3333         channel: AstcChannel::Unorm,
3334     }; // 8x5 blocks
3335     assert_eq!(
3336         Extent3d {
3337             width: 7,
3338             height: 7,
3339             depth_or_array_layers: 1
3340         }
3341         .physical_size(format),
3342         Extent3d {
3343             width: 8,
3344             height: 10,
3345             depth_or_array_layers: 1
3346         }
3347     );
3350 #[test]
3351 fn test_max_mips() {
3352     // 1D
3353     assert_eq!(
3354         Extent3d {
3355             width: 240,
3356             height: 1,
3357             depth_or_array_layers: 1
3358         }
3359         .max_mips(TextureDimension::D1),
3360         1
3361     );
3362     // 2D
3363     assert_eq!(
3364         Extent3d {
3365             width: 1,
3366             height: 1,
3367             depth_or_array_layers: 1
3368         }
3369         .max_mips(TextureDimension::D2),
3370         1
3371     );
3372     assert_eq!(
3373         Extent3d {
3374             width: 60,
3375             height: 60,
3376             depth_or_array_layers: 1
3377         }
3378         .max_mips(TextureDimension::D2),
3379         6
3380     );
3381     assert_eq!(
3382         Extent3d {
3383             width: 240,
3384             height: 1,
3385             depth_or_array_layers: 1000
3386         }
3387         .max_mips(TextureDimension::D2),
3388         8
3389     );
3390     // 3D
3391     assert_eq!(
3392         Extent3d {
3393             width: 16,
3394             height: 30,
3395             depth_or_array_layers: 60
3396         }
3397         .max_mips(TextureDimension::D3),
3398         6
3399     );
3402 /// Describes a [`Texture`](../wgpu/struct.Texture.html).
3404 /// Corresponds to [WebGPU `GPUTextureDescriptor`](
3405 /// https://gpuweb.github.io/gpuweb/#dictdef-gputexturedescriptor).
3406 #[repr(C)]
3407 #[derive(Clone, Debug, PartialEq, Eq, Hash)]
3408 #[cfg_attr(feature = "trace", derive(Serialize))]
3409 #[cfg_attr(feature = "replay", derive(Deserialize))]
3410 pub struct TextureDescriptor<L> {
3411     /// Debug label of the texture. This will show up in graphics debuggers for easy identification.
3412     pub label: L,
3413     /// Size of the texture. All components must be greater than zero. For a
3414     /// regular 1D/2D texture, the unused sizes will be 1. For 2DArray textures,
3415     /// Z is the number of 2D textures in that array.
3416     pub size: Extent3d,
3417     /// Mip count of texture. For a texture with no extra mips, this must be 1.
3418     pub mip_level_count: u32,
3419     /// Sample count of texture. If this is not 1, texture must have [`BindingType::Texture::multisampled`] set to true.
3420     pub sample_count: u32,
3421     /// Dimensions of the texture.
3422     pub dimension: TextureDimension,
3423     /// Format of the texture.
3424     pub format: TextureFormat,
3425     /// Allowed usages of the texture. If used in other ways, the operation will panic.
3426     pub usage: TextureUsages,
3427     // TODO: missing view_formats https://www.w3.org/TR/webgpu/#dom-gputexturedescriptor-viewformats
3430 impl<L> TextureDescriptor<L> {
3431     ///
3432     pub fn map_label<K>(&self, fun: impl FnOnce(&L) -> K) -> TextureDescriptor<K> {
3433         TextureDescriptor {
3434             label: fun(&self.label),
3435             size: self.size,
3436             mip_level_count: self.mip_level_count,
3437             sample_count: self.sample_count,
3438             dimension: self.dimension,
3439             format: self.format,
3440             usage: self.usage,
3441         }
3442     }
3444     /// Calculates the extent at a given mip level.
3445     ///
3446     /// If the given mip level is larger than possible, returns None.
3447     ///
3448     /// Treats the depth as part of the mipmaps. If calculating
3449     /// for a 2DArray texture, which does not mipmap depth, set depth to 1.
3450     ///
3451     /// ```rust
3452     /// # use wgpu_types as wgpu;
3453     /// let desc = wgpu::TextureDescriptor {
3454     ///   label: (),
3455     ///   size: wgpu::Extent3d { width: 100, height: 60, depth_or_array_layers: 1 },
3456     ///   mip_level_count: 7,
3457     ///   sample_count: 1,
3458     ///   dimension: wgpu::TextureDimension::D3,
3459     ///   format: wgpu::TextureFormat::Rgba8Sint,
3460     ///   usage: wgpu::TextureUsages::empty(),
3461     /// };
3462     ///
3463     /// assert_eq!(desc.mip_level_size(0), Some(wgpu::Extent3d { width: 100, height: 60, depth_or_array_layers: 1 }));
3464     /// assert_eq!(desc.mip_level_size(1), Some(wgpu::Extent3d { width: 50, height: 30, depth_or_array_layers: 1 }));
3465     /// assert_eq!(desc.mip_level_size(2), Some(wgpu::Extent3d { width: 25, height: 15, depth_or_array_layers: 1 }));
3466     /// assert_eq!(desc.mip_level_size(3), Some(wgpu::Extent3d { width: 12, height: 7, depth_or_array_layers: 1 }));
3467     /// assert_eq!(desc.mip_level_size(4), Some(wgpu::Extent3d { width: 6, height: 3, depth_or_array_layers: 1 }));
3468     /// assert_eq!(desc.mip_level_size(5), Some(wgpu::Extent3d { width: 3, height: 1, depth_or_array_layers: 1 }));
3469     /// assert_eq!(desc.mip_level_size(6), Some(wgpu::Extent3d { width: 1, height: 1, depth_or_array_layers: 1 }));
3470     /// assert_eq!(desc.mip_level_size(7), None);
3471     /// ```
3472     pub fn mip_level_size(&self, level: u32) -> Option<Extent3d> {
3473         if level >= self.mip_level_count {
3474             return None;
3475         }
3477         Some(
3478             self.size
3479                 .mip_level_size(level, self.dimension == TextureDimension::D3),
3480         )
3481     }
3483     /// Returns the number of array layers.
3484     pub fn array_layer_count(&self) -> u32 {
3485         match self.dimension {
3486             TextureDimension::D1 | TextureDimension::D3 => 1,
3487             TextureDimension::D2 => self.size.depth_or_array_layers,
3488         }
3489     }
3492 /// Kind of data the texture holds.
3494 /// Corresponds to [WebGPU `GPUTextureAspect`](
3495 /// https://gpuweb.github.io/gpuweb/#enumdef-gputextureaspect).
3496 #[repr(C)]
3497 #[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
3498 #[cfg_attr(feature = "trace", derive(Serialize))]
3499 #[cfg_attr(feature = "replay", derive(Deserialize))]
3500 #[cfg_attr(feature = "serde", serde(rename_all = "kebab-case"))]
3501 pub enum TextureAspect {
3502     /// Depth, Stencil, and Color.
3503     All,
3504     /// Stencil.
3505     StencilOnly,
3506     /// Depth.
3507     DepthOnly,
3510 impl Default for TextureAspect {
3511     fn default() -> Self {
3512         Self::All
3513     }
3516 /// How edges should be handled in texture addressing.
3518 /// Corresponds to [WebGPU `GPUAddressMode`](
3519 /// https://gpuweb.github.io/gpuweb/#enumdef-gpuaddressmode).
3520 #[repr(C)]
3521 #[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
3522 #[cfg_attr(feature = "trace", derive(Serialize))]
3523 #[cfg_attr(feature = "replay", derive(Deserialize))]
3524 #[cfg_attr(feature = "serde", serde(rename_all = "kebab-case"))]
3525 pub enum AddressMode {
3526     /// Clamp the value to the edge of the texture
3527     ///
3528     /// -0.25 -> 0.0
3529     /// 1.25  -> 1.0
3530     ClampToEdge = 0,
3531     /// Repeat the texture in a tiling fashion
3532     ///
3533     /// -0.25 -> 0.75
3534     /// 1.25 -> 0.25
3535     Repeat = 1,
3536     /// Repeat the texture, mirroring it every repeat
3537     ///
3538     /// -0.25 -> 0.25
3539     /// 1.25 -> 0.75
3540     MirrorRepeat = 2,
3541     /// Clamp the value to the border of the texture
3542     /// Requires feature [`Features::ADDRESS_MODE_CLAMP_TO_BORDER`]
3543     ///
3544     /// -0.25 -> border
3545     /// 1.25 -> border
3546     ClampToBorder = 3,
3549 impl Default for AddressMode {
3550     fn default() -> Self {
3551         Self::ClampToEdge
3552     }
3555 /// Texel mixing mode when sampling between texels.
3557 /// Corresponds to [WebGPU `GPUFilterMode`](
3558 /// https://gpuweb.github.io/gpuweb/#enumdef-gpufiltermode).
3559 #[repr(C)]
3560 #[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
3561 #[cfg_attr(feature = "trace", derive(Serialize))]
3562 #[cfg_attr(feature = "replay", derive(Deserialize))]
3563 #[cfg_attr(feature = "serde", serde(rename_all = "kebab-case"))]
3564 pub enum FilterMode {
3565     /// Nearest neighbor sampling.
3566     ///
3567     /// This creates a pixelated effect when used as a mag filter
3568     Nearest = 0,
3569     /// Linear Interpolation
3570     ///
3571     /// This makes textures smooth but blurry when used as a mag filter.
3572     Linear = 1,
3575 impl Default for FilterMode {
3576     fn default() -> Self {
3577         Self::Nearest
3578     }
3581 /// A range of push constant memory to pass to a shader stage.
3582 #[derive(Clone, Debug, PartialEq, Eq, Hash)]
3583 #[cfg_attr(feature = "trace", derive(Serialize))]
3584 #[cfg_attr(feature = "replay", derive(Deserialize))]
3585 pub struct PushConstantRange {
3586     /// Stage push constant range is visible from. Each stage can only be served by at most one range.
3587     /// One range can serve multiple stages however.
3588     pub stages: ShaderStages,
3589     /// Range in push constant memory to use for the stage. Must be less than [`Limits::max_push_constant_size`].
3590     /// Start and end must be aligned to the 4s.
3591     pub range: Range<u32>,
3594 /// Describes a [`CommandBuffer`](../wgpu/struct.CommandBuffer.html).
3596 /// Corresponds to [WebGPU `GPUCommandBufferDescriptor`](
3597 /// https://gpuweb.github.io/gpuweb/#dictdef-gpucommandbufferdescriptor).
3598 #[repr(C)]
3599 #[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
3600 #[cfg_attr(feature = "trace", derive(Serialize))]
3601 #[cfg_attr(feature = "replay", derive(Deserialize))]
3602 pub struct CommandBufferDescriptor<L> {
3603     /// Debug label of this command buffer.
3604     pub label: L,
3607 impl<L> CommandBufferDescriptor<L> {
3608     ///
3609     pub fn map_label<K>(&self, fun: impl FnOnce(&L) -> K) -> CommandBufferDescriptor<K> {
3610         CommandBufferDescriptor {
3611             label: fun(&self.label),
3612         }
3613     }
3616 /// Describes the depth/stencil attachment for render bundles.
3618 /// Corresponds to a portion of [WebGPU `GPURenderBundleEncoderDescriptor`](
3619 /// https://gpuweb.github.io/gpuweb/#dictdef-gpurenderbundleencoderdescriptor).
3620 #[repr(C)]
3621 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
3622 #[cfg_attr(feature = "trace", derive(serde::Serialize))]
3623 #[cfg_attr(feature = "replay", derive(serde::Deserialize))]
3624 pub struct RenderBundleDepthStencil {
3625     /// Format of the attachment.
3626     pub format: TextureFormat,
3627     /// True if the depth aspect is used but not modified.
3628     pub depth_read_only: bool,
3629     /// True if the stencil aspect is used but not modified.
3630     pub stencil_read_only: bool,
3633 /// Describes a [`RenderBundle`](../wgpu/struct.RenderBundle.html).
3635 /// Corresponds to [WebGPU `GPURenderBundleDescriptor`](
3636 /// https://gpuweb.github.io/gpuweb/#dictdef-gpurenderbundledescriptor).
3637 #[repr(C)]
3638 #[derive(Clone, Debug, PartialEq, Eq, Hash)]
3639 #[cfg_attr(feature = "trace", derive(Serialize))]
3640 #[cfg_attr(feature = "replay", derive(Deserialize))]
3641 pub struct RenderBundleDescriptor<L> {
3642     /// Debug label of the render bundle encoder. This will show up in graphics debuggers for easy identification.
3643     pub label: L,
3646 impl<L> RenderBundleDescriptor<L> {
3647     ///
3648     pub fn map_label<K>(&self, fun: impl FnOnce(&L) -> K) -> RenderBundleDescriptor<K> {
3649         RenderBundleDescriptor {
3650             label: fun(&self.label),
3651         }
3652     }
3655 impl<T> Default for RenderBundleDescriptor<Option<T>> {
3656     fn default() -> Self {
3657         Self { label: None }
3658     }
3661 /// Layout of a texture in a buffer's memory.
3663 /// The bytes per row and rows per image can be hard to figure out so here are some examples:
3665 /// | Resolution | Format | Bytes per block | Pixels per block | Bytes per row                          | Rows per image               |
3666 /// |------------|--------|-----------------|------------------|----------------------------------------|------------------------------|
3667 /// | 256x256    | RGBA8  | 4               | 1 * 1 * 1        | 256 * 4 = Some(1024)                   | None                         |
3668 /// | 32x16x8    | RGBA8  | 4               | 1 * 1 * 1        | 32 * 4 = 128 padded to 256 = Some(256) | None                         |
3669 /// | 256x256    | BC3    | 16              | 4 * 4 * 1        | 16 * (256 / 4) = 1024 = Some(1024)     | None                         |
3670 /// | 64x64x8    | BC3    | 16              | 4 * 4 * 1        | 16 * (64 / 4) = 256 = Some(256)        | 64 / 4 = 16 = Some(16)       |
3672 /// Corresponds to [WebGPU `GPUImageDataLayout`](
3673 /// https://gpuweb.github.io/gpuweb/#dictdef-gpuimagedatalayout).
3674 #[repr(C)]
3675 #[derive(Clone, Copy, Debug, Default)]
3676 #[cfg_attr(feature = "trace", derive(serde::Serialize))]
3677 #[cfg_attr(feature = "replay", derive(serde::Deserialize))]
3678 pub struct ImageDataLayout {
3679     /// Offset into the buffer that is the start of the texture. Must be a multiple of texture block size.
3680     /// For non-compressed textures, this is 1.
3681     pub offset: BufferAddress,
3682     /// Bytes per "row" in an image.
3683     ///
3684     /// A row is one row of pixels or of compressed blocks in the x direction.
3685     ///
3686     /// This value is required if there are multiple rows (i.e. height or depth is more than one pixel or pixel block for compressed textures)
3687     ///
3688     /// Must be a multiple of 256 for [`CommandEncoder::copy_buffer_to_texture`][CEcbtt]
3689     /// and [`CommandEncoder::copy_texture_to_buffer`][CEcttb]. You must manually pad the
3690     /// image such that this is a multiple of 256. It will not affect the image data.
3691     ///
3692     /// [`Queue::write_texture`][Qwt] does not have this requirement.
3693     ///
3694     /// Must be a multiple of the texture block size. For non-compressed textures, this is 1.
3695     ///
3696     /// [CEcbtt]: ../wgpu/struct.CommandEncoder.html#method.copy_buffer_to_texture
3697     /// [CEcttb]: ../wgpu/struct.CommandEncoder.html#method.copy_texture_to_buffer
3698     /// [Qwt]: ../wgpu/struct.Queue.html#method.write_texture
3699     pub bytes_per_row: Option<NonZeroU32>,
3700     /// "Rows" that make up a single "image".
3701     ///
3702     /// A row is one row of pixels or of compressed blocks in the x direction.
3703     ///
3704     /// An image is one layer in the z direction of a 3D image or 2DArray texture.
3705     ///
3706     /// The amount of rows per image may be larger than the actual amount of rows of data.
3707     ///
3708     /// Required if there are multiple images (i.e. the depth is more than one).
3709     pub rows_per_image: Option<NonZeroU32>,
3712 /// Specific type of a buffer binding.
3714 /// Corresponds to [WebGPU `GPUBufferBindingType`](
3715 /// https://gpuweb.github.io/gpuweb/#enumdef-gpubufferbindingtype).
3716 #[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
3717 #[cfg_attr(feature = "trace", derive(Serialize))]
3718 #[cfg_attr(feature = "replay", derive(Deserialize))]
3719 pub enum BufferBindingType {
3720     /// A buffer for uniform values.
3721     ///
3722     /// Example WGSL syntax:
3723     /// ```rust,ignore
3724     /// struct Globals {
3725     ///     a_uniform: vec2<f32>,
3726     ///     another_uniform: vec2<f32>,
3727     /// }
3728     /// @group(0) @binding(0)
3729     /// var<uniform> globals: Globals;
3730     /// ```
3731     ///
3732     /// Example GLSL syntax:
3733     /// ```cpp,ignore
3734     /// layout(std140, binding = 0)
3735     /// uniform Globals {
3736     ///     vec2 aUniform;
3737     ///     vec2 anotherUniform;
3738     /// };
3739     /// ```
3740     Uniform,
3741     /// A storage buffer.
3742     ///
3743     /// Example WGSL syntax:
3744     /// ```rust,ignore
3745     /// @group(0) @binding(0)
3746     /// var<storage, read_write> my_element: array<vec4<f32>>;
3747     /// ```
3748     ///
3749     /// Example GLSL syntax:
3750     /// ```cpp,ignore
3751     /// layout (set=0, binding=0) buffer myStorageBuffer {
3752     ///     vec4 myElement[];
3753     /// };
3754     /// ```
3755     Storage {
3756         /// If `true`, the buffer can only be read in the shader,
3757         /// and it:
3758         /// - may or may not be annotated with `read` (WGSL).
3759         /// - must be annotated with `readonly` (GLSL).
3760         ///
3761         /// Example WGSL syntax:
3762         /// ```rust,ignore
3763         /// @group(0) @binding(0)
3764         /// var<storage, read> my_element: array<vec4<f32>>;
3765         /// ```
3766         ///
3767         /// Example GLSL syntax:
3768         /// ```cpp,ignore
3769         /// layout (set=0, binding=0) readonly buffer myStorageBuffer {
3770         ///     vec4 myElement[];
3771         /// };
3772         /// ```
3773         read_only: bool,
3774     },
3777 impl Default for BufferBindingType {
3778     fn default() -> Self {
3779         Self::Uniform
3780     }
3783 /// Specific type of a sample in a texture binding.
3785 /// Corresponds to [WebGPU `GPUTextureSampleType`](
3786 /// https://gpuweb.github.io/gpuweb/#enumdef-gputexturesampletype).
3787 #[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
3788 #[cfg_attr(feature = "trace", derive(Serialize))]
3789 #[cfg_attr(feature = "replay", derive(Deserialize))]
3790 pub enum TextureSampleType {
3791     /// Sampling returns floats.
3792     ///
3793     /// Example WGSL syntax:
3794     /// ```rust,ignore
3795     /// @group(0) @binding(0)
3796     /// var t: texure_2d<f32>;
3797     /// ```
3798     ///
3799     /// Example GLSL syntax:
3800     /// ```cpp,ignore
3801     /// layout(binding = 0)
3802     /// uniform texture2D t;
3803     /// ```
3804     Float {
3805         /// If `filterable` is false, the texture can't be sampled with
3806         /// a filtering sampler.
3807         filterable: bool,
3808     },
3809     /// Sampling does the depth reference comparison.
3810     ///
3811     /// Example WGSL syntax:
3812     /// ```rust,ignore
3813     /// @group(0) @binding(0)
3814     /// var t: texture_depth_2d;
3815     /// ```
3816     ///
3817     /// Example GLSL syntax:
3818     /// ```cpp,ignore
3819     /// layout(binding = 0)
3820     /// uniform texture2DShadow t;
3821     /// ```
3822     Depth,
3823     /// Sampling returns signed integers.
3824     ///
3825     /// Example WGSL syntax:
3826     /// ```rust,ignore
3827     /// @group(0) @binding(0)
3828     /// var t: texture_2d<i32>;
3829     /// ```
3830     ///
3831     /// Example GLSL syntax:
3832     /// ```cpp,ignore
3833     /// layout(binding = 0)
3834     /// uniform itexture2D t;
3835     /// ```
3836     Sint,
3837     /// Sampling returns unsigned integers.
3838     ///
3839     /// Example WGSL syntax:
3840     /// ```rust,ignore
3841     /// @group(0) @binding(0)
3842     /// var t: texture_2d<u32>;
3843     /// ```
3844     ///
3845     /// Example GLSL syntax:
3846     /// ```cpp,ignore
3847     /// layout(binding = 0)
3848     /// uniform utexture2D t;
3849     /// ```
3850     Uint,
3853 impl Default for TextureSampleType {
3854     fn default() -> Self {
3855         Self::Float { filterable: true }
3856     }
3859 /// Specific type of a sample in a texture binding.
3861 /// For use in [`BindingType::StorageTexture`].
3863 /// Corresponds to [WebGPU `GPUStorageTextureAccess`](
3864 /// https://gpuweb.github.io/gpuweb/#enumdef-gpustoragetextureaccess).
3865 #[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
3866 #[cfg_attr(feature = "trace", derive(Serialize))]
3867 #[cfg_attr(feature = "replay", derive(Deserialize))]
3868 #[cfg_attr(feature = "serde", serde(rename_all = "kebab-case"))]
3869 pub enum StorageTextureAccess {
3870     /// The texture can only be written in the shader and it:
3871     /// - may or may not be annotated with `write` (WGSL).
3872     /// - must be annotated with `writeonly` (GLSL).
3873     ///
3874     /// Example WGSL syntax:
3875     /// ```rust,ignore
3876     /// @group(0) @binding(0)
3877     /// var my_storage_image: texture_storage_2d<f32, write>;
3878     /// ```
3879     ///
3880     /// Example GLSL syntax:
3881     /// ```cpp,ignore
3882     /// layout(set=0, binding=0, r32f) writeonly uniform image2D myStorageImage;
3883     /// ```
3884     WriteOnly,
3885     /// The texture can only be read in the shader and it must be annotated with `read` (WGSL) or
3886     /// `readonly` (GLSL).
3887     ///
3888     /// [`Features::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES`] must be enabled to use this access
3889     /// mode. This is a native-only extension.
3890     ///
3891     /// Example WGSL syntax:
3892     /// ```rust,ignore
3893     /// @group(0) @binding(0)
3894     /// var my_storage_image: texture_storage_2d<f32, read>;
3895     /// ```
3896     ///
3897     /// Example GLSL syntax:
3898     /// ```cpp,ignore
3899     /// layout(set=0, binding=0, r32f) readonly uniform image2D myStorageImage;
3900     /// ```
3901     ReadOnly,
3902     /// The texture can be both read and written in the shader and must be annotated with
3903     /// `read_write` in WGSL.
3904     ///
3905     /// [`Features::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES`] must be enabled to use this access
3906     /// mode.  This is a nonstandard, native-only extension.
3907     ///
3908     /// Example WGSL syntax:
3909     /// ```rust,ignore
3910     /// @group(0) @binding(0)
3911     /// var my_storage_image: texture_storage_2d<f32, read_write>;
3912     /// ```
3913     ///
3914     /// Example GLSL syntax:
3915     /// ```cpp,ignore
3916     /// layout(set=0, binding=0, r32f) uniform image2D myStorageImage;
3917     /// ```
3918     ReadWrite,
3921 /// Specific type of a sampler binding.
3923 /// For use in [`BindingType::Sampler`].
3925 /// Corresponds to [WebGPU `GPUSamplerBindingType`](
3926 /// https://gpuweb.github.io/gpuweb/#enumdef-gpusamplerbindingtype).
3927 #[repr(C)]
3928 #[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
3929 #[cfg_attr(feature = "trace", derive(Serialize))]
3930 #[cfg_attr(feature = "replay", derive(Deserialize))]
3931 #[cfg_attr(feature = "serde", serde(rename_all = "kebab-case"))]
3932 pub enum SamplerBindingType {
3933     /// The sampling result is produced based on more than a single color sample from a texture,
3934     /// e.g. when bilinear interpolation is enabled.
3935     Filtering,
3936     /// The sampling result is produced based on a single color sample from a texture.
3937     NonFiltering,
3938     /// Use as a comparison sampler instead of a normal sampler.
3939     /// For more info take a look at the analogous functionality in OpenGL: <https://www.khronos.org/opengl/wiki/Sampler_Object#Comparison_mode>.
3940     Comparison,
3943 /// Specific type of a binding.
3945 /// For use in [`BindGroupLayoutEntry`].
3947 /// Corresponds to WebGPU's mutually exclusive fields within [`GPUBindGroupLayoutEntry`](
3948 /// https://gpuweb.github.io/gpuweb/#dictdef-gpubindgrouplayoutentry).
3949 #[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
3950 #[cfg_attr(feature = "trace", derive(Serialize))]
3951 #[cfg_attr(feature = "replay", derive(Deserialize))]
3952 pub enum BindingType {
3953     /// A buffer binding.
3954     ///
3955     /// Corresponds to [WebGPU `GPUBufferBindingLayout`](
3956     /// https://gpuweb.github.io/gpuweb/#dictdef-gpubufferbindinglayout).
3957     Buffer {
3958         /// Sub-type of the buffer binding.
3959         ty: BufferBindingType,
3960         /// Indicates that the binding has a dynamic offset.
3961         ///
3962         /// One offset must be passed to [`RenderPass::set_bind_group`][RPsbg] for each dynamic
3963         /// binding in increasing order of binding number.
3964         ///
3965         /// [RPsbg]: ../wgpu/struct.RenderPass.html#method.set_bind_group
3966         #[cfg_attr(any(feature = "trace", feature = "replay"), serde(default))]
3967         has_dynamic_offset: bool,
3968         /// Minimum size of the corresponding `BufferBinding` required to match this entry.
3969         /// When pipeline is created, the size has to cover at least the corresponding structure in the shader
3970         /// plus one element of the unbound array, which can only be last in the structure.
3971         /// If `None`, the check is performed at draw call time instead of pipeline and bind group creation.
3972         #[cfg_attr(any(feature = "trace", feature = "replay"), serde(default))]
3973         min_binding_size: Option<BufferSize>,
3974     },
3975     /// A sampler that can be used to sample a texture.
3976     ///
3977     /// Example WGSL syntax:
3978     /// ```rust,ignore
3979     /// @group(0) @binding(0)
3980     /// var s: sampler;
3981     /// ```
3982     ///
3983     /// Example GLSL syntax:
3984     /// ```cpp,ignore
3985     /// layout(binding = 0)
3986     /// uniform sampler s;
3987     /// ```
3988     ///
3989     /// Corresponds to [WebGPU `GPUSamplerBindingLayout`](
3990     /// https://gpuweb.github.io/gpuweb/#dictdef-gpusamplerbindinglayout).
3991     Sampler(SamplerBindingType),
3992     /// A texture binding.
3993     ///
3994     /// Example WGSL syntax:
3995     /// ```rust,ignore
3996     /// @group(0) @binding(0)
3997     /// var t: texture_2d<f32>;
3998     /// ```
3999     ///
4000     /// Example GLSL syntax:
4001     /// ```cpp,ignore
4002     /// layout(binding = 0)
4003     /// uniform texture2D t;
4004     /// ```
4005     ///
4006     /// Corresponds to [WebGPU `GPUTextureBindingLayout`](
4007     /// https://gpuweb.github.io/gpuweb/#dictdef-gputexturebindinglayout).
4008     Texture {
4009         /// Sample type of the texture binding.
4010         sample_type: TextureSampleType,
4011         /// Dimension of the texture view that is going to be sampled.
4012         view_dimension: TextureViewDimension,
4013         /// True if the texture has a sample count greater than 1. If this is true,
4014         /// the texture must be read from shaders with `texture1DMS`, `texture2DMS`, or `texture3DMS`,
4015         /// depending on `dimension`.
4016         multisampled: bool,
4017     },
4018     /// A storage texture.
4019     ///
4020     /// Example WGSL syntax:
4021     /// ```rust,ignore
4022     /// @group(0) @binding(0)
4023     /// var my_storage_image: texture_storage_2d<f32, write>;
4024     /// ```
4025     ///
4026     /// Example GLSL syntax:
4027     /// ```cpp,ignore
4028     /// layout(set=0, binding=0, r32f) writeonly uniform image2D myStorageImage;
4029     /// ```
4030     /// Note that the texture format must be specified in the shader as well.
4031     /// A list of valid formats can be found in the specification here: <https://www.khronos.org/registry/OpenGL/specs/gl/GLSLangSpec.4.60.html#layout-qualifiers>
4032     ///
4033     /// Corresponds to [WebGPU `GPUStorageTextureBindingLayout`](
4034     /// https://gpuweb.github.io/gpuweb/#dictdef-gpustoragetexturebindinglayout).
4035     StorageTexture {
4036         /// Allowed access to this texture.
4037         access: StorageTextureAccess,
4038         /// Format of the texture.
4039         format: TextureFormat,
4040         /// Dimension of the texture view that is going to be sampled.
4041         view_dimension: TextureViewDimension,
4042     },
4045 impl BindingType {
4046     /// Returns true for buffer bindings with dynamic offset enabled.
4047     pub fn has_dynamic_offset(&self) -> bool {
4048         match *self {
4049             Self::Buffer {
4050                 has_dynamic_offset, ..
4051             } => has_dynamic_offset,
4052             _ => false,
4053         }
4054     }
4057 /// Describes a single binding inside a bind group.
4059 /// Corresponds to [WebGPU `GPUBindGroupLayoutEntry`](
4060 /// https://gpuweb.github.io/gpuweb/#dictdef-gpubindgrouplayoutentry).
4061 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
4062 #[cfg_attr(feature = "trace", derive(Serialize))]
4063 #[cfg_attr(feature = "replay", derive(Deserialize))]
4064 pub struct BindGroupLayoutEntry {
4065     /// Binding index. Must match shader index and be unique inside a BindGroupLayout. A binding
4066     /// of index 1, would be described as `layout(set = 0, binding = 1) uniform` in shaders.
4067     pub binding: u32,
4068     /// Which shader stages can see this binding.
4069     pub visibility: ShaderStages,
4070     /// The type of the binding
4071     pub ty: BindingType,
4072     /// If this value is Some, indicates this entry is an array. Array size must be 1 or greater.
4073     ///
4074     /// If this value is Some and `ty` is `BindingType::Texture`, [`Features::TEXTURE_BINDING_ARRAY`] must be supported.
4075     ///
4076     /// If this value is Some and `ty` is any other variant, bind group creation will fail.
4077     #[cfg_attr(any(feature = "trace", feature = "replay"), serde(default))]
4078     pub count: Option<NonZeroU32>,
4081 /// View of a buffer which can be used to copy to/from a texture.
4083 /// Corresponds to [WebGPU `GPUImageCopyBuffer`](
4084 /// https://gpuweb.github.io/gpuweb/#dictdef-gpuimagecopybuffer).
4085 #[repr(C)]
4086 #[derive(Clone, Debug)]
4087 #[cfg_attr(feature = "trace", derive(serde::Serialize))]
4088 #[cfg_attr(feature = "replay", derive(serde::Deserialize))]
4089 pub struct ImageCopyBuffer<B> {
4090     /// The buffer to be copied to/from.
4091     pub buffer: B,
4092     /// The layout of the texture data in this buffer.
4093     pub layout: ImageDataLayout,
4096 /// View of a texture which can be used to copy to/from a buffer/texture.
4098 /// Corresponds to [WebGPU `GPUImageCopyTexture`](
4099 /// https://gpuweb.github.io/gpuweb/#dictdef-gpuimagecopytexture).
4100 #[repr(C)]
4101 #[derive(Clone, Debug)]
4102 #[cfg_attr(feature = "trace", derive(serde::Serialize))]
4103 #[cfg_attr(feature = "replay", derive(serde::Deserialize))]
4104 pub struct ImageCopyTexture<T> {
4105     /// The texture to be copied to/from.
4106     pub texture: T,
4107     /// The target mip level of the texture.
4108     pub mip_level: u32,
4109     /// The base texel of the texture in the selected `mip_level`.
4110     #[cfg_attr(any(feature = "trace", feature = "replay"), serde(default))]
4111     pub origin: Origin3d,
4112     /// The copy aspect.
4113     #[cfg_attr(any(feature = "trace", feature = "replay"), serde(default))]
4114     pub aspect: TextureAspect,
4117 /// Subresource range within an image
4118 #[repr(C)]
4119 #[derive(Clone, Debug, Default, Eq, PartialEq)]
4120 #[cfg_attr(feature = "trace", derive(serde::Serialize))]
4121 #[cfg_attr(feature = "replay", derive(serde::Deserialize))]
4122 pub struct ImageSubresourceRange {
4123     /// Aspect of the texture. Color textures must be [`TextureAspect::All`][TAA].
4124     ///
4125     /// [TAA]: ../wgpu/enum.TextureAspect.html#variant.All
4126     pub aspect: TextureAspect,
4127     /// Base mip level.
4128     pub base_mip_level: u32,
4129     /// Mip level count.
4130     /// If `Some(count)`, `base_mip_level + count` must be less or equal to underlying texture mip count.
4131     /// If `None`, considered to include the rest of the mipmap levels, but at least 1 in total.
4132     pub mip_level_count: Option<NonZeroU32>,
4133     /// Base array layer.
4134     pub base_array_layer: u32,
4135     /// Layer count.
4136     /// If `Some(count)`, `base_array_layer + count` must be less or equal to the underlying array count.
4137     /// If `None`, considered to include the rest of the array layers, but at least 1 in total.
4138     pub array_layer_count: Option<NonZeroU32>,
4141 impl ImageSubresourceRange {
4142     /// Returns the mip level range of a subresource range describes for a specific texture.
4143     pub fn mip_range<L>(&self, texture_desc: &TextureDescriptor<L>) -> Range<u32> {
4144         self.base_mip_level..match self.mip_level_count {
4145             Some(mip_level_count) => self.base_mip_level + mip_level_count.get(),
4146             None => texture_desc.mip_level_count,
4147         }
4148     }
4150     /// Returns the layer range of a subresource range describes for a specific texture.
4151     pub fn layer_range<L>(&self, texture_desc: &TextureDescriptor<L>) -> Range<u32> {
4152         self.base_array_layer..match self.array_layer_count {
4153             Some(array_layer_count) => self.base_array_layer + array_layer_count.get(),
4154             None => {
4155                 if texture_desc.dimension == TextureDimension::D3 {
4156                     self.base_array_layer + 1
4157                 } else {
4158                     texture_desc.size.depth_or_array_layers
4159                 }
4160             }
4161         }
4162     }
4165 /// Color variation to use when sampler addressing mode is [`AddressMode::ClampToBorder`]
4166 #[repr(C)]
4167 #[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
4168 #[cfg_attr(feature = "trace", derive(serde::Serialize))]
4169 #[cfg_attr(feature = "replay", derive(serde::Deserialize))]
4170 pub enum SamplerBorderColor {
4171     /// [0, 0, 0, 0]
4172     TransparentBlack,
4173     /// [0, 0, 0, 1]
4174     OpaqueBlack,
4175     /// [1, 1, 1, 1]
4176     OpaqueWhite,
4178     /// On the Metal backend, this is equivalent to `TransparentBlack` for
4179     /// textures that have an alpha component, and equivalent to `OpaqueBlack`
4180     /// for textures that do not have an alpha component. On other backends,
4181     /// this is equivalent to `TransparentBlack`. Requires
4182     /// [`Features::ADDRESS_MODE_CLAMP_TO_ZERO`]. Not supported on the web.
4183     Zero,
4186 /// Describes how to create a QuerySet.
4188 /// Corresponds to [WebGPU `GPUQuerySetDescriptor`](
4189 /// https://gpuweb.github.io/gpuweb/#dictdef-gpuquerysetdescriptor).
4190 #[derive(Clone, Debug)]
4191 #[cfg_attr(feature = "trace", derive(serde::Serialize))]
4192 #[cfg_attr(feature = "replay", derive(serde::Deserialize))]
4193 pub struct QuerySetDescriptor<L> {
4194     /// Debug label for the query set.
4195     pub label: L,
4196     /// Kind of query that this query set should contain.
4197     pub ty: QueryType,
4198     /// Total count of queries the set contains. Must not be zero.
4199     /// Must not be greater than [`QUERY_SET_MAX_QUERIES`].
4200     pub count: u32,
4203 impl<L> QuerySetDescriptor<L> {
4204     ///
4205     pub fn map_label<'a, K>(&'a self, fun: impl FnOnce(&'a L) -> K) -> QuerySetDescriptor<K> {
4206         QuerySetDescriptor {
4207             label: fun(&self.label),
4208             ty: self.ty,
4209             count: self.count,
4210         }
4211     }
4214 /// Type of query contained in a QuerySet.
4216 /// Corresponds to [WebGPU `GPUQueryType`](
4217 /// https://gpuweb.github.io/gpuweb/#enumdef-gpuquerytype).
4218 #[derive(Copy, Clone, Debug)]
4219 #[cfg_attr(feature = "trace", derive(serde::Serialize))]
4220 #[cfg_attr(feature = "replay", derive(serde::Deserialize))]
4221 pub enum QueryType {
4222     /// Query returns a single 64-bit number, serving as an occlusion boolean.
4223     Occlusion,
4224     /// Query returns up to 5 64-bit numbers based on the given flags.
4225     ///
4226     /// See [`PipelineStatisticsTypes`]'s documentation for more information
4227     /// on how they get resolved.
4228     ///
4229     /// [`Features::PIPELINE_STATISTICS_QUERY`] must be enabled to use this query type.
4230     PipelineStatistics(PipelineStatisticsTypes),
4231     /// Query returns a 64-bit number indicating the GPU-timestamp
4232     /// where all previous commands have finished executing.
4233     ///
4234     /// Must be multiplied by [`Queue::get_timestamp_period`][Qgtp] to get
4235     /// the value in nanoseconds. Absolute values have no meaning,
4236     /// but timestamps can be subtracted to get the time it takes
4237     /// for a string of operations to complete.
4238     ///
4239     /// [`Features::TIMESTAMP_QUERY`] must be enabled to use this query type.
4240     ///
4241     /// [Qgtp]: ../wgpu/struct.Queue.html#method.get_timestamp_period
4242     Timestamp,
4245 bitflags::bitflags! {
4246     /// Flags for which pipeline data should be recorded.
4247     ///
4248     /// The amount of values written when resolved depends
4249     /// on the amount of flags. If 3 flags are enabled, 3
4250     /// 64-bit values will be written per-query.
4251     ///
4252     /// The order they are written is the order they are declared
4253     /// in this bitflags. If you enabled `CLIPPER_PRIMITIVES_OUT`
4254     /// and `COMPUTE_SHADER_INVOCATIONS`, it would write 16 bytes,
4255     /// the first 8 bytes being the primitive out value, the last 8
4256     /// bytes being the compute shader invocation count.
4257     #[repr(transparent)]
4258     pub struct PipelineStatisticsTypes : u8 {
4259         /// Amount of times the vertex shader is ran. Accounts for
4260         /// the vertex cache when doing indexed rendering.
4261         const VERTEX_SHADER_INVOCATIONS = 1 << 0;
4262         /// Amount of times the clipper is invoked. This
4263         /// is also the amount of triangles output by the vertex shader.
4264         const CLIPPER_INVOCATIONS = 1 << 1;
4265         /// Amount of primitives that are not culled by the clipper.
4266         /// This is the amount of triangles that are actually on screen
4267         /// and will be rasterized and rendered.
4268         const CLIPPER_PRIMITIVES_OUT = 1 << 2;
4269         /// Amount of times the fragment shader is ran. Accounts for
4270         /// fragment shaders running in 2x2 blocks in order to get
4271         /// derivatives.
4272         const FRAGMENT_SHADER_INVOCATIONS = 1 << 3;
4273         /// Amount of times a compute shader is invoked. This will
4274         /// be equivalent to the dispatch count times the workgroup size.
4275         const COMPUTE_SHADER_INVOCATIONS = 1 << 4;
4276     }
4279 #[cfg(feature = "bitflags_serde_shim")]
4280 bitflags_serde_shim::impl_serde_for_bitflags!(PipelineStatisticsTypes);
4282 /// Argument buffer layout for draw_indirect commands.
4283 #[repr(C)]
4284 #[derive(Clone, Copy, Debug)]
4285 pub struct DrawIndirectArgs {
4286     /// The number of vertices to draw.
4287     pub vertex_count: u32,
4288     /// The number of instances to draw.
4289     pub instance_count: u32,
4290     /// Offset into the vertex buffers, in vertices, to begin drawing from.
4291     pub first_vertex: u32,
4292     /// First instance to draw.
4293     pub first_instance: u32,
4296 /// Argument buffer layout for draw_indexed_indirect commands.
4297 #[repr(C)]
4298 #[derive(Clone, Copy, Debug)]
4299 pub struct DrawIndexedIndirectArgs {
4300     /// The number of indices to draw.
4301     pub index_count: u32,
4302     /// The number of instances to draw.
4303     pub instance_count: u32,
4304     /// Offset into the index buffer, in indices, begin drawing from.
4305     pub first_index: u32,
4306     /// Added to each index value before indexing into the vertex buffers.
4307     pub base_vertex: i32,
4308     /// First instance to draw.
4309     pub first_instance: u32,
4312 /// Argument buffer layout for dispatch_indirect commands.
4313 #[repr(C)]
4314 #[derive(Clone, Copy, Debug)]
4315 pub struct DispatchIndirectArgs {
4316     /// X dimension of the grid of workgroups to dispatch.
4317     pub group_size_x: u32,
4318     /// Y dimension of the grid of workgroups to dispatch.
4319     pub group_size_y: u32,
4320     /// Z dimension of the grid of workgroups to dispatch.
4321     pub group_size_z: u32,
4324 /// Describes how shader bound checks should be performed.
4325 #[derive(Clone, Debug)]
4326 #[cfg_attr(feature = "trace", derive(serde::Serialize))]
4327 #[cfg_attr(feature = "replay", derive(serde::Deserialize))]
4328 pub struct ShaderBoundChecks {
4329     runtime_checks: bool,
4332 impl ShaderBoundChecks {
4333     /// Creates a new configuration where the shader is bound checked.
4334     pub fn new() -> Self {
4335         ShaderBoundChecks {
4336             runtime_checks: true,
4337         }
4338     }
4340     /// Creates a new configuration where the shader isn't bound checked.
4341     ///
4342     /// # Safety
4343     /// The caller MUST ensure that all shaders built with this configuration don't perform any
4344     /// out of bounds reads or writes.
4345     pub unsafe fn unchecked() -> Self {
4346         ShaderBoundChecks {
4347             runtime_checks: false,
4348         }
4349     }
4351     /// Query whether runtime bound checks are enabled in this configuration
4352     pub fn runtime_checks(&self) -> bool {
4353         self.runtime_checks
4354     }
4357 impl Default for ShaderBoundChecks {
4358     fn default() -> Self {
4359         Self::new()
4360     }