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