wgpu_types/features.rs
1//! # Features
2//!
3//! Types identifying optional features of WebGPU and wgpu. Availability varies
4//! by hardware and can be checked when requesting an adapter and device.
5//!
6//! The `wgpu` Rust API always uses the `Features` bit flag type to represent a
7//! set of features. However, the WebGPU-defined JavaScript API uses
8//! `kebab-case` feature name strings, so some utilities are provided for
9//! working with those names. See [`Features::as_str`] and [`Features::from_str`].
10//!
11//! The [`bitflags`] crate names flags by stringifying the
12//! `SCREAMING_SNAKE_CASE` identifier. These names are returned by
13//! [`Features::iter_names`] and parsed by [`Features::from_name`].
14//! [`bitflags`] does not currently support customized flag naming.
15//! See <https://github.com/bitflags/bitflags/issues/470>.
16
17use crate::{link_to_wgpu_docs, link_to_wgpu_item, VertexFormat};
18use alloc::vec::Vec;
19use bitflags::Flags;
20#[cfg(feature = "serde")]
21use core::mem::size_of;
22use core::str::FromStr;
23#[cfg(feature = "serde")]
24use serde::{Deserialize, Serialize};
25
26pub use webgpu_impl::*;
27mod webgpu_impl {
28 //! Constant values for [`super::FeaturesWebGPU`], separated so they can be picked up by
29 //! `cbindgen` in `mozilla-central` (where Firefox is developed).
30 //!
31 //! Bitmask feature encoding is not defined by the WebGPU specification, and the values
32 //! are subject to change.
33 #![allow(missing_docs)]
34
35 #[doc(hidden)]
36 pub const WEBGPU_FEATURE_DEPTH_CLIP_CONTROL: u64 = 1 << 0;
37
38 #[doc(hidden)]
39 pub const WEBGPU_FEATURE_DEPTH32FLOAT_STENCIL8: u64 = 1 << 1;
40
41 #[doc(hidden)]
42 pub const WEBGPU_FEATURE_TEXTURE_COMPRESSION_BC: u64 = 1 << 2;
43
44 #[doc(hidden)]
45 pub const WEBGPU_FEATURE_TEXTURE_COMPRESSION_BC_SLICED_3D: u64 = 1 << 3;
46
47 #[doc(hidden)]
48 pub const WEBGPU_FEATURE_TEXTURE_COMPRESSION_ETC2: u64 = 1 << 4;
49
50 #[doc(hidden)]
51 pub const WEBGPU_FEATURE_TEXTURE_COMPRESSION_ASTC: u64 = 1 << 5;
52
53 #[doc(hidden)]
54 pub const WEBGPU_FEATURE_TEXTURE_COMPRESSION_ASTC_SLICED_3D: u64 = 1 << 6;
55
56 #[doc(hidden)]
57 pub const WEBGPU_FEATURE_TIMESTAMP_QUERY: u64 = 1 << 7;
58
59 #[doc(hidden)]
60 pub const WEBGPU_FEATURE_INDIRECT_FIRST_INSTANCE: u64 = 1 << 8;
61
62 #[doc(hidden)]
63 pub const WEBGPU_FEATURE_SHADER_F16: u64 = 1 << 9;
64
65 #[doc(hidden)]
66 pub const WEBGPU_FEATURE_RG11B10UFLOAT_RENDERABLE: u64 = 1 << 10;
67
68 #[doc(hidden)]
69 pub const WEBGPU_FEATURE_BGRA8UNORM_STORAGE: u64 = 1 << 11;
70
71 #[doc(hidden)]
72 pub const WEBGPU_FEATURE_FLOAT32_FILTERABLE: u64 = 1 << 12;
73
74 #[doc(hidden)]
75 pub const WEBGPU_FEATURE_FLOAT32_BLENDABLE: u64 = 1 << 13;
76
77 #[doc(hidden)]
78 pub const WEBGPU_FEATURE_DUAL_SOURCE_BLENDING: u64 = 1 << 14;
79
80 #[doc(hidden)]
81 pub const WEBGPU_FEATURE_CLIP_DISTANCES: u64 = 1 << 15;
82
83 #[doc(hidden)]
84 pub const WEBGPU_FEATURE_IMMEDIATES: u64 = 1 << 16;
85
86 #[doc(hidden)]
87 pub const WEBGPU_FEATURE_PRIMITIVE_INDEX: u64 = 1 << 17;
88
89 #[doc(hidden)]
90 pub const WEBGPU_FEATURE_TEXTURE_COMPONENT_SWIZZLE: u64 = 1 << 18;
91}
92
93/// Prefer `From<(FeaturesWGPU, FeaturesWebGPU)>` instead, which protects against swapping
94/// the two feature sets.
95impl From<FeatureBits> for Features {
96 fn from(value: FeatureBits) -> Self {
97 Self::from_bits_retain(value)
98 }
99}
100
101impl From<(FeaturesWGPU, FeaturesWebGPU)> for Features {
102 fn from(value: (FeaturesWGPU, FeaturesWebGPU)) -> Self {
103 let (wgpu, webgpu) = value;
104 Self::from_parts(wgpu, webgpu)
105 }
106}
107
108impl From<Features> for FeatureBits {
109 fn from(value: Features) -> Self {
110 value.bits()
111 }
112}
113
114/// Maps a feature's `#[web(...)]` attribute to whether the feature is allowed on the web
115/// backend, rejecting a missing or unrecognized value.
116macro_rules! web_attr_allows {
117 ($flag:tt; allow) => {
118 true
119 };
120 ($flag:tt; ignore) => {
121 false
122 };
123 ($flag:tt; $other:tt) => {
124 compile_error!(concat!(
125 "`#[web(",
126 stringify!($other),
127 ")]` on `",
128 stringify!($flag),
129 "`: the value must be `allow` or `ignore`",
130 ))
131 };
132 ($flag:tt;) => {
133 compile_error!(concat!(
134 "WebGPU feature `",
135 stringify!($flag),
136 "` needs a `#[web(allow)]` or `#[web(ignore)]` attribute",
137 ))
138 };
139}
140
141/// Generate the `Features::ALLOWED_ON_WEB_BACKEND` constant.
142///
143/// Each [`FeaturesWebGPU`] feature must have the `web` attribute, specifying
144/// whether or not to expose it on the web backend (typically yes, unless
145/// there are known deficiencies in the bindings that prevent using the
146/// feature). Standards-track native-only features can be added as special
147/// cases.
148macro_rules! features_web {
149 (FeaturesWebGPU; $($flag:tt [$($web:tt)?])*) => {
150 impl Features {
151 /// The features that the web backend will allow through from an underlying
152 /// browser WebGPU implementation.
153 ///
154 /// This may include bits in [`FeaturesWGPU`] for standards-track features
155 /// that have not yet been migrated to [`FeaturesWebGPU`].
156 pub const ALLOWED_ON_WEB_BACKEND: Self = Self::from_parts(
157 FeaturesWGPU::SUBGROUP,
158 FeaturesWebGPU::from_bits_retain(
159 0 $(| if web_attr_allows!($flag; $($web)?) {
160 FeaturesWebGPU::$flag.bits()
161 } else {
162 0
163 })*
164 ),
165 );
166 }
167 };
168 ($inner_name:tt; $($flag:tt [$($web:tt)?])*) => {
169 $($(
170 compile_error!(concat!(
171 "`#[web(", stringify!($web), ")]` on `", stringify!($flag),
172 "`: only `FeaturesWebGPU` features have a `web` attribute, and `",
173 stringify!($flag), "` is a `", stringify!($inner_name), "` feature",
174 ));
175 )?)*
176 };
177}
178
179/// Defines the feature bitflags, using [`bitflags_array`](crate::bitflags_array) for storage.
180///
181/// On top of what `bitflags_array!` accepts, each flag carries feature-specific attributes,
182/// written after its doc comments. These are consumed here rather than passed on to
183/// `bitflags_array!`. Adding another one means adding a matcher for it, in a fixed position
184/// relative to the existing ones, and generating whatever it should produce.
185///
186/// `#[name("kebab-case-name", "alias", ...)]` gives the names that the WebGPU API uses for
187/// the feature: the name from the spec, for features in [`FeaturesWebGPU`], and otherwise a
188/// `wgpu-` prefixed name. It is required on every feature.
189///
190/// `#[web(allow)]` or `#[web(ignore)]` controls whether `wgpu`'s WebGPU backend will
191/// offer the feature when the underlying WebGPU implementation does. Typically should be
192/// `allow`, but `ignore` may be appropriate in cases where missing logic in the WebGPU
193/// backend means the feature will not work via `wgpu` even though it is supported by the
194/// underlying backend, or where there is concern about interactions or confusion with
195/// `wgpu` native features having subtly different API or behavior.
196macro_rules! features {
197 (
198 $(#[$outer:meta])*
199 pub struct ($name:ident, $name_bits:ident): [$T:ty; $Len:expr];
200
201 $(
202 $(#[$bit_outer:meta])*
203 $vis:vis struct $inner_name:ident $lower_inner_name:ident {
204 $(
205 $(#[doc $($args:tt)*])*
206 #[name($str_name:literal $(, $alias:literal)*)]
207 $(#[web($web:tt)])?
208 const $Flag:tt = $value:expr;
209 )*
210 }
211 )*
212 ) => {
213 crate::bitflags_array! {
214 $(#[$outer])*
215 pub struct ($name, $name_bits): [$T; $Len];
216
217 $(
218 $(#[$bit_outer])*
219 $vis struct $inner_name $lower_inner_name {
220 $(
221 $(#[doc $($args)*])*
222 const $Flag = $value;
223 )*
224 }
225 )*
226 }
227
228 $( features_web! { $inner_name; $($Flag [$($web)?])* } )*
229
230 // Parses kebab-case feature names (i.e. the names given in the spec, for features
231 // in FeaturesWebGPU, and otherwise the `wgpu-` prefixed names).
232 impl FromStr for $name {
233 type Err = ();
234
235 fn from_str(s: &str) -> Result<Self, Self::Err> {
236 Ok(match s {
237 $($($str_name $(| $alias)* => Self::$Flag,)*)*
238 _ => return Err(()),
239 })
240 }
241 }
242
243 impl $name {
244 #[doc = concat!("If the argument is a single [`", stringify!($name), "`] flag,")]
245 /// returns the corresponding `kebab-case` flag name, otherwise `None`.
246 #[must_use]
247 pub fn as_str(&self) -> Option<&'static str> {
248 Some(match *self {
249 $($(Self::$Flag => $str_name,)*)*
250 _ => return None,
251 })
252 }
253 }
254 };
255}
256
257features! {
258 /// Features that are not guaranteed to be supported.
259 ///
260 /// These are either part of the webgpu standard, or are extension features supported by
261 /// wgpu when targeting native.
262 ///
263 /// If you want to use a feature, you need to first verify that the adapter supports
264 /// the feature. If the adapter does not support the feature, requesting a device with it enabled
265 /// will panic.
266 ///
267 /// Corresponds to [WebGPU `GPUFeatureName`](
268 /// https://gpuweb.github.io/gpuweb/#enumdef-gpufeaturename).
269 #[repr(C)]
270 #[derive(Default, Debug, Copy, Clone, PartialEq, Eq, Hash)]
271 pub struct (Features, FeatureBits): [u64; 2];
272
273 /// Features that are not guaranteed to be supported.
274 ///
275 /// Most of these are native-only extension features supported by wgpu only when targeting
276 /// native. A few are intended to align with a proposed WebGPU extension, and one
277 /// (`EXTERNAL_TEXTURE`) controls WebGPU-specified behavior that is not optional in the
278 /// standard, but that we don't want to make a [`crate::DownlevelFlags`] until the
279 /// implementation is more complete. For all features see [`Features`].
280 ///
281 /// If you want to use a feature, you need to first verify that the adapter supports
282 /// the feature. If the adapter does not support the feature, requesting a device with it enabled
283 /// will panic.
284 ///
285 /// Corresponds to [WebGPU `GPUFeatureName`](
286 /// https://gpuweb.github.io/gpuweb/#enumdef-gpufeaturename).
287 #[repr(transparent)]
288 #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
289 #[cfg_attr(feature = "serde", serde(transparent))]
290 #[derive(Default, Debug, Copy, Clone, PartialEq, Eq, Hash)]
291 pub struct FeaturesWGPU features_wgpu {
292 /// Allows shaders to use f32 atomic load, store, add, sub, and exchange.
293 ///
294 /// Supported platforms:
295 /// - Metal (with MSL 3.0+ and Apple7+/Mac2)
296 /// - Vulkan (with [VK_EXT_shader_atomic_float])
297 ///
298 /// This is a native only feature.
299 ///
300 /// [VK_EXT_shader_atomic_float]: https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VK_EXT_shader_atomic_float.html
301 #[name("wgpu-shader-float32-atomic")]
302 const SHADER_FLOAT32_ATOMIC = 1 << 0;
303
304 // The features starting with a ? are features that might become part of the spec or
305 // at the very least we can implement as native features; since they should cover all
306 // possible formats and capabilities across backends.
307 //
308 // ? const FORMATS_TIER_1 = 1 << ??; (https://github.com/gpuweb/gpuweb/issues/3837)
309 // ? const RW_STORAGE_TEXTURE_TIER_1 = 1 << ??; (https://github.com/gpuweb/gpuweb/issues/3838)
310 // ? const NORM16_FILTERABLE = 1 << ??; (https://github.com/gpuweb/gpuweb/issues/3839)
311 // ? const NORM16_RESOLVE = 1 << ??; (https://github.com/gpuweb/gpuweb/issues/3839)
312 // ? const 32BIT_FORMAT_MULTISAMPLE = 1 << ??; (https://github.com/gpuweb/gpuweb/issues/3844)
313 // ? const 32BIT_FORMAT_RESOLVE = 1 << ??; (https://github.com/gpuweb/gpuweb/issues/3844)
314 // TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES might not be necessary if we have all the texture features implemented
315
316 // Texture Formats:
317
318 /// Enables normalized `16-bit` texture formats.
319 ///
320 /// Supported platforms:
321 /// - Vulkan
322 /// - DX12
323 /// - Metal
324 /// - OpenGL (desktop GL 3.3+ for UNORM; GLES / WebGL2 needs
325 /// `EXT_texture_norm16`. SNORM color-attachment usage
326 /// additionally requires `EXT_render_snorm` on both paths.)
327 ///
328 /// This is a native only feature.
329 #[name("wgpu-texture-format-16-bit-norm", "texture-format-16-bit-norm")]
330 const TEXTURE_FORMAT_16BIT_NORM = 1 << 1;
331 /// Enables ASTC HDR family of compressed textures.
332 ///
333 /// Compressed textures sacrifice some quality in exchange for significantly reduced
334 /// bandwidth usage.
335 ///
336 /// Support for this feature guarantees availability of [`TextureUsages::COPY_SRC | TextureUsages::COPY_DST | TextureUsages::TEXTURE_BINDING`] for ASTC formats with the HDR channel type.
337 /// [`Features::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES`] may enable additional usages.
338 ///
339 /// Supported Platforms:
340 /// - Metal
341 /// - Vulkan
342 /// - OpenGL
343 ///
344 /// This is a native only feature.
345 #[name("wgpu-texture-compression-astc-hdr", "texture-compression-astc-hdr")]
346 const TEXTURE_COMPRESSION_ASTC_HDR = 1 << 2;
347 /// Enables device specific texture format features.
348 ///
349 /// See `TextureFormatFeatures` for a listing of the features in question.
350 ///
351 /// By default only texture format properties as defined by the WebGPU specification are allowed.
352 /// Enabling this feature flag extends the features of each format to the ones supported by the current device.
353 /// Note that without this flag, read/write storage access is not allowed at all.
354 ///
355 /// This extension does not enable additional formats.
356 ///
357 /// This is a native only feature.
358 #[name("wgpu-texture-adapter-specific-format-features", "texture-adapter-specific-format-features")]
359 const TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES = 1 << 3;
360
361 // API:
362
363 /// Enables use of Pipeline Statistics Queries. These queries tell the count of various operations
364 /// performed between the start and stop call. Call [`RenderPass::begin_pipeline_statistics_query`] to start
365 /// a query, then call [`RenderPass::end_pipeline_statistics_query`] to stop one.
366 ///
367 /// They must be resolved using [`CommandEncoder::resolve_query_set`] into a buffer.
368 /// The rules on how these resolve into buffers are detailed in the documentation for [`PipelineStatisticsTypes`].
369 ///
370 /// Supported Platforms:
371 /// - Vulkan
372 /// - DX12
373 ///
374 /// This is a native only feature with a [proposal](https://github.com/gpuweb/gpuweb/blob/0008bd30da2366af88180b511a5d0d0c1dffbc36/proposals/pipeline-statistics-query.md) for the web.
375 ///
376 #[doc = link_to_wgpu_docs!(["`RenderPass::begin_pipeline_statistics_query`"]: "struct.RenderPass.html#method.begin_pipeline_statistics_query")]
377 #[doc = link_to_wgpu_docs!(["`RenderPass::end_pipeline_statistics_query`"]: "struct.RenderPass.html#method.end_pipeline_statistics_query")]
378 #[doc = link_to_wgpu_docs!(["`CommandEncoder::resolve_query_set`"]: "struct.CommandEncoder.html#method.resolve_query_set")]
379 /// [`PipelineStatisticsTypes`]: super::PipelineStatisticsTypes
380 #[name("wgpu-pipeline-statistics-query", "pipeline-statistics-query")]
381 const PIPELINE_STATISTICS_QUERY = 1 << 4;
382 /// Allows for timestamp queries directly on command encoders.
383 ///
384 /// Adapters that support this feature also support
385 /// [`Features::TIMESTAMP_QUERY`]. Both features must be requested
386 /// explicitly to use timestamp queries on command encoders.
387 ///
388 /// Additionally allows for timestamp writes on command encoders
389 /// using [`CommandEncoder::write_timestamp`].
390 ///
391 /// Supported platforms:
392 /// - Vulkan
393 /// - DX12
394 /// - Metal (AMD & Intel, not Apple GPUs)
395 /// - OpenGL (with GL_ARB_timer_query)
396 ///
397 /// This is a native only feature.
398 ///
399 #[doc = link_to_wgpu_docs!(["`CommandEncoder::write_timestamp`"]: "struct.CommandEncoder.html#method.write_timestamp")]
400 #[name("wgpu-timestamp-query-inside-encoders")]
401 const TIMESTAMP_QUERY_INSIDE_ENCODERS = 1 << 5;
402 /// Allows for timestamp queries directly inside render and compute passes.
403 ///
404 /// Adapters that support this feature also support
405 /// [`Features::TIMESTAMP_QUERY`] and [`Features::TIMESTAMP_QUERY_INSIDE_ENCODERS`].
406 /// This feature must be requested with [`Features::TIMESTAMP_QUERY`] to use timestamp
407 /// queries inside passes. Additionally, [`Features::TIMESTAMP_QUERY_INSIDE_ENCODERS`]
408 /// must be requested to use timestamp queries on command encoders.
409 ///
410 /// Additionally allows for timestamp queries to be used inside render & compute passes using:
411 /// - [`RenderPass::write_timestamp`]
412 /// - [`ComputePass::write_timestamp`]
413 ///
414 /// Supported platforms:
415 /// - Vulkan
416 /// - DX12
417 /// - Metal (AMD & Intel, not Apple GPUs)
418 /// - OpenGL (with GL_ARB_timer_query)
419 ///
420 /// This is generally not available on tile-based rasterization GPUs.
421 ///
422 /// This is a native only feature with a [proposal](https://github.com/gpuweb/gpuweb/blob/0008bd30da2366af88180b511a5d0d0c1dffbc36/proposals/timestamp-query-inside-passes.md) for the web.
423 ///
424 #[doc = link_to_wgpu_docs!(["`RenderPass::write_timestamp`"]: "struct.RenderPass.html#method.write_timestamp")]
425 #[doc = link_to_wgpu_docs!(["`ComputePass::write_timestamp`"]: "struct.ComputePass.html#method.write_timestamp")]
426 #[name("wgpu-timestamp-query-inside-passes", "timestamp-query-inside-passes")]
427 const TIMESTAMP_QUERY_INSIDE_PASSES = 1 << 6;
428 /// Webgpu only allows the MAP_READ and MAP_WRITE buffer usage to be matched with
429 /// COPY_DST and COPY_SRC respectively. This removes this requirement.
430 ///
431 /// This is only beneficial on systems that share memory between CPU and GPU. If enabled
432 /// on a system that doesn't, this can severely hinder performance. Only use if you understand
433 /// the consequences.
434 ///
435 /// Supported platforms:
436 /// - Vulkan
437 /// - DX12
438 /// - Metal
439 ///
440 /// This is a native only feature.
441 #[name("wgpu-mappable-primary-buffers", "mappable-primary-buffers")]
442 const MAPPABLE_PRIMARY_BUFFERS = 1 << 7;
443 /// Allows the user to create uniform arrays of textures in shaders:
444 ///
445 /// ex.
446 /// - `var textures: binding_array<texture_2d<f32>, 10>` (WGSL)
447 /// - `uniform texture2D textures[10]` (GLSL)
448 ///
449 /// If [`Features::STORAGE_RESOURCE_BINDING_ARRAY`] is supported as well as this, the user
450 /// may also create uniform arrays of storage textures.
451 ///
452 /// ex.
453 /// - `var textures: array<texture_storage_2d<r32float, write>, 10>` (WGSL)
454 /// - `uniform image2D textures[10]` (GLSL)
455 ///
456 /// This capability allows them to exist and to be indexed by dynamically uniform
457 /// values.
458 ///
459 /// Supported platforms:
460 /// - DX12
461 /// - Metal (with MSL 2.0+ on macOS 10.13+)
462 /// - Vulkan
463 ///
464 /// This is a native only feature.
465 #[name("wgpu-texture-binding-array", "texture-binding-array")]
466 const TEXTURE_BINDING_ARRAY = 1 << 8;
467 /// Allows the user to create arrays of buffers in shaders:
468 ///
469 /// ex.
470 /// - `var<uniform> buffer_array: array<MyBuffer, 10>` (WGSL)
471 /// - `uniform myBuffer { ... } buffer_array[10]` (GLSL)
472 ///
473 /// This capability allows them to exist and to be indexed by dynamically uniform
474 /// values.
475 ///
476 /// If [`Features::STORAGE_RESOURCE_BINDING_ARRAY`] is supported as well as this, the user
477 /// may also create arrays of storage buffers.
478 ///
479 /// ex.
480 /// - `var<storage> buffer_array: array<MyBuffer, 10>` (WGSL)
481 /// - `buffer myBuffer { ... } buffer_array[10]` (GLSL)
482 ///
483 /// Supported platforms:
484 /// - Vulkan
485 ///
486 /// This is a native only feature.
487 #[name("wgpu-buffer-binding-array", "buffer-binding-array")]
488 const BUFFER_BINDING_ARRAY = 1 << 9;
489 /// Allows the user to create uniform arrays of storage buffers or textures in shaders,
490 /// if resp. [`Features::BUFFER_BINDING_ARRAY`] or [`Features::TEXTURE_BINDING_ARRAY`]
491 /// is supported.
492 ///
493 /// This capability allows them to exist and to be indexed by dynamically uniform
494 /// values.
495 ///
496 /// Supported platforms:
497 /// - Metal (with MSL 2.2+ on macOS 10.13+)
498 /// - Vulkan
499 ///
500 /// This is a native only feature.
501 #[name("wgpu-storage-resource-binding-array", "storage-resource-binding-array")]
502 const STORAGE_RESOURCE_BINDING_ARRAY = 1 << 10;
503 /// Allows shaders to index sampled texture and storage buffer resource arrays with dynamically non-uniform values:
504 ///
505 /// ex. `texture_array[vertex_data]`
506 ///
507 /// In order to use this capability, the corresponding GLSL extension must be enabled like so:
508 ///
509 /// `#extension GL_EXT_nonuniform_qualifier : require`
510 ///
511 /// and then used either as `nonuniformEXT` qualifier in variable declaration:
512 ///
513 /// ex. `layout(location = 0) nonuniformEXT flat in int vertex_data;`
514 ///
515 /// or as `nonuniformEXT` constructor:
516 ///
517 /// ex. `texture_array[nonuniformEXT(vertex_data)]`
518 ///
519 /// WGSL and HLSL do not need any extension.
520 ///
521 /// Supported platforms:
522 /// - DX12
523 /// - Metal (with MSL 2.0+ on macOS 10.13+)
524 /// - Vulkan 1.2+ (or VK_EXT_descriptor_indexing)'s shaderSampledImageArrayNonUniformIndexing & shaderStorageBufferArrayNonUniformIndexing feature)
525 ///
526 /// This is a native only feature.
527 #[name("wgpu-sampled-texture-and-storage-buffer-array-non-uniform-indexing", "sampled-texture-and-storage-buffer-array-non-uniform-indexing")]
528 const SAMPLED_TEXTURE_AND_STORAGE_BUFFER_ARRAY_NON_UNIFORM_INDEXING = 1 << 11;
529 /// Allows shaders to index storage texture resource arrays with dynamically non-uniform values:
530 ///
531 /// ex. `texture_array[vertex_data]`
532 ///
533 /// Supported platforms:
534 /// - DX12
535 /// - Metal (with MSL 2.0+ on macOS 10.13+)
536 /// - Vulkan 1.2+ (or VK_EXT_descriptor_indexing)'s shaderStorageTextureArrayNonUniformIndexing feature)
537 ///
538 /// This is a native only feature.
539 #[name("wgpu-storage-texture-array-non-uniform-indexing", "storage-texture-array-non-uniform-indexing")]
540 const STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING = 1 << 12;
541 /// Allows the user to create bind groups containing arrays with less bindings than the BindGroupLayout.
542 ///
543 /// Supported platforms:
544 /// - Vulkan
545 /// - DX12
546 ///
547 /// This is a native only feature.
548 #[name("wgpu-partially-bound-binding-array", "partially-bound-binding-array")]
549 const PARTIALLY_BOUND_BINDING_ARRAY = 1 << 13;
550
551 /// Allows the user to print debug messages from shaders using `debugPrintf()`.
552 ///
553 /// Each WGSL module using `debugPrintf` must opt in with `enable wgpu_debug_printf;`.
554 /// See the [`debugPrintf` extension specification][debug_printf]
555 /// for the syntax, how to receive the output, and per-backend requirements.
556 ///
557 /// Supported platforms:
558 /// - Metal (3.2+, lowered to shader logging)
559 /// - Vulkan (lowered to SPIR-V `NonSemantic.DebugPrintf`; output requires the
560 /// validation layer's debug-printf path, enabled with
561 /// [`InstanceFlags::VALIDATION`](crate::InstanceFlags::VALIDATION) and
562 /// [`InstanceFlags::DEBUG_PRINTF`](crate::InstanceFlags::DEBUG_PRINTF))
563 ///
564 /// This is a native only feature.
565 ///
566 #[doc = link_to_wgpu_docs!(["debug_printf"]: "documentation/extensions/debug_printf/index.html")]
567 #[name("wgpu-debug-printf")]
568 const DEBUG_PRINTF = 1 << 14;
569
570 /// Allows the user to call [`RenderPass::multi_draw_indirect_count`] and [`RenderPass::multi_draw_indexed_indirect_count`].
571 ///
572 /// This allows the use of a buffer containing the actual number of draw calls. This feature being present also implies
573 /// that all calls to [`RenderPass::multi_draw_indirect`] and [`RenderPass::multi_draw_indexed_indirect`] are not being emulated
574 /// with a series of `draw_indirect` calls.
575 ///
576 /// Supported platforms:
577 /// - DX12
578 /// - Vulkan 1.2+ (or VK_KHR_draw_indirect_count)
579 ///
580 /// This is a native only feature.
581 ///
582 #[doc = link_to_wgpu_docs!(["`RenderPass::multi_draw_indirect`"]: "struct.RenderPass.html#method.multi_draw_indirect")]
583 #[doc = link_to_wgpu_docs!(["`RenderPass::multi_draw_indexed_indirect`"]: "struct.RenderPass.html#method.multi_draw_indexed_indirect")]
584 #[doc = link_to_wgpu_docs!(["`RenderPass::multi_draw_indirect_count`"]: "struct.RenderPass.html#method.multi_draw_indirect_count")]
585 #[doc = link_to_wgpu_docs!(["`RenderPass::multi_draw_indexed_indirect_count`"]: "struct.RenderPass.html#method.multi_draw_indexed_indirect_count")]
586 #[name("wgpu-multi-draw-indirect-count", "multi-draw-indirect-count")]
587 const MULTI_DRAW_INDIRECT_COUNT = 1 << 15;
588
589 // Bit 16 is available.
590
591 /// Allows the use of [`AddressMode::ClampToBorder`] with a border color
592 /// of [`SamplerBorderColor::Zero`].
593 ///
594 /// Supported platforms:
595 /// - DX12
596 /// - Vulkan
597 /// - Metal
598 /// - OpenGL
599 ///
600 /// This is a native only feature.
601 ///
602 /// [`AddressMode::ClampToBorder`]: super::AddressMode::ClampToBorder
603 /// [`SamplerBorderColor::Zero`]: super::SamplerBorderColor::Zero
604 #[name("wgpu-address-mode-clamp-to-zero", "address-mode-clamp-to-zero")]
605 const ADDRESS_MODE_CLAMP_TO_ZERO = 1 << 17;
606 /// Allows the use of [`AddressMode::ClampToBorder`] with a border color
607 /// other than [`SamplerBorderColor::Zero`].
608 ///
609 /// Supported platforms:
610 /// - DX12
611 /// - Vulkan
612 /// - Metal (macOS 10.12+ only)
613 /// - OpenGL
614 ///
615 /// This is a native only feature.
616 ///
617 /// [`AddressMode::ClampToBorder`]: super::AddressMode::ClampToBorder
618 /// [`SamplerBorderColor::Zero`]: super::SamplerBorderColor::Zero
619 #[name("wgpu-address-mode-clamp-to-border", "address-mode-clamp-to-border")]
620 const ADDRESS_MODE_CLAMP_TO_BORDER = 1 << 18;
621 /// Allows the user to set [`PolygonMode::Line`] in [`PrimitiveState::polygon_mode`]
622 ///
623 /// This allows drawing polygons/triangles as lines (wireframe) instead of filled
624 ///
625 /// Supported platforms:
626 /// - DX12
627 /// - Vulkan
628 /// - Metal
629 /// - OpenGL (not GLES)
630 ///
631 /// This is a native only feature.
632 ///
633 /// [`PrimitiveState::polygon_mode`]: super::PrimitiveState
634 /// [`PolygonMode::Line`]: super::PolygonMode::Line
635 #[name("wgpu-polygon-mode-line", "polygon-mode-line")]
636 const POLYGON_MODE_LINE = 1 << 19;
637 /// Allows the user to set [`PolygonMode::Point`] in [`PrimitiveState::polygon_mode`]
638 ///
639 /// This allows only drawing the vertices of polygons/triangles instead of filled
640 ///
641 /// Supported platforms:
642 /// - Vulkan
643 /// - OpenGL (not GLES)
644 ///
645 /// This is a native only feature.
646 ///
647 /// [`PrimitiveState::polygon_mode`]: super::PrimitiveState
648 /// [`PolygonMode::Point`]: super::PolygonMode::Point
649 #[name("wgpu-polygon-mode-point", "polygon-mode-point")]
650 const POLYGON_MODE_POINT = 1 << 20;
651 /// Allows the user to set a overestimation-conservative-rasterization in [`PrimitiveState::conservative`]
652 ///
653 /// Processing of degenerate triangles/lines is hardware specific.
654 /// Only triangles are supported.
655 ///
656 /// Supported platforms:
657 /// - Vulkan
658 ///
659 /// This is a native only feature.
660 ///
661 /// [`PrimitiveState::conservative`]: super::PrimitiveState::conservative
662 #[name("wgpu-conservative-rasterization", "conservative-rasterization")]
663 const CONSERVATIVE_RASTERIZATION = 1 << 21;
664 /// Enables bindings of writable storage buffers and textures visible to vertex shaders.
665 ///
666 /// Note: some (tiled-based) platforms do not support vertex shaders with any side-effects.
667 ///
668 /// Supported Platforms:
669 /// - All
670 ///
671 /// This is a native only feature.
672 #[name("wgpu-vertex-writable-storage", "vertex-writable-storage")]
673 const VERTEX_WRITABLE_STORAGE = 1 << 22;
674 /// Enables clear to zero for textures.
675 ///
676 /// Supported platforms:
677 /// - All
678 ///
679 /// This is a native only feature.
680 #[name("wgpu-clear-texture", "clear-texture")]
681 const CLEAR_TEXTURE = 1 << 23;
682
683 /// Allows for constructing ray tracing pipelines.
684 #[name("wgpu-ray-tracing-pipelines")]
685 const EXPERIMENTAL_RAY_TRACING_PIPELINES = 1 << 24;
686
687 // Bit 25 is available.
688
689 /// Enables multiview render passes and `builtin(view_index)` in vertex/mesh shaders.
690 ///
691 /// Supported platforms:
692 /// - Vulkan
693 /// - Metal
694 /// - DX12
695 /// - OpenGL (web only)
696 ///
697 /// This is a native only feature.
698 #[name("wgpu-multiview", "multiview")]
699 const MULTIVIEW = 1 << 26;
700 /// Enables using 64-bit types for vertex attributes.
701 ///
702 /// Requires SHADER_FLOAT64.
703 ///
704 /// Supported Platforms: N/A
705 ///
706 /// This is a native only feature.
707 #[name("wgpu-vertex-attribute-64-bit", "vertex-attribute-64-bit")]
708 const VERTEX_ATTRIBUTE_64BIT = 1 << 27;
709 /// Enables image atomic fetch add, and, xor, or, min, and max for R32Uint and R32Sint textures.
710 ///
711 /// Supported platforms:
712 /// - Vulkan
713 /// - DX12
714 /// - Metal (with MSL 3.1+)
715 ///
716 /// This is a native only feature.
717 #[name("wgpu-texture-atomic")]
718 const TEXTURE_ATOMIC = 1 << 28;
719 /// Allows for creation of textures of format [`TextureFormat::NV12`]
720 ///
721 /// Supported platforms:
722 /// - DX12
723 /// - Vulkan
724 ///
725 /// This is a native only feature.
726 ///
727 /// [`TextureFormat::NV12`]: super::TextureFormat::NV12
728 #[name("wgpu-texture-format-nv12")]
729 const TEXTURE_FORMAT_NV12 = 1 << 29;
730 /// Allows for creation of textures of format [`TextureFormat::P010`]
731 ///
732 /// Supported platforms:
733 /// - DX12
734 /// - Vulkan
735 ///
736 /// This is a native only feature.
737 ///
738 /// [`TextureFormat::P010`]: super::TextureFormat::P010
739 #[name("wgpu-texture-format-p010")]
740 const TEXTURE_FORMAT_P010 = 1 << 30;
741
742 /// Allows for the creation and usage of `ExternalTexture`s, and bind
743 /// group layouts containing external texture `BindingType`s.
744 ///
745 /// Conceptually this should really be a [`crate::DownlevelFlags`] as
746 /// it corresponds to WebGPU's [`GPUExternalTexture`](
747 /// https://www.w3.org/TR/webgpu/#gpuexternaltexture).
748 /// However, the implementation is currently in-progress, and until it
749 /// is complete we do not want applications to ignore adapters due to
750 /// a missing downlevel flag, when they may not require this feature at
751 /// all.
752 ///
753 /// Supported platforms:
754 /// - DX12
755 /// - Metal
756 #[name("wgpu-external-texture", "external-texture")]
757 const EXTERNAL_TEXTURE = 1 << 31;
758
759 // Shader:
760
761 /// ***THIS IS EXPERIMENTAL:*** Features enabled by this may have
762 /// major bugs in it and are expected to be subject to breaking changes, suggestions
763 /// for the API exposed by this should be posted on [the ray-tracing issue](https://github.com/gfx-rs/wgpu/issues/1040)
764 ///
765 /// Allows for the creation of ray-tracing queries within shaders.
766 ///
767 /// Supported platforms:
768 /// - Vulkan
769 ///
770 /// This is a native-only feature.
771 #[name("wgpu-ray-query")]
772 const EXPERIMENTAL_RAY_QUERY = 1 << 32;
773 /// Enables 64-bit floating point types in SPIR-V shaders.
774 ///
775 /// Note: even when supported by GPU hardware, 64-bit floating point operations are
776 /// frequently between 16 and 64 _times_ slower than equivalent operations on 32-bit floats.
777 ///
778 /// Supported Platforms:
779 /// - Vulkan
780 ///
781 /// This is a native only feature.
782 #[name("wgpu-shader-f64", "shader-f64")]
783 const SHADER_F64 = 1 << 33;
784 /// Allows shaders to use `i16` and `u16` 16-bit integer types.
785 ///
786 /// Requires `enable wgpu_int16;` in WGSL shaders.
787 ///
788 /// Supported platforms:
789 /// - Vulkan (with `shaderInt16` and `VK_KHR_16bit_storage`)
790 /// - Metal (always available)
791 /// - DX12 (with `Native16BitShaderOpsSupported`, SM 6.2+)
792 ///
793 /// This is a native only feature.
794 #[name("wgpu-shader-i16", "shader-i16")]
795 const SHADER_I16 = 1 << 34;
796
797 // Bit 35 is available.
798
799 /// Allows shaders to use the `early_depth_test` attribute.
800 ///
801 /// The attribute is applied to the fragment shader entry point. It can be used in two
802 /// ways:
803 ///
804 /// 1. Force early depth/stencil tests:
805 ///
806 /// - `@early_depth_test(force)` (WGSL)
807 ///
808 /// - `layout(early_fragment_tests) in;` (GLSL)
809 ///
810 /// 2. Provide a conservative depth specifier that allows an additional early
811 /// depth test under certain conditions:
812 ///
813 /// - `@early_depth_test(greater_equal/less_equal/unchanged)` (WGSL)
814 ///
815 /// - `layout(depth_<greater/less/unchanged>) out float gl_FragDepth;` (GLSL)
816 ///
817 /// See [`EarlyDepthTest`] for more details.
818 ///
819 /// Supported platforms:
820 /// - Vulkan
821 /// - GLES 3.1+
822 ///
823 /// This is a native only feature.
824 ///
825 /// [`EarlyDepthTest`]: https://docs.rs/naga/latest/naga/ir/enum.EarlyDepthTest.html
826 #[name("wgpu-shader-early-depth-test", "shader-early-depth-test")]
827 const SHADER_EARLY_DEPTH_TEST = 1 << 36;
828 /// Allows shaders to use i64 and u64.
829 ///
830 /// Supported platforms:
831 /// - Vulkan
832 /// - DX12 (DXC only)
833 /// - Metal (with MSL 2.3+)
834 ///
835 /// This is a native only feature.
836 #[name("wgpu-shader-int64")]
837 const SHADER_INT64 = 1 << 37;
838 /// Allows compute and fragment shaders to use the subgroup operation
839 /// built-ins and perform subgroup operations (except barriers).
840 ///
841 /// Supported Platforms:
842 /// - Vulkan
843 /// - DX12
844 /// - Metal
845 /// - WebGPU
846 ///
847 /// The `subgroups` feature has been added to WebGPU, but there may be
848 /// differences between the standard and the `wgpu` implementation,
849 /// so it has not yet been moved to [`FeaturesWebGPU`].
850 /// See <https://github.com/gfx-rs/wgpu/issues/5555>.
851 ///
852 /// Because it is expected to move to the WebGPU feature set in the
853 /// not-too-distant future, the name omits the `wgpu-` prefix.
854 #[name("subgroups")]
855 const SUBGROUP = 1 << 38;
856 /// Allows vertex shaders to use the subgroup operation built-ins and
857 /// perform subgroup operations (except barriers).
858 ///
859 /// Supported Platforms:
860 /// - Vulkan
861 ///
862 /// This is a native only feature.
863 #[name("wgpu-subgroup-vertex")]
864 const SUBGROUP_VERTEX = 1 << 39;
865 /// Allows compute shaders to use the subgroup barrier.
866 ///
867 /// Requires [`Features::SUBGROUP`]. Without it, enables nothing.
868 ///
869 /// Supported Platforms:
870 /// - Vulkan
871 /// - Metal
872 ///
873 /// This is a native only feature.
874 #[name("wgpu-subgroup-barrier")]
875 const SUBGROUP_BARRIER = 1 << 40;
876 /// Allows the use of pipeline cache objects
877 ///
878 /// Supported platforms:
879 /// - Vulkan
880 ///
881 /// Unimplemented Platforms:
882 /// - DX12
883 /// - Metal
884 #[name("wgpu-pipeline-cache")]
885 const PIPELINE_CACHE = 1 << 41;
886 /// Allows shaders to use i64 and u64 atomic min and max.
887 ///
888 /// Supported platforms:
889 /// - Vulkan (with VK_KHR_shader_atomic_int64)
890 /// - DX12 (with SM 6.6+)
891 /// - Metal (with MSL 2.4+)
892 ///
893 /// This is a native only feature.
894 #[name("wgpu-shader-int64-atomic-min-max")]
895 const SHADER_INT64_ATOMIC_MIN_MAX = 1 << 42;
896 /// Allows shaders to use all i64 and u64 atomic operations.
897 ///
898 /// Supported platforms:
899 /// - Vulkan (with VK_KHR_shader_atomic_int64)
900 /// - DX12 (with SM 6.6+)
901 ///
902 /// This is a native only feature.
903 #[name("wgpu-shader-int64-atomic-all-ops")]
904 const SHADER_INT64_ATOMIC_ALL_OPS = 1 << 43;
905
906 // Bit 44 is available.
907
908 // Bit 45 is available.
909
910 /// Enables R64Uint image atomic min and max.
911 ///
912 /// Supported platforms:
913 /// - Vulkan (with VK_EXT_shader_image_atomic_int64)
914 /// - DX12 (with SM 6.6+)
915 /// - Metal (with MSL 3.1+)
916 ///
917 /// This is a native only feature.
918 #[name("wgpu-texture-int64-atomic")]
919 const TEXTURE_INT64_ATOMIC = 1 << 46;
920
921 /// Allows uniform buffers to be bound as binding arrays.
922 ///
923 /// This allows:
924 /// - Shaders to contain `var<uniform> buffer: binding_array<UniformBuffer>;`
925 /// - The `count` field of `BindGroupLayoutEntry`s with `Uniform` buffers, to be set to `Some`.
926 ///
927 /// Supported platforms:
928 /// - None (<https://github.com/gfx-rs/wgpu/issues/7149>)
929 ///
930 /// Potential Platforms:
931 /// - DX12
932 /// - Metal
933 /// - Vulkan 1.2+ (or VK_EXT_descriptor_indexing)'s `shaderUniformBufferArrayNonUniformIndexing` feature)
934 ///
935 /// This is a native only feature.
936 #[name("wgpu-uniform-buffer-binding-arrays", "uniform-buffer-binding-arrays")]
937 const UNIFORM_BUFFER_BINDING_ARRAYS = 1 << 47;
938
939 /// Enables mesh shaders and task shaders in mesh shader pipelines. This extension does NOT imply support for
940 /// compiling mesh shaders at runtime.
941 ///
942 /// Supported platforms:
943 /// - Vulkan (with [VK_EXT_mesh_shader](https://registry.khronos.org/vulkan/specs/latest/man/html/VK_EXT_mesh_shader.html))
944 /// - DX12
945 /// - Metal
946 ///
947 /// Naga is only supported on vulkan. On other platforms you will have to use passthrough shaders.
948 ///
949 /// It is recommended to use [`Device::create_shader_module_trusted`] with [`ShaderRuntimeChecks::unchecked()`]
950 /// to avoid workgroup memory zero initialization, which can be expensive due to zero initialization being
951 /// single-threaded currently.
952 ///
953 /// Some Mesa drivers including LLVMPIPE but not RADV fail to run the naga generated code.
954 /// [This may be our bug and will be investigated.](https://github.com/gfx-rs/wgpu/issues/8727)
955 /// However, due to the nature of the failure, the fact that it is unique, and the random changes
956 /// that make it go away, this is believed to be a Mesa bug. See
957 /// [this Mesa issue.](https://gitlab.freedesktop.org/mesa/mesa/-/issues/14376)
958 ///
959 /// This is a native only feature.
960 ///
961 /// [`Device::create_shader_module_trusted`]: https://docs.rs/wgpu/latest/wgpu/struct.Device.html#method.create_shader_module_trusted
962 /// [`ShaderRuntimeChecks::unchecked()`]: crate::ShaderRuntimeChecks::unchecked
963 #[name("wgpu-mesh-shader")]
964 const EXPERIMENTAL_MESH_SHADER = 1 << 48;
965
966 /// ***THIS IS EXPERIMENTAL:*** Features enabled by this may have
967 /// major bugs in them and are expected to be subject to breaking changes, suggestions
968 /// for the API exposed by this should be posted on [the ray-tracing issue](https://github.com/gfx-rs/wgpu/issues/6762)
969 ///
970 /// Allows for returning of the hit triangle's vertex position when tracing with an
971 /// acceleration structure marked with [`AccelerationStructureFlags::ALLOW_RAY_HIT_VERTEX_RETURN`].
972 ///
973 /// Supported platforms:
974 /// - Vulkan
975 ///
976 /// This is a native only feature
977 ///
978 /// [`AccelerationStructureFlags::ALLOW_RAY_HIT_VERTEX_RETURN`]: super::AccelerationStructureFlags::ALLOW_RAY_HIT_VERTEX_RETURN
979 #[name("wgpu-ray-hit-vertex-return")]
980 const EXPERIMENTAL_RAY_HIT_VERTEX_RETURN = 1 << 49;
981
982 /// Enables multiview in mesh shader pipelines
983 ///
984 /// Supported platforms:
985 /// - Vulkan (with [VK_EXT_mesh_shader](https://registry.khronos.org/vulkan/specs/latest/man/html/VK_EXT_mesh_shader.html))
986 ///
987 /// Potential Platforms:
988 /// - DX12
989 /// - Metal
990 ///
991 /// This is a native only feature.
992 #[name("wgpu-mesh-shader-multiview")]
993 const EXPERIMENTAL_MESH_SHADER_MULTIVIEW = 1 << 50;
994
995 /// Allows usage of additional vertex formats in [BlasTriangleGeometrySizeDescriptor::vertex_format]
996 ///
997 /// Supported platforms
998 /// - Vulkan
999 /// - DX12
1000 ///
1001 /// [BlasTriangleGeometrySizeDescriptor::vertex_format]: super::BlasTriangleGeometrySizeDescriptor
1002 #[name("wgpu-extended-acceleration-structure-vertex-formats")]
1003 const EXTENDED_ACCELERATION_STRUCTURE_VERTEX_FORMATS = 1 << 51;
1004
1005 /// Enables creating shaders from passthrough with reflection info (unsafe)
1006 ///
1007 /// Allows using [`Device::create_shader_module_passthrough`].
1008 /// Shader code isn't parsed or interpreted in any way. It is the user's
1009 /// responsibility to ensure the code and reflection (if passed) are correct.
1010 ///
1011 /// Supported platforms
1012 /// - Vulkan
1013 /// - DX12
1014 /// - Metal
1015 /// - WebGPU
1016 ///
1017 /// Ideally, in the future, all platforms will be supported. For more info, see
1018 /// [this comment](https://github.com/gfx-rs/wgpu/issues/3103#issuecomment-2833058367).
1019 ///
1020 #[doc = link_to_wgpu_docs!(["`Device::create_shader_module_passthrough`"]: "struct.Device.html#method.create_shader_module_passthrough")]
1021 #[name("wgpu-passthrough-shaders", "passthrough-shaders")]
1022 const PASSTHROUGH_SHADERS = 1 << 52;
1023
1024 /// Enables shader barycentric coordinates.
1025 ///
1026 /// Supported platforms:
1027 /// - Vulkan (with VK_KHR_fragment_shader_barycentric)
1028 /// - DX12 (with SM 6.1+)
1029 /// - Metal (with MSL 2.2+)
1030 ///
1031 /// This is a native only feature.
1032 #[name("wgpu-shader-barycentrics")]
1033 const SHADER_BARYCENTRICS = 1 << 53;
1034
1035 /// Enables using multiview where not all texture array layers are rendered to in a single render pass/render pipeline. Making
1036 /// use of this feature also requires enabling `Features::MULTIVIEW`.
1037 ///
1038 /// Supported platforms
1039 /// - Vulkan
1040 /// - DX12
1041 ///
1042 ///
1043 /// While metal supports this in theory, the behavior of `view_index` differs from vulkan and dx12 so the feature isn't exposed.
1044 #[name("wgpu-selective-multiview")]
1045 const SELECTIVE_MULTIVIEW = 1 << 54;
1046
1047 /// Enables the use of point-primitive outputs from mesh shaders. Making use of this feature also requires enabling
1048 /// `Features::EXPERIMENTAL_MESH_SHADER`.
1049 ///
1050 /// Supported platforms
1051 /// - Vulkan
1052 /// - Metal
1053 ///
1054 /// This is a native only feature.
1055 #[name("wgpu-mesh-shader-points")]
1056 const EXPERIMENTAL_MESH_SHADER_POINTS = 1 << 55;
1057
1058 /// Enables creating texture arrays that are also multisampled.
1059 ///
1060 /// Without this feature, you cannot create a texture that has both a `sample_count` higher
1061 /// than 1, and a `depth_or_array_layers` higher than 1.
1062 ///
1063 /// Supported platforms:
1064 /// - Vulkan (except VK_KHR_portability_subset if multisampleArrayImage is not available)
1065 /// - Metal (with macos 10.14+, ios 14.0+, tvos 16.0+, visionos 1.0+)
1066 #[name("wgpu-multisample-array")]
1067 const MULTISAMPLE_ARRAY = 1 << 56;
1068
1069 /// Enables cooperative matrix operations (also known as tensor cores on NVIDIA GPUs
1070 /// or simdgroup matrix operations on Apple GPUs).
1071 ///
1072 /// Cooperative matrices allow a workgroup to collectively load, store, and perform
1073 /// matrix multiply-accumulate operations on small tiles of data, enabling
1074 /// hardware-accelerated matrix math.
1075 ///
1076 /// **Current limitations:** The implementation currently only supports 8x8 f32 matrices.
1077 /// On Vulkan, support is determined by querying `vkGetPhysicalDeviceCooperativeMatrixPropertiesKHR`
1078 /// for configurations matching 8x8x8 f32. Most Vulkan implementations (NVIDIA, AMD) primarily
1079 /// support f16 inputs at larger sizes (e.g., 16x16), so Vulkan support may be limited.
1080 ///
1081 /// Supported platforms:
1082 /// - Metal (with MSL 2.3+ and Apple7+/Mac2+, using simdgroup matrix operations)
1083 /// - Vulkan (with [VK_KHR_cooperative_matrix](https://registry.khronos.org/vulkan/specs/latest/man/html/VK_KHR_cooperative_matrix.html), if 8x8 f32 is supported)
1084 ///
1085 /// This is a native only feature.
1086 #[name("wgpu-cooperative-matrix")]
1087 const EXPERIMENTAL_COOPERATIVE_MATRIX = 1 << 57;
1088
1089 /// Enables shader per-vertex attributes.
1090 ///
1091 /// Supported platforms:
1092 /// - Vulkan (with VK_KHR_fragment_shader_barycentric)
1093 ///
1094 /// This is a native only feature.
1095 #[name("wgpu-shader-per-vertex")]
1096 const SHADER_PER_VERTEX = 1 << 58;
1097
1098 /// Enables shader `draw_index` builtin.
1099 ///
1100 /// Supported platforms:
1101 /// - GLES
1102 /// - Vulkan
1103 ///
1104 /// Potential platforms:
1105 /// - DX12
1106 /// - Metal
1107 ///
1108 /// This is a native only feature.
1109 #[name("wgpu-shader-draw-index")]
1110 const SHADER_DRAW_INDEX = 1 << 59;
1111 /// Allows the user to create arrays of acceleration structures in shaders:
1112 ///
1113 /// ex.
1114 /// - `var tlas: binding_array<acceleration_structure, 10>` (WGSL)
1115 ///
1116 /// This capability allows them to exist and to be indexed by dynamically uniform values.
1117 ///
1118 /// Supported platforms:
1119 /// - DX12
1120 /// - Vulkan
1121 ///
1122 /// This is a native only feature.
1123 #[name("wgpu-acceleration-structure-binding-array")]
1124 const ACCELERATION_STRUCTURE_BINDING_ARRAY = 1 << 60;
1125
1126 /// Enables the `@coherent` memory decoration on storage buffer variables.
1127 ///
1128 /// Backend mapping:
1129 /// - Vulkan
1130 /// - DX12
1131 /// - Metal (3.2+)
1132 /// - GLES (ES 3.1+ / GL 4.3+)
1133 ///
1134 /// This is a native only feature.
1135 #[name("wgpu-memory-decoration-coherent")]
1136 const MEMORY_DECORATION_COHERENT = 1 << 61;
1137
1138 /// Enables the `@volatile` memory decoration on storage buffer variables.
1139 ///
1140 /// Backend mapping:
1141 /// - Vulkan
1142 /// - GLES (ES 3.1+ / GL 4.3+)
1143 ///
1144 /// This is a native only feature.
1145 #[name("wgpu-memory-decoration-volatile")]
1146 const MEMORY_DECORATION_VOLATILE = 1 << 62;
1147
1148 // Bit 63 is available.
1149
1150 // Search for "is available" to check for free bits earlier in the list.
1151 }
1152
1153 /// Features that are not guaranteed to be supported.
1154 ///
1155 /// These are part of the WebGPU standard. For all features, see [`Features`].
1156 ///
1157 /// If you want to use a feature, you need to first verify that the adapter supports
1158 /// the feature. If the adapter does not support the feature, requesting a device with it enabled
1159 /// will panic.
1160 ///
1161 /// Corresponds to [WebGPU `GPUFeatureName`](
1162 /// https://gpuweb.github.io/gpuweb/#enumdef-gpufeaturename).
1163 #[repr(transparent)]
1164 #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1165 #[cfg_attr(feature = "serde", serde(transparent))]
1166 #[derive(Default, Debug, Copy, Clone, PartialEq, Eq, Hash)]
1167 pub struct FeaturesWebGPU features_webgpu {
1168 // API:
1169
1170 /// By default, polygon depth is clipped to 0-1 range before/during rasterization.
1171 /// Anything outside of that range is rejected, and respective fragments are not touched.
1172 ///
1173 /// With this extension, we can disabling clipping. That allows
1174 /// shadow map occluders to be rendered into a tighter depth range.
1175 ///
1176 /// Supported platforms:
1177 /// - desktops
1178 /// - some mobile chips
1179 /// - WebGPU
1180 ///
1181 /// This is a web and native feature.
1182 #[name("depth-clip-control")]
1183 #[web(allow)]
1184 const DEPTH_CLIP_CONTROL = WEBGPU_FEATURE_DEPTH_CLIP_CONTROL;
1185
1186 /// Allows for explicit creation of textures of format [`TextureFormat::Depth32FloatStencil8`]
1187 ///
1188 /// Supported platforms:
1189 /// - Vulkan (mostly)
1190 /// - DX12
1191 /// - Metal
1192 /// - OpenGL
1193 /// - WebGPU
1194 ///
1195 /// This is a web and native feature.
1196 ///
1197 /// [`TextureFormat::Depth32FloatStencil8`]: super::TextureFormat::Depth32FloatStencil8
1198 #[name("depth32float-stencil8")]
1199 #[web(allow)]
1200 const DEPTH32FLOAT_STENCIL8 = WEBGPU_FEATURE_DEPTH32FLOAT_STENCIL8;
1201
1202 /// Enables BCn family of compressed textures. All BCn textures use 4x4 pixel blocks
1203 /// with 8 or 16 bytes per block.
1204 ///
1205 /// Compressed textures sacrifice some quality in exchange for significantly reduced
1206 /// bandwidth usage.
1207 ///
1208 /// Support for this feature guarantees availability of [`TextureUsages::COPY_SRC | TextureUsages::COPY_DST | TextureUsages::TEXTURE_BINDING`] for BCn formats.
1209 /// [`Features::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES`] may enable additional usages.
1210 ///
1211 /// This feature guarantees availability of sliced-3d textures for BC formats when combined with TEXTURE_COMPRESSION_BC_SLICED_3D.
1212 ///
1213 /// Supported Platforms:
1214 /// - desktops
1215 /// - Mobile (All Apple9 and some Apple7 and Apple8 devices)
1216 /// - WebGPU
1217 ///
1218 /// This is a web and native feature.
1219 #[name("texture-compression-bc")]
1220 #[web(allow)]
1221 const TEXTURE_COMPRESSION_BC = WEBGPU_FEATURE_TEXTURE_COMPRESSION_BC;
1222
1223
1224 /// Allows the 3d dimension for textures with BC compressed formats.
1225 ///
1226 /// This feature must be used in combination with TEXTURE_COMPRESSION_BC to enable 3D textures with BC compression.
1227 /// It does not enable the BC formats by itself.
1228 ///
1229 /// Supported Platforms:
1230 /// - desktops
1231 /// - Mobile (All Apple9 and some Apple7 and Apple8 devices)
1232 /// - WebGPU
1233 ///
1234 /// This is a web and native feature.
1235 #[name("texture-compression-bc-sliced-3d")]
1236 #[web(allow)]
1237 const TEXTURE_COMPRESSION_BC_SLICED_3D = WEBGPU_FEATURE_TEXTURE_COMPRESSION_BC_SLICED_3D;
1238
1239 /// Enables ETC family of compressed textures. All ETC textures use 4x4 pixel blocks.
1240 /// ETC2 RGB and RGBA1 are 8 bytes per block. RTC2 RGBA8 and EAC are 16 bytes per block.
1241 ///
1242 /// Compressed textures sacrifice some quality in exchange for significantly reduced
1243 /// bandwidth usage.
1244 ///
1245 /// Support for this feature guarantees availability of [`TextureUsages::COPY_SRC | TextureUsages::COPY_DST | TextureUsages::TEXTURE_BINDING`] for ETC2 formats.
1246 /// [`Features::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES`] may enable additional usages.
1247 ///
1248 /// Supported Platforms:
1249 /// - Vulkan on Intel
1250 /// - Mobile (some)
1251 /// - WebGPU
1252 ///
1253 /// This is a web and native feature.
1254 #[name("texture-compression-etc2")]
1255 #[web(allow)]
1256 const TEXTURE_COMPRESSION_ETC2 = WEBGPU_FEATURE_TEXTURE_COMPRESSION_ETC2;
1257
1258 /// Enables ASTC family of compressed textures. ASTC textures use pixel blocks varying from 4x4 to 12x12.
1259 /// Blocks are always 16 bytes.
1260 ///
1261 /// Compressed textures sacrifice some quality in exchange for significantly reduced
1262 /// bandwidth usage.
1263 ///
1264 /// Support for this feature guarantees availability of [`TextureUsages::COPY_SRC | TextureUsages::COPY_DST | TextureUsages::TEXTURE_BINDING`] for ASTC formats with Unorm/UnormSrgb channel type.
1265 /// [`Features::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES`] may enable additional usages.
1266 ///
1267 /// This feature does not guarantee availability of sliced 3d textures for ASTC formats.
1268 /// If available, 3d support can be enabled by TEXTURE_COMPRESSION_ASTC_SLICED_3D feature.
1269 ///
1270 /// Supported Platforms:
1271 /// - Vulkan on Intel
1272 /// - Mobile (some)
1273 /// - WebGPU
1274 ///
1275 /// This is a web and native feature.
1276 #[name("texture-compression-astc")]
1277 #[web(allow)]
1278 const TEXTURE_COMPRESSION_ASTC = WEBGPU_FEATURE_TEXTURE_COMPRESSION_ASTC;
1279
1280
1281 /// Allows the 3d dimension for textures with ASTC compressed formats.
1282 ///
1283 /// This feature must be used in combination with TEXTURE_COMPRESSION_ASTC to enable 3D textures with ASTC compression.
1284 /// It does not enable the ASTC formats by itself.
1285 ///
1286 /// Supported Platforms:
1287 /// - Vulkan (some)
1288 /// - Metal on Apple3+
1289 /// - OpenGL/WebGL (some)
1290 /// - WebGPU
1291 ///
1292 /// Not Supported:
1293 /// - DX12
1294 ///
1295 /// This is a web and native feature.
1296 #[name("texture-compression-astc-sliced-3d")]
1297 #[web(allow)]
1298 const TEXTURE_COMPRESSION_ASTC_SLICED_3D = WEBGPU_FEATURE_TEXTURE_COMPRESSION_ASTC_SLICED_3D;
1299
1300 /// Enables use of Timestamp Queries. These queries tell the current gpu timestamp when
1301 /// all work before the query is finished.
1302 ///
1303 /// This feature allows the use of
1304 /// - [`RenderPassDescriptor::timestamp_writes`]
1305 /// - [`ComputePassDescriptor::timestamp_writes`]
1306 /// to write out timestamps.
1307 ///
1308 /// For arbitrary timestamp write commands on encoders refer to [`Features::TIMESTAMP_QUERY_INSIDE_ENCODERS`].
1309 /// For arbitrary timestamp write commands on passes refer to [`Features::TIMESTAMP_QUERY_INSIDE_PASSES`].
1310 ///
1311 /// They must be resolved using [`CommandEncoder::resolve_query_set`] into a buffer,
1312 /// then the result must be multiplied by the timestamp period [`Queue::get_timestamp_period`]
1313 /// to get the timestamp in nanoseconds. Multiple timestamps can then be diffed to get the
1314 /// time for operations between them to finish.
1315 ///
1316 /// Supported Platforms:
1317 /// - Vulkan
1318 /// - DX12
1319 /// - Metal
1320 /// - OpenGL (with GL_ARB_timer_query)
1321 /// - WebGPU
1322 ///
1323 /// This is a web and native feature.
1324 ///
1325 #[doc = link_to_wgpu_docs!(["`RenderPassDescriptor::timestamp_writes`"]: "struct.RenderPassDescriptor.html#structfield.timestamp_writes")]
1326 #[doc = link_to_wgpu_docs!(["`ComputePassDescriptor::timestamp_writes`"]: "struct.ComputePassDescriptor.html#structfield.timestamp_writes")]
1327 #[doc = link_to_wgpu_docs!(["`CommandEncoder::resolve_query_set`"]: "struct.CommandEncoder.html#method.resolve_query_set")]
1328 #[doc = link_to_wgpu_docs!(["`Queue::get_timestamp_period`"]: "struct.Queue.html#method.get_timestamp_period")]
1329 #[name("timestamp-query")]
1330 #[web(allow)]
1331 const TIMESTAMP_QUERY = WEBGPU_FEATURE_TIMESTAMP_QUERY;
1332
1333 /// Allows non-zero value for the `first_instance` member in indirect draw calls.
1334 ///
1335 /// If this feature is not enabled, and the `first_instance` member is non-zero, the behavior may be:
1336 /// - The draw call is ignored.
1337 /// - The draw call is executed as if the `first_instance` is zero.
1338 /// - The draw call is executed with the correct `first_instance` value.
1339 ///
1340 /// Supported Platforms:
1341 /// - Vulkan (mostly)
1342 /// - DX12
1343 /// - Metal on Apple3+ or Mac1+
1344 /// - OpenGL (Desktop 4.2+ with ARB_shader_draw_parameters only)
1345 /// - WebGPU
1346 ///
1347 /// Not Supported:
1348 /// - OpenGL ES / WebGL
1349 ///
1350 /// This is a web and native feature.
1351 #[name("indirect-first-instance")]
1352 #[web(allow)]
1353 const INDIRECT_FIRST_INSTANCE = WEBGPU_FEATURE_INDIRECT_FIRST_INSTANCE;
1354
1355 /// Allows shaders to use 16-bit floating point types. You may use them uniform buffers,
1356 /// storage buffers, and local variables. You may not use them in immediates.
1357 ///
1358 /// In order to use this in WGSL shaders, you must add `enable f16;` to the top of your shader,
1359 /// before any global items.
1360 ///
1361 /// Supported Platforms:
1362 /// - Vulkan
1363 /// - Metal
1364 /// - DX12
1365 /// - WebGPU
1366 ///
1367 /// This is a web and native feature.
1368 #[name("shader-f16")]
1369 #[web(allow)]
1370 const SHADER_F16 = WEBGPU_FEATURE_SHADER_F16;
1371
1372 /// Allows for usage of textures of format [`TextureFormat::Rg11b10Ufloat`] as a render target
1373 ///
1374 /// Supported platforms:
1375 /// - Vulkan
1376 /// - DX12
1377 /// - Metal
1378 /// - WebGPU
1379 ///
1380 /// This is a web and native feature.
1381 ///
1382 /// [`TextureFormat::Rg11b10Ufloat`]: super::TextureFormat::Rg11b10Ufloat
1383 #[name("rg11b10ufloat-renderable")]
1384 #[web(allow)]
1385 const RG11B10UFLOAT_RENDERABLE = WEBGPU_FEATURE_RG11B10UFLOAT_RENDERABLE;
1386
1387 /// Allows the [`TextureUsages::STORAGE_BINDING`] usage on textures with format [`TextureFormat::Bgra8Unorm`]
1388 ///
1389 /// Supported Platforms:
1390 /// - Vulkan
1391 /// - DX12
1392 /// - Metal
1393 /// - WebGPU
1394 ///
1395 /// This is a web and native feature.
1396 ///
1397 /// [`TextureFormat::Bgra8Unorm`]: super::TextureFormat::Bgra8Unorm
1398 /// [`TextureUsages::STORAGE_BINDING`]: super::TextureUsages::STORAGE_BINDING
1399 #[name("bgra8unorm-storage")]
1400 #[web(allow)]
1401 const BGRA8UNORM_STORAGE = WEBGPU_FEATURE_BGRA8UNORM_STORAGE;
1402
1403
1404 /// Allows textures with formats "r32float", "rg32float", and "rgba32float" to be filterable.
1405 ///
1406 /// Supported Platforms:
1407 /// - Vulkan (mainly on Desktop GPUs)
1408 /// - DX12
1409 /// - Metal on macOS or Apple9+ GPUs, optional on iOS/iPadOS with Apple7/8 GPUs
1410 /// - GL with one of `GL_ARB_color_buffer_float`/`GL_EXT_color_buffer_float`/`OES_texture_float_linear`
1411 /// - WebGPU
1412 ///
1413 /// This is a web and native feature.
1414 #[name("float32-filterable")]
1415 #[web(allow)]
1416 const FLOAT32_FILTERABLE = WEBGPU_FEATURE_FLOAT32_FILTERABLE;
1417
1418 /// Allows textures with formats "r32float", "rg32float", and "rgba32float" to be blendable.
1419 ///
1420 /// Supported Platforms:
1421 /// - Vulkan
1422 /// - WebGPU
1423 #[name("float32-blendable")]
1424 #[web(allow)]
1425 const FLOAT32_BLENDABLE = WEBGPU_FEATURE_FLOAT32_BLENDABLE;
1426
1427 /// Allows two outputs from a shader to be used for blending.
1428 /// Note that dual-source blending doesn't support multiple render targets.
1429 ///
1430 /// For more info see the OpenGL ES extension GL_EXT_blend_func_extended.
1431 ///
1432 /// Supported platforms:
1433 /// - OpenGL ES (with GL_EXT_blend_func_extended)
1434 /// - Metal (with MSL 1.2+)
1435 /// - Vulkan (with dualSrcBlend)
1436 /// - DX12
1437 /// - WebGPU
1438 ///
1439 /// This is a web and native feature.
1440 #[name("dual-source-blending")]
1441 #[web(allow)]
1442 const DUAL_SOURCE_BLENDING = WEBGPU_FEATURE_DUAL_SOURCE_BLENDING;
1443
1444 /// Allows the use of `@builtin(clip_distances)` in WGSL.
1445 ///
1446 /// Supported platforms:
1447 /// - Vulkan (mainly on Desktop GPUs)
1448 /// - Metal
1449 /// - GL (Desktop or `GL_EXT_clip_cull_distance`)
1450 /// - WebGPU
1451 ///
1452 /// This is a web and native feature.
1453 #[name("clip-distances")]
1454 #[web(allow)]
1455 const CLIP_DISTANCES = WEBGPU_FEATURE_CLIP_DISTANCES;
1456
1457 /// Allows the use of immediate data: small, fast bits of memory that can be updated
1458 /// inside a [`RenderPass`].
1459 ///
1460 /// Allows the user to call [`RenderPass::set_immediates`], provide a non-zero immediate data size
1461 /// to [`PipelineLayoutDescriptor`], and provide a non-zero limit to [`Limits::max_immediate_size`].
1462 ///
1463 /// A block of immediate data can be declared in WGSL with `var<immediate>`:
1464 ///
1465 /// ```rust,ignore
1466 /// struct Immediates { example: f32, }
1467 /// var<immediate> c: Immediates;
1468 /// ```
1469 ///
1470 /// In GLSL, this corresponds to `layout(immediates) uniform Name {..}`.
1471 ///
1472 /// Supported platforms:
1473 /// - DX12
1474 /// - Vulkan
1475 /// - Metal
1476 /// - OpenGL (emulated with uniforms)
1477 /// - WebGPU
1478 ///
1479 /// WebGPU support is currently a proposal and will be available in browsers in the future.
1480 ///
1481 /// This is a web and native feature.
1482 ///
1483 #[doc = link_to_wgpu_item!(struct RenderPass)]
1484 #[doc = link_to_wgpu_item!(struct PipelineLayoutDescriptor)]
1485 #[doc = link_to_wgpu_docs!(["`RenderPass::set_immediates`"]: "struct.RenderPass.html#method.set_immediates")]
1486 /// [`Limits::max_immediate_size`]: super::Limits
1487 #[name("immediates")]
1488 #[web(allow)]
1489 const IMMEDIATES = WEBGPU_FEATURE_IMMEDIATES;
1490
1491 /// Enables `builtin(primitive_index)` in fragment shaders.
1492 ///
1493 /// Note: enables geometry processing for pipelines using the builtin.
1494 /// This may come with a significant performance impact on some hardware.
1495 /// Other pipelines are not affected.
1496 ///
1497 /// Supported platforms:
1498 /// - Vulkan (with geometryShader)
1499 /// - DX12
1500 /// - Metal (some)
1501 /// - OpenGL (some)
1502 ///
1503 /// This is a web and native feature. `primitive-index` is its
1504 /// WebGPU-defined name, and `shader-primitive-index` is accepted to
1505 /// remain compatible with previous wgpu behavior.
1506 #[name("primitive-index", "shader-primitive-index")]
1507 #[web(allow)]
1508 const PRIMITIVE_INDEX = WEBGPU_FEATURE_PRIMITIVE_INDEX;
1509
1510 /// Allows `TextureView`s to rearrange or replace the color components
1511 /// from texture's red/green/blue/alpha channels when used as a `TEXTURE_BINDING`.
1512 ///
1513 /// Supported platforms:
1514 /// - Vulkan
1515 /// - DX12
1516 /// - Metal on Apple2+ or Mac2+
1517 ///
1518 /// Not yet implemented:
1519 /// - OpenGL
1520 ///
1521 /// This is a web and native feature.
1522 #[name("texture-component-swizzle")]
1523 #[web(allow)]
1524 const TEXTURE_COMPONENT_SWIZZLE = WEBGPU_FEATURE_TEXTURE_COMPONENT_SWIZZLE;
1525 }
1526}
1527
1528impl Features {
1529 /// Construct a [`Features`] from separate [`FeaturesWGPU`] and [`FeaturesWebGPU`].
1530 ///
1531 /// This `const` constructor is also available as a `From` impl.
1532 pub const fn from_parts(wgpu: FeaturesWGPU, webgpu: FeaturesWebGPU) -> Self {
1533 Self::from_bits_retain(FeatureBits([wgpu.bits(), webgpu.bits()]))
1534 }
1535
1536 /// Mask of all features which are part of the upstream WebGPU standard.
1537 #[must_use]
1538 pub const fn all_webgpu_mask() -> Self {
1539 Self::from_parts(FeaturesWGPU::empty(), FeaturesWebGPU::all())
1540 }
1541
1542 /// Mask of all features that are only available when targeting native (not web).
1543 #[must_use]
1544 pub const fn all_native_mask() -> Self {
1545 Self::from_parts(FeaturesWGPU::all(), FeaturesWebGPU::empty())
1546 }
1547
1548 /// Mask of all features which are experimental.
1549 #[must_use]
1550 pub const fn all_experimental_mask() -> Self {
1551 Self::from_parts(
1552 FeaturesWGPU::from_bits_truncate(
1553 FeaturesWGPU::EXPERIMENTAL_MESH_SHADER.bits()
1554 | FeaturesWGPU::EXPERIMENTAL_MESH_SHADER_MULTIVIEW.bits()
1555 | FeaturesWGPU::EXPERIMENTAL_MESH_SHADER_POINTS.bits()
1556 | FeaturesWGPU::EXPERIMENTAL_RAY_QUERY.bits()
1557 | FeaturesWGPU::EXPERIMENTAL_RAY_HIT_VERTEX_RETURN.bits()
1558 | FeaturesWGPU::EXPERIMENTAL_COOPERATIVE_MATRIX.bits()
1559 | FeaturesWGPU::EXPERIMENTAL_RAY_TRACING_PIPELINES.bits(),
1560 ),
1561 FeaturesWebGPU::empty(),
1562 )
1563 }
1564
1565 /// Vertex formats allowed for creating and building BLASes
1566 #[must_use]
1567 pub fn allowed_vertex_formats_for_blas(&self) -> Vec<VertexFormat> {
1568 let mut formats = Vec::new();
1569 if self.intersects(Self::EXPERIMENTAL_RAY_QUERY | Self::EXPERIMENTAL_RAY_TRACING_PIPELINES)
1570 {
1571 formats.push(VertexFormat::Float32x3);
1572 }
1573 if self.contains(Self::EXTENDED_ACCELERATION_STRUCTURE_VERTEX_FORMATS) {
1574 formats.push(VertexFormat::Float32x2);
1575 formats.push(VertexFormat::Float16x2);
1576 formats.push(VertexFormat::Float16x4);
1577 formats.push(VertexFormat::Snorm16x2);
1578 formats.push(VertexFormat::Snorm16x4);
1579 }
1580 formats
1581 }
1582}
1583
1584#[cfg(test)]
1585mod tests {
1586 use crate::{Features, FeaturesWGPU, FeaturesWebGPU};
1587 use bitflags::{Flag, Flags};
1588
1589 #[cfg(feature = "serde")]
1590 #[test]
1591 fn check_hex() {
1592 use crate::FeatureBits;
1593
1594 use bitflags::{
1595 parser::{ParseHex as _, WriteHex as _},
1596 Bits as _,
1597 };
1598
1599 let mut hex = alloc::string::String::new();
1600 FeatureBits::ALL.write_hex(&mut hex).unwrap();
1601 assert_eq!(
1602 FeatureBits::parse_hex(hex.as_str()).unwrap(),
1603 FeatureBits::ALL
1604 );
1605
1606 hex.clear();
1607 FeatureBits::EMPTY.write_hex(&mut hex).unwrap();
1608 assert_eq!(
1609 FeatureBits::parse_hex(hex.as_str()).unwrap(),
1610 FeatureBits::EMPTY
1611 );
1612
1613 for feature in Features::FLAGS {
1614 hex.clear();
1615 feature.value().bits().write_hex(&mut hex).unwrap();
1616 assert_eq!(
1617 FeatureBits::parse_hex(hex.as_str()).unwrap(),
1618 feature.value().bits(),
1619 "{hex}"
1620 );
1621 }
1622 }
1623
1624 #[test]
1625 fn allowed_on_web_backend() {
1626 // Every WebGPU feature is currently allowed on the web backend,
1627 // as well as `subgroups`.
1628 assert_eq!(
1629 Features::ALLOWED_ON_WEB_BACKEND,
1630 Features::from_parts(FeaturesWGPU::SUBGROUP, FeaturesWebGPU::all()),
1631 );
1632 }
1633
1634 #[test]
1635 fn check_features_display() {
1636 use alloc::format;
1637
1638 let feature = Features::CLEAR_TEXTURE;
1639 assert_eq!(format!("{feature}"), "CLEAR_TEXTURE");
1640
1641 let feature = Features::CLEAR_TEXTURE | Features::BGRA8UNORM_STORAGE;
1642 assert_eq!(format!("{feature}"), "CLEAR_TEXTURE | BGRA8UNORM_STORAGE");
1643 }
1644
1645 #[test]
1646 fn check_features_bits() {
1647 let bits = Features::all().bits();
1648 assert_eq!(Features::from_bits_retain(bits), Features::all());
1649
1650 let bits = Features::empty().bits();
1651 assert_eq!(Features::from_bits_retain(bits), Features::empty());
1652
1653 for feature in Features::FLAGS {
1654 let bits = feature.value().bits();
1655 assert_eq!(Features::from_bits_retain(bits), *feature.value());
1656 }
1657
1658 let bits = FeaturesWebGPU::all().bits();
1659 assert_eq!(
1660 FeaturesWebGPU::from_bits_truncate(bits),
1661 FeaturesWebGPU::all()
1662 );
1663
1664 let bits = FeaturesWebGPU::empty().bits();
1665 assert_eq!(
1666 FeaturesWebGPU::from_bits_truncate(bits),
1667 FeaturesWebGPU::empty()
1668 );
1669
1670 for feature in FeaturesWebGPU::FLAGS {
1671 let bits = feature.value().bits();
1672 assert_eq!(FeaturesWebGPU::from_bits_truncate(bits), *feature.value());
1673 }
1674
1675 let bits = FeaturesWGPU::all().bits();
1676 assert_eq!(FeaturesWGPU::from_bits(bits).unwrap(), FeaturesWGPU::all());
1677
1678 let bits = FeaturesWGPU::empty().bits();
1679 assert_eq!(
1680 FeaturesWGPU::from_bits(bits).unwrap(),
1681 FeaturesWGPU::empty()
1682 );
1683
1684 for feature in FeaturesWGPU::FLAGS {
1685 let bits = feature.value().bits();
1686 assert_eq!(FeaturesWGPU::from_bits(bits).unwrap(), *feature.value());
1687 }
1688 }
1689
1690 #[test]
1691 fn features_names() {
1692 for feature in Features::FLAGS.iter().map(Flag::value).copied() {
1693 let Some(name) = feature.as_str() else {
1694 panic!("`.as_str()` for {feature:?} returned `None`");
1695 };
1696 assert_eq!(name.parse(), Ok(feature));
1697
1698 // Native-only features that are accepted without `wgpu-` prefix for backwards compatibility
1699 let prefix_backcompat_features = [
1700 Features::TEXTURE_FORMAT_16BIT_NORM,
1701 Features::TEXTURE_COMPRESSION_ASTC_HDR,
1702 Features::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES,
1703 Features::PIPELINE_STATISTICS_QUERY,
1704 Features::TIMESTAMP_QUERY_INSIDE_PASSES,
1705 Features::MAPPABLE_PRIMARY_BUFFERS,
1706 Features::TEXTURE_BINDING_ARRAY,
1707 Features::BUFFER_BINDING_ARRAY,
1708 Features::STORAGE_RESOURCE_BINDING_ARRAY,
1709 Features::SAMPLED_TEXTURE_AND_STORAGE_BUFFER_ARRAY_NON_UNIFORM_INDEXING,
1710 Features::STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING,
1711 Features::UNIFORM_BUFFER_BINDING_ARRAYS,
1712 Features::PARTIALLY_BOUND_BINDING_ARRAY,
1713 Features::MULTI_DRAW_INDIRECT_COUNT,
1714 Features::ADDRESS_MODE_CLAMP_TO_ZERO,
1715 Features::ADDRESS_MODE_CLAMP_TO_BORDER,
1716 Features::POLYGON_MODE_LINE,
1717 Features::POLYGON_MODE_POINT,
1718 Features::CONSERVATIVE_RASTERIZATION,
1719 Features::VERTEX_WRITABLE_STORAGE,
1720 Features::CLEAR_TEXTURE,
1721 Features::MULTIVIEW,
1722 Features::VERTEX_ATTRIBUTE_64BIT,
1723 Features::EXTERNAL_TEXTURE,
1724 Features::SHADER_F64,
1725 Features::SHADER_I16,
1726 Features::SHADER_EARLY_DEPTH_TEST,
1727 Features::PASSTHROUGH_SHADERS,
1728 ];
1729
1730 if feature == Features::SUBGROUP {
1731 // Standard-track feature that does not have `wgpu-` prefix
1732 assert_eq!(name.parse(), Ok(feature));
1733 } else if feature & Features::all_native_mask() != Features::empty() {
1734 let stripped_name = name.strip_prefix("wgpu-").unwrap_or_else(|| {
1735 panic!("Native feature `{name}` should have `wgpu-` prefix")
1736 });
1737 let expected = if prefix_backcompat_features.contains(&feature) {
1738 Ok(feature)
1739 } else {
1740 Err(())
1741 };
1742 assert_eq!(stripped_name.parse(), expected);
1743 }
1744
1745 // Special backcompat case
1746 if feature == Features::PRIMITIVE_INDEX {
1747 assert_eq!("shader-primitive-index".parse(), Ok(feature));
1748 }
1749 }
1750 }
1751
1752 #[test]
1753 fn create_features_from_parts() {
1754 let features: Features = FeaturesWGPU::TEXTURE_ATOMIC.into();
1755 assert_eq!(features, Features::TEXTURE_ATOMIC);
1756
1757 let features: Features = FeaturesWebGPU::TIMESTAMP_QUERY.into();
1758 assert_eq!(features, Features::TIMESTAMP_QUERY);
1759
1760 let features: Features = Features::from(FeaturesWGPU::TEXTURE_ATOMIC)
1761 | Features::from(FeaturesWebGPU::TIMESTAMP_QUERY);
1762 assert_eq!(
1763 features,
1764 Features::TEXTURE_ATOMIC | Features::TIMESTAMP_QUERY
1765 );
1766 assert_eq!(
1767 features,
1768 Features::from_internal_flags(
1769 FeaturesWGPU::TEXTURE_ATOMIC,
1770 FeaturesWebGPU::TIMESTAMP_QUERY
1771 )
1772 );
1773 }
1774
1775 #[test]
1776 fn experimental_features_part_of_experimental_mask() {
1777 for (name, feature) in Features::all().iter_names() {
1778 let prefixed_with_experimental = name.starts_with("EXPERIMENTAL_");
1779 let in_experimental_mask = Features::all_experimental_mask().contains(feature);
1780 assert_eq!(in_experimental_mask, prefixed_with_experimental);
1781 }
1782 }
1783}