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